diff --git a/.golangci.yml b/.golangci.yml index 15c67928a..73e25a38d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -6,3 +6,4 @@ linters: enable: - gofmt - goimports + - unused diff --git a/components/fctl/cmd/ledger/accounts/list.go b/components/fctl/cmd/ledger/accounts/list.go index 5c548e9f0..997673c7f 100644 --- a/components/fctl/cmd/ledger/accounts/list.go +++ b/components/fctl/cmd/ledger/accounts/list.go @@ -3,7 +3,7 @@ package accounts import ( "fmt" - internal "github.com/formancehq/fctl/cmd/ledger/internal" + "github.com/formancehq/fctl/cmd/ledger/internal" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" @@ -74,9 +74,20 @@ func (c *ListController) Run(cmd *cobra.Command, args []string) (fctl.Renderable return nil, err } + body := make([]map[string]map[string]any, 0) + for key, value := range metadata { + body = append(body, map[string]map[string]any{ + "$match": { + "metadata[" + key + "]": value, + }, + }) + } + request := operations.ListAccountsRequest{ - Ledger: fctl.GetString(cmd, internal.LedgerFlag), - Metadata: metadata, + Ledger: fctl.GetString(cmd, internal.LedgerFlag), + RequestBody: map[string]interface{}{ + "$and": body, + }, } rsp, err := ledgerClient.Ledger.ListAccounts(cmd.Context(), request) if err != nil { diff --git a/components/fctl/cmd/ledger/balances.go b/components/fctl/cmd/ledger/balances.go deleted file mode 100644 index 0bcccef1a..000000000 --- a/components/fctl/cmd/ledger/balances.go +++ /dev/null @@ -1,113 +0,0 @@ -package ledger - -import ( - "fmt" - - "github.com/formancehq/fctl/cmd/ledger/internal" - fctl "github.com/formancehq/fctl/pkg" - "github.com/formancehq/formance-sdk-go/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/pkg/models/shared" - "github.com/pterm/pterm" - "github.com/spf13/cobra" -) - -type BalancesStore struct { - Balances shared.BalancesCursorResponseCursor `json:"balances"` -} -type BalancesController struct { - store *BalancesStore - addressFlag string -} - -var _ fctl.Controller[*BalancesStore] = (*BalancesController)(nil) - -func NewDefaultBalancesStore() *BalancesStore { - return &BalancesStore{} -} - -func NewBalancesController() *BalancesController { - return &BalancesController{ - store: NewDefaultBalancesStore(), - addressFlag: "address", - } -} - -func NewBalancesCommand() *cobra.Command { - c := NewBalancesController() - return fctl.NewCommand("balances", - fctl.WithAliases("balance", "bal", "b"), - fctl.WithStringFlag(c.addressFlag, "", "Filter on specific address"), - fctl.WithShortDescription("Read balances"), - fctl.WithArgs(cobra.ExactArgs(0)), - fctl.WithController[*BalancesStore](c), - ) -} - -func (c *BalancesController) GetStore() *BalancesStore { - return c.store -} - -func (c *BalancesController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) { - cfg, err := fctl.GetConfig(cmd) - if err != nil { - return nil, err - } - - organizationID, err := fctl.ResolveOrganizationID(cmd, cfg) - if err != nil { - return nil, err - } - - stack, err := fctl.ResolveStack(cmd, cfg, organizationID) - if err != nil { - return nil, err - } - - client, err := fctl.NewStackClient(cmd, cfg, stack) - if err != nil { - return nil, err - } - - response, err := client.Ledger.GetBalances( - cmd.Context(), - operations.GetBalancesRequest{ - Address: fctl.Ptr(fctl.GetString(cmd, c.addressFlag)), - Ledger: fctl.GetString(cmd, internal.LedgerFlag), - }, - ) - if err != nil { - return nil, err - } - - if response.ErrorResponse != nil { - return nil, fmt.Errorf("%s: %s", response.ErrorResponse.ErrorCode, response.ErrorResponse.ErrorMessage) - } - - if response.StatusCode >= 300 { - return nil, fmt.Errorf("unexpected status code: %d", response.StatusCode) - } - - c.store.Balances = response.BalancesCursorResponse.Cursor - - return c, nil -} - -func (c *BalancesController) Render(cmd *cobra.Command, args []string) error { - tableData := pterm.TableData{} - tableData = append(tableData, []string{"Account", "Asset", "Balance"}) - for _, accountBalances := range c.store.Balances.Data { - for account, volumes := range accountBalances { - for asset, balance := range volumes { - tableData = append(tableData, []string{ - account, asset, fmt.Sprint(balance), - }) - } - } - } - - return pterm.DefaultTable. - WithHasHeader(true). - WithWriter(cmd.OutOrStdout()). - WithData(tableData). - Render() -} diff --git a/components/fctl/cmd/ledger/internal/list.go b/components/fctl/cmd/ledger/internal/list.go index 3c7fd8616..79d3e7fa6 100644 --- a/components/fctl/cmd/ledger/internal/list.go +++ b/components/fctl/cmd/ledger/internal/list.go @@ -15,11 +15,11 @@ import ( // Copy from SDK type TransactionsCursorResponseCursor struct { - Data []ExpandedTransaction `json:"data"` - HasMore bool `json:"hasMore"` - Next *string `json:"next,omitempty"` - PageSize int64 `json:"pageSize"` - Previous *string `json:"previous,omitempty"` + Data []shared.ExpandedTransaction `json:"data"` + HasMore bool `json:"hasMore"` + Next *string `json:"next,omitempty"` + PageSize int64 `json:"pageSize"` + Previous *string `json:"previous,omitempty"` } // Copy from SDK diff --git a/components/fctl/cmd/ledger/internal/print.go b/components/fctl/cmd/ledger/internal/print.go index f5a7348a9..61a1042d0 100644 --- a/components/fctl/cmd/ledger/internal/print.go +++ b/components/fctl/cmd/ledger/internal/print.go @@ -16,7 +16,7 @@ func printCommonInformation( out io.Writer, txID int64, reference string, - postings []*shared.Posting, + postings []shared.Posting, timestamp time.Time, ) error { fctl.Section.WithWriter(out).Println("Information") @@ -53,11 +53,11 @@ func printCommonInformation( return nil } -func PrintExpandedTransaction(out io.Writer, transaction ExpandedTransaction) error { +func PrintExpandedTransaction(out io.Writer, transaction shared.ExpandedTransaction) error { if err := printCommonInformation( out, - transaction.Txid, + transaction.ID, *transaction.Reference, transaction.Postings, transaction.Timestamp, @@ -96,11 +96,11 @@ func PrintExpandedTransaction(out io.Writer, transaction ExpandedTransaction) er return nil } -func PrintTransaction(out io.Writer, transaction Transaction) error { +func PrintTransaction(out io.Writer, transaction shared.Transaction) error { if err := printCommonInformation( out, - transaction.Txid, + transaction.ID, *transaction.Reference, transaction.Postings, transaction.Timestamp, @@ -113,7 +113,7 @@ func PrintTransaction(out io.Writer, transaction Transaction) error { } return nil } -func PrintMetadata(out io.Writer, metadata Metadata) error { +func PrintMetadata(out io.Writer, metadata map[string]string) error { fctl.Section.WithWriter(out).Println("Metadata") if len(metadata) == 0 { fmt.Println("No metadata.") diff --git a/components/fctl/cmd/ledger/internal/revert.go b/components/fctl/cmd/ledger/internal/revert.go index df699f441..07c43bc1d 100644 --- a/components/fctl/cmd/ledger/internal/revert.go +++ b/components/fctl/cmd/ledger/internal/revert.go @@ -14,7 +14,7 @@ import ( ) type RevertTransactionResponseData struct { - Data Transaction `json:"data"` + Data shared.Transaction `json:"data"` } type RevertTransactionResponse struct { ContentType string @@ -31,7 +31,7 @@ func RevertTransaction(client *formance.Formance, ctx context.Context, baseURL s field := reflect.ValueOf(client).Elem().FieldByName("_securityClient") httpClient := reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface().(formance.HTTPClient) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions/{txid}/revert", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions/{id}/revert", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } diff --git a/components/fctl/cmd/ledger/internal/show.go b/components/fctl/cmd/ledger/internal/show.go index 1e96d50c2..c0bfd1984 100644 --- a/components/fctl/cmd/ledger/internal/show.go +++ b/components/fctl/cmd/ledger/internal/show.go @@ -15,7 +15,7 @@ import ( // GetTransactionResponse - OK type GetTransactionResponseData struct { - Data ExpandedTransaction `json:"data"` + Data shared.ExpandedTransaction `json:"data"` } type GetTransactionResponse struct { @@ -34,7 +34,7 @@ func GetTransaction(client *formance.Formance, ctx context.Context, baseURL stri field := reflect.ValueOf(client).Elem().FieldByName("_securityClient") httpClient := reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface().(formance.HTTPClient) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions/{txid}", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions/{id}", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } diff --git a/components/fctl/cmd/ledger/internal/transaction.go b/components/fctl/cmd/ledger/internal/transaction.go index a76cbbe42..ea05697fb 100644 --- a/components/fctl/cmd/ledger/internal/transaction.go +++ b/components/fctl/cmd/ledger/internal/transaction.go @@ -4,57 +4,13 @@ import ( "context" "errors" "fmt" - "net/http" - "reflect" "strconv" "strings" - "time" - "unsafe" "github.com/formancehq/formance-sdk-go" "github.com/formancehq/formance-sdk-go/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/pkg/models/shared" - "github.com/formancehq/formance-sdk-go/pkg/utils" - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "golang.org/x/mod/semver" ) -// Copy from SDK, + fix int64 to big.Int -type Transaction struct { - Metadata map[string]interface{} `json:"metadata"` - Postings []*shared.Posting `json:"postings"` - Reference *string `json:"reference,omitempty"` - Timestamp time.Time `json:"timestamp"` - Txid int64 `json:"txid"` -} - -// Copy from SDK, + change metadata type to map[string]interface{} -// The is 2 types of metadata, one is map[string]interface{}, another is map[string]string -type ExpandedTransaction struct { - Metadata map[string]interface{} `json:"metadata"` - PostCommitVolumes map[string]map[string]*shared.Volume `json:"postCommitVolumes"` - Postings []*shared.Posting `json:"postings"` - PreCommitVolumes map[string]map[string]*shared.Volume `json:"preCommitVolumes"` - Reference *string `json:"reference,omitempty"` - Timestamp time.Time `json:"timestamp"` - Txid int64 `json:"txid"` -} - -// CreateTransactionResponse - OK -type CreateTransactionResponse struct { - Data []Transaction `json:"data"` -} - -type CreateTransactionWrapper struct { - ContentType string - // OK - CreateTransactionResponse *CreateTransactionResponse - // Error - ErrorResponse *shared.ErrorResponse - StatusCode int - RawResponse *http.Response -} - func TransactionIDOrLastN(ctx context.Context, ledgerClient *formance.Formance, ledger, id string) (int64, error) { if strings.HasPrefix(id, "last") { id = strings.TrimPrefix(id, "last") @@ -87,149 +43,8 @@ func TransactionIDOrLastN(ctx context.Context, ledgerClient *formance.Formance, if len(response.TransactionsCursorResponse.Cursor.Data) == 0 { return 0, errors.New("no transaction found") } - return response.TransactionsCursorResponse.Cursor.Data[0].Txid + sub, nil + return response.TransactionsCursorResponse.Cursor.Data[0].ID + sub, nil } return strconv.ParseInt(id, 10, 64) } - -// CreateTransaction - Create a new transaction to a ledger -func createTransactionV1(ctx context.Context, client *formance.Formance, baseURL string, request operations.CreateTransactionRequest) (*CreateTransactionWrapper, error) { - - // Dirty hack to get the http client from the sdk client struct - field := reflect.ValueOf(client).Elem().FieldByName("_securityClient") - httpClient := reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface().(formance.HTTPClient) - - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "PostTransaction", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "POST", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json;q=1, application/json;q=0") - req.Header.Set("Content-Type", reqContentType) - - utils.PopulateHeaders(ctx, req, request) - - if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { - return nil, fmt.Errorf("error populating query params: %w", err) - } - - httpRes, err := httpClient.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - defer httpRes.Body.Close() - - contentType := httpRes.Header.Get("Content-Type") - - res := &CreateTransactionWrapper{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *CreateTransactionResponse - if err := utils.UnmarshalJsonFromResponseBody(httpRes.Body, &out); err != nil { - return nil, err - } - - res.CreateTransactionResponse = out - } - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.ErrorResponse - if err := utils.UnmarshalJsonFromResponseBody(httpRes.Body, &out); err != nil { - return nil, err - } - - res.ErrorResponse = out - } - } - - return res, nil -} - -func CreateTransaction(client *formance.Formance, ctx context.Context, request operations.CreateTransactionRequest) (*Transaction, error) { - - versionsResponse, err := client.GetVersions(ctx) - if err != nil { - return nil, err - } - if versionsResponse.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unexpected status code %d when getting versions", versionsResponse.StatusCode) - } - - version := collectionutils.Filter(versionsResponse.GetVersionsResponse.Versions, func(version shared.Version) bool { - return version.Name == "ledger" - })[0].Version - - if semver.IsValid(version) && semver.Compare(version, "v2.0.0") < 0 { - baseURL := strings.TrimSuffix(versionsResponse.RawResponse.Request.URL.String(), "/versions") - - v, err := createTransactionV1(ctx, client, baseURL, request) - if err != nil { - return nil, err - } - - if v.ErrorResponse != nil { - return nil, fmt.Errorf("%s: %s", v.ErrorResponse.ErrorCode, v.ErrorResponse.ErrorMessage) - } - - if v.StatusCode >= 300 { - return nil, fmt.Errorf("unexpected status code: %d", v.StatusCode) - } - - return &v.CreateTransactionResponse.Data[0], nil - } else { - response, err := client.Ledger.CreateTransaction(ctx, request) - if err != nil { - return nil, err - } - - if response.ErrorResponse != nil { - return nil, fmt.Errorf("%s: %s", response.ErrorResponse.ErrorCode, response.ErrorResponse.ErrorMessage) - } - - if response.StatusCode >= 300 { - return nil, fmt.Errorf("unexpected status code %d when creating transaction", response.StatusCode) - } - - st := &response.CreateTransactionResponse.Data - - metadata := make(map[string]interface{}) - if st.Metadata != nil { - for k, v := range st.Metadata { - metadata[k] = v - } - } - - t := &Transaction{ - Txid: st.Txid, - Postings: make([]*shared.Posting, len(st.Postings)), - Reference: st.Reference, - Timestamp: st.Timestamp, - Metadata: metadata, - } - - return t, nil - } -} diff --git a/components/fctl/cmd/ledger/root.go b/components/fctl/cmd/ledger/root.go index 3cbe11fdf..fd76f6816 100644 --- a/components/fctl/cmd/ledger/root.go +++ b/components/fctl/cmd/ledger/root.go @@ -14,7 +14,6 @@ func NewCommand() *cobra.Command { fctl.WithPersistentStringFlag(internal.LedgerFlag, "default", "Specific ledger"), fctl.WithShortDescription("Ledger management"), fctl.WithChildCommands( - NewBalancesCommand(), NewSendCommand(), NewStatsCommand(), NewServerInfoCommand(), diff --git a/components/fctl/cmd/ledger/send.go b/components/fctl/cmd/ledger/send.go index 58e08c3e4..5cacb1426 100644 --- a/components/fctl/cmd/ledger/send.go +++ b/components/fctl/cmd/ledger/send.go @@ -12,7 +12,7 @@ import ( ) type SendStore struct { - Transaction *internal.Transaction `json:"transaction"` + Transaction *shared.Transaction `json:"transaction"` } type SendController struct { store *SendStore @@ -102,7 +102,7 @@ func (c *SendController) Run(cmd *cobra.Command, args []string) (fctl.Renderable reference := fctl.GetString(cmd, c.referenceFlag) - tx, err := internal.CreateTransaction(ledgerClient, cmd.Context(), operations.CreateTransactionRequest{ + response, err := ledgerClient.Ledger.CreateTransaction(cmd.Context(), operations.CreateTransactionRequest{ PostTransaction: shared.PostTransaction{ Metadata: metadata, Postings: []shared.Posting{ @@ -120,7 +120,16 @@ func (c *SendController) Run(cmd *cobra.Command, args []string) (fctl.Renderable if err != nil { return nil, err } - c.store.Transaction = tx + + if response.ErrorResponse != nil { + return nil, fmt.Errorf("%s: %s", response.ErrorResponse.ErrorCode, response.ErrorResponse.ErrorMessage) + } + + if response.StatusCode >= 300 { + return nil, fmt.Errorf("unexpected status code %d when creating transaction", response.StatusCode) + } + + c.store.Transaction = &response.CreateTransactionResponse.Data return c, nil } diff --git a/components/fctl/cmd/ledger/transactions/list.go b/components/fctl/cmd/ledger/transactions/list.go index 388118fe0..f92db6a4f 100644 --- a/components/fctl/cmd/ledger/transactions/list.go +++ b/components/fctl/cmd/ledger/transactions/list.go @@ -96,36 +96,54 @@ func (c *ListController) Run(cmd *cobra.Command, args []string) (fctl.Renderable return nil, err } - var ( - endTime time.Time - startTime time.Time - ) - if startTimeStr := fctl.GetString(cmd, c.startTimeFlag); startTimeStr != "" { - startTime, err = time.Parse(time.RFC3339Nano, startTimeStr) - if err != nil { - return nil, err - } + options := make([]map[string]map[string]any, 0) + if account := fctl.GetString(cmd, c.accountFlag); account != "" { + options = append(options, map[string]map[string]any{ + "$match": {"account": account}, + }) } - if endTimeStr := fctl.GetString(cmd, c.endTimeFlag); endTimeStr != "" { - endTime, err = time.Parse(time.RFC3339Nano, endTimeStr) - if err != nil { - return nil, err - } + if source := fctl.GetString(cmd, c.sourceFlag); source != "" { + options = append(options, map[string]map[string]any{ + "$match": {"source": source}, + }) + } + if destination := fctl.GetString(cmd, c.destinationFlag); destination != "" { + options = append(options, map[string]map[string]any{ + "$match": {"destination": destination}, + }) + } + if reference := fctl.GetString(cmd, c.referenceFlag); reference != "" { + options = append(options, map[string]map[string]any{ + "$match": {"reference": reference}, + }) + } + if startTime := fctl.GetString(cmd, c.startTimeFlag); startTime != "" { + options = append(options, map[string]map[string]any{ + "$gte": {"date": startTime}, + }) + } + if endTime := fctl.GetString(cmd, c.endTimeFlag); endTime != "" { + options = append(options, map[string]map[string]any{ + "$lt": {"date": endTime}, + }) + } + for key, value := range metadata { + options = append(options, map[string]map[string]any{ + "$match": { + "metadata[" + key + "]": value, + }, + }) } ledger := fctl.GetString(cmd, internal.LedgerFlag) response, err := ledgerClient.Ledger.ListTransactions( cmd.Context(), operations.ListTransactionsRequest{ - Account: fctl.Ptr(fctl.GetString(cmd, c.accountFlag)), - Destination: fctl.Ptr(fctl.GetString(cmd, c.destinationFlag)), - EndTime: &endTime, - Ledger: ledger, - Metadata: metadata, - PageSize: fctl.Ptr(int64(fctl.GetInt(cmd, c.pageSizeFlag))), - Reference: fctl.Ptr(fctl.GetString(cmd, c.referenceFlag)), - Source: fctl.Ptr(fctl.GetString(cmd, c.sourceFlag)), - StartTime: &startTime, + RequestBody: map[string]interface{}{ + "$and": options, + }, + Ledger: ledger, + PageSize: fctl.Ptr(int64(fctl.GetInt(cmd, c.pageSizeFlag))), }, ) if err != nil { @@ -153,7 +171,7 @@ func (c *ListController) Render(cmd *cobra.Command, args []string) error { tableData := fctl.Map(c.store.Transaction.Data, func(tx shared.ExpandedTransaction) []string { return []string{ - fmt.Sprintf("%d", tx.Txid), + fmt.Sprintf("%d", tx.ID), func() string { if tx.Reference == nil { return "" diff --git a/components/fctl/cmd/ledger/transactions/num.go b/components/fctl/cmd/ledger/transactions/num.go index ec479204c..50d6389b9 100644 --- a/components/fctl/cmd/ledger/transactions/num.go +++ b/components/fctl/cmd/ledger/transactions/num.go @@ -6,7 +6,7 @@ import ( "strings" "time" - internal "github.com/formancehq/fctl/cmd/ledger/internal" + "github.com/formancehq/fctl/cmd/ledger/internal" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" @@ -14,7 +14,7 @@ import ( ) type NumStore struct { - Transaction *internal.Transaction `json:"transaction"` + Transaction *shared.Transaction `json:"transaction"` } type NumController struct { store *NumStore @@ -154,7 +154,7 @@ func (c *NumController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, ledger := fctl.GetString(cmd, internal.LedgerFlag) - tx, err := internal.CreateTransaction(client, cmd.Context(), operations.CreateTransactionRequest{ + response, err := client.Ledger.CreateTransaction(cmd.Context(), operations.CreateTransactionRequest{ PostTransaction: shared.PostTransaction{ Metadata: metadata, Reference: &reference, @@ -175,7 +175,15 @@ func (c *NumController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, return nil, err } - c.store.Transaction = tx + if response.ErrorResponse != nil { + return nil, fmt.Errorf("%s: %s", response.ErrorResponse.ErrorCode, response.ErrorResponse.ErrorMessage) + } + + if response.StatusCode >= 300 { + return nil, fmt.Errorf("unexpected status code %d when creating transaction", response.StatusCode) + } + + c.store.Transaction = &response.CreateTransactionResponse.Data return c, nil } diff --git a/components/fctl/cmd/ledger/transactions/revert.go b/components/fctl/cmd/ledger/transactions/revert.go index 378af08ab..089bd83d0 100644 --- a/components/fctl/cmd/ledger/transactions/revert.go +++ b/components/fctl/cmd/ledger/transactions/revert.go @@ -6,11 +6,12 @@ import ( "github.com/formancehq/fctl/cmd/ledger/internal" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/spf13/cobra" ) type RevertStore struct { - Transaction *internal.Transaction `json:"transaction"` + Transaction *shared.Transaction `json:"transaction"` } type RevertController struct { store *RevertStore @@ -75,7 +76,7 @@ func (c *RevertController) Run(cmd *cobra.Command, args []string) (fctl.Renderab request := operations.RevertTransactionRequest{ Ledger: ledger, - Txid: txId, + ID: txId, } profile := fctl.GetCurrentProfile(cmd, cfg) diff --git a/components/fctl/cmd/ledger/transactions/set_metadata.go b/components/fctl/cmd/ledger/transactions/set_metadata.go index cd07fef27..aa40fa0fe 100644 --- a/components/fctl/cmd/ledger/transactions/set_metadata.go +++ b/components/fctl/cmd/ledger/transactions/set_metadata.go @@ -83,7 +83,7 @@ func (c *SetMetadataController) Run(cmd *cobra.Command, args []string) (fctl.Ren request := operations.AddMetadataOnTransactionRequest{ Ledger: fctl.GetString(cmd, internal.LedgerFlag), - Txid: transactionID, + ID: transactionID, RequestBody: metadata, } response, err := ledgerClient.Ledger.AddMetadataOnTransaction(cmd.Context(), request) diff --git a/components/fctl/cmd/ledger/transactions/show.go b/components/fctl/cmd/ledger/transactions/show.go index d8369c60f..c57c8a7ed 100644 --- a/components/fctl/cmd/ledger/transactions/show.go +++ b/components/fctl/cmd/ledger/transactions/show.go @@ -6,11 +6,12 @@ import ( "github.com/formancehq/fctl/cmd/ledger/internal" fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/spf13/cobra" ) type ShowStore struct { - Transaction internal.ExpandedTransaction `json:"transaction"` + Transaction shared.ExpandedTransaction `json:"transaction"` } type ShowController struct { store *ShowStore @@ -78,7 +79,7 @@ func (c *ShowController) Run(cmd *cobra.Command, args []string) (fctl.Renderable baseUrl, operations.GetTransactionRequest{ Ledger: ledger, - Txid: txId, + ID: txId, }, ) if err != nil { diff --git a/components/fctl/cmd/orchestration/instances/describe.go b/components/fctl/cmd/orchestration/instances/describe.go index dc99cd3ca..13934d2b1 100644 --- a/components/fctl/cmd/orchestration/instances/describe.go +++ b/components/fctl/cmd/orchestration/instances/describe.go @@ -221,7 +221,7 @@ func printStage(cmd *cobra.Command, i int, client *formance.Formance, id string, *historyStage.Input.CreateTransaction.Ledger, )) if historyStage.Error == nil && historyStage.LastFailure == nil && historyStage.Terminated { - listItems = append(listItems, historyItemDetails("Created transaction: %d", historyStage.Output.CreateTransaction.Data.Txid)) + listItems = append(listItems, historyItemDetails("Created transaction: %d", historyStage.Output.CreateTransaction.Data.ID)) if historyStage.Input.CreateTransaction.Data.Reference != nil { listItems = append(listItems, historyItemDetails("Reference: %s", *historyStage.Output.CreateTransaction.Data.Reference)) } @@ -275,7 +275,7 @@ func printStage(cmd *cobra.Command, i int, client *formance.Formance, id string, case historyStage.Input.RevertTransaction != nil: listItems = append(listItems, historyItemTitle("Revert transaction %s", historyStage.Input.RevertTransaction.ID)) if historyStage.Error == nil { - listItems = append(listItems, historyItemTitle("Created transaction: %d", historyStage.Output.RevertTransaction.Data.Txid)) + listItems = append(listItems, historyItemTitle("Created transaction: %d", historyStage.Output.RevertTransaction.Data.ID)) } case historyStage.Input.VoidHold != nil: listItems = append(listItems, historyItemTitle("Cancel debit hold %s", historyStage.Input.VoidHold.ID)) diff --git a/components/fctl/cmd/payments/connectors/getconfig.go b/components/fctl/cmd/payments/connectors/getconfig.go index f21708cec..a145142cc 100644 --- a/components/fctl/cmd/payments/connectors/getconfig.go +++ b/components/fctl/cmd/payments/connectors/getconfig.go @@ -1,7 +1,6 @@ package connectors import ( - "errors" "fmt" "github.com/formancehq/fctl/cmd/payments/connectors/internal" @@ -113,43 +112,3 @@ func (c *PaymentsGetConfigController) Render(cmd *cobra.Command, args []string) return err } - -func displayMangoPayConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { - config, ok := connectorConfig.Data.(*shared.MangoPayConfig) - if !ok { - return errors.New("invalid currency cloud connector config") - } - - tableData := pterm.TableData{} - tableData = append(tableData, []string{pterm.LightCyan("API key:"), config.APIKey}) - tableData = append(tableData, []string{pterm.LightCyan("Client ID:"), config.ClientID}) - tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), config.Endpoint}) - - if err := pterm.DefaultTable. - WithWriter(cmd.OutOrStdout()). - WithData(tableData). - Render(); err != nil { - return err - } - return nil -} - -func displayMoneycorpConfig(cmd *cobra.Command, connectorConfig *shared.ConnectorConfigResponse) error { - config, ok := connectorConfig.Data.(*shared.MoneycorpConfig) - if !ok { - return errors.New("invalid currency cloud connector config") - } - - tableData := pterm.TableData{} - tableData = append(tableData, []string{pterm.LightCyan("API key:"), config.APIKey}) - tableData = append(tableData, []string{pterm.LightCyan("Client ID:"), config.ClientID}) - tableData = append(tableData, []string{pterm.LightCyan("Endpoint:"), config.Endpoint}) - - if err := pterm.DefaultTable. - WithWriter(cmd.OutOrStdout()). - WithData(tableData). - Render(); err != nil { - return err - } - return nil -} diff --git a/components/fctl/cmd/search/views/transactions.go b/components/fctl/cmd/search/views/transactions.go index 404379e4f..e01d05c51 100644 --- a/components/fctl/cmd/search/views/transactions.go +++ b/components/fctl/cmd/search/views/transactions.go @@ -13,7 +13,7 @@ func DisplayTransactions(out io.Writer, txs []map[string]interface{}) error { for _, tx := range txs { tableData = append(tableData, []string{ tx["ledger"].(string), - fmt.Sprint(tx["txid"].(float64)), + fmt.Sprint(tx["id"].(float64)), tx["reference"].(string), tx["timestamp"].(string), }) diff --git a/components/fctl/cmd/wallets/transactions/list.go b/components/fctl/cmd/wallets/transactions/list.go index 890508136..599e5c2c6 100644 --- a/components/fctl/cmd/wallets/transactions/list.go +++ b/components/fctl/cmd/wallets/transactions/list.go @@ -101,7 +101,7 @@ func (c *ListController) Render(cmd *cobra.Command, args []string) error { tableData := fctl.Map(c.store.Transactions, func(tx shared.WalletsTransaction) []string { return []string{ - fmt.Sprintf("%d", tx.Txid), + fmt.Sprintf("%d", tx.ID), tx.Timestamp.Format(time.RFC3339), fctl.MetadataAsShortString(tx.Metadata), } diff --git a/components/fctl/go.mod b/components/fctl/go.mod index ff0db60c9..5adbf45f6 100644 --- a/components/fctl/go.mod +++ b/components/fctl/go.mod @@ -18,7 +18,6 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/spf13/cobra v1.6.1 github.com/zitadel/oidc/v2 v2.6.4 - golang.org/x/mod v0.10.0 golang.org/x/oauth2 v0.9.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/components/fctl/go.sum b/components/fctl/go.sum index e02c9fac8..97df9dfa6 100644 --- a/components/fctl/go.sum +++ b/components/fctl/go.sum @@ -160,8 +160,6 @@ golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= diff --git a/components/fctl/membershipclient/go.sum b/components/fctl/membershipclient/go.sum index 734252e68..3dee6d681 100644 --- a/components/fctl/membershipclient/go.sum +++ b/components/fctl/membershipclient/go.sum @@ -1,13 +1,360 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/components/ledger/.dockerignore b/components/ledger/.dockerignore index 478c25bf6..25a704494 100644 --- a/components/ledger/.dockerignore +++ b/components/ledger/.dockerignore @@ -1,3 +1,14 @@ vendor sdk .git +.devbox +.direnv +.github +.moon +sdks +config +docs +nix +openapi +tests +worktrees diff --git a/components/ledger/Dockerfile b/components/ledger/Dockerfile index d05f18586..36facf7fb 100644 --- a/components/ledger/Dockerfile +++ b/components/ledger/Dockerfile @@ -1,31 +1,25 @@ -FROM --platform=$BUILDPLATFORM golang:1.20 AS builder -RUN apt-get update && \ - apt-get install -y gcc-aarch64-linux-gnu gcc-x86-64-linux-gnu && \ - ln -s /usr/bin/aarch64-linux-gnu-gcc /usr/bin/arm64-linux-gnu-gcc && \ - ln -s /usr/bin/x86_64-linux-gnu-gcc /usr/bin/amd64-linux-gnu-gcc -# 1. Precompile the entire go standard library into the first Docker cache layer: useful for other projects too! -RUN CGO_ENABLED=1 GOOS=linux go install -v -installsuffix cgo -a std -ARG TARGETARCH -ARG APP_SHA -ARG VERSION +FROM golang:1.20-alpine3.16 AS builder ARG SEGMENT_WRITE_KEY +ARG VERSION +ARG APP_SHA + WORKDIR /src -COPY . . -WORKDIR /src/components/ledger +COPY libs libs +COPY components/ledger components/ledger +WORKDIR components/ledger RUN --mount=type=cache,mode=0755,target=/go/pkg/mod go mod download RUN --mount=type=cache,id=gomod,target=/go/pkg/mod \ --mount=type=cache,id=gobuild,target=/root/.cache/go-build \ - CGO_ENABLED=1 GOOS=linux GOARCH=$TARGETARCH \ - CC=$TARGETARCH-linux-gnu-gcc \ - go build -o ledger -tags json1,netgo \ - -ldflags="-X github.com/ledger/ledger/cmd.Version=${VERSION} \ - -X github.com/ledger/ledger/cmd.BuildDate=$(date +%s) \ - -X github.com/ledger/ledger/cmd.Commit=${APP_SHA} \ - -X github.com/ledger/ledger/cmd.DefaultSegmentWriteKey=${SEGMENT_WRITE_KEY}" ./ + go build -o ledger \ + -ldflags="-X github.com/formancehq/ledger/cmd.Version=${VERSION} \ + -X github.com/formancehq/ledger/cmd.BuildDate=$(date +%s) \ + -X github.com/formancehq/ledger/cmd.Commit=${APP_SHA} \ + -X github.com/formancehq/ledger/cmd.DefaultSegmentWriteKey=${SEGMENT_WRITE_KEY}" ./ -FROM ubuntu:22.04 as app -RUN apt update && apt install -y ca-certificates wget && rm -rf /var/lib/apt/lists/* +FROM alpine:3.16 as app +RUN apk update && apk add ca-certificates COPY --from=builder /src/components/ledger/ledger /usr/local/bin/ledger +RUN chmod +x /usr/local/bin/ledger EXPOSE 3068 ENTRYPOINT ["ledger"] ENV OTEL_SERVICE_NAME ledger diff --git a/components/ledger/benchmarks/ledger_test.go b/components/ledger/benchmarks/ledger_test.go index f761e9012..5a7b00e44 100644 --- a/components/ledger/benchmarks/ledger_test.go +++ b/components/ledger/benchmarks/ledger_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "math/big" "net/http" "net/http/httptest" "net/url" @@ -13,12 +14,12 @@ import ( "testing" "time" - "github.com/formancehq/ledger/pkg/api/controllers" - "github.com/formancehq/ledger/pkg/api/routes" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage/storagetesting" + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/api/backend" + v2 "github.com/formancehq/ledger/internal/api/v2" + "github.com/formancehq/ledger/internal/engine" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/storagetesting" "github.com/formancehq/stack/libs/go-libs/api" "github.com/formancehq/stack/libs/go-libs/logging" "github.com/google/uuid" @@ -31,15 +32,15 @@ func BenchmarkParallelWrites(b *testing.B) { ctx := logging.TestingContext() driver := storagetesting.StorageDriver(b) - resolver := ledger.NewResolver(driver, ledger.WithLogger(logging.FromContext(ctx))) + resolver := engine.NewResolver(driver, engine.WithLogger(logging.FromContext(ctx))) b.Cleanup(func() { require.NoError(b, resolver.CloseLedgers(ctx)) }) ledgerName := uuid.NewString() - backend := controllers.NewDefaultBackend(driver, "latest", resolver) - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + backend := backend.NewDefaultBackend(driver, "latest", resolver) + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := logging.ContextWithLogger(r.Context(), logging.FromContext(ctx)) router.ServeHTTP(w, r.WithContext(ctx)) @@ -52,7 +53,7 @@ func BenchmarkParallelWrites(b *testing.B) { startOfBench := time.Now() counter := atomic.NewInt64(0) longestTxLock := sync.Mutex{} - longestTransactionID := uint64(0) + longestTransactionID := big.NewInt(0) longestTransactionDuration := time.Duration(0) b.RunParallel(func(pb *testing.PB) { buf := bytes.NewBufferString("") @@ -77,8 +78,8 @@ func BenchmarkParallelWrites(b *testing.B) { // }, //} - script := controllers.Script{ - Script: core.Script{ + script := v2.Script{ + Script: ledger.Script{ Plain: `vars { account $account } @@ -111,7 +112,7 @@ send [USD/2 100] ( // }, // } - err := json.NewEncoder(buf).Encode(controllers.PostTransactionRequest{ + err := json.NewEncoder(buf).Encode(v2.PostTransactionRequest{ Script: script, }) require.NoError(b, err) @@ -131,7 +132,7 @@ send [USD/2 100] ( totalDuration.Add(latency) require.Equal(b, http.StatusOK, rsp.Code) - tx, _ := api.DecodeSingleResponse[core.Transaction](b, rsp.Body) + tx, _ := api.DecodeSingleResponse[ledger.Transaction](b, rsp.Body) longestTxLock.Lock() if time.Millisecond*time.Duration(latency) > longestTransactionDuration { diff --git a/components/ledger/benchmarks/main_test.go b/components/ledger/benchmarks/main_test.go index 72d31abb8..da45c38b1 100644 --- a/components/ledger/benchmarks/main_test.go +++ b/components/ledger/benchmarks/main_test.go @@ -4,7 +4,6 @@ import ( "os" "testing" - _ "github.com/formancehq/ledger/pkg/storage/ledgerstore/migrates/0-init-schema" "github.com/formancehq/stack/libs/go-libs/logging" "github.com/formancehq/stack/libs/go-libs/pgtesting" "github.com/ory/dockertest/v3/docker" diff --git a/components/ledger/cmd/container.go b/components/ledger/cmd/container.go index c374dbf9b..3a5abaf10 100644 --- a/components/ledger/cmd/container.go +++ b/components/ledger/cmd/container.go @@ -4,9 +4,9 @@ import ( "io" "github.com/formancehq/ledger/cmd/internal" - "github.com/formancehq/ledger/pkg/api" - "github.com/formancehq/ledger/pkg/ledger" - "github.com/formancehq/ledger/pkg/storage/driver" + "github.com/formancehq/ledger/internal/api" + "github.com/formancehq/ledger/internal/engine" + driver2 "github.com/formancehq/ledger/internal/storage/driver" "github.com/formancehq/stack/libs/go-libs/otlp/otlpmetrics" "github.com/formancehq/stack/libs/go-libs/otlp/otlptraces" "github.com/formancehq/stack/libs/go-libs/publish" @@ -24,7 +24,7 @@ func resolveOptions(output io.Writer, userOptions ...fx.Option) []fx.Option { v := viper.GetViper() debug := v.GetBool(service.DebugFlag) if debug { - driver.InstrumentalizeSQLDriver() + driver2.InstrumentalizeSQLDriver() } options = append(options, @@ -34,10 +34,10 @@ func resolveOptions(output io.Writer, userOptions ...fx.Option) []fx.Option { api.Module(api.Config{ Version: Version, }), - driver.CLIModule(v, output, debug), + driver2.CLIModule(v, output, debug), internal.NewAnalyticsModule(v, Version), - ledger.Module(ledger.Configuration{ - NumscriptCache: ledger.NumscriptCacheConfiguration{ + engine.Module(engine.Configuration{ + NumscriptCache: engine.NumscriptCacheConfiguration{ MaxCount: v.GetInt(numscriptCacheMaxCount), }, }), diff --git a/components/ledger/cmd/internal/analytics.go b/components/ledger/cmd/internal/analytics.go index 153cfcf8e..8b54fd519 100644 --- a/components/ledger/cmd/internal/analytics.go +++ b/components/ledger/cmd/internal/analytics.go @@ -4,7 +4,7 @@ import ( "time" "github.com/Masterminds/semver/v3" - "github.com/formancehq/ledger/pkg/analytics" + "github.com/formancehq/ledger/internal/analytics" "github.com/formancehq/stack/libs/go-libs/logging" "github.com/spf13/cobra" "github.com/spf13/viper" diff --git a/components/ledger/cmd/root.go b/components/ledger/cmd/root.go index 6d838b04d..a3fc943d7 100644 --- a/components/ledger/cmd/root.go +++ b/components/ledger/cmd/root.go @@ -5,8 +5,7 @@ import ( "os" "github.com/formancehq/ledger/cmd/internal" - "github.com/formancehq/ledger/pkg/storage/driver" - initschema "github.com/formancehq/ledger/pkg/storage/ledgerstore/migrates/0-init-schema" + "github.com/formancehq/ledger/internal/storage/driver" "github.com/formancehq/stack/libs/go-libs/otlp/otlpmetrics" "github.com/formancehq/stack/libs/go-libs/otlp/otlptraces" "github.com/formancehq/stack/libs/go-libs/publish" @@ -63,7 +62,6 @@ func NewRootCommand() *cobra.Command { internal.InitAnalyticsFlags(root, DefaultSegmentWriteKey) publish.InitCLIFlags(root) driver.InitCLIFlags(root) - initschema.InitMigrationConfigCLIFlags(root.PersistentFlags()) if err := viper.BindPFlags(root.PersistentFlags()); err != nil { panic(err) diff --git a/components/ledger/cmd/serve.go b/components/ledger/cmd/serve.go index 275ca89c4..629070549 100644 --- a/components/ledger/cmd/serve.go +++ b/components/ledger/cmd/serve.go @@ -2,8 +2,9 @@ package cmd import ( "net/http" + "time" - "github.com/formancehq/ledger/pkg/api/middlewares" + ledger "github.com/formancehq/ledger/internal" "github.com/formancehq/stack/libs/go-libs/ballast" "github.com/formancehq/stack/libs/go-libs/httpserver" "github.com/formancehq/stack/libs/go-libs/logging" @@ -28,20 +29,17 @@ func NewServe() *cobra.Command { ballast.Module(viper.GetUint(ballastSizeInBytesFlag)), fx.Invoke(func(lc fx.Lifecycle, h chi.Router, logger logging.Logger) { - if viper.GetBool(app.DebugFlag) { - wrappedRouter := chi.NewRouter() - wrappedRouter.Use(func(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - r = r.WithContext(logging.ContextWithLogger(r.Context(), logger)) - handler.ServeHTTP(w, r) - }) + wrappedRouter := chi.NewRouter() + wrappedRouter.Use(func(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + r = r.WithContext(logging.ContextWithLogger(r.Context(), logger)) + handler.ServeHTTP(w, r) }) - wrappedRouter.Use(middlewares.Log()) - wrappedRouter.Mount("/", h) - h = wrappedRouter - } + }) + wrappedRouter.Use(Log()) + wrappedRouter.Mount("/", h) - lc.Append(httpserver.NewHook(viper.GetString(bindFlag), h)) + lc.Append(httpserver.NewHook(viper.GetString(bindFlag), wrappedRouter)) }), )...).Run(cmd.Context()) }, @@ -50,3 +48,20 @@ func NewServe() *cobra.Command { cmd.Flags().Int(numscriptCacheMaxCount, 1024, "Numscript cache max count") return cmd } + +func Log() func(h http.Handler) http.Handler { + return func(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := ledger.Now() + h.ServeHTTP(w, r) + latency := time.Since(start.Time) + logging.FromContext(r.Context()).WithFields(map[string]interface{}{ + "method": r.Method, + "path": r.URL.Path, + "latency": latency, + "user_agent": r.UserAgent(), + "params": r.URL.Query().Encode(), + }).Debug("Request") + }) + } +} diff --git a/components/ledger/cmd/storage.go b/components/ledger/cmd/storage.go index ce0aaad92..83ad405ce 100644 --- a/components/ledger/cmd/storage.go +++ b/components/ledger/cmd/storage.go @@ -4,9 +4,9 @@ import ( "context" "errors" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/driver" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/driver" + "github.com/formancehq/ledger/internal/storage/ledgerstore" "github.com/formancehq/stack/libs/go-libs/logging" "github.com/formancehq/stack/libs/go-libs/service" "github.com/spf13/cobra" @@ -124,7 +124,7 @@ func NewStorageUpgrade() *cobra.Command { } defer sqlDB.Close() - driver := driver.New(storage.NewDatabase(sqlDB)) + driver := driver.New(sqlDB) if err := driver.Initialize(cmd.Context()); err != nil { return err } @@ -149,18 +149,19 @@ func NewStorageUpgradeAll() *cobra.Command { SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { + logger := service.GetDefaultLogger(cmd.OutOrStdout(), viper.GetBool(service.DebugFlag), false) + ctx := logging.ContextWithLogger(cmd.Context(), logger) + sqlDB, err := storage.OpenSQLDB(storage.ConnectionOptionsFromFlags(viper.GetViper(), cmd.OutOrStdout(), viper.GetBool(service.DebugFlag))) if err != nil { return err } defer sqlDB.Close() - driver := driver.New(storage.NewDatabase(sqlDB)) - if err := driver.Initialize(cmd.Context()); err != nil { + driver := driver.New(sqlDB) + if err := driver.Initialize(ctx); err != nil { return err } - logger := service.GetDefaultLogger(cmd.OutOrStdout(), viper.GetBool(service.DebugFlag), false) - ctx := logging.ContextWithLogger(cmd.Context(), logger) systemStore := driver.GetSystemStore() ledgers, err := systemStore.ListLedgers(ctx) @@ -169,7 +170,7 @@ func NewStorageUpgradeAll() *cobra.Command { } for _, ledger := range ledgers { - store, err := driver.GetLedgerStore(cmd.Context(), ledger) + store, err := driver.GetLedgerStore(ctx, ledger) if err != nil { return err } diff --git a/components/ledger/docker-compose.release.yml b/components/ledger/docker-compose.release.yml new file mode 100644 index 000000000..d450c7631 --- /dev/null +++ b/components/ledger/docker-compose.release.yml @@ -0,0 +1,39 @@ +version: '3.8' +volumes: + postgres: +services: + postgres: + image: "postgres:13-alpine" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ledger"] + interval: 10s + timeout: 5s + retries: 5 + ports: + - "5432:5432" + command: + - -c + - max_connections=200 + environment: + POSTGRES_USER: "ledger" + POSTGRES_PASSWORD: "ledger" + POSTGRES_DB: "ledger" + PGDATA: /data/postgres + volumes: + - postgres:/data/postgres + + ledger: + image: "ghcr.io/formancehq/ledger:v1.10.4" + healthcheck: + test: ["CMD", "wget", "http://127.0.0.1:3068/_info", "-O", "-", "-q"] + interval: 10s + timeout: 5s + retries: 5 + depends_on: + postgres: + condition: service_healthy + ports: + - "3068:3068" + environment: + STORAGE_DRIVER: "postgres" + STORAGE_POSTGRES_CONN_STRING: "postgresql://ledger:ledger@postgres/ledger?sslmode=disable" diff --git a/components/ledger/docker-compose.yml b/components/ledger/docker-compose.yml index 3440f609e..5be7f5fc6 100644 --- a/components/ledger/docker-compose.yml +++ b/components/ledger/docker-compose.yml @@ -3,14 +3,12 @@ volumes: postgres: services: postgres: - image: "postgres:13-alpine" + image: "postgres:15-alpine" healthcheck: test: ["CMD-SHELL", "pg_isready -U ledger"] interval: 10s timeout: 5s retries: 5 - ports: - - "5432:5432" command: - -c - max_connections=200 @@ -20,20 +18,20 @@ services: POSTGRES_DB: "ledger" PGDATA: /data/postgres volumes: - - postgres:/data/postgres + - postgres:/data/postgres ledger: - image: "ghcr.io/formancehq/ledger:v1.9.2" - healthcheck: - test: ["CMD", "wget", "http://127.0.0.1:3068/_info", "-O", "-", "-q"] - interval: 10s - timeout: 5s - retries: 5 + image: golang:1.19-alpine + entrypoint: go run main.go serve + volumes: + - .:/src + ports: + - 3068:3068 + working_dir: /src depends_on: postgres: condition: service_healthy - ports: - - "3068:3068" environment: STORAGE_DRIVER: "postgres" STORAGE_POSTGRES_CONN_STRING: "postgresql://ledger:ledger@postgres/ledger?sslmode=disable" + DEBUG: "true" diff --git a/components/ledger/go.mod b/components/ledger/go.mod index 66a5ff6c8..f3477c2a6 100644 --- a/components/ledger/go.mod +++ b/components/ledger/go.mod @@ -21,17 +21,13 @@ require ( github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pborman/uuid v1.2.1 github.com/pkg/errors v0.9.1 - github.com/psanford/memfs v0.0.0-20210214183328-a001468d78ef github.com/riandyrn/otelchi v0.5.1 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.6.1 - github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.3 github.com/uptrace/bun v1.1.14 github.com/uptrace/bun/dialect/pgdialect v1.1.14 - github.com/uptrace/bun/extra/bunbig v1.1.14 - github.com/uptrace/bun/extra/bundebug v1.1.14 github.com/uptrace/bun/extra/bunotel v1.1.14 go.nhat.io/otelsql v0.11.0 go.opentelemetry.io/otel v1.16.0 @@ -61,7 +57,6 @@ require ( github.com/eapache/go-resiliency v1.3.0 // indirect github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6 // indirect github.com/eapache/queue v1.1.0 // indirect - github.com/fatih/color v1.15.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect @@ -92,8 +87,6 @@ require ( github.com/lithammer/shortuuid/v3 v3.0.7 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect github.com/nats-io/nats.go v1.23.0 // indirect @@ -114,6 +107,7 @@ require ( github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tklauser/numcpus v0.6.0 // indirect diff --git a/components/ledger/go.sum b/components/ledger/go.sum index 665c3e8a2..025e432bd 100644 --- a/components/ledger/go.sum +++ b/components/ledger/go.sum @@ -131,7 +131,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -325,10 +324,7 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2 github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -385,8 +381,6 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/psanford/memfs v0.0.0-20210214183328-a001468d78ef h1:NKxTG6GVGbfMXc2mIk+KphcH6hagbVXhcFkbTgYleTI= -github.com/psanford/memfs v0.0.0-20210214183328-a001468d78ef/go.mod h1:tcaRap0jS3eifrEEllL6ZMd9dg8IlDpi2S1oARrQ+NI= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/riandyrn/otelchi v0.5.1 h1:0/45omeqpP7f/cvdL16GddQBfAEmZvUyl2QzLSE6uYo= @@ -455,10 +449,7 @@ github.com/uptrace/bun v1.1.14 h1:S5vvNnjEynJ0CvnrBOD7MIRW7q/WbtvFXrdfy0lddAM= github.com/uptrace/bun v1.1.14/go.mod h1:RHk6DrIisO62dv10pUOJCz5MphXThuOTpVNYEYv7NI8= github.com/uptrace/bun/dialect/pgdialect v1.1.14 h1:b7+V1KDJPQSFYgkG/6YLXCl2uvwEY3kf/GSM7hTHRDY= github.com/uptrace/bun/dialect/pgdialect v1.1.14/go.mod h1:v6YiaXmnKQ2FlhRD2c0ZfKd+QXH09pYn4H8ojaavkKk= -github.com/uptrace/bun/extra/bunbig v1.1.14 h1:3vAI0x2ObtWaXp2G5YJA0fBJTGzwv5gwTPbtEj0Ma00= -github.com/uptrace/bun/extra/bunbig v1.1.14/go.mod h1:+tVzMLS0bTkILD9JcRm5INUd/Wwd/1gKIw6GogAUAfw= github.com/uptrace/bun/extra/bundebug v1.1.14 h1:9OCGfP9ZDlh41u6OLerWdhBtJAVGXHr0xtxO4xWi6t0= -github.com/uptrace/bun/extra/bundebug v1.1.14/go.mod h1:lto3guzS2v6mnQp1+akyE+ecBLOltevDDe324NXEYdw= github.com/uptrace/bun/extra/bunotel v1.1.14 h1:jKA1zNfD2/Y/O3eFP15ao+V0cMigXN+ReNbsVUqrOhg= github.com/uptrace/bun/extra/bunotel v1.1.14/go.mod h1:BBuePZ4ciMqoeyRfef4GL7Z75FsiOm3Q3fvNt0z4sQk= github.com/uptrace/opentelemetry-go-extra/otellogrus v0.1.21 h1:OXsouNDvuET5o1A4uvoCnAXuuNke8JlfZWceciyUlC8= @@ -726,10 +717,8 @@ golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/components/ledger/internal/account.go b/components/ledger/internal/account.go new file mode 100644 index 000000000..0f4a3726f --- /dev/null +++ b/components/ledger/internal/account.go @@ -0,0 +1,69 @@ +package ledger + +import ( + "encoding/json" + "regexp" + + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/uptrace/bun" +) + +const ( + WORLD = "world" +) + +type Account struct { + bun.BaseModel `bun:"table:accounts,alias:accounts"` + + Address string `json:"address"` + Metadata metadata.Metadata `json:"metadata"` +} + +func (a Account) copy() Account { + a.Metadata = a.Metadata.Copy() + return a +} + +func NewAccount(address string) Account { + return Account{ + Address: address, + Metadata: metadata.Metadata{}, + } +} + +type ExpandedAccount struct { + Account `bun:",extend"` + Volumes VolumesByAssets `json:"volumes,omitempty" bun:"volumes,type:jsonb"` + EffectiveVolumes VolumesByAssets `json:"effectiveVolumes,omitempty" bun:"effective_volumes,type:jsonb"` +} + +func NewExpandedAccount(address string) ExpandedAccount { + return ExpandedAccount{ + Account: Account{ + Address: address, + Metadata: metadata.Metadata{}, + }, + Volumes: map[string]*Volumes{}, + } +} + +func (v ExpandedAccount) MarshalJSON() ([]byte, error) { + type aux ExpandedAccount + return json.Marshal(struct { + aux + Balances BalancesByAssets `json:"balances"` + }{ + aux: aux(v), + Balances: v.Volumes.Balances(), + }) +} + +func (v ExpandedAccount) Copy() ExpandedAccount { + v.Account = v.Account.copy() + v.Volumes = v.Volumes.copy() + return v +} + +const AccountPattern = "^[a-zA-Z_]+[a-zA-Z0-9_:]*$" + +var AccountRegexp = regexp.MustCompile(AccountPattern) diff --git a/components/ledger/pkg/analytics/analytics.go b/components/ledger/internal/analytics/analytics.go similarity index 95% rename from components/ledger/pkg/analytics/analytics.go rename to components/ledger/internal/analytics/analytics.go index 3d37000b3..91a051339 100644 --- a/components/ledger/pkg/analytics/analytics.go +++ b/components/ledger/internal/analytics/analytics.go @@ -7,8 +7,8 @@ import ( "runtime" "time" - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" + ledger "github.com/formancehq/ledger/internal" + storageerrors "github.com/formancehq/ledger/internal/storage" "github.com/formancehq/stack/libs/go-libs/logging" "github.com/pbnjay/memory" "gopkg.in/segmentio/analytics-go.v3" @@ -79,7 +79,7 @@ func (m *heartbeat) enqueue(ctx context.Context) error { return err } - tz, _ := core.Now().Local().Zone() + tz, _ := ledger.Now().Local().Zone() properties := analytics.NewProperties(). Set(VersionProperty, m.version). diff --git a/components/ledger/pkg/analytics/analytics_test.go b/components/ledger/internal/analytics/analytics_test.go similarity index 100% rename from components/ledger/pkg/analytics/analytics_test.go rename to components/ledger/internal/analytics/analytics_test.go diff --git a/components/ledger/internal/analytics/backend.go b/components/ledger/internal/analytics/backend.go new file mode 100644 index 000000000..951803d1a --- /dev/null +++ b/components/ledger/internal/analytics/backend.go @@ -0,0 +1,83 @@ +package analytics + +import ( + "context" + + storageerrors "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/driver" + ledgerstore "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/google/uuid" + "github.com/pkg/errors" +) + +//go:generate mockgen -source backend.go -destination backend_test.go -package analytics . Ledger + +type Ledger interface { + CountTransactions(ctx context.Context) (uint64, error) + CountAccounts(ctx context.Context) (uint64, error) +} + +type defaultLedger struct { + store *ledgerstore.Store +} + +func (d defaultLedger) CountTransactions(ctx context.Context) (uint64, error) { + return d.store.CountTransactions(ctx, ledgerstore.NewGetTransactionsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}))) +} + +func (d defaultLedger) CountAccounts(ctx context.Context) (uint64, error) { + return d.store.CountAccounts(ctx, ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}))) +} + +var _ Ledger = (*defaultLedger)(nil) + +type Backend interface { + AppID(ctx context.Context) (string, error) + ListLedgers(ctx context.Context) ([]string, error) + GetLedgerStore(ctx context.Context, l string) (Ledger, error) +} + +type defaultBackend struct { + driver *driver.Driver + appID string +} + +func (d defaultBackend) AppID(ctx context.Context) (string, error) { + var err error + if d.appID == "" { + d.appID, err = d.driver.GetSystemStore().GetConfiguration(ctx, "appId") + if err != nil && !errors.Is(err, storageerrors.ErrNotFound) { + return "", err + } + if errors.Is(err, storageerrors.ErrNotFound) { + d.appID = uuid.NewString() + if err := d.driver.GetSystemStore().InsertConfiguration(ctx, "appId", d.appID); err != nil { + return "", err + } + } + } + return d.appID, nil +} + +func (d defaultBackend) ListLedgers(ctx context.Context) ([]string, error) { + return d.driver.GetSystemStore().ListLedgers(ctx) +} + +func (d defaultBackend) GetLedgerStore(ctx context.Context, name string) (Ledger, error) { + ledgerStore, err := d.driver.GetLedgerStore(ctx, name) + if err != nil { + return nil, err + } + return &defaultLedger{ + store: ledgerStore, + }, nil +} + +var _ Backend = (*defaultBackend)(nil) + +func newDefaultBackend(driver *driver.Driver, appID string) *defaultBackend { + return &defaultBackend{ + driver: driver, + appID: appID, + } +} diff --git a/components/ledger/pkg/analytics/backend_test.go b/components/ledger/internal/analytics/backend_test.go similarity index 100% rename from components/ledger/pkg/analytics/backend_test.go rename to components/ledger/internal/analytics/backend_test.go diff --git a/components/ledger/internal/analytics/module.go b/components/ledger/internal/analytics/module.go new file mode 100644 index 000000000..bef19428e --- /dev/null +++ b/components/ledger/internal/analytics/module.go @@ -0,0 +1,48 @@ +package analytics + +import ( + "context" + "time" + + "github.com/formancehq/ledger/internal/storage/driver" + "go.uber.org/fx" + "gopkg.in/segmentio/analytics-go.v3" +) + +func NewHeartbeatModule(version, writeKey, appID string, interval time.Duration) fx.Option { + return fx.Options( + fx.Supply(analytics.Config{}), // Provide empty config to be able to replace (use fx.Replace) if necessary + fx.Provide(func(cfg analytics.Config) (analytics.Client, error) { + return analytics.NewWithConfig(writeKey, cfg) + }), + fx.Provide(func(client analytics.Client, backend Backend) *heartbeat { + return newHeartbeat(backend, client, version, interval) + }), + fx.Provide(func(driver *driver.Driver) Backend { + return newDefaultBackend(driver, appID) + }), + fx.Invoke(func(m *heartbeat, lc fx.Lifecycle) { + lc.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + go func() { + err := m.Run(context.Background()) + if err != nil { + panic(err) + } + }() + return nil + }, + OnStop: func(ctx context.Context) error { + return m.Stop(ctx) + }, + }) + }), + fx.Invoke(func(lc fx.Lifecycle, client analytics.Client) { + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return client.Close() + }, + }) + }), + ) +} diff --git a/components/ledger/internal/api/backend/backend.go b/components/ledger/internal/api/backend/backend.go new file mode 100644 index 000000000..806a33cce --- /dev/null +++ b/components/ledger/internal/api/backend/backend.go @@ -0,0 +1,69 @@ +package backend + +import ( + "context" + "math/big" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/engine" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/driver" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/formancehq/stack/libs/go-libs/migrations" +) + +//go:generate mockgen -source backend.go -destination backend_generated.go -package backend . Ledger + +type Ledger interface { + GetAccountWithVolumes(ctx context.Context, query ledgerstore.GetAccountQuery) (*ledger.ExpandedAccount, error) + GetAccountsWithVolumes(ctx context.Context, query *ledgerstore.GetAccountsQuery) (*api.Cursor[ledger.ExpandedAccount], error) + CountAccounts(ctx context.Context, query *ledgerstore.GetAccountsQuery) (uint64, error) + GetAggregatedBalances(ctx context.Context, q *ledgerstore.GetAggregatedBalanceQuery) (ledger.BalancesByAssets, error) + GetMigrationsInfo(ctx context.Context) ([]migrations.Info, error) + Stats(ctx context.Context) (engine.Stats, error) + GetLogs(ctx context.Context, query *ledgerstore.GetLogsQuery) (*api.Cursor[ledger.ChainedLog], error) + CountTransactions(ctx context.Context, query *ledgerstore.GetTransactionsQuery) (uint64, error) + GetTransactions(ctx context.Context, query *ledgerstore.GetTransactionsQuery) (*api.Cursor[ledger.ExpandedTransaction], error) + GetTransactionWithVolumes(ctx context.Context, query ledgerstore.GetTransactionQuery) (*ledger.ExpandedTransaction, error) + + CreateTransaction(ctx context.Context, parameters command.Parameters, data ledger.RunScript) (*ledger.Transaction, error) + RevertTransaction(ctx context.Context, parameters command.Parameters, id *big.Int) (*ledger.Transaction, error) + SaveMeta(ctx context.Context, parameters command.Parameters, targetType string, targetID any, m metadata.Metadata) error + DeleteMetadata(ctx context.Context, parameters command.Parameters, targetType string, targetID any, key string) error +} + +type Backend interface { + GetLedger(ctx context.Context, name string) (Ledger, error) + ListLedgers(ctx context.Context) ([]string, error) + GetVersion() string +} + +type DefaultBackend struct { + storageDriver *driver.Driver + resolver *engine.Resolver + version string +} + +func (d DefaultBackend) GetLedger(ctx context.Context, name string) (Ledger, error) { + return d.resolver.GetLedger(ctx, name) +} + +func (d DefaultBackend) ListLedgers(ctx context.Context) ([]string, error) { + return d.storageDriver.GetSystemStore().ListLedgers(ctx) +} + +func (d DefaultBackend) GetVersion() string { + return d.version +} + +var _ Backend = (*DefaultBackend)(nil) + +func NewDefaultBackend(driver *driver.Driver, version string, resolver *engine.Resolver) *DefaultBackend { + return &DefaultBackend{ + storageDriver: driver, + resolver: resolver, + version: version, + } +} diff --git a/components/ledger/internal/api/backend/backend_generated.go b/components/ledger/internal/api/backend/backend_generated.go new file mode 100644 index 000000000..a9f054f30 --- /dev/null +++ b/components/ledger/internal/api/backend/backend_generated.go @@ -0,0 +1,318 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: backend.go + +// Package backend is a generated GoMock package. +package backend + +import ( + context "context" + big "math/big" + reflect "reflect" + + internal "github.com/formancehq/ledger/internal" + engine "github.com/formancehq/ledger/internal/engine" + command "github.com/formancehq/ledger/internal/engine/command" + ledgerstore "github.com/formancehq/ledger/internal/storage/ledgerstore" + api "github.com/formancehq/stack/libs/go-libs/api" + metadata "github.com/formancehq/stack/libs/go-libs/metadata" + migrations "github.com/formancehq/stack/libs/go-libs/migrations" + gomock "github.com/golang/mock/gomock" +) + +// MockLedger is a mock of Ledger interface. +type MockLedger struct { + ctrl *gomock.Controller + recorder *MockLedgerMockRecorder +} + +// MockLedgerMockRecorder is the mock recorder for MockLedger. +type MockLedgerMockRecorder struct { + mock *MockLedger +} + +// NewMockLedger creates a new mock instance. +func NewMockLedger(ctrl *gomock.Controller) *MockLedger { + mock := &MockLedger{ctrl: ctrl} + mock.recorder = &MockLedgerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockLedger) EXPECT() *MockLedgerMockRecorder { + return m.recorder +} + +// CountAccounts mocks base method. +func (m *MockLedger) CountAccounts(ctx context.Context, query *ledgerstore.GetAccountsQuery) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CountAccounts", ctx, query) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CountAccounts indicates an expected call of CountAccounts. +func (mr *MockLedgerMockRecorder) CountAccounts(ctx, query interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CountAccounts", reflect.TypeOf((*MockLedger)(nil).CountAccounts), ctx, query) +} + +// CountTransactions mocks base method. +func (m *MockLedger) CountTransactions(ctx context.Context, query *ledgerstore.GetTransactionsQuery) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CountTransactions", ctx, query) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CountTransactions indicates an expected call of CountTransactions. +func (mr *MockLedgerMockRecorder) CountTransactions(ctx, query interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CountTransactions", reflect.TypeOf((*MockLedger)(nil).CountTransactions), ctx, query) +} + +// CreateTransaction mocks base method. +func (m *MockLedger) CreateTransaction(ctx context.Context, parameters command.Parameters, data internal.RunScript) (*internal.Transaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateTransaction", ctx, parameters, data) + ret0, _ := ret[0].(*internal.Transaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateTransaction indicates an expected call of CreateTransaction. +func (mr *MockLedgerMockRecorder) CreateTransaction(ctx, parameters, data interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTransaction", reflect.TypeOf((*MockLedger)(nil).CreateTransaction), ctx, parameters, data) +} + +// DeleteMetadata mocks base method. +func (m *MockLedger) DeleteMetadata(ctx context.Context, parameters command.Parameters, targetType string, targetID any, key string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteMetadata", ctx, parameters, targetType, targetID, key) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteMetadata indicates an expected call of DeleteMetadata. +func (mr *MockLedgerMockRecorder) DeleteMetadata(ctx, parameters, targetType, targetID, key interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteMetadata", reflect.TypeOf((*MockLedger)(nil).DeleteMetadata), ctx, parameters, targetType, targetID, key) +} + +// GetAccountWithVolumes mocks base method. +func (m *MockLedger) GetAccountWithVolumes(ctx context.Context, query ledgerstore.GetAccountQuery) (*internal.ExpandedAccount, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAccountWithVolumes", ctx, query) + ret0, _ := ret[0].(*internal.ExpandedAccount) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAccountWithVolumes indicates an expected call of GetAccountWithVolumes. +func (mr *MockLedgerMockRecorder) GetAccountWithVolumes(ctx, query interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccountWithVolumes", reflect.TypeOf((*MockLedger)(nil).GetAccountWithVolumes), ctx, query) +} + +// GetAccountsWithVolumes mocks base method. +func (m *MockLedger) GetAccountsWithVolumes(ctx context.Context, query *ledgerstore.GetAccountsQuery) (*api.Cursor[internal.ExpandedAccount], error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAccountsWithVolumes", ctx, query) + ret0, _ := ret[0].(*api.Cursor[internal.ExpandedAccount]) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAccountsWithVolumes indicates an expected call of GetAccountsWithVolumes. +func (mr *MockLedgerMockRecorder) GetAccountsWithVolumes(ctx, query interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccountsWithVolumes", reflect.TypeOf((*MockLedger)(nil).GetAccountsWithVolumes), ctx, query) +} + +// GetAggregatedBalances mocks base method. +func (m *MockLedger) GetAggregatedBalances(ctx context.Context, q *ledgerstore.GetAggregatedBalanceQuery) (internal.BalancesByAssets, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAggregatedBalances", ctx, q) + ret0, _ := ret[0].(internal.BalancesByAssets) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAggregatedBalances indicates an expected call of GetAggregatedBalances. +func (mr *MockLedgerMockRecorder) GetAggregatedBalances(ctx, q interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAggregatedBalances", reflect.TypeOf((*MockLedger)(nil).GetAggregatedBalances), ctx, q) +} + +// GetLogs mocks base method. +func (m *MockLedger) GetLogs(ctx context.Context, query *ledgerstore.GetLogsQuery) (*api.Cursor[internal.ChainedLog], error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLogs", ctx, query) + ret0, _ := ret[0].(*api.Cursor[internal.ChainedLog]) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLogs indicates an expected call of GetLogs. +func (mr *MockLedgerMockRecorder) GetLogs(ctx, query interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogs", reflect.TypeOf((*MockLedger)(nil).GetLogs), ctx, query) +} + +// GetMigrationsInfo mocks base method. +func (m *MockLedger) GetMigrationsInfo(ctx context.Context) ([]migrations.Info, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMigrationsInfo", ctx) + ret0, _ := ret[0].([]migrations.Info) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMigrationsInfo indicates an expected call of GetMigrationsInfo. +func (mr *MockLedgerMockRecorder) GetMigrationsInfo(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMigrationsInfo", reflect.TypeOf((*MockLedger)(nil).GetMigrationsInfo), ctx) +} + +// GetTransactionWithVolumes mocks base method. +func (m *MockLedger) GetTransactionWithVolumes(ctx context.Context, query ledgerstore.GetTransactionQuery) (*internal.ExpandedTransaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTransactionWithVolumes", ctx, query) + ret0, _ := ret[0].(*internal.ExpandedTransaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTransactionWithVolumes indicates an expected call of GetTransactionWithVolumes. +func (mr *MockLedgerMockRecorder) GetTransactionWithVolumes(ctx, query interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTransactionWithVolumes", reflect.TypeOf((*MockLedger)(nil).GetTransactionWithVolumes), ctx, query) +} + +// GetTransactions mocks base method. +func (m *MockLedger) GetTransactions(ctx context.Context, query *ledgerstore.GetTransactionsQuery) (*api.Cursor[internal.ExpandedTransaction], error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTransactions", ctx, query) + ret0, _ := ret[0].(*api.Cursor[internal.ExpandedTransaction]) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTransactions indicates an expected call of GetTransactions. +func (mr *MockLedgerMockRecorder) GetTransactions(ctx, query interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTransactions", reflect.TypeOf((*MockLedger)(nil).GetTransactions), ctx, query) +} + +// RevertTransaction mocks base method. +func (m *MockLedger) RevertTransaction(ctx context.Context, parameters command.Parameters, id *big.Int) (*internal.Transaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RevertTransaction", ctx, parameters, id) + ret0, _ := ret[0].(*internal.Transaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RevertTransaction indicates an expected call of RevertTransaction. +func (mr *MockLedgerMockRecorder) RevertTransaction(ctx, parameters, id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertTransaction", reflect.TypeOf((*MockLedger)(nil).RevertTransaction), ctx, parameters, id) +} + +// SaveMeta mocks base method. +func (m_2 *MockLedger) SaveMeta(ctx context.Context, parameters command.Parameters, targetType string, targetID any, m metadata.Metadata) error { + m_2.ctrl.T.Helper() + ret := m_2.ctrl.Call(m_2, "SaveMeta", ctx, parameters, targetType, targetID, m) + ret0, _ := ret[0].(error) + return ret0 +} + +// SaveMeta indicates an expected call of SaveMeta. +func (mr *MockLedgerMockRecorder) SaveMeta(ctx, parameters, targetType, targetID, m interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveMeta", reflect.TypeOf((*MockLedger)(nil).SaveMeta), ctx, parameters, targetType, targetID, m) +} + +// Stats mocks base method. +func (m *MockLedger) Stats(ctx context.Context) (engine.Stats, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Stats", ctx) + ret0, _ := ret[0].(engine.Stats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Stats indicates an expected call of Stats. +func (mr *MockLedgerMockRecorder) Stats(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stats", reflect.TypeOf((*MockLedger)(nil).Stats), ctx) +} + +// MockBackend is a mock of Backend interface. +type MockBackend struct { + ctrl *gomock.Controller + recorder *MockBackendMockRecorder +} + +// MockBackendMockRecorder is the mock recorder for MockBackend. +type MockBackendMockRecorder struct { + mock *MockBackend +} + +// NewMockBackend creates a new mock instance. +func NewMockBackend(ctrl *gomock.Controller) *MockBackend { + mock := &MockBackend{ctrl: ctrl} + mock.recorder = &MockBackendMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBackend) EXPECT() *MockBackendMockRecorder { + return m.recorder +} + +// GetLedger mocks base method. +func (m *MockBackend) GetLedger(ctx context.Context, name string) (Ledger, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLedger", ctx, name) + ret0, _ := ret[0].(Ledger) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLedger indicates an expected call of GetLedger. +func (mr *MockBackendMockRecorder) GetLedger(ctx, name interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLedger", reflect.TypeOf((*MockBackend)(nil).GetLedger), ctx, name) +} + +// GetVersion mocks base method. +func (m *MockBackend) GetVersion() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetVersion") + ret0, _ := ret[0].(string) + return ret0 +} + +// GetVersion indicates an expected call of GetVersion. +func (mr *MockBackendMockRecorder) GetVersion() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVersion", reflect.TypeOf((*MockBackend)(nil).GetVersion)) +} + +// ListLedgers mocks base method. +func (m *MockBackend) ListLedgers(ctx context.Context) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListLedgers", ctx) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListLedgers indicates an expected call of ListLedgers. +func (mr *MockBackendMockRecorder) ListLedgers(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLedgers", reflect.TypeOf((*MockBackend)(nil).ListLedgers), ctx) +} diff --git a/components/ledger/internal/api/module.go b/components/ledger/internal/api/module.go new file mode 100644 index 000000000..024f1ba0f --- /dev/null +++ b/components/ledger/internal/api/module.go @@ -0,0 +1,32 @@ +package api + +import ( + _ "embed" + + "github.com/formancehq/ledger/internal/api/backend" + "github.com/formancehq/ledger/internal/engine" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/driver" + "github.com/formancehq/stack/libs/go-libs/health" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" + "go.uber.org/fx" +) + +type Config struct { + Version string +} + +func Module(cfg Config) fx.Option { + return fx.Options( + fx.Provide(NewRouter), + fx.Provide(func(storageDriver *driver.Driver, resolver *engine.Resolver) backend.Backend { + return backend.NewDefaultBackend(storageDriver, cfg.Version, resolver) + }), + fx.Provide(fx.Annotate(noop.NewMeterProvider, fx.As(new(metric.MeterProvider)))), + fx.Decorate(fx.Annotate(func(meterProvider metric.MeterProvider) (metrics.GlobalRegistry, error) { + return metrics.RegisterGlobalRegistry(meterProvider) + }, fx.As(new(metrics.GlobalRegistry)))), + health.Module(), + ) +} diff --git a/components/ledger/internal/api/router.go b/components/ledger/internal/api/router.go new file mode 100644 index 000000000..9b1d22725 --- /dev/null +++ b/components/ledger/internal/api/router.go @@ -0,0 +1,28 @@ +package api + +import ( + "net/http" + + "github.com/formancehq/ledger/internal/api/backend" + v1 "github.com/formancehq/ledger/internal/api/v1" + v2 "github.com/formancehq/ledger/internal/api/v2" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/stack/libs/go-libs/health" + "github.com/go-chi/chi/v5" +) + +func NewRouter( + backend backend.Backend, + healthController *health.HealthController, + globalMetricsRegistry metrics.GlobalRegistry, +) chi.Router { + mux := chi.NewRouter() + v2Router := v2.NewRouter(backend, healthController, globalMetricsRegistry) + mux.Handle("/v2/*", http.StripPrefix("/v2", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + chi.RouteContext(r.Context()).Reset() + v2Router.ServeHTTP(w, r) + }))) + mux.Handle("/*", v1.NewRouter(backend, healthController, globalMetricsRegistry)) + + return mux +} diff --git a/components/ledger/internal/api/v1/api_utils_test.go b/components/ledger/internal/api/v1/api_utils_test.go new file mode 100644 index 000000000..bf8918f0e --- /dev/null +++ b/components/ledger/internal/api/v1/api_utils_test.go @@ -0,0 +1,23 @@ +package v1_test + +import ( + "testing" + + "github.com/formancehq/ledger/internal/api/backend" + "github.com/golang/mock/gomock" +) + +func newTestingBackend(t *testing.T) (*backend.MockBackend, *backend.MockLedger) { + ctrl := gomock.NewController(t) + mockLedger := backend.NewMockLedger(ctrl) + backend := backend.NewMockBackend(ctrl) + backend. + EXPECT(). + GetLedger(gomock.Any(), gomock.Any()). + MinTimes(0). + Return(mockLedger, nil) + t.Cleanup(func() { + ctrl.Finish() + }) + return backend, mockLedger +} diff --git a/components/ledger/internal/api/v1/context.go b/components/ledger/internal/api/v1/context.go new file mode 100644 index 000000000..3b8b76937 --- /dev/null +++ b/components/ledger/internal/api/v1/context.go @@ -0,0 +1,19 @@ +package v1 + +import ( + "context" + + "github.com/formancehq/ledger/internal/api/backend" +) + +type ledgerKey struct{} + +var _ledgerKey = ledgerKey{} + +func ContextWithLedger(ctx context.Context, ledger backend.Ledger) context.Context { + return context.WithValue(ctx, _ledgerKey, ledger) +} + +func LedgerFromContext(ctx context.Context) backend.Ledger { + return ctx.Value(_ledgerKey).(backend.Ledger) +} diff --git a/components/ledger/internal/api/v1/controllers_accounts.go b/components/ledger/internal/api/v1/controllers_accounts.go new file mode 100644 index 000000000..ff789aaf0 --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_accounts.go @@ -0,0 +1,180 @@ +package v1 + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + "strings" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/collectionutils" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/go-chi/chi/v5" + "github.com/pkg/errors" +) + +func buildAccountsFilterQuery(r *http.Request) (query.Builder, error) { + clauses := make([]query.Builder, 0) + + if balance := r.URL.Query().Get("balance"); balance != "" { + if _, err := strconv.ParseInt(balance, 10, 64); err != nil { + return nil, err + } + + balanceOperator, err := getBalanceOperator(r) + if err != nil { + return nil, err + } + + switch balanceOperator { + case "e": + clauses = append(clauses, query.Match("balance", balance)) + case "ne": + clauses = append(clauses, query.Not(query.Match("balance", balance))) + case "lt": + clauses = append(clauses, query.Lt("balance", balance)) + case "lte": + clauses = append(clauses, query.Lte("balance", balance)) + case "gt": + clauses = append(clauses, query.Gt("balance", balance)) + case "gte": + clauses = append(clauses, query.Gte("balance", balance)) + default: + return nil, errors.New("invalid balance operator") + } + } + + if address := r.URL.Query().Get("address"); address != "" { + clauses = append(clauses, query.Match("address", address)) + } + + for elem, value := range r.URL.Query() { + if strings.HasPrefix(elem, "metadata") { + clauses = append(clauses, query.Match(elem, value[0])) + } + } + + if len(clauses) == 0 { + return nil, nil + } + + return query.And(clauses...), nil +} + +func countAccounts(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + options, err := getPaginatedQueryOptionsOfPITFilterWithVolumes(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + + count, err := l.CountAccounts(r.Context(), ledgerstore.NewGetAccountsQuery(*options)) + if err != nil { + ResponseError(w, r, err) + return + } + + w.Header().Set("Count", fmt.Sprint(count)) + sharedapi.NoContent(w) +} + +func getAccounts(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + q := &ledgerstore.GetAccountsQuery{} + + if r.URL.Query().Get(QueryKeyCursor) != "" { + err := paginate.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), q) + if err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.Errorf("invalid '%s' query param", QueryKeyCursor))) + return + } + } else { + options, err := getPaginatedQueryOptionsOfPITFilterWithVolumes(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + options.QueryBuilder, err = buildAccountsFilterQuery(r) + q = ledgerstore.NewGetAccountsQuery(*options) + } + + cursor, err := l.GetAccountsWithVolumes(r.Context(), q) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.RenderCursor(w, *cursor) +} + +func getAccount(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + query := ledgerstore.NewGetAccountQuery(chi.URLParam(r, "address")) + if collectionutils.Contains(r.URL.Query()["expand"], "volumes") { + query = query.WithExpandVolumes() + } + if collectionutils.Contains(r.URL.Query()["expand"], "effectiveVolumes") { + query = query.WithExpandEffectiveVolumes() + } + + acc, err := l.GetAccountWithVolumes(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, acc) +} + +func postAccountMetadata(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + if !ledger.ValidateAddress(chi.URLParam(r, "address")) { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid account address format"))) + return + } + + var m metadata.Metadata + if err := json.NewDecoder(r.Body).Decode(&m); err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid metadata format"))) + return + } + + err := l.SaveMeta(r.Context(), getCommandParameters(r), ledger.MetaTargetTypeAccount, chi.URLParam(r, "address"), m) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.NoContent(w) +} + +func deleteAccountMetadata(w http.ResponseWriter, r *http.Request) { + if err := LedgerFromContext(r.Context()). + DeleteMetadata( + r.Context(), + getCommandParameters(r), + ledger.MetaTargetTypeAccount, + chi.URLParam(r, "address"), + chi.URLParam(r, "key"), + ); err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.NoContent(w) +} diff --git a/components/ledger/internal/api/v1/controllers_accounts_test.go b/components/ledger/internal/api/v1/controllers_accounts_test.go new file mode 100644 index 000000000..a234af769 --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_accounts_test.go @@ -0,0 +1,238 @@ +package v1_test + +import ( + "net/http" + "net/http/httptest" + "net/url" + "testing" + + ledger "github.com/formancehq/ledger/internal" + v1 "github.com/formancehq/ledger/internal/api/v1" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestGetAccounts(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + expectQuery ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilterWithVolumes] + expectStatusCode int + expectedErrorCode string + } + + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithPageSize(v1.DefaultPageSize), + }, + { + name: "using metadata", + queryParams: url.Values{ + "metadata[roles]": []string{"admin"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.And(query.Match("metadata[roles]", "admin"))). + WithPageSize(v1.DefaultPageSize), + }, + { + name: "using address", + queryParams: url.Values{ + "address": []string{"foo"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.And(query.Match("address", "foo"))). + WithPageSize(v1.DefaultPageSize), + }, + { + name: "using empty cursor", + queryParams: url.Values{ + "cursor": []string{paginate.EncodeCursor(ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{})))}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}), + }, + { + name: "using invalid cursor", + queryParams: url.Values{ + "cursor": []string{"XXX"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + { + name: "invalid page size", + queryParams: url.Values{ + "pageSize": []string{"nan"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + { + name: "page size over maximum", + queryParams: url.Values{ + "pageSize": []string{"1000000"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithPageSize(v1.MaxPageSize), + }, + { + name: "using balance filter", + queryParams: url.Values{ + "balance": []string{"100"}, + "balanceOperator": []string{"e"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.And(query.Match("balance", "100"))). + WithPageSize(v1.DefaultPageSize), + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusOK + } + + expectedCursor := sharedapi.Cursor[ledger.ExpandedAccount]{ + Data: []ledger.ExpandedAccount{ + { + Account: ledger.Account{ + Address: "world", + Metadata: metadata.Metadata{}, + }, + }, + }, + } + + backend, mockLedger := newTestingBackend(t) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + mockLedger.EXPECT(). + GetAccountsWithVolumes(gomock.Any(), ledgerstore.NewGetAccountsQuery(testCase.expectQuery)). + Return(&expectedCursor, nil) + } + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/accounts", nil) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + cursor := sharedapi.DecodeCursorResponse[ledger.ExpandedAccount](t, rec.Body) + require.Equal(t, expectedCursor, *cursor) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestGetAccount(t *testing.T) { + t.Parallel() + + account := ledger.ExpandedAccount{ + Account: ledger.Account{ + Address: "foo", + Metadata: metadata.Metadata{}, + }, + } + + backend, mock := newTestingBackend(t) + mock.EXPECT(). + GetAccountWithVolumes(gomock.Any(), ledgerstore.NewGetAccountQuery("foo")). + Return(&account, nil) + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/accounts/foo", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + response, _ := sharedapi.DecodeSingleResponse[ledger.ExpandedAccount](t, rec.Body) + require.Equal(t, account, response) +} + +func TestPostAccountMetadata(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + expectStatusCode int + expectedErrorCode string + account string + body any + } + + testCases := []testCase{ + { + name: "nominal", + account: "world", + body: metadata.Metadata{ + "foo": "bar", + }, + }, + { + name: "invalid account address format", + account: "invalid-acc", + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + { + name: "invalid body", + account: "world", + body: "invalid - not an object", + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusNoContent + } + + backend, mock := newTestingBackend(t) + if testCase.expectStatusCode == http.StatusNoContent { + mock.EXPECT(). + SaveMeta(gomock.Any(), command.Parameters{}, ledger.MetaTargetTypeAccount, testCase.account, testCase.body). + Return(nil) + } + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodPost, "/xxx/accounts/"+testCase.account+"/metadata", sharedapi.Buffer(t, testCase.body)) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode >= 300 || testCase.expectStatusCode < 200 { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} diff --git a/components/ledger/internal/api/v1/controllers_balances.go b/components/ledger/internal/api/v1/controllers_balances.go new file mode 100644 index 000000000..bbb0f7c34 --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_balances.go @@ -0,0 +1,88 @@ +package v1 + +import ( + "math/big" + "net/http" + + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/pkg/errors" +) + +func buildAggregatedBalancesQuery(r *http.Request) (query.Builder, error) { + if address := r.URL.Query().Get("address"); address != "" { + return query.Match("address", address), nil + } + + return nil, nil +} + +func getBalancesAggregated(w http.ResponseWriter, r *http.Request) { + options, err := getPaginatedQueryOptionsOfPITFilter(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + + query := ledgerstore.NewGetAggregatedBalancesQuery(*options) + query.Options.QueryBuilder, err = buildAggregatedBalancesQuery(r) + + balances, err := LedgerFromContext(r.Context()).GetAggregatedBalances(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, balances) +} + +func getBalances(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + q := &ledgerstore.GetAccountsQuery{} + + if r.URL.Query().Get(QueryKeyCursor) != "" { + err := paginate.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), q) + if err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, errors.Errorf("invalid '%s' query param", QueryKeyCursor))) + return + } + } else { + options, err := getPaginatedQueryOptionsOfPITFilterWithVolumes(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + options.QueryBuilder, err = buildAccountsFilterQuery(r) + q = ledgerstore.NewGetAccountsQuery(*options) + } + + cursor, err := l.GetAccountsWithVolumes(r.Context(), q) + if err != nil { + ResponseError(w, r, err) + return + } + + ret := make([]map[string]map[string]*big.Int, 0) + for _, item := range cursor.Data { + e := map[string]map[string]*big.Int{ + item.Address: {}, + } + for asset, volumes := range item.Volumes { + e[item.Address][asset] = volumes.Balance() + } + ret = append(ret, e) + } + + sharedapi.RenderCursor(w, sharedapi.Cursor[map[string]map[string]*big.Int]{ + PageSize: cursor.PageSize, + HasMore: cursor.HasMore, + Previous: cursor.Previous, + Next: cursor.Next, + Data: ret, + }) +} diff --git a/components/ledger/internal/api/v1/controllers_balances_test.go b/components/ledger/internal/api/v1/controllers_balances_test.go new file mode 100644 index 000000000..97a9205bb --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_balances_test.go @@ -0,0 +1,69 @@ +package v1_test + +import ( + "math/big" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + ledger "github.com/formancehq/ledger/internal" + v1 "github.com/formancehq/ledger/internal/api/v1" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestGetBalancesAggregated(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + expectQuery ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilter] + } + + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilter{}), + }, + { + name: "using address", + queryParams: url.Values{ + "address": []string{"foo"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilter{}). + WithQueryBuilder(query.Match("address", "foo")), + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + expectedBalances := ledger.BalancesByAssets{ + "world": big.NewInt(-100), + } + backend, mock := newTestingBackend(t) + mock.EXPECT(). + GetAggregatedBalances(gomock.Any(), ledgerstore.NewGetAggregatedBalancesQuery(testCase.expectQuery)). + Return(expectedBalances, nil) + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/aggregate/balances", nil) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + balances, ok := sharedapi.DecodeSingleResponse[ledger.BalancesByAssets](t, rec.Body) + require.True(t, ok) + require.Equal(t, expectedBalances, balances) + }) + } +} diff --git a/components/ledger/internal/api/v1/controllers_config.go b/components/ledger/internal/api/v1/controllers_config.go new file mode 100644 index 000000000..f0036becd --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_config.go @@ -0,0 +1,44 @@ +package v1 + +import ( + _ "embed" + "net/http" + + "github.com/formancehq/ledger/internal/api/backend" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" +) + +type ConfigInfo struct { + Server string `json:"server"` + Version string `json:"version"` + Config *LedgerConfig `json:"config"` +} + +type LedgerConfig struct { + LedgerStorage *LedgerStorage `json:"storage"` +} + +type LedgerStorage struct { + Driver string `json:"driver"` + Ledgers []string `json:"ledgers"` +} + +func getInfo(backend backend.Backend) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + ledgers, err := backend.ListLedgers(r.Context()) + if err != nil { + panic(err) + } + + sharedapi.Ok(w, ConfigInfo{ + Server: "ledger", + Version: backend.GetVersion(), + Config: &LedgerConfig{ + LedgerStorage: &LedgerStorage{ + Driver: "postgres", + Ledgers: ledgers, + }, + }, + }) + } +} diff --git a/components/ledger/internal/api/v1/controllers_config_test.go b/components/ledger/internal/api/v1/controllers_config_test.go new file mode 100644 index 000000000..1b7fe085c --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_config_test.go @@ -0,0 +1,51 @@ +package v1_test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + v2 "github.com/formancehq/ledger/internal/api/v2" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestGetInfo(t *testing.T) { + t.Parallel() + + backend, _ := newTestingBackend(t) + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + backend. + EXPECT(). + ListLedgers(gomock.Any()). + Return([]string{"a", "b"}, nil) + + backend. + EXPECT(). + GetVersion(). + Return("latest") + + req := httptest.NewRequest(http.MethodGet, "/_info", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + + info := v2.ConfigInfo{} + require.NoError(t, json.NewDecoder(rec.Body).Decode(&info)) + + require.EqualValues(t, v2.ConfigInfo{ + Server: "ledger", + Version: "latest", + Config: &v2.LedgerConfig{ + LedgerStorage: &v2.LedgerStorage{ + Driver: "postgres", + Ledgers: []string{"a", "b"}, + }, + }, + }, info) +} diff --git a/components/ledger/internal/api/v1/controllers_info.go b/components/ledger/internal/api/v1/controllers_info.go new file mode 100644 index 000000000..2220eb46a --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_info.go @@ -0,0 +1,118 @@ +package v1 + +import ( + "net/http" + + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/formancehq/stack/libs/go-libs/migrations" + "github.com/go-chi/chi/v5" + "github.com/pkg/errors" +) + +type Info struct { + Name string `json:"name"` + Storage StorageInfo `json:"storage"` +} + +type StorageInfo struct { + Migrations []migrations.Info `json:"migrations"` +} + +func getLedgerInfo(w http.ResponseWriter, r *http.Request) { + ledger := LedgerFromContext(r.Context()) + + var err error + res := Info{ + Name: chi.URLParam(r, "ledger"), + Storage: StorageInfo{}, + } + res.Storage.Migrations, err = ledger.GetMigrationsInfo(r.Context()) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, res) +} + +func getStats(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + stats, err := l.Stats(r.Context()) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, stats) +} + +func buildGetLogsQuery(r *http.Request) (query.Builder, error) { + clauses := make([]query.Builder, 0) + if after := r.URL.Query().Get("after"); after != "" { + clauses = append(clauses, query.Lt("id", after)) + } + + if startTime := r.URL.Query().Get("start_time"); startTime != "" { + clauses = append(clauses, query.Gte("date", startTime)) + } + if endTime := r.URL.Query().Get("end_time"); endTime != "" { + clauses = append(clauses, query.Lt("date", endTime)) + } + + if len(clauses) == 0 { + return nil, nil + } + if len(clauses) == 1 { + return clauses[0], nil + } + + return query.And(clauses...), nil +} + +func getLogs(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + query := &ledgerstore.GetLogsQuery{} + + if r.URL.Query().Get(QueryKeyCursor) != "" { + err := paginate.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), query) + if err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.Errorf("invalid '%s' query param", QueryKeyCursor))) + return + } + } else { + var err error + + pageSize, err := getPageSize(r) + if err != nil { + ResponseError(w, r, err) + return + } + + qb, err := buildGetLogsQuery(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + + query = ledgerstore.NewGetLogsQuery(ledgerstore.PaginatedQueryOptions[any]{ + QueryBuilder: qb, + PageSize: uint64(pageSize), + }) + } + + cursor, err := l.GetLogs(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.RenderCursor(w, *cursor) +} diff --git a/components/ledger/internal/api/v1/controllers_info_test.go b/components/ledger/internal/api/v1/controllers_info_test.go new file mode 100644 index 000000000..af94bd844 --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_info_test.go @@ -0,0 +1,198 @@ +package v1_test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + ledger "github.com/formancehq/ledger/internal" + v1 "github.com/formancehq/ledger/internal/api/v1" + "github.com/formancehq/ledger/internal/engine" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/formancehq/stack/libs/go-libs/migrations" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestGetLedgerInfo(t *testing.T) { + t.Parallel() + + backend, mock := newTestingBackend(t) + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + migrationInfo := []migrations.Info{ + { + Version: "1", + Name: "init", + State: "ready", + Date: time.Now().Add(-2 * time.Minute).Round(time.Second), + }, + { + Version: "2", + Name: "fix", + State: "ready", + Date: time.Now().Add(-time.Minute).Round(time.Second), + }, + } + + mock.EXPECT(). + GetMigrationsInfo(gomock.Any()). + Return(migrationInfo, nil) + + req := httptest.NewRequest(http.MethodGet, "/xxx/_info", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + + info, ok := sharedapi.DecodeSingleResponse[v1.Info](t, rec.Body) + require.True(t, ok) + + require.EqualValues(t, v1.Info{ + Name: "xxx", + Storage: v1.StorageInfo{ + Migrations: migrationInfo, + }, + }, info) +} + +func TestGetStats(t *testing.T) { + t.Parallel() + + backend, mock := newTestingBackend(t) + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + expectedStats := engine.Stats{ + Transactions: 10, + Accounts: 5, + } + + mock.EXPECT(). + Stats(gomock.Any()). + Return(expectedStats, nil) + + req := httptest.NewRequest(http.MethodGet, "/xxx/stats", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + + stats, ok := sharedapi.DecodeSingleResponse[engine.Stats](t, rec.Body) + require.True(t, ok) + + require.EqualValues(t, expectedStats, stats) +} + +func TestGetLogs(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + expectQuery ledgerstore.PaginatedQueryOptions[any] + expectStatusCode int + expectedErrorCode string + } + + now := ledger.Now() + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions[any](nil), + }, + { + name: "using start time", + queryParams: url.Values{ + "start_time": []string{now.Format(ledger.DateFormat)}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions[any](nil).WithQueryBuilder(query.Gte("date", now.Format(ledger.DateFormat))), + }, + { + name: "using end time", + queryParams: url.Values{ + "end_time": []string{now.Format(ledger.DateFormat)}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions[any](nil). + WithQueryBuilder(query.Lt("date", now.Format(ledger.DateFormat))), + }, + { + name: "using empty cursor", + queryParams: url.Values{ + "cursor": []string{paginate.EncodeCursor(ledgerstore.NewGetLogsQuery(ledgerstore.NewPaginatedQueryOptions[any](nil)))}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions[any](nil), + }, + { + name: "using invalid cursor", + queryParams: url.Values{ + "cursor": []string{"xxx"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusOK + } + + expectedCursor := sharedapi.Cursor[ledger.ChainedLog]{ + Data: []ledger.ChainedLog{ + *ledger.NewTransactionLog(ledger.NewTransaction(), map[string]metadata.Metadata{}). + ChainLog(nil), + }, + } + + backend, mockLedger := newTestingBackend(t) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + mockLedger.EXPECT(). + GetLogs(gomock.Any(), ledgerstore.NewGetLogsQuery(testCase.expectQuery)). + Return(&expectedCursor, nil) + } + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/logs", nil) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + cursor := sharedapi.DecodeCursorResponse[ledger.ChainedLog](t, rec.Body) + + cursorData, err := json.Marshal(cursor) + require.NoError(t, err) + + cursorAsMap := make(map[string]any) + require.NoError(t, json.Unmarshal(cursorData, &cursorAsMap)) + + expectedCursorData, err := json.Marshal(expectedCursor) + require.NoError(t, err) + + expectedCursorAsMap := make(map[string]any) + require.NoError(t, json.Unmarshal(expectedCursorData, &expectedCursorAsMap)) + + require.Equal(t, expectedCursorAsMap, cursorAsMap) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} diff --git a/components/ledger/internal/api/v1/controllers_transactions.go b/components/ledger/internal/api/v1/controllers_transactions.go new file mode 100644 index 000000000..ca538d94e --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_transactions.go @@ -0,0 +1,316 @@ +package v1 + +import ( + "encoding/json" + "fmt" + "math/big" + "net/http" + "strconv" + "strings" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/collectionutils" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/go-chi/chi/v5" + "github.com/pkg/errors" +) + +func mapTransactionToV1(tx ledger.Transaction) any { + return struct { + ledger.Transaction + TxID *big.Int `json:"txid"` + ID *big.Int `json:"-"` + }{ + Transaction: tx, + TxID: tx.ID, + } +} + +func mapExpandedTransactionToV1(tx ledger.ExpandedTransaction) any { + return struct { + ledger.ExpandedTransaction + TxID *big.Int `json:"txid"` + ID *big.Int `json:"-"` + }{ + ExpandedTransaction: tx, + TxID: tx.ID, + } +} + +func buildGetTransactionsQuery(r *http.Request) (query.Builder, error) { + clauses := make([]query.Builder, 0) + if after := r.URL.Query().Get("after"); after != "" { + clauses = append(clauses, query.Lt("id", after)) + } + + if startTime := r.URL.Query().Get("start_time"); startTime != "" { + clauses = append(clauses, query.Gte("date", startTime)) + } + if endTime := r.URL.Query().Get("end_time"); endTime != "" { + clauses = append(clauses, query.Lt("date", endTime)) + } + + if reference := r.URL.Query().Get("reference"); reference != "" { + clauses = append(clauses, query.Match("reference", reference)) + } + if source := r.URL.Query().Get("source"); source != "" { + clauses = append(clauses, query.Match("source", source)) + } + if destination := r.URL.Query().Get("destination"); destination != "" { + clauses = append(clauses, query.Match("destination", destination)) + } + if address := r.URL.Query().Get("account"); address != "" { + clauses = append(clauses, query.Match("account", address)) + } + for elem, value := range r.URL.Query() { + if strings.HasPrefix(elem, "metadata") { + clauses = append(clauses, query.Match(elem, value[0])) + } + } + + if len(clauses) == 0 { + return nil, nil + } + if len(clauses) == 1 { + return clauses[0], nil + } + + return query.And(clauses...), nil +} + +func countTransactions(w http.ResponseWriter, r *http.Request) { + + options, err := getPaginatedQueryOptionsOfPITFilterWithVolumes(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + options.QueryBuilder, err = buildGetTransactionsQuery(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + + count, err := LedgerFromContext(r.Context()). + CountTransactions(r.Context(), ledgerstore.NewGetTransactionsQuery(*options)) + if err != nil { + ResponseError(w, r, err) + return + } + + w.Header().Set("Count", fmt.Sprint(count)) + sharedapi.NoContent(w) +} + +func getTransactions(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + query := &ledgerstore.GetTransactionsQuery{} + + if r.URL.Query().Get(QueryKeyCursor) != "" { + err := paginate.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), &query) + if err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.Errorf("invalid '%s' query param", QueryKeyCursor))) + return + } + } else { + options, err := getPaginatedQueryOptionsOfPITFilterWithVolumes(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + options.QueryBuilder, err = buildGetTransactionsQuery(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + query = ledgerstore.NewGetTransactionsQuery(*options) + } + + cursor, err := l.GetTransactions(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.RenderCursor(w, *sharedapi.MapCursor(cursor, mapExpandedTransactionToV1)) +} + +type Script struct { + ledger.Script + Vars map[string]any `json:"vars"` +} + +func (s Script) ToCore() ledger.Script { + s.Script.Vars = map[string]string{} + for k, v := range s.Vars { + switch v := v.(type) { + case string: + s.Script.Vars[k] = v + case map[string]any: + s.Script.Vars[k] = fmt.Sprintf("%s %v", v["asset"], v["amount"]) + default: + s.Script.Vars[k] = fmt.Sprint(v) + } + } + return s.Script +} + +type PostTransactionRequest struct { + Postings ledger.Postings `json:"postings"` + Script Script `json:"script"` + Timestamp ledger.Time `json:"timestamp"` + Reference string `json:"reference"` + Metadata metadata.Metadata `json:"metadata" swaggertype:"object"` +} + +func postTransaction(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + payload := PostTransactionRequest{} + if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { + ResponseError(w, r, + errorsutil.NewError(command.ErrValidation, + errors.New("invalid transaction format"))) + return + } + + if len(payload.Postings) > 0 && payload.Script.Plain != "" || + len(payload.Postings) == 0 && payload.Script.Plain == "" { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid payload: should contain either postings or script"))) + return + } else if len(payload.Postings) > 0 { + if i, err := payload.Postings.Validate(); err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, errors.Wrap(err, + fmt.Sprintf("invalid posting %d", i)))) + return + } + txData := ledger.TransactionData{ + Postings: payload.Postings, + Timestamp: payload.Timestamp, + Reference: payload.Reference, + Metadata: payload.Metadata, + } + + res, err := l.CreateTransaction(r.Context(), getCommandParameters(r), ledger.TxToScriptData(txData)) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, []any{mapTransactionToV1(*res)}) + return + } + + script := ledger.RunScript{ + Script: payload.Script.ToCore(), + Timestamp: payload.Timestamp, + Reference: payload.Reference, + Metadata: payload.Metadata, + } + + res, err := l.CreateTransaction(r.Context(), getCommandParameters(r), script) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, []any{mapTransactionToV1(*res)}) +} + +func getTransaction(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + txId, ok := big.NewInt(0).SetString(chi.URLParam(r, "id"), 10) + if !ok { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid transaction ID"))) + return + } + + query := ledgerstore.NewGetTransactionQuery(txId) + if collectionutils.Contains(r.URL.Query()["expand"], "volumes") { + query = query.WithExpandVolumes() + } + if collectionutils.Contains(r.URL.Query()["expand"], "effectiveVolumes") { + query = query.WithExpandEffectiveVolumes() + } + + tx, err := l.GetTransactionWithVolumes(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, mapExpandedTransactionToV1(*tx)) +} + +func revertTransaction(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + transactionID, ok := big.NewInt(0).SetString(chi.URLParam(r, "id"), 10) + if !ok { + sharedapi.NotFound(w) + return + } + + tx, err := l.RevertTransaction(r.Context(), getCommandParameters(r), transactionID) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Created(w, mapTransactionToV1(*tx)) +} + +func postTransactionMetadata(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + var m metadata.Metadata + if err := json.NewDecoder(r.Body).Decode(&m); err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid metadata format"))) + return + } + + txID, ok := big.NewInt(0).SetString(chi.URLParam(r, "id"), 10) + if !ok { + sharedapi.NotFound(w) + return + } + + if err := l.SaveMeta(r.Context(), getCommandParameters(r), ledger.MetaTargetTypeTransaction, txID, m); err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.NoContent(w) +} + +func deleteTransactionMetadata(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + transactionID, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 64) + if err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid transaction ID"))) + return + } + + metadataKey := chi.URLParam(r, "key") + + if err := l.DeleteMetadata(r.Context(), getCommandParameters(r), ledger.MetaTargetTypeTransaction, transactionID, metadataKey); err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.NoContent(w) +} diff --git a/components/ledger/internal/api/v1/controllers_transactions_test.go b/components/ledger/internal/api/v1/controllers_transactions_test.go new file mode 100644 index 000000000..73f1c7d43 --- /dev/null +++ b/components/ledger/internal/api/v1/controllers_transactions_test.go @@ -0,0 +1,625 @@ +package v1_test + +import ( + "math/big" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + ledger "github.com/formancehq/ledger/internal" + v1 "github.com/formancehq/ledger/internal/api/v1" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestPostTransactions(t *testing.T) { + type testCase struct { + name string + expectedPreview bool + expectedRunScript ledger.RunScript + payload any + expectedStatusCode int + expectedErrorCode string + queryParams url.Values + } + + testCases := []testCase{ + { + name: "using plain numscript", + payload: v1.PostTransactionRequest{ + Script: v1.Script{ + Script: ledger.Script{ + Plain: `XXX`, + }, + }, + }, + expectedRunScript: ledger.RunScript{ + Script: ledger.Script{ + Plain: `XXX`, + Vars: map[string]string{}, + }, + }, + }, + { + name: "using plain numscript with variables", + payload: v1.PostTransactionRequest{ + Script: v1.Script{ + Script: ledger.Script{ + Plain: `vars { + monetary $val + } + + send $val ( + source = @world + destination = @bank + )`, + }, + Vars: map[string]any{ + "val": "USD/2 100", + }, + }, + }, + expectedRunScript: ledger.RunScript{ + Script: ledger.Script{ + Plain: `vars { + monetary $val + } + + send $val ( + source = @world + destination = @bank + )`, + Vars: map[string]string{ + "val": "USD/2 100", + }, + }, + }, + }, + { + name: "using plain numscript with variables (legacy format)", + payload: v1.PostTransactionRequest{ + Script: v1.Script{ + Script: ledger.Script{ + Plain: `vars { + monetary $val + } + + send $val ( + source = @world + destination = @bank + )`, + }, + Vars: map[string]any{ + "val": map[string]any{ + "asset": "USD/2", + "amount": 100, + }, + }, + }, + }, + expectedRunScript: ledger.RunScript{ + Script: ledger.Script{ + Plain: `vars { + monetary $val + } + + send $val ( + source = @world + destination = @bank + )`, + Vars: map[string]string{ + "val": "USD/2 100", + }, + }, + }, + }, + { + name: "using plain numscript and dry run", + payload: v1.PostTransactionRequest{ + Script: v1.Script{ + Script: ledger.Script{ + Plain: `send ( + source = @world + destination = @bank + )`, + }, + }, + }, + expectedRunScript: ledger.RunScript{ + Script: ledger.Script{ + Plain: `send ( + source = @world + destination = @bank + )`, + Vars: map[string]string{}, + }, + }, + expectedPreview: true, + queryParams: url.Values{ + "preview": []string{"true"}, + }, + }, + { + name: "using JSON postings", + payload: v1.PostTransactionRequest{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + }, + }, + expectedRunScript: ledger.TxToScriptData(ledger.NewTransactionData().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + )), + }, + { + name: "using JSON postings and dry run", + queryParams: url.Values{ + "preview": []string{"true"}, + }, + payload: v1.PostTransactionRequest{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + }, + }, + expectedPreview: true, + expectedRunScript: ledger.TxToScriptData(ledger.NewTransactionData().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + )), + }, + { + name: "no postings or script", + payload: v1.PostTransactionRequest{}, + expectedStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + { + name: "postings and script", + payload: v1.PostTransactionRequest{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "alice", + Amount: big.NewInt(100), + Asset: "COIN", + }, + }, + Script: v1.Script{ + Script: ledger.Script{ + Plain: ` + send [COIN 100] ( + source = @world + destination = @bob + )`, + }, + }, + }, + expectedStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + { + name: "using invalid body", + payload: "not a valid payload", + expectedStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + } + + for _, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + if testCase.expectedStatusCode == 0 { + testCase.expectedStatusCode = http.StatusOK + } + + expectedTx := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ) + + backend, mockLedger := newTestingBackend(t) + if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { + mockLedger.EXPECT(). + CreateTransaction(gomock.Any(), command.Parameters{ + DryRun: tc.expectedPreview, + }, testCase.expectedRunScript). + Return(expectedTx, nil) + } + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodPost, "/xxx/transactions", sharedapi.Buffer(t, testCase.payload)) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectedStatusCode, rec.Code) + if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { + tx, ok := sharedapi.DecodeSingleResponse[[]ledger.Transaction](t, rec.Body) + require.True(t, ok) + require.Equal(t, *expectedTx, tx[0]) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestPostTransactionMetadata(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + expectStatusCode int + expectedErrorCode string + body any + } + + testCases := []testCase{ + { + name: "nominal", + body: metadata.Metadata{ + "foo": "bar", + }, + }, + { + name: "invalid body", + body: "invalid - not an object", + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusNoContent + } + + backend, mock := newTestingBackend(t) + if testCase.expectStatusCode == http.StatusNoContent { + mock.EXPECT(). + SaveMeta(gomock.Any(), command.Parameters{}, ledger.MetaTargetTypeTransaction, big.NewInt(0), testCase.body). + Return(nil) + } + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodPost, "/xxx/transactions/0/metadata", sharedapi.Buffer(t, testCase.body)) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode >= 300 || testCase.expectStatusCode < 200 { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestGetTransaction(t *testing.T) { + t.Parallel() + + tx := ledger.ExpandTransaction( + ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ), + nil, + ) + + backend, mock := newTestingBackend(t) + mock.EXPECT(). + GetTransactionWithVolumes(gomock.Any(), ledgerstore.NewGetTransactionQuery(big.NewInt(0))). + Return(&tx, nil) + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/transactions/0", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + response, _ := sharedapi.DecodeSingleResponse[ledger.ExpandedTransaction](t, rec.Body) + require.Equal(t, tx, response) +} + +func TestGetTransactions(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + expectQuery ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilterWithVolumes] + expectStatusCode int + expectedErrorCode string + } + now := ledger.Now() + + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}), + }, + { + name: "using metadata", + queryParams: url.Values{ + "metadata[roles]": []string{"admin"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("metadata[roles]", "admin")), + }, + { + name: "using startTime", + queryParams: url.Values{ + "start_time": []string{now.Format(ledger.DateFormat)}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Gte("date", now.Format(ledger.DateFormat))), + }, + { + name: "using endTime", + queryParams: url.Values{ + "end_time": []string{now.Format(ledger.DateFormat)}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Lt("date", now.Format(ledger.DateFormat))), + }, + { + name: "using account", + queryParams: url.Values{ + "account": []string{"xxx"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("account", "xxx")), + }, + { + name: "using reference", + queryParams: url.Values{ + "reference": []string{"xxx"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("reference", "xxx")), + }, + { + name: "using destination", + queryParams: url.Values{ + "destination": []string{"xxx"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("destination", "xxx")), + }, + { + name: "using source", + queryParams: url.Values{ + "source": []string{"xxx"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("source", "xxx")), + }, + { + name: "using empty cursor", + queryParams: url.Values{ + "cursor": []string{paginate.EncodeCursor(ledgerstore.NewGetTransactionsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{})))}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}), + }, + { + name: "using invalid cursor", + queryParams: url.Values{ + "cursor": []string{"XXX"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + { + name: "invalid page size", + queryParams: url.Values{ + "pageSize": []string{"nan"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v1.ErrValidation, + }, + { + name: "page size over maximum", + queryParams: url.Values{ + "pageSize": []string{"1000000"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithPageSize(v1.MaxPageSize), + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusOK + } + + expectedCursor := sharedapi.Cursor[ledger.ExpandedTransaction]{ + Data: []ledger.ExpandedTransaction{ + ledger.ExpandTransaction( + ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ), + nil, + ), + }, + } + + backend, mockLedger := newTestingBackend(t) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + mockLedger.EXPECT(). + GetTransactions(gomock.Any(), ledgerstore.NewGetTransactionsQuery(testCase.expectQuery)). + Return(&expectedCursor, nil) + } + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/transactions", nil) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + cursor := sharedapi.DecodeCursorResponse[ledger.ExpandedTransaction](t, rec.Body) + require.Equal(t, expectedCursor, *cursor) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestCountTransactions(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + expectQuery ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilterWithVolumes] + expectStatusCode int + expectedErrorCode string + } + now := ledger.Now() + + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}), + }, + { + name: "using metadata", + queryParams: url.Values{ + "metadata[roles]": []string{"admin"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("metadata[roles]", "admin")), + }, + { + name: "using startTime", + queryParams: url.Values{ + "start_time": []string{now.Format(ledger.DateFormat)}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Gte("date", now.Format(ledger.DateFormat))), + }, + { + name: "using endTime", + queryParams: url.Values{ + "end_time": []string{now.Format(ledger.DateFormat)}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Lt("date", now.Format(ledger.DateFormat))), + }, + { + name: "using account", + queryParams: url.Values{ + "account": []string{"xxx"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("account", "xxx")), + }, + { + name: "using reference", + queryParams: url.Values{ + "reference": []string{"xxx"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("reference", "xxx")), + }, + { + name: "using destination", + queryParams: url.Values{ + "destination": []string{"xxx"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("destination", "xxx")), + }, + { + name: "using source", + queryParams: url.Values{ + "source": []string{"xxx"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("source", "xxx")), + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusNoContent + } + + backend, mockLedger := newTestingBackend(t) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + mockLedger.EXPECT(). + CountTransactions(gomock.Any(), ledgerstore.NewGetTransactionsQuery(testCase.expectQuery)). + Return(uint64(10), nil) + } + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodHead, "/xxx/transactions", nil) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + require.Equal(t, "10", rec.Header().Get("Count")) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestRevertTransaction(t *testing.T) { + + expectedTx := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ) + + backend, mockLedger := newTestingBackend(t) + mockLedger. + EXPECT(). + RevertTransaction(gomock.Any(), command.Parameters{}, big.NewInt(0)). + Return(expectedTx, nil) + + router := v1.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodPost, "/xxx/transactions/0/revert", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusCreated, rec.Code) + tx, ok := sharedapi.DecodeSingleResponse[ledger.Transaction](t, rec.Body) + require.True(t, ok) + require.Equal(t, *expectedTx, tx) +} diff --git a/components/ledger/internal/api/v1/errors.go b/components/ledger/internal/api/v1/errors.go new file mode 100644 index 000000000..5d4615107 --- /dev/null +++ b/components/ledger/internal/api/v1/errors.go @@ -0,0 +1,110 @@ +package v1 + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/machine/vm" + storageerrors "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/pkg/errors" +) + +const ( + ErrInternal = "INTERNAL" + ErrConflict = "CONFLICT" + ErrInsufficientFund = "INSUFFICIENT_FUND" + ErrValidation = "VALIDATION" + ErrContextCancelled = "CONTEXT_CANCELLED" + ErrStore = "STORE" + ErrNotFound = "NOT_FOUND" + ErrScriptCompilationFailed = "COMPILATION_FAILED" + ErrScriptNoScript = "NO_SCRIPT" + ErrScriptMetadataOverride = "METADATA_OVERRIDE" + ScriptErrorInsufficientFund = "INSUFFICIENT_FUND" + ScriptErrorCompilationFailed = "COMPILATION_FAILED" + ScriptErrorNoScript = "NO_SCRIPT" + ScriptErrorMetadataOverride = "METADATA_OVERRIDE" + ResourceResolutionError = "RESOURCE_RESOLUTION_ERROR" +) + +func ResponseError(w http.ResponseWriter, r *http.Request, err error) { + status, code, details := coreErrorToErrorCode(err) + + baseError := errors.Cause(err) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + if status < 500 { + err := json.NewEncoder(w).Encode(api.ErrorResponse{ + ErrorCode: code, + ErrorMessage: baseError.Error(), + Details: details, + }) + if err != nil { + panic(err) + } + } else { + logging.FromContext(r.Context()).Errorf("internal server error: %s", err) + } +} + +func coreErrorToErrorCode(err error) (int, string, string) { + switch { + case command.IsConflictError(err): + return http.StatusConflict, ErrConflict, "" + case + command.IsValidationError(err), + command.IsPastTransactionError(err), + command.IsNoPostingsError(err), + errors.Is(err, command.ErrAlreadyReverted), + errors.Is(err, command.ErrRevertOccurring): + return http.StatusBadRequest, ErrValidation, "" + case storageerrors.IsNotFoundError(err): + return http.StatusNotFound, ErrNotFound, "" + case command.IsNoScriptError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ScriptErrorNoScript, EncodeLink(baseError.Error()) + case vm.IsInsufficientFundError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ScriptErrorInsufficientFund, EncodeLink(baseError.Error()) + case command.IsCompilationFailedError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ScriptErrorCompilationFailed, EncodeLink(baseError.Error()) + case vm.IsMetadataOverrideError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ScriptErrorMetadataOverride, EncodeLink(baseError.Error()) + case vm.IsResourceResolutionInvalidTypeFromExtSourcesError(err), + vm.IsResourceResolutionMissingMetadataError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ResourceResolutionError, EncodeLink(baseError.Error()) + case errors.Is(err, context.Canceled): + return http.StatusInternalServerError, ErrContextCancelled, "" + case storageerrors.IsStorageError(err): + return http.StatusServiceUnavailable, ErrStore, "" + default: + return http.StatusInternalServerError, ErrInternal, "" + } +} + +func EncodeLink(errStr string) string { + if errStr == "" { + return "" + } + + errStr = strings.ReplaceAll(errStr, "\n", "\r\n") + payload, err := json.Marshal(map[string]string{ + "error": errStr, + }) + if err != nil { + panic(err) + } + payloadB64 := base64.StdEncoding.EncodeToString(payload) + return fmt.Sprintf("https://play.numscript.org/?payload=%v", payloadB64) +} diff --git a/components/ledger/internal/api/v1/middlewares_metrics.go b/components/ledger/internal/api/v1/middlewares_metrics.go new file mode 100644 index 000000000..c552ad2e3 --- /dev/null +++ b/components/ledger/internal/api/v1/middlewares_metrics.go @@ -0,0 +1,54 @@ +package v1 + +import ( + "net/http" + "time" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/go-chi/chi/v5" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" +) + +type statusRecorder struct { + http.ResponseWriter + Status int +} + +func newStatusRecorder(w http.ResponseWriter) *statusRecorder { + return &statusRecorder{ResponseWriter: w} +} + +func (r *statusRecorder) WriteHeader(status int) { + r.Status = status + r.ResponseWriter.WriteHeader(status) +} + +func MetricsMiddleware(globalMetricsRegistry metrics.GlobalRegistry) func(h http.Handler) http.Handler { + return func(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + attrs := []attribute.KeyValue{} + + ctx := r.Context() + name := chi.URLParam(r, "ledger") + if name != "" { + attrs = append(attrs, attribute.String("ledger", name)) + } + + recorder := newStatusRecorder(w) + + start := ledger.Now() + h.ServeHTTP(recorder, r) + latency := time.Since(start.Time) + + attrs = append(attrs, + attribute.String("route", chi.RouteContext(r.Context()).RoutePattern())) + + globalMetricsRegistry.APILatencies().Record(ctx, latency.Milliseconds(), metric.WithAttributes(attrs...)) + + attrs = append(attrs, attribute.Int("status", recorder.Status)) + globalMetricsRegistry.StatusCodes().Add(ctx, 1, metric.WithAttributes(attrs...)) + }) + } +} diff --git a/components/ledger/internal/api/v1/middlewares_resolver.go b/components/ledger/internal/api/v1/middlewares_resolver.go new file mode 100644 index 000000000..c0e986fb0 --- /dev/null +++ b/components/ledger/internal/api/v1/middlewares_resolver.go @@ -0,0 +1,79 @@ +package v1 + +import ( + "math/rand" + "net/http" + "sync" + "time" + + "github.com/formancehq/ledger/internal/api/backend" + "github.com/formancehq/ledger/internal/opentelemetry/tracer" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/go-chi/chi/v5" +) + +var ( + r *rand.Rand + mu sync.Mutex +) + +func init() { + r = rand.New(rand.NewSource(time.Now().UnixNano())) +} + +var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") + +func randomTraceID(n int) string { + mu.Lock() + defer mu.Unlock() + + b := make([]rune, n) + for i := range b { + b[i] = letterRunes[r.Intn(len(letterRunes))] + } + return string(b) +} + +func LedgerMiddleware( + resolver backend.Backend, +) func(handler http.Handler) http.Handler { + return func(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + name := chi.URLParam(r, "ledger") + if name == "" { + w.WriteHeader(http.StatusNotFound) + return + } + + ctx, span := tracer.Start(r.Context(), name) + defer span.End() + + r = r.WithContext(ctx) + + loggerFields := map[string]any{ + "ledger": name, + } + if span.SpanContext().TraceID().IsValid() { + loggerFields["trace-id"] = span.SpanContext().TraceID().String() + } else { + loggerFields["trace-id"] = randomTraceID(10) + } + + r = r.WithContext(logging.ContextWithFields(r.Context(), loggerFields)) + + l, err := resolver.GetLedger(r.Context(), name) + if err != nil { + ResponseError(w, r, err) + return + } + // TODO(polo/gfyrag): close ledger if not used for x minutes + // defer l.Close(context.Background()) + // When close, we have to decrease the active ledgers counter: + // globalMetricsRegistry.ActiveLedgers.Add(r.Context(), -1) + + r = r.WithContext(ContextWithLedger(r.Context(), l)) + + handler.ServeHTTP(w, r) + }) + } +} diff --git a/components/ledger/internal/api/v1/query.go b/components/ledger/internal/api/v1/query.go new file mode 100644 index 000000000..6807bfa17 --- /dev/null +++ b/components/ledger/internal/api/v1/query.go @@ -0,0 +1,50 @@ +package v1 + +import ( + "errors" + "net/http" + "strconv" + + "github.com/formancehq/ledger/internal/storage/paginate" +) + +const ( + MaxPageSize = 1000 + DefaultPageSize = paginate.QueryDefaultPageSize + + QueryKeyCursor = "cursor" + QueryKeyPageSize = "pageSize" + QueryKeyBalanceOperator = "balanceOperator" +) + +func getPageSize(c *http.Request) (uint, error) { + pageSizeParam := c.URL.Query().Get(QueryKeyPageSize) + if pageSizeParam == "" { + return DefaultPageSize, nil + } + + var pageSize uint64 + var err error + if pageSizeParam != "" { + pageSize, err = strconv.ParseUint(pageSizeParam, 10, 32) + if err != nil { + return 0, errors.New("invalid page size") + } + } + + if pageSize > MaxPageSize { + return MaxPageSize, nil + } + + return uint(pageSize), nil +} + +func getBalanceOperator(c *http.Request) (string, error) { + balanceOperator := "eq" + balanceOperatorStr := c.URL.Query().Get(QueryKeyBalanceOperator) + if balanceOperatorStr != "" { + return balanceOperatorStr, nil + } + + return balanceOperator, nil +} diff --git a/components/ledger/internal/api/v1/routes.go b/components/ledger/internal/api/v1/routes.go new file mode 100644 index 000000000..98ebffa4e --- /dev/null +++ b/components/ledger/internal/api/v1/routes.go @@ -0,0 +1,79 @@ +package v1 + +import ( + "net/http" + + "github.com/formancehq/ledger/internal/api/backend" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/stack/libs/go-libs/health" + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" + "github.com/go-chi/cors" + "github.com/riandyrn/otelchi" +) + +func NewRouter( + backend backend.Backend, + healthController *health.HealthController, + globalMetricsRegistry metrics.GlobalRegistry, +) chi.Router { + router := chi.NewMux() + + router.Use( + cors.New(cors.Options{ + AllowOriginFunc: func(r *http.Request, origin string) bool { + return true + }, + AllowCredentials: true, + }).Handler, + MetricsMiddleware(globalMetricsRegistry), + middleware.Recoverer, + ) + + router.Get("/_healthcheck", healthController.Check) + + router.Group(func(router chi.Router) { + router.Use(otelchi.Middleware("ledger")) + router.Get("/_info", getInfo(backend)) + + router.Route("/{ledger}", func(router chi.Router) { + router.Use(func(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler.ServeHTTP(w, r) + }) + }) + router.Use(LedgerMiddleware(backend)) + + // LedgerController + router.Get("/_info", getLedgerInfo) + router.Get("/stats", getStats) + router.Get("/logs", getLogs) + + // AccountController + router.Get("/accounts", getAccounts) + router.Head("/accounts", countAccounts) + router.Get("/accounts/{address}", getAccount) + router.Post("/accounts/{address}/metadata", postAccountMetadata) + router.Delete("/accounts/{address}/metadata/{key}", deleteAccountMetadata) + + // TransactionController + router.Get("/transactions", getTransactions) + router.Head("/transactions", countTransactions) + + router.Post("/transactions", postTransaction) + router.Post("/transactions/batch", func(w http.ResponseWriter, r *http.Request) { + http.Error(w, "not supported", http.StatusBadRequest) + }) + + router.Get("/transactions/{id}", getTransaction) + router.Post("/transactions/{id}/revert", revertTransaction) + router.Post("/transactions/{id}/metadata", postTransactionMetadata) + router.Delete("/transactions/{id}/metadata/{key}", deleteTransactionMetadata) + + router.Get("/balances", getBalances) + router.Get("/aggregate/balances", getBalancesAggregated) + }) + }) + + return router +} diff --git a/components/ledger/internal/api/v1/utils.go b/components/ledger/internal/api/v1/utils.go new file mode 100644 index 000000000..592ee757f --- /dev/null +++ b/components/ledger/internal/api/v1/utils.go @@ -0,0 +1,97 @@ +package v1 + +import ( + "net/http" + "strings" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/query" + "github.com/formancehq/stack/libs/go-libs/collectionutils" + "github.com/formancehq/stack/libs/go-libs/pointer" +) + +func getPITFilter(r *http.Request) (*ledgerstore.PITFilter, error) { + pitString := r.URL.Query().Get("pit") + if pitString == "" { + return &ledgerstore.PITFilter{}, nil + } + pit, err := ledger.ParseTime(pitString) + if err != nil { + return nil, err + } + return &ledgerstore.PITFilter{ + PIT: &pit, + }, nil +} + +func getPITFilterWithVolumes(r *http.Request) (*ledgerstore.PITFilterWithVolumes, error) { + pit, err := getPITFilter(r) + if err != nil { + return nil, err + } + return &ledgerstore.PITFilterWithVolumes{ + PITFilter: *pit, + ExpandVolumes: collectionutils.Contains(r.URL.Query()["expand"], "volumes"), + ExpandEffectiveVolumes: collectionutils.Contains(r.URL.Query()["expand"], "effectiveVolumes"), + }, nil +} + +func getQueryBuilder(r *http.Request) (query.Builder, error) { + return query.ParseJSON(r.URL.Query().Get("query")) +} + +func getPaginatedQueryOptionsOfPITFilterWithVolumes(r *http.Request) (*ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilterWithVolumes], error) { + qb, err := getQueryBuilder(r) + if err != nil { + return nil, err + } + + pitFilter, err := getPITFilterWithVolumes(r) + if err != nil { + return nil, err + } + + pageSize, err := getPageSize(r) + if err != nil { + return nil, err + } + + return pointer.For(ledgerstore.NewPaginatedQueryOptions(*pitFilter). + WithQueryBuilder(qb). + WithPageSize(uint64(pageSize))), nil +} + +func getPaginatedQueryOptionsOfPITFilter(r *http.Request) (*ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilter], error) { + qb, err := getQueryBuilder(r) + if err != nil { + return nil, err + } + + pitFilter, err := getPITFilter(r) + if err != nil { + return nil, err + } + + pageSize, err := getPageSize(r) + if err != nil { + return nil, err + } + + return pointer.For(ledgerstore.NewPaginatedQueryOptions(*pitFilter). + WithQueryBuilder(qb). + WithPageSize(uint64(pageSize))), nil +} + +func getCommandParameters(r *http.Request) command.Parameters { + dryRunAsString := r.URL.Query().Get("preview") + dryRun := strings.ToUpper(dryRunAsString) == "YES" || strings.ToUpper(dryRunAsString) == "TRUE" || dryRunAsString == "1" + + idempotencyKey := r.Header.Get("Idempotency-Key") + + return command.Parameters{ + DryRun: dryRun, + IdempotencyKey: idempotencyKey, + } +} diff --git a/components/ledger/internal/api/v2/api_utils_test.go b/components/ledger/internal/api/v2/api_utils_test.go new file mode 100644 index 000000000..8a42c93ac --- /dev/null +++ b/components/ledger/internal/api/v2/api_utils_test.go @@ -0,0 +1,23 @@ +package v2_test + +import ( + "testing" + + "github.com/formancehq/ledger/internal/api/backend" + "github.com/golang/mock/gomock" +) + +func newTestingBackend(t *testing.T) (*backend.MockBackend, *backend.MockLedger) { + ctrl := gomock.NewController(t) + mockLedger := backend.NewMockLedger(ctrl) + backend := backend.NewMockBackend(ctrl) + backend. + EXPECT(). + GetLedger(gomock.Any(), gomock.Any()). + MinTimes(0). + Return(mockLedger, nil) + t.Cleanup(func() { + ctrl.Finish() + }) + return backend, mockLedger +} diff --git a/components/ledger/internal/api/v2/context.go b/components/ledger/internal/api/v2/context.go new file mode 100644 index 000000000..a2029ed9b --- /dev/null +++ b/components/ledger/internal/api/v2/context.go @@ -0,0 +1,19 @@ +package v2 + +import ( + "context" + + "github.com/formancehq/ledger/internal/api/backend" +) + +type ledgerKey struct{} + +var _ledgerKey = ledgerKey{} + +func ContextWithLedger(ctx context.Context, ledger backend.Ledger) context.Context { + return context.WithValue(ctx, _ledgerKey, ledger) +} + +func LedgerFromContext(ctx context.Context) backend.Ledger { + return ctx.Value(_ledgerKey).(backend.Ledger) +} diff --git a/components/ledger/internal/api/v2/controllers_accounts.go b/components/ledger/internal/api/v2/controllers_accounts.go new file mode 100644 index 000000000..fad853191 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_accounts.go @@ -0,0 +1,134 @@ +package v2 + +import ( + "encoding/json" + "fmt" + "net/http" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/collectionutils" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/go-chi/chi/v5" + "github.com/pkg/errors" +) + +func countAccounts(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + options, err := getPaginatedQueryOptionsOfPITFilterWithVolumes(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + + count, err := l.CountAccounts(r.Context(), ledgerstore.NewGetAccountsQuery(*options)) + if err != nil { + ResponseError(w, r, err) + return + } + + w.Header().Set("Count", fmt.Sprint(count)) + sharedapi.NoContent(w) +} + +func getAccounts(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + query := &ledgerstore.GetAccountsQuery{} + + if r.URL.Query().Get(QueryKeyCursor) != "" { + err := paginate.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), query) + if err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.Errorf("invalid '%s' query param", QueryKeyCursor))) + return + } + } else { + options, err := getPaginatedQueryOptionsOfPITFilterWithVolumes(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + query = ledgerstore.NewGetAccountsQuery(*options) + } + + cursor, err := l.GetAccountsWithVolumes(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.RenderCursor(w, *cursor) +} + +func getAccount(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + query := ledgerstore.NewGetAccountQuery(chi.URLParam(r, "address")) + if collectionutils.Contains(r.URL.Query()["expand"], "volumes") { + query = query.WithExpandVolumes() + } + if collectionutils.Contains(r.URL.Query()["expand"], "effectiveVolumes") { + query = query.WithExpandEffectiveVolumes() + } + pitFilter, err := getPITFilter(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + query.PITFilter = *pitFilter + + acc, err := l.GetAccountWithVolumes(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, acc) +} + +func postAccountMetadata(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + if !ledger.ValidateAddress(chi.URLParam(r, "address")) { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid account address format"))) + return + } + + var m metadata.Metadata + if err := json.NewDecoder(r.Body).Decode(&m); err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid metadata format"))) + return + } + + err := l.SaveMeta(r.Context(), getCommandParameters(r), ledger.MetaTargetTypeAccount, chi.URLParam(r, "address"), m) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.NoContent(w) +} + +func deleteAccountMetadata(w http.ResponseWriter, r *http.Request) { + if err := LedgerFromContext(r.Context()). + DeleteMetadata( + r.Context(), + getCommandParameters(r), + ledger.MetaTargetTypeAccount, + chi.URLParam(r, "address"), + chi.URLParam(r, "key"), + ); err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.NoContent(w) +} diff --git a/components/ledger/internal/api/v2/controllers_accounts_test.go b/components/ledger/internal/api/v2/controllers_accounts_test.go new file mode 100644 index 000000000..bc51bab78 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_accounts_test.go @@ -0,0 +1,235 @@ +package v2_test + +import ( + "bytes" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + ledger "github.com/formancehq/ledger/internal" + v2 "github.com/formancehq/ledger/internal/api/v2" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestGetAccounts(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + body string + expectQuery ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilterWithVolumes] + expectStatusCode int + expectedErrorCode string + } + + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithPageSize(v2.DefaultPageSize), + }, + { + name: "using metadata", + body: `{"$match": { "metadata[roles]": "admin" }}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("metadata[roles]", "admin")). + WithPageSize(v2.DefaultPageSize), + }, + { + name: "using address", + body: `{"$match": { "address": "foo" }}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("address", "foo")). + WithPageSize(v2.DefaultPageSize), + }, + { + name: "using empty cursor", + queryParams: url.Values{ + "cursor": []string{paginate.EncodeCursor(ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{})))}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}), + }, + { + name: "using invalid cursor", + queryParams: url.Values{ + "cursor": []string{"XXX"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + { + name: "invalid page size", + queryParams: url.Values{ + "pageSize": []string{"nan"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + { + name: "page size over maximum", + queryParams: url.Values{ + "pageSize": []string{"1000000"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithPageSize(v2.MaxPageSize), + }, + { + name: "using balance filter", + body: `{"$lt": { "balance[USD/2]": 100 }}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Lt("balance[USD/2]", float64(100))). + WithPageSize(v2.DefaultPageSize), + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusOK + } + + expectedCursor := sharedapi.Cursor[ledger.ExpandedAccount]{ + Data: []ledger.ExpandedAccount{ + { + Account: ledger.Account{ + Address: "world", + Metadata: metadata.Metadata{}, + }, + }, + }, + } + + backend, mockLedger := newTestingBackend(t) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + mockLedger.EXPECT(). + GetAccountsWithVolumes(gomock.Any(), ledgerstore.NewGetAccountsQuery(testCase.expectQuery)). + Return(&expectedCursor, nil) + } + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/accounts", bytes.NewBufferString(testCase.body)) + rec := httptest.NewRecorder() + if testCase.queryParams != nil { + req.URL.RawQuery = testCase.queryParams.Encode() + } + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + cursor := sharedapi.DecodeCursorResponse[ledger.ExpandedAccount](t, rec.Body) + require.Equal(t, expectedCursor, *cursor) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestGetAccount(t *testing.T) { + t.Parallel() + + account := ledger.ExpandedAccount{ + Account: ledger.Account{ + Address: "foo", + Metadata: metadata.Metadata{}, + }, + } + + backend, mock := newTestingBackend(t) + mock.EXPECT(). + GetAccountWithVolumes(gomock.Any(), ledgerstore.NewGetAccountQuery("foo")). + Return(&account, nil) + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/accounts/foo", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + response, _ := sharedapi.DecodeSingleResponse[ledger.ExpandedAccount](t, rec.Body) + require.Equal(t, account, response) +} + +func TestPostAccountMetadata(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + expectStatusCode int + expectedErrorCode string + account string + body any + } + + testCases := []testCase{ + { + name: "nominal", + account: "world", + body: metadata.Metadata{ + "foo": "bar", + }, + }, + { + name: "invalid account address format", + account: "invalid-acc", + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + { + name: "invalid body", + account: "world", + body: "invalid - not an object", + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusNoContent + } + + backend, mock := newTestingBackend(t) + if testCase.expectStatusCode == http.StatusNoContent { + mock.EXPECT(). + SaveMeta(gomock.Any(), command.Parameters{}, ledger.MetaTargetTypeAccount, testCase.account, testCase.body). + Return(nil) + } + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodPost, "/xxx/accounts/"+testCase.account+"/metadata", sharedapi.Buffer(t, testCase.body)) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode >= 300 || testCase.expectStatusCode < 200 { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} diff --git a/components/ledger/internal/api/v2/controllers_balances.go b/components/ledger/internal/api/v2/controllers_balances.go new file mode 100644 index 000000000..a66c35de8 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_balances.go @@ -0,0 +1,25 @@ +package v2 + +import ( + "net/http" + + "github.com/formancehq/ledger/internal/storage/ledgerstore" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" +) + +func getBalancesAggregated(w http.ResponseWriter, r *http.Request) { + options, err := getPaginatedQueryOptionsOfPITFilter(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + + balances, err := LedgerFromContext(r.Context()). + GetAggregatedBalances(r.Context(), ledgerstore.NewGetAggregatedBalancesQuery(*options)) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, balances) +} diff --git a/components/ledger/internal/api/v2/controllers_balances_test.go b/components/ledger/internal/api/v2/controllers_balances_test.go new file mode 100644 index 000000000..8842c91a4 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_balances_test.go @@ -0,0 +1,71 @@ +package v2_test + +import ( + "bytes" + "math/big" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + ledger "github.com/formancehq/ledger/internal" + v2 "github.com/formancehq/ledger/internal/api/v2" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestGetBalancesAggregated(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + body string + expectQuery ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilter] + } + + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilter{}), + }, + { + name: "using address", + body: `{"$match": {"address": "foo"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilter{}). + WithQueryBuilder(query.Match("address", "foo")), + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + expectedBalances := ledger.BalancesByAssets{ + "world": big.NewInt(-100), + } + backend, mock := newTestingBackend(t) + mock.EXPECT(). + GetAggregatedBalances(gomock.Any(), ledgerstore.NewGetAggregatedBalancesQuery(testCase.expectQuery)). + Return(expectedBalances, nil) + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/aggregate/balances", bytes.NewBufferString(testCase.body)) + rec := httptest.NewRecorder() + if testCase.queryParams != nil { + req.URL.RawQuery = testCase.queryParams.Encode() + } + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + balances, ok := sharedapi.DecodeSingleResponse[ledger.BalancesByAssets](t, rec.Body) + require.True(t, ok) + require.Equal(t, expectedBalances, balances) + }) + } +} diff --git a/components/ledger/internal/api/v2/controllers_config.go b/components/ledger/internal/api/v2/controllers_config.go new file mode 100644 index 000000000..a159dd632 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_config.go @@ -0,0 +1,44 @@ +package v2 + +import ( + _ "embed" + "net/http" + + "github.com/formancehq/ledger/internal/api/backend" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" +) + +type ConfigInfo struct { + Server string `json:"server"` + Version string `json:"version"` + Config *LedgerConfig `json:"config"` +} + +type LedgerConfig struct { + LedgerStorage *LedgerStorage `json:"storage"` +} + +type LedgerStorage struct { + Driver string `json:"driver"` + Ledgers []string `json:"ledgers"` +} + +func getInfo(backend backend.Backend) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + ledgers, err := backend.ListLedgers(r.Context()) + if err != nil { + panic(err) + } + + sharedapi.RawOk(w, ConfigInfo{ + Server: "ledger", + Version: backend.GetVersion(), + Config: &LedgerConfig{ + LedgerStorage: &LedgerStorage{ + Driver: "postgres", + Ledgers: ledgers, + }, + }, + }) + } +} diff --git a/components/ledger/internal/api/v2/controllers_config_test.go b/components/ledger/internal/api/v2/controllers_config_test.go new file mode 100644 index 000000000..cf87e6435 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_config_test.go @@ -0,0 +1,51 @@ +package v2_test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + v2 "github.com/formancehq/ledger/internal/api/v2" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestGetInfo(t *testing.T) { + t.Parallel() + + backend, _ := newTestingBackend(t) + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + backend. + EXPECT(). + ListLedgers(gomock.Any()). + Return([]string{"a", "b"}, nil) + + backend. + EXPECT(). + GetVersion(). + Return("latest") + + req := httptest.NewRequest(http.MethodGet, "/_info", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + + info := v2.ConfigInfo{} + require.NoError(t, json.NewDecoder(rec.Body).Decode(&info)) + + require.EqualValues(t, v2.ConfigInfo{ + Server: "ledger", + Version: "latest", + Config: &v2.LedgerConfig{ + LedgerStorage: &v2.LedgerStorage{ + Driver: "postgres", + Ledgers: []string{"a", "b"}, + }, + }, + }, info) +} diff --git a/components/ledger/internal/api/v2/controllers_info.go b/components/ledger/internal/api/v2/controllers_info.go new file mode 100644 index 000000000..18e17b381 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_info.go @@ -0,0 +1,94 @@ +package v2 + +import ( + "net/http" + + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/formancehq/stack/libs/go-libs/migrations" + "github.com/go-chi/chi/v5" + "github.com/pkg/errors" +) + +type Info struct { + Name string `json:"name"` + Storage StorageInfo `json:"storage"` +} + +type StorageInfo struct { + Migrations []migrations.Info `json:"migrations"` +} + +func getLedgerInfo(w http.ResponseWriter, r *http.Request) { + ledger := LedgerFromContext(r.Context()) + + var err error + res := Info{ + Name: chi.URLParam(r, "ledger"), + Storage: StorageInfo{}, + } + res.Storage.Migrations, err = ledger.GetMigrationsInfo(r.Context()) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, res) +} + +func getStats(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + stats, err := l.Stats(r.Context()) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, stats) +} + +func getLogs(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + query := &ledgerstore.GetLogsQuery{} + + if r.URL.Query().Get(QueryKeyCursor) != "" { + err := paginate.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), query) + if err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.Errorf("invalid '%s' query param", QueryKeyCursor))) + return + } + } else { + var err error + + pageSize, err := getPageSize(r) + if err != nil { + ResponseError(w, r, err) + return + } + + qb, err := getQueryBuilder(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + + query = ledgerstore.NewGetLogsQuery(ledgerstore.PaginatedQueryOptions[any]{ + QueryBuilder: qb, + PageSize: pageSize, + }) + } + + cursor, err := l.GetLogs(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.RenderCursor(w, *cursor) +} diff --git a/components/ledger/internal/api/v2/controllers_info_test.go b/components/ledger/internal/api/v2/controllers_info_test.go new file mode 100644 index 000000000..d22bfa177 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_info_test.go @@ -0,0 +1,199 @@ +package v2_test + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + ledger "github.com/formancehq/ledger/internal" + v2 "github.com/formancehq/ledger/internal/api/v2" + "github.com/formancehq/ledger/internal/engine" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/formancehq/stack/libs/go-libs/migrations" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestGetLedgerInfo(t *testing.T) { + t.Parallel() + + backend, mock := newTestingBackend(t) + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + migrationInfo := []migrations.Info{ + { + Version: "1", + Name: "init", + State: "ready", + Date: time.Now().Add(-2 * time.Minute).Round(time.Second), + }, + { + Version: "2", + Name: "fix", + State: "ready", + Date: time.Now().Add(-time.Minute).Round(time.Second), + }, + } + + mock.EXPECT(). + GetMigrationsInfo(gomock.Any()). + Return(migrationInfo, nil) + + req := httptest.NewRequest(http.MethodGet, "/xxx/_info", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + + info, ok := sharedapi.DecodeSingleResponse[v2.Info](t, rec.Body) + require.True(t, ok) + + require.EqualValues(t, v2.Info{ + Name: "xxx", + Storage: v2.StorageInfo{ + Migrations: migrationInfo, + }, + }, info) +} + +func TestGetStats(t *testing.T) { + t.Parallel() + + backend, mock := newTestingBackend(t) + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + expectedStats := engine.Stats{ + Transactions: 10, + Accounts: 5, + } + + mock.EXPECT(). + Stats(gomock.Any()). + Return(expectedStats, nil) + + req := httptest.NewRequest(http.MethodGet, "/xxx/stats", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + + stats, ok := sharedapi.DecodeSingleResponse[engine.Stats](t, rec.Body) + require.True(t, ok) + + require.EqualValues(t, expectedStats, stats) +} + +func TestGetLogs(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + body string + expectQuery ledgerstore.PaginatedQueryOptions[any] + expectStatusCode int + expectedErrorCode string + } + + now := ledger.Now() + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions[any](nil), + }, + { + name: "using start time", + body: fmt.Sprintf(`{"$gte": {"date": "%s"}}`, now.Format(ledger.DateFormat)), + expectQuery: ledgerstore.NewPaginatedQueryOptions[any](nil).WithQueryBuilder(query.Gte("date", now.Format(ledger.DateFormat))), + }, + { + name: "using end time", + body: fmt.Sprintf(`{"$lt": {"date": "%s"}}`, now.Format(ledger.DateFormat)), + expectQuery: ledgerstore.NewPaginatedQueryOptions[any](nil). + WithQueryBuilder(query.Lt("date", now.Format(ledger.DateFormat))), + }, + { + name: "using empty cursor", + queryParams: url.Values{ + "cursor": []string{paginate.EncodeCursor(ledgerstore.NewGetLogsQuery(ledgerstore.NewPaginatedQueryOptions[any](nil)))}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions[any](nil), + }, + { + name: "using invalid cursor", + queryParams: url.Values{ + "cursor": []string{"xxx"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusOK + } + + expectedCursor := sharedapi.Cursor[ledger.ChainedLog]{ + Data: []ledger.ChainedLog{ + *ledger.NewTransactionLog(ledger.NewTransaction(), map[string]metadata.Metadata{}). + ChainLog(nil), + }, + } + + backend, mockLedger := newTestingBackend(t) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + mockLedger.EXPECT(). + GetLogs(gomock.Any(), ledgerstore.NewGetLogsQuery(testCase.expectQuery)). + Return(&expectedCursor, nil) + } + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/logs", bytes.NewBufferString(testCase.body)) + rec := httptest.NewRecorder() + if testCase.queryParams != nil { + req.URL.RawQuery = testCase.queryParams.Encode() + } + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + cursor := sharedapi.DecodeCursorResponse[ledger.ChainedLog](t, rec.Body) + + cursorData, err := json.Marshal(cursor) + require.NoError(t, err) + + cursorAsMap := make(map[string]any) + require.NoError(t, json.Unmarshal(cursorData, &cursorAsMap)) + + expectedCursorData, err := json.Marshal(expectedCursor) + require.NoError(t, err) + + expectedCursorAsMap := make(map[string]any) + require.NoError(t, json.Unmarshal(expectedCursorData, &expectedCursorAsMap)) + + require.Equal(t, expectedCursorAsMap, cursorAsMap) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} diff --git a/components/ledger/internal/api/v2/controllers_transactions.go b/components/ledger/internal/api/v2/controllers_transactions.go new file mode 100644 index 000000000..cdb67f0d1 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_transactions.go @@ -0,0 +1,248 @@ +package v2 + +import ( + "encoding/json" + "fmt" + "math/big" + "net/http" + "strconv" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/collectionutils" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/go-chi/chi/v5" + "github.com/pkg/errors" +) + +func countTransactions(w http.ResponseWriter, r *http.Request) { + + options, err := getPaginatedQueryOptionsOfPITFilterWithVolumes(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + + count, err := LedgerFromContext(r.Context()). + CountTransactions(r.Context(), ledgerstore.NewGetTransactionsQuery(*options)) + if err != nil { + ResponseError(w, r, err) + return + } + + w.Header().Set("Count", fmt.Sprint(count)) + sharedapi.NoContent(w) +} + +func getTransactions(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + query := &ledgerstore.GetTransactionsQuery{} + + if r.URL.Query().Get(QueryKeyCursor) != "" { + err := paginate.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), &query) + if err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.Errorf("invalid '%s' query param", QueryKeyCursor))) + return + } + } else { + options, err := getPaginatedQueryOptionsOfPITFilterWithVolumes(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + query = ledgerstore.NewGetTransactionsQuery(*options) + } + + cursor, err := l.GetTransactions(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.RenderCursor(w, *cursor) +} + +type Script struct { + ledger.Script + Vars map[string]any `json:"vars"` +} + +func (s Script) ToCore() ledger.Script { + s.Script.Vars = map[string]string{} + for k, v := range s.Vars { + switch v := v.(type) { + case string: + s.Script.Vars[k] = v + case map[string]any: + s.Script.Vars[k] = fmt.Sprintf("%s %v", v["asset"], v["amount"]) + default: + s.Script.Vars[k] = fmt.Sprint(v) + } + } + return s.Script +} + +type PostTransactionRequest struct { + Postings ledger.Postings `json:"postings"` + Script Script `json:"script"` + Timestamp ledger.Time `json:"timestamp"` + Reference string `json:"reference"` + Metadata metadata.Metadata `json:"metadata" swaggertype:"object"` +} + +func postTransaction(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + payload := PostTransactionRequest{} + if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { + ResponseError(w, r, + errorsutil.NewError(command.ErrValidation, + errors.New("invalid transaction format"))) + return + } + + if len(payload.Postings) > 0 && payload.Script.Plain != "" || + len(payload.Postings) == 0 && payload.Script.Plain == "" { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid payload: should contain either postings or script"))) + return + } else if len(payload.Postings) > 0 { + if i, err := payload.Postings.Validate(); err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, errors.Wrap(err, + fmt.Sprintf("invalid posting %d", i)))) + return + } + txData := ledger.TransactionData{ + Postings: payload.Postings, + Timestamp: payload.Timestamp, + Reference: payload.Reference, + Metadata: payload.Metadata, + } + + res, err := l.CreateTransaction(r.Context(), getCommandParameters(r), ledger.TxToScriptData(txData)) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, res) + return + } + + script := ledger.RunScript{ + Script: payload.Script.ToCore(), + Timestamp: payload.Timestamp, + Reference: payload.Reference, + Metadata: payload.Metadata, + } + + res, err := l.CreateTransaction(r.Context(), getCommandParameters(r), script) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, res) +} + +func getTransaction(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + txId, ok := big.NewInt(0).SetString(chi.URLParam(r, "id"), 10) + if !ok { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid transaction ID"))) + return + } + + query := ledgerstore.NewGetTransactionQuery(txId) + if collectionutils.Contains(r.URL.Query()["expand"], "volumes") { + query = query.WithExpandVolumes() + } + if collectionutils.Contains(r.URL.Query()["expand"], "effectiveVolumes") { + query = query.WithExpandEffectiveVolumes() + } + + pitFilter, err := getPITFilter(r) + if err != nil { + sharedapi.BadRequest(w, ErrValidation, err) + return + } + query.PITFilter = *pitFilter + + tx, err := l.GetTransactionWithVolumes(r.Context(), query) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Ok(w, tx) +} + +func revertTransaction(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + transactionID, ok := big.NewInt(0).SetString(chi.URLParam(r, "id"), 10) + if !ok { + sharedapi.NotFound(w) + return + } + + tx, err := l.RevertTransaction(r.Context(), getCommandParameters(r), transactionID) + if err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.Created(w, tx) +} + +func postTransactionMetadata(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + var m metadata.Metadata + if err := json.NewDecoder(r.Body).Decode(&m); err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid metadata format"))) + return + } + + txID, ok := big.NewInt(0).SetString(chi.URLParam(r, "id"), 10) + if !ok { + sharedapi.NotFound(w) + return + } + + if err := l.SaveMeta(r.Context(), getCommandParameters(r), ledger.MetaTargetTypeTransaction, txID, m); err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.NoContent(w) +} + +func deleteTransactionMetadata(w http.ResponseWriter, r *http.Request) { + l := LedgerFromContext(r.Context()) + + transactionID, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 64) + if err != nil { + ResponseError(w, r, errorsutil.NewError(command.ErrValidation, + errors.New("invalid transaction ID"))) + return + } + + metadataKey := chi.URLParam(r, "key") + + if err := l.DeleteMetadata(r.Context(), getCommandParameters(r), ledger.MetaTargetTypeTransaction, transactionID, metadataKey); err != nil { + ResponseError(w, r, err) + return + } + + sharedapi.NoContent(w) +} diff --git a/components/ledger/internal/api/v2/controllers_transactions_test.go b/components/ledger/internal/api/v2/controllers_transactions_test.go new file mode 100644 index 000000000..5c5d3aee1 --- /dev/null +++ b/components/ledger/internal/api/v2/controllers_transactions_test.go @@ -0,0 +1,605 @@ +package v2_test + +import ( + "bytes" + "fmt" + "math/big" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + ledger "github.com/formancehq/ledger/internal" + v2 "github.com/formancehq/ledger/internal/api/v2" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + sharedapi "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestPostTransactions(t *testing.T) { + type testCase struct { + name string + expectedDryRun bool + expectedRunScript ledger.RunScript + payload any + expectedStatusCode int + expectedErrorCode string + queryParams url.Values + } + + testCases := []testCase{ + { + name: "using plain numscript", + payload: v2.PostTransactionRequest{ + Script: v2.Script{ + Script: ledger.Script{ + Plain: `XXX`, + }, + }, + }, + expectedRunScript: ledger.RunScript{ + Script: ledger.Script{ + Plain: `XXX`, + Vars: map[string]string{}, + }, + }, + }, + { + name: "using plain numscript with variables", + payload: v2.PostTransactionRequest{ + Script: v2.Script{ + Script: ledger.Script{ + Plain: `vars { + monetary $val + } + + send $val ( + source = @world + destination = @bank + )`, + }, + Vars: map[string]any{ + "val": "USD/2 100", + }, + }, + }, + expectedRunScript: ledger.RunScript{ + Script: ledger.Script{ + Plain: `vars { + monetary $val + } + + send $val ( + source = @world + destination = @bank + )`, + Vars: map[string]string{ + "val": "USD/2 100", + }, + }, + }, + }, + { + name: "using plain numscript with variables (legacy format)", + payload: v2.PostTransactionRequest{ + Script: v2.Script{ + Script: ledger.Script{ + Plain: `vars { + monetary $val + } + + send $val ( + source = @world + destination = @bank + )`, + }, + Vars: map[string]any{ + "val": map[string]any{ + "asset": "USD/2", + "amount": 100, + }, + }, + }, + }, + expectedRunScript: ledger.RunScript{ + Script: ledger.Script{ + Plain: `vars { + monetary $val + } + + send $val ( + source = @world + destination = @bank + )`, + Vars: map[string]string{ + "val": "USD/2 100", + }, + }, + }, + }, + { + name: "using plain numscript and dry run", + payload: v2.PostTransactionRequest{ + Script: v2.Script{ + Script: ledger.Script{ + Plain: `send ( + source = @world + destination = @bank + )`, + }, + }, + }, + expectedRunScript: ledger.RunScript{ + Script: ledger.Script{ + Plain: `send ( + source = @world + destination = @bank + )`, + Vars: map[string]string{}, + }, + }, + expectedDryRun: true, + queryParams: url.Values{ + "dryRun": []string{"true"}, + }, + }, + { + name: "using JSON postings", + payload: v2.PostTransactionRequest{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + }, + }, + expectedRunScript: ledger.TxToScriptData(ledger.NewTransactionData().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + )), + }, + { + name: "using JSON postings and dry run", + queryParams: url.Values{ + "dryRun": []string{"true"}, + }, + payload: v2.PostTransactionRequest{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + }, + }, + expectedDryRun: true, + expectedRunScript: ledger.TxToScriptData(ledger.NewTransactionData().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + )), + }, + { + name: "no postings or script", + payload: v2.PostTransactionRequest{}, + expectedStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + { + name: "postings and script", + payload: v2.PostTransactionRequest{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "alice", + Amount: big.NewInt(100), + Asset: "COIN", + }, + }, + Script: v2.Script{ + Script: ledger.Script{ + Plain: ` + send [COIN 100] ( + source = @world + destination = @bob + )`, + }, + }, + }, + expectedStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + { + name: "using invalid body", + payload: "not a valid payload", + expectedStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + } + + for _, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + if testCase.expectedStatusCode == 0 { + testCase.expectedStatusCode = http.StatusOK + } + + expectedTx := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ) + + backend, mockLedger := newTestingBackend(t) + if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { + mockLedger.EXPECT(). + CreateTransaction(gomock.Any(), command.Parameters{ + DryRun: tc.expectedDryRun, + }, testCase.expectedRunScript). + Return(expectedTx, nil) + } + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodPost, "/xxx/transactions", sharedapi.Buffer(t, testCase.payload)) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectedStatusCode, rec.Code) + if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { + tx, ok := sharedapi.DecodeSingleResponse[ledger.Transaction](t, rec.Body) + require.True(t, ok) + require.Equal(t, *expectedTx, tx) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestPostTransactionMetadata(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + expectStatusCode int + expectedErrorCode string + body any + } + + testCases := []testCase{ + { + name: "nominal", + body: metadata.Metadata{ + "foo": "bar", + }, + }, + { + name: "invalid body", + body: "invalid - not an object", + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusNoContent + } + + backend, mock := newTestingBackend(t) + if testCase.expectStatusCode == http.StatusNoContent { + mock.EXPECT(). + SaveMeta(gomock.Any(), command.Parameters{}, ledger.MetaTargetTypeTransaction, big.NewInt(0), testCase.body). + Return(nil) + } + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodPost, "/xxx/transactions/0/metadata", sharedapi.Buffer(t, testCase.body)) + rec := httptest.NewRecorder() + req.URL.RawQuery = testCase.queryParams.Encode() + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode >= 300 || testCase.expectStatusCode < 200 { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestGetTransaction(t *testing.T) { + t.Parallel() + + tx := ledger.ExpandTransaction( + ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ), + nil, + ) + + backend, mock := newTestingBackend(t) + mock.EXPECT(). + GetTransactionWithVolumes(gomock.Any(), ledgerstore.NewGetTransactionQuery(big.NewInt(0))). + Return(&tx, nil) + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/transactions/0", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusOK, rec.Code) + response, _ := sharedapi.DecodeSingleResponse[ledger.ExpandedTransaction](t, rec.Body) + require.Equal(t, tx, response) +} + +func TestGetTransactions(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + body string + expectQuery ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilterWithVolumes] + expectStatusCode int + expectedErrorCode string + } + now := ledger.Now() + + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}), + }, + { + name: "using metadata", + body: `{"$match": {"metadata[roles]": "admin"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("metadata[roles]", "admin")), + }, + { + name: "using startTime", + body: fmt.Sprintf(`{"$gte": {"start_time": "%s"}}`, now.Format(ledger.DateFormat)), + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Gte("start_time", now.Format(ledger.DateFormat))), + }, + { + name: "using endTime", + body: fmt.Sprintf(`{"$lte": {"end_time": "%s"}}`, now.Format(ledger.DateFormat)), + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Lte("end_time", now.Format(ledger.DateFormat))), + }, + { + name: "using account", + body: `{"$match": {"account": "xxx"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("account", "xxx")), + }, + { + name: "using reference", + body: `{"$match": {"reference": "xxx"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("reference", "xxx")), + }, + { + name: "using destination", + body: `{"$match": {"destination": "xxx"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("destination", "xxx")), + }, + { + name: "using source", + body: `{"$match": {"source": "xxx"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("source", "xxx")), + }, + { + name: "using empty cursor", + queryParams: url.Values{ + "cursor": []string{paginate.EncodeCursor(ledgerstore.NewGetTransactionsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{})))}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}), + }, + { + name: "using invalid cursor", + queryParams: url.Values{ + "cursor": []string{"XXX"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + { + name: "invalid page size", + queryParams: url.Values{ + "pageSize": []string{"nan"}, + }, + expectStatusCode: http.StatusBadRequest, + expectedErrorCode: v2.ErrValidation, + }, + { + name: "page size over maximum", + queryParams: url.Values{ + "pageSize": []string{"1000000"}, + }, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithPageSize(v2.MaxPageSize), + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusOK + } + + expectedCursor := sharedapi.Cursor[ledger.ExpandedTransaction]{ + Data: []ledger.ExpandedTransaction{ + ledger.ExpandTransaction( + ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ), + nil, + ), + }, + } + + backend, mockLedger := newTestingBackend(t) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + mockLedger.EXPECT(). + GetTransactions(gomock.Any(), ledgerstore.NewGetTransactionsQuery(testCase.expectQuery)). + Return(&expectedCursor, nil) + } + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodGet, "/xxx/transactions", bytes.NewBufferString(testCase.body)) + rec := httptest.NewRecorder() + if testCase.queryParams != nil { + req.URL.RawQuery = testCase.queryParams.Encode() + } + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + cursor := sharedapi.DecodeCursorResponse[ledger.ExpandedTransaction](t, rec.Body) + require.Equal(t, expectedCursor, *cursor) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestCountTransactions(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + queryParams url.Values + body string + expectQuery ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilterWithVolumes] + expectStatusCode int + expectedErrorCode string + } + now := ledger.Now() + + testCases := []testCase{ + { + name: "nominal", + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}), + }, + { + name: "using metadata", + body: `{"$match": {"metadata[roles]": "admin"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("metadata[roles]", "admin")), + }, + { + name: "using startTime", + body: fmt.Sprintf(`{"$gte": {"date": "%s"}}`, now.Format(ledger.DateFormat)), + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Gte("date", now.Format(ledger.DateFormat))), + }, + { + name: "using endTime", + body: fmt.Sprintf(`{"$gte": {"date": "%s"}}`, now.Format(ledger.DateFormat)), + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Gte("date", now.Format(ledger.DateFormat))), + }, + { + name: "using account", + body: `{"$match": {"account": "xxx"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("account", "xxx")), + }, + { + name: "using reference", + body: `{"$match": {"reference": "xxx"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("reference", "xxx")), + }, + { + name: "using destination", + body: `{"$match": {"destination": "xxx"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("destination", "xxx")), + }, + { + name: "using source", + body: `{"$match": {"source": "xxx"}}`, + expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("source", "xxx")), + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + + if testCase.expectStatusCode == 0 { + testCase.expectStatusCode = http.StatusNoContent + } + + backend, mockLedger := newTestingBackend(t) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + mockLedger.EXPECT(). + CountTransactions(gomock.Any(), ledgerstore.NewGetTransactionsQuery(testCase.expectQuery)). + Return(uint64(10), nil) + } + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodHead, "/xxx/transactions", bytes.NewBufferString(testCase.body)) + rec := httptest.NewRecorder() + if testCase.queryParams != nil { + req.URL.RawQuery = testCase.queryParams.Encode() + } + + router.ServeHTTP(rec, req) + + require.Equal(t, testCase.expectStatusCode, rec.Code) + if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { + require.Equal(t, "10", rec.Header().Get("Count")) + } else { + err := sharedapi.ErrorResponse{} + sharedapi.Decode(t, rec.Body, &err) + require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) + } + }) + } +} + +func TestRevertTransaction(t *testing.T) { + + expectedTx := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ) + + backend, mockLedger := newTestingBackend(t) + mockLedger. + EXPECT(). + RevertTransaction(gomock.Any(), command.Parameters{}, big.NewInt(0)). + Return(expectedTx, nil) + + router := v2.NewRouter(backend, nil, metrics.NewNoOpRegistry()) + + req := httptest.NewRequest(http.MethodPost, "/xxx/transactions/0/revert", nil) + rec := httptest.NewRecorder() + + router.ServeHTTP(rec, req) + + require.Equal(t, http.StatusCreated, rec.Code) + tx, ok := sharedapi.DecodeSingleResponse[ledger.Transaction](t, rec.Body) + require.True(t, ok) + require.Equal(t, *expectedTx, tx) +} diff --git a/components/ledger/internal/api/v2/errors.go b/components/ledger/internal/api/v2/errors.go new file mode 100644 index 000000000..888749900 --- /dev/null +++ b/components/ledger/internal/api/v2/errors.go @@ -0,0 +1,110 @@ +package v2 + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/machine/vm" + storageerrors "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/pkg/errors" +) + +const ( + ErrInternal = "INTERNAL" + ErrConflict = "CONFLICT" + ErrInsufficientFund = "INSUFFICIENT_FUND" + ErrValidation = "VALIDATION" + ErrContextCancelled = "CONTEXT_CANCELLED" + ErrStore = "STORE" + ErrNotFound = "NOT_FOUND" + ErrScriptCompilationFailed = "COMPILATION_FAILED" + ErrScriptNoScript = "NO_SCRIPT" + ErrScriptMetadataOverride = "METADATA_OVERRIDE" + ScriptErrorInsufficientFund = "INSUFFICIENT_FUND" + ScriptErrorCompilationFailed = "COMPILATION_FAILED" + ScriptErrorNoScript = "NO_SCRIPT" + ScriptErrorMetadataOverride = "METADATA_OVERRIDE" + ResourceResolutionError = "RESOURCE_RESOLUTION_ERROR" +) + +func ResponseError(w http.ResponseWriter, r *http.Request, err error) { + status, code, details := coreErrorToErrorCode(err) + + baseError := errors.Cause(err) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + if status < 500 { + err := json.NewEncoder(w).Encode(api.ErrorResponse{ + ErrorCode: code, + ErrorMessage: baseError.Error(), + Details: details, + }) + if err != nil { + panic(err) + } + } else { + logging.FromContext(r.Context()).Errorf("internal server error: %s", err) + } +} + +func coreErrorToErrorCode(err error) (int, string, string) { + switch { + case command.IsConflictError(err): + return http.StatusConflict, ErrConflict, "" + case + command.IsValidationError(err), + command.IsPastTransactionError(err), + command.IsNoPostingsError(err), + errors.Is(err, command.ErrAlreadyReverted), + errors.Is(err, command.ErrRevertOccurring): + return http.StatusBadRequest, ErrValidation, "" + case storageerrors.IsNotFoundError(err): + return http.StatusNotFound, ErrNotFound, "" + case command.IsNoScriptError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ScriptErrorNoScript, EncodeLink(baseError.Error()) + case vm.IsInsufficientFundError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ScriptErrorInsufficientFund, EncodeLink(baseError.Error()) + case command.IsCompilationFailedError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ScriptErrorCompilationFailed, EncodeLink(baseError.Error()) + case vm.IsMetadataOverrideError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ScriptErrorMetadataOverride, EncodeLink(baseError.Error()) + case vm.IsResourceResolutionInvalidTypeFromExtSourcesError(err), + vm.IsResourceResolutionMissingMetadataError(err): + baseError := errors.Cause(err) + return http.StatusBadRequest, ResourceResolutionError, EncodeLink(baseError.Error()) + case errors.Is(err, context.Canceled): + return http.StatusInternalServerError, ErrContextCancelled, "" + case storageerrors.IsStorageError(err): + return http.StatusServiceUnavailable, ErrStore, "" + default: + return http.StatusInternalServerError, ErrInternal, "" + } +} + +func EncodeLink(errStr string) string { + if errStr == "" { + return "" + } + + errStr = strings.ReplaceAll(errStr, "\n", "\r\n") + payload, err := json.Marshal(map[string]string{ + "error": errStr, + }) + if err != nil { + panic(err) + } + payloadB64 := base64.StdEncoding.EncodeToString(payload) + return fmt.Sprintf("https://play.numscript.org/?payload=%v", payloadB64) +} diff --git a/components/ledger/internal/api/v2/middlewares_metrics.go b/components/ledger/internal/api/v2/middlewares_metrics.go new file mode 100644 index 000000000..40ec7814d --- /dev/null +++ b/components/ledger/internal/api/v2/middlewares_metrics.go @@ -0,0 +1,54 @@ +package v2 + +import ( + "net/http" + "time" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/go-chi/chi/v5" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" +) + +type statusRecorder struct { + http.ResponseWriter + Status int +} + +func newStatusRecorder(w http.ResponseWriter) *statusRecorder { + return &statusRecorder{ResponseWriter: w} +} + +func (r *statusRecorder) WriteHeader(status int) { + r.Status = status + r.ResponseWriter.WriteHeader(status) +} + +func MetricsMiddleware(globalMetricsRegistry metrics.GlobalRegistry) func(h http.Handler) http.Handler { + return func(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + attrs := []attribute.KeyValue{} + + ctx := r.Context() + name := chi.URLParam(r, "ledger") + if name != "" { + attrs = append(attrs, attribute.String("ledger", name)) + } + + recorder := newStatusRecorder(w) + + start := ledger.Now() + h.ServeHTTP(recorder, r) + latency := time.Since(start.Time) + + attrs = append(attrs, + attribute.String("route", chi.RouteContext(r.Context()).RoutePattern())) + + globalMetricsRegistry.APILatencies().Record(ctx, latency.Milliseconds(), metric.WithAttributes(attrs...)) + + attrs = append(attrs, attribute.Int("status", recorder.Status)) + globalMetricsRegistry.StatusCodes().Add(ctx, 1, metric.WithAttributes(attrs...)) + }) + } +} diff --git a/components/ledger/internal/api/v2/middlewares_resolver.go b/components/ledger/internal/api/v2/middlewares_resolver.go new file mode 100644 index 000000000..ee5548bcd --- /dev/null +++ b/components/ledger/internal/api/v2/middlewares_resolver.go @@ -0,0 +1,79 @@ +package v2 + +import ( + "math/rand" + "net/http" + "sync" + "time" + + "github.com/formancehq/ledger/internal/api/backend" + "github.com/formancehq/ledger/internal/opentelemetry/tracer" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/go-chi/chi/v5" +) + +var ( + r *rand.Rand + mu sync.Mutex +) + +func init() { + r = rand.New(rand.NewSource(time.Now().UnixNano())) +} + +var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") + +func randomTraceID(n int) string { + mu.Lock() + defer mu.Unlock() + + b := make([]rune, n) + for i := range b { + b[i] = letterRunes[r.Intn(len(letterRunes))] + } + return string(b) +} + +func LedgerMiddleware( + resolver backend.Backend, +) func(handler http.Handler) http.Handler { + return func(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + name := chi.URLParam(r, "ledger") + if name == "" { + w.WriteHeader(http.StatusNotFound) + return + } + + ctx, span := tracer.Start(r.Context(), name) + defer span.End() + + r = r.WithContext(ctx) + + loggerFields := map[string]any{ + "ledger": name, + } + if span.SpanContext().TraceID().IsValid() { + loggerFields["trace-id"] = span.SpanContext().TraceID().String() + } else { + loggerFields["trace-id"] = randomTraceID(10) + } + + r = r.WithContext(logging.ContextWithFields(r.Context(), loggerFields)) + + l, err := resolver.GetLedger(r.Context(), name) + if err != nil { + ResponseError(w, r, err) + return + } + // TODO(polo/gfyrag): close ledger if not used for x minutes + // defer l.Close(context.Background()) + // When close, we have to decrease the active ledgers counter: + // globalMetricsRegistry.ActiveLedgers.Add(r.Context(), -1) + + r = r.WithContext(ContextWithLedger(r.Context(), l)) + + handler.ServeHTTP(w, r) + }) + } +} diff --git a/components/ledger/internal/api/v2/query.go b/components/ledger/internal/api/v2/query.go new file mode 100644 index 000000000..a055051c5 --- /dev/null +++ b/components/ledger/internal/api/v2/query.go @@ -0,0 +1,62 @@ +package v2 + +import ( + "net/http" + "strconv" + "strings" + + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/pkg/errors" +) + +const ( + MaxPageSize = 100 + DefaultPageSize = paginate.QueryDefaultPageSize + + QueryKeyCursor = "cursor" + QueryKeyPageSize = "pageSize" +) + +var ( + ErrInvalidPageSize = errors.New("invalid 'pageSize' query param") + ErrInvalidBalanceOperator = errors.New( + "invalid parameter 'balanceOperator', should be one of 'e, ne, gt, gte, lt, lte'") + ErrInvalidStartTime = errors.New("invalid 'startTime' query param") + ErrInvalidEndTime = errors.New("invalid 'endTime' query param") +) + +func getPageSize(r *http.Request) (uint64, error) { + pageSizeParam := r.URL.Query().Get(QueryKeyPageSize) + if pageSizeParam == "" { + return DefaultPageSize, nil + } + + var pageSize uint64 + var err error + if pageSizeParam != "" { + pageSize, err = strconv.ParseUint(pageSizeParam, 10, 32) + if err != nil { + return 0, errorsutil.NewError(command.ErrValidation, ErrInvalidPageSize) + } + } + + if pageSize > MaxPageSize { + return MaxPageSize, nil + } + + return pageSize, nil +} + +func getCommandParameters(r *http.Request) command.Parameters { + dryRunAsString := r.URL.Query().Get("dryRun") + dryRun := strings.ToUpper(dryRunAsString) == "YES" || strings.ToUpper(dryRunAsString) == "TRUE" || dryRunAsString == "1" + + idempotencyKey := r.Header.Get("Idempotency-Key") + + return command.Parameters{ + DryRun: dryRun, + IdempotencyKey: idempotencyKey, + } +} diff --git a/components/ledger/internal/api/v2/routes.go b/components/ledger/internal/api/v2/routes.go new file mode 100644 index 000000000..30a729bee --- /dev/null +++ b/components/ledger/internal/api/v2/routes.go @@ -0,0 +1,71 @@ +package v2 + +import ( + "net/http" + + "github.com/formancehq/ledger/internal/api/backend" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/stack/libs/go-libs/health" + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" + "github.com/go-chi/cors" + "github.com/riandyrn/otelchi" +) + +func NewRouter( + backend backend.Backend, + healthController *health.HealthController, + globalMetricsRegistry metrics.GlobalRegistry, +) chi.Router { + router := chi.NewMux() + + router.Use( + cors.New(cors.Options{ + AllowOriginFunc: func(r *http.Request, origin string) bool { + return true + }, + AllowCredentials: true, + }).Handler, + MetricsMiddleware(globalMetricsRegistry), + middleware.Recoverer, + ) + + router.Get("/_healthcheck", healthController.Check) + + router.Group(func(router chi.Router) { + router.Use(otelchi.Middleware("ledger")) + router.Get("/_info", getInfo(backend)) + + router.Route("/{ledger}", func(router chi.Router) { + router.Use(LedgerMiddleware(backend)) + + // LedgerController + router.Get("/_info", getLedgerInfo) + router.Get("/stats", getStats) + router.Get("/logs", getLogs) + + // AccountController + router.Get("/accounts", getAccounts) + router.Head("/accounts", countAccounts) + router.Get("/accounts/{address}", getAccount) + router.Post("/accounts/{address}/metadata", postAccountMetadata) + router.Delete("/accounts/{address}/metadata/{key}", deleteAccountMetadata) + + // TransactionController + router.Get("/transactions", getTransactions) + router.Head("/transactions", countTransactions) + + router.Post("/transactions", postTransaction) + + router.Get("/transactions/{id}", getTransaction) + router.Post("/transactions/{id}/revert", revertTransaction) + router.Post("/transactions/{id}/metadata", postTransactionMetadata) + router.Delete("/transactions/{id}/metadata/{key}", deleteTransactionMetadata) + + // TODO: Rename to /aggregatedBalances + router.Get("/aggregate/balances", getBalancesAggregated) + }) + }) + + return router +} diff --git a/components/ledger/internal/api/v2/utils.go b/components/ledger/internal/api/v2/utils.go new file mode 100644 index 000000000..cc73fb3e8 --- /dev/null +++ b/components/ledger/internal/api/v2/utils.go @@ -0,0 +1,92 @@ +package v2 + +import ( + "io" + "net/http" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/query" + "github.com/formancehq/stack/libs/go-libs/collectionutils" + "github.com/formancehq/stack/libs/go-libs/pointer" +) + +func getPITFilter(r *http.Request) (*ledgerstore.PITFilter, error) { + pitString := r.URL.Query().Get("pit") + if pitString == "" { + return &ledgerstore.PITFilter{}, nil + } + pit, err := ledger.ParseTime(pitString) + if err != nil { + return nil, err + } + return &ledgerstore.PITFilter{ + PIT: &pit, + }, nil +} + +func getPITFilterWithVolumes(r *http.Request) (*ledgerstore.PITFilterWithVolumes, error) { + pit, err := getPITFilter(r) + if err != nil { + return nil, err + } + return &ledgerstore.PITFilterWithVolumes{ + PITFilter: *pit, + ExpandVolumes: collectionutils.Contains(r.URL.Query()["expand"], "volumes"), + ExpandEffectiveVolumes: collectionutils.Contains(r.URL.Query()["expand"], "effectiveVolumes"), + }, nil +} + +func getQueryBuilder(r *http.Request) (query.Builder, error) { + data, err := io.ReadAll(r.Body) + if err != nil { + return nil, err + } + + if len(data) > 0 { + return query.ParseJSON(string(data)) + } + return nil, nil +} + +func getPaginatedQueryOptionsOfPITFilterWithVolumes(r *http.Request) (*ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilterWithVolumes], error) { + qb, err := getQueryBuilder(r) + if err != nil { + return nil, err + } + + pitFilter, err := getPITFilterWithVolumes(r) + if err != nil { + return nil, err + } + + pageSize, err := getPageSize(r) + if err != nil { + return nil, err + } + + return pointer.For(ledgerstore.NewPaginatedQueryOptions(*pitFilter). + WithQueryBuilder(qb). + WithPageSize(pageSize)), nil +} + +func getPaginatedQueryOptionsOfPITFilter(r *http.Request) (*ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilter], error) { + qb, err := getQueryBuilder(r) + if err != nil { + return nil, err + } + + pitFilter, err := getPITFilter(r) + if err != nil { + return nil, err + } + + pageSize, err := getPageSize(r) + if err != nil { + return nil, err + } + + return pointer.For(ledgerstore.NewPaginatedQueryOptions(*pitFilter). + WithQueryBuilder(qb). + WithPageSize(pageSize)), nil +} diff --git a/components/ledger/internal/asset.go b/components/ledger/internal/asset.go new file mode 100644 index 000000000..bca09f3f0 --- /dev/null +++ b/components/ledger/internal/asset.go @@ -0,0 +1,13 @@ +package ledger + +import ( + "regexp" +) + +const AssetPattern = `[A-Z][A-Z0-9]{0,16}(\/\d{1,6})?` + +var AssetRegexp = regexp.MustCompile("^" + AssetPattern + "$") + +func AssetIsValid(v string) bool { + return AssetRegexp.Match([]byte(v)) +} diff --git a/components/ledger/internal/bigint.go b/components/ledger/internal/bigint.go new file mode 100644 index 000000000..d0bd3f2cf --- /dev/null +++ b/components/ledger/internal/bigint.go @@ -0,0 +1,7 @@ +package ledger + +import ( + "math/big" +) + +var Zero = big.NewInt(0) diff --git a/components/ledger/internal/bus/message.go b/components/ledger/internal/bus/message.go new file mode 100644 index 000000000..87e0fcd58 --- /dev/null +++ b/components/ledger/internal/bus/message.go @@ -0,0 +1,81 @@ +package bus + +import ( + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/pkg/events" + "github.com/formancehq/stack/libs/go-libs/metadata" +) + +type EventMessage struct { + Date ledger.Time `json:"date"` + App string `json:"app"` + Version string `json:"version"` + Type string `json:"type"` + Payload any `json:"payload"` +} + +type CommittedTransactions struct { + Ledger string `json:"ledger"` + Transaction ledger.Transaction `json:"transaction"` + AccountMetadata map[string]metadata.Metadata `json:"accountMetadata"` +} + +func newEventCommittedTransactions(txs CommittedTransactions) EventMessage { + return EventMessage{ + Date: ledger.Now(), + App: events.EventApp, + Version: events.EventVersion, + Type: events.EventTypeCommittedTransactions, + Payload: txs, + } +} + +type SavedMetadata struct { + Ledger string `json:"ledger"` + TargetType string `json:"targetType"` + TargetID string `json:"targetId"` + Metadata metadata.Metadata `json:"metadata"` +} + +func newEventSavedMetadata(metadata SavedMetadata) EventMessage { + return EventMessage{ + Date: ledger.Now(), + App: events.EventApp, + Version: events.EventVersion, + Type: events.EventTypeSavedMetadata, + Payload: metadata, + } +} + +type RevertedTransaction struct { + Ledger string `json:"ledger"` + RevertedTransaction ledger.Transaction `json:"revertedTransaction"` + RevertTransaction ledger.Transaction `json:"revertTransaction"` +} + +func newEventRevertedTransaction(tx RevertedTransaction) EventMessage { + return EventMessage{ + Date: ledger.Now(), + App: events.EventApp, + Version: events.EventVersion, + Type: events.EventTypeRevertedTransaction, + Payload: tx, + } +} + +type DeletedMetadata struct { + Ledger string `json:"ledger"` + TargetType string `json:"targetType"` + TargetID any `json:"targetID"` + Key string `json:"key"` +} + +func newEventDeletedMetadata(tx DeletedMetadata) EventMessage { + return EventMessage{ + Date: ledger.Now(), + App: events.EventApp, + Version: events.EventVersion, + Type: events.EventTypeDeletedMetadata, + Payload: tx, + } +} diff --git a/components/ledger/internal/bus/monitor.go b/components/ledger/internal/bus/monitor.go new file mode 100644 index 000000000..926460aa7 --- /dev/null +++ b/components/ledger/internal/bus/monitor.go @@ -0,0 +1,97 @@ +package bus + +import ( + "context" + + "github.com/ThreeDotsLabs/watermill/message" + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/pkg/events" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/formancehq/stack/libs/go-libs/publish" +) + +type Monitor interface { + CommittedTransactions(ctx context.Context, res ledger.Transaction, accountMetadata map[string]metadata.Metadata) + SavedMetadata(ctx context.Context, targetType, id string, metadata metadata.Metadata) + RevertedTransaction(ctx context.Context, reverted, revert *ledger.Transaction) + DeletedMetadata(ctx context.Context, targetType string, targetID any, key string) +} + +type noOpMonitor struct{} + +func (n noOpMonitor) DeletedMetadata(ctx context.Context, targetType string, targetID any, key string) { +} + +func (n noOpMonitor) CommittedTransactions(ctx context.Context, res ledger.Transaction, accountMetadata map[string]metadata.Metadata) { +} +func (n noOpMonitor) SavedMetadata(ctx context.Context, targetType string, id string, metadata metadata.Metadata) { +} +func (n noOpMonitor) RevertedTransaction(ctx context.Context, reverted, revert *ledger.Transaction) { +} + +var _ Monitor = &noOpMonitor{} + +func NewNoOpMonitor() *noOpMonitor { + return &noOpMonitor{} +} + +type ledgerMonitor struct { + publisher message.Publisher + ledgerName string +} + +var _ Monitor = &ledgerMonitor{} + +func NewLedgerMonitor(publisher message.Publisher, ledgerName string) *ledgerMonitor { + m := &ledgerMonitor{ + publisher: publisher, + ledgerName: ledgerName, + } + return m +} + +func (l *ledgerMonitor) CommittedTransactions(ctx context.Context, txs ledger.Transaction, accountMetadata map[string]metadata.Metadata) { + l.publish(ctx, events.EventTypeCommittedTransactions, + newEventCommittedTransactions(CommittedTransactions{ + Ledger: l.ledgerName, + Transaction: txs, + AccountMetadata: accountMetadata, + })) +} + +func (l *ledgerMonitor) SavedMetadata(ctx context.Context, targetType, targetID string, metadata metadata.Metadata) { + l.publish(ctx, events.EventTypeSavedMetadata, + newEventSavedMetadata(SavedMetadata{ + Ledger: l.ledgerName, + TargetType: targetType, + TargetID: targetID, + Metadata: metadata, + })) +} + +func (l *ledgerMonitor) RevertedTransaction(ctx context.Context, reverted, revert *ledger.Transaction) { + l.publish(ctx, events.EventTypeRevertedTransaction, + newEventRevertedTransaction(RevertedTransaction{ + Ledger: l.ledgerName, + RevertedTransaction: *reverted, + RevertTransaction: *revert, + })) +} + +func (l *ledgerMonitor) DeletedMetadata(ctx context.Context, targetType string, targetID any, key string) { + l.publish(ctx, events.EventTypeDeletedMetadata, + newEventDeletedMetadata(DeletedMetadata{ + Ledger: l.ledgerName, + TargetType: targetType, + TargetID: targetID, + Key: key, + })) +} + +func (l *ledgerMonitor) publish(ctx context.Context, topic string, ev EventMessage) { + if err := l.publisher.Publish(topic, publish.NewMessage(ctx, ev)); err != nil { + logging.FromContext(ctx).Errorf("publishing message: %s", err) + return + } +} diff --git a/components/ledger/pkg/bus/monitor_test.go b/components/ledger/internal/bus/monitor_test.go similarity index 86% rename from components/ledger/pkg/bus/monitor_test.go rename to components/ledger/internal/bus/monitor_test.go index 907275956..dc76884b1 100644 --- a/components/ledger/pkg/bus/monitor_test.go +++ b/components/ledger/internal/bus/monitor_test.go @@ -2,6 +2,7 @@ package bus import ( "context" + ledger "github.com/formancehq/ledger/internal" "testing" "time" @@ -26,7 +27,7 @@ func TestMonitor(t *testing.T) { "*": "testing", }) m := NewLedgerMonitor(p, uuid.New()) - go m.CommittedTransactions(context.Background()) + go m.CommittedTransactions(context.Background(), ledger.Transaction{}, nil) select { case m := <-messages: diff --git a/components/ledger/internal/engine/command/commander.go b/components/ledger/internal/engine/command/commander.go new file mode 100644 index 000000000..a204aaee7 --- /dev/null +++ b/components/ledger/internal/engine/command/commander.go @@ -0,0 +1,334 @@ +package command + +import ( + "context" + "fmt" + "math/big" + "sync" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/bus" + "github.com/formancehq/ledger/internal/engine/utils/batching" + "github.com/formancehq/ledger/internal/machine" + "github.com/formancehq/ledger/internal/machine/vm" + storageerrors "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/stack/libs/go-libs/collectionutils" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/pkg/errors" +) + +type Parameters struct { + DryRun bool + IdempotencyKey string +} + +type Commander struct { + *batching.Batcher[*ledger.ChainedLog] + store Store + locker Locker + compiler *Compiler + running sync.WaitGroup + lastTXID *big.Int + referencer *Referencer + mu sync.Mutex + + lastLog *ledger.ChainedLog + monitor bus.Monitor +} + +func New(store Store, locker Locker, compiler *Compiler, referencer *Referencer, monitor bus.Monitor) *Commander { + return &Commander{ + store: store, + locker: locker, + compiler: compiler, + lastTXID: big.NewInt(-1), + referencer: referencer, + Batcher: batching.NewBatcher(store.InsertLogs, 1, 4096), + monitor: monitor, + } +} + +func (commander *Commander) Init(ctx context.Context) error { + lastTx, err := commander.store.GetLastTransaction(ctx) + if err != nil && !storageerrors.IsNotFoundError(err) { + return err + } + if lastTx != nil { + commander.lastTXID = lastTx.ID + } + + commander.lastLog, err = commander.store.GetLastLog(ctx) + if err != nil && !storageerrors.IsNotFoundError(err) { + return err + } + return nil +} + +func (commander *Commander) GetLedgerStore() Store { + return commander.store +} + +func (commander *Commander) exec(ctx context.Context, parameters Parameters, script ledger.RunScript, + logComputer func(tx *ledger.Transaction, accountMetadata map[string]metadata.Metadata) *ledger.Log) (*ledger.ChainedLog, error) { + + if script.Script.Plain == "" { + return nil, ErrNoScript + } + + if script.Timestamp.IsZero() { + script.Timestamp = ledger.Now() + } + + execContext := newExecutionContext(commander, parameters) + return execContext.run(ctx, func(executionContext *executionContext) (*ledger.ChainedLog, chan struct{}, error) { + if script.Reference != "" { + if err := commander.referencer.take(referenceTxReference, script.Reference); err != nil { + return nil, nil, ErrConflictError + } + defer commander.referencer.release(referenceTxReference, script.Reference) + + _, err := commander.store.GetTransactionByReference(ctx, script.Reference) + if err == nil { + return nil, nil, ErrConflictError + } + if err != storageerrors.ErrNotFound && err != nil { + return nil, nil, err + } + } + + program, err := commander.compiler.Compile(ctx, script.Plain) + if err != nil { + return nil, nil, errorsutil.NewError(ErrCompilationFailed, errors.Wrap(err, "compiling numscript")) + } + + m := vm.NewMachine(*program) + + if err := m.SetVarsFromJSON(script.Vars); err != nil { + return nil, nil, errorsutil.NewError(ErrCompilationFailed, + errors.Wrap(err, "could not set variables")) + } + + involvedAccounts, involvedSources, err := m.ResolveResources(ctx, commander.store) + if err != nil { + return nil, nil, errorsutil.NewError(ErrCompilationFailed, + errors.Wrap(err, "could not resolve program resources")) + } + + worldFilter := collectionutils.FilterNot(collectionutils.FilterEq("world")) + lockAccounts := Accounts{ + Read: collectionutils.Filter(involvedAccounts, worldFilter), + Write: collectionutils.Filter(involvedSources, worldFilter), + } + + unlock, err := commander.locker.Lock(ctx, lockAccounts) + if err != nil { + return nil, nil, errors.Wrap(err, "locking accounts for tx processing") + } + unlock(ctx) + + err = m.ResolveBalances(ctx, commander.store) + if err != nil { + return nil, nil, errorsutil.NewError(ErrCompilationFailed, + errors.Wrap(err, "could not resolve balances")) + } + + result, err := machine.Run(m, script) + if err != nil { + return nil, nil, errors.Wrap(err, "running numscript") + } + + if len(result.Postings) == 0 { + return nil, nil, ErrNoPostings + } + + tx := ledger.NewTransaction(). + WithPostings(result.Postings...). + WithMetadata(result.Metadata). + WithDate(script.Timestamp). + WithID(commander.nextTXID()). + WithReference(script.Reference) + + log := logComputer(tx, result.AccountMetadata) + if parameters.IdempotencyKey != "" { + log = log.WithIdempotencyKey(parameters.IdempotencyKey) + } + + return executionContext.AppendLog(ctx, log) + }) +} + +func (commander *Commander) CreateTransaction(ctx context.Context, parameters Parameters, script ledger.RunScript) (*ledger.Transaction, error) { + log, err := commander.exec(ctx, parameters, script, ledger.NewTransactionLog) + if err != nil { + return nil, err + } + + commander.monitor.CommittedTransactions(ctx, *log.Data.(ledger.NewTransactionLogPayload).Transaction, log.Data.(ledger.NewTransactionLogPayload).AccountMetadata) + + return log.Data.(ledger.NewTransactionLogPayload).Transaction, nil +} + +func (commander *Commander) SaveMeta(ctx context.Context, parameters Parameters, targetType string, targetID interface{}, m metadata.Metadata) error { + if m == nil { + return nil + } + + if targetType == "" { + return errorsutil.NewError(ErrValidation, errors.New("empty target type")) + } + if targetID == "" { + return errorsutil.NewError(ErrValidation, errors.New("empty target id")) + } + + execContext := newExecutionContext(commander, parameters) + _, err := execContext.run(ctx, func(executionContext *executionContext) (*ledger.ChainedLog, chan struct{}, error) { + var ( + log *ledger.Log + at = ledger.Now() + ) + switch targetType { + case ledger.MetaTargetTypeTransaction: + _, err := commander.store.GetTransaction(ctx, targetID.(*big.Int)) + if err != nil { + return nil, nil, err + } + log = ledger.NewSetMetadataLog(at, ledger.SetMetadataLogPayload{ + TargetType: ledger.MetaTargetTypeTransaction, + TargetID: targetID.(*big.Int), + Metadata: m, + }) + case ledger.MetaTargetTypeAccount: + log = ledger.NewSetMetadataLog(at, ledger.SetMetadataLogPayload{ + TargetType: ledger.MetaTargetTypeAccount, + TargetID: targetID.(string), + Metadata: m, + }) + default: + return nil, nil, errorsutil.NewError(ErrValidation, errors.Errorf("unknown target type '%s'", targetType)) + } + + return executionContext.AppendLog(ctx, log) + }) + if err != nil { + return err + } + + commander.monitor.SavedMetadata(ctx, targetType, fmt.Sprint(targetID), m) + return nil +} + +func (commander *Commander) RevertTransaction(ctx context.Context, parameters Parameters, id *big.Int) (*ledger.Transaction, error) { + + if err := commander.referencer.take(referenceReverts, id); err != nil { + return nil, ErrRevertOccurring + } + defer commander.referencer.release(referenceReverts, id) + + tx, err := commander.store.GetTransaction(ctx, id) + if err != nil { + if errors.Is(err, storageerrors.ErrNotFound) { + return nil, errors.New("tx not found") + } + return nil, err + } + if tx.Reverted { + return nil, ErrAlreadyReverted + } + + transactionToRevert, err := commander.store.GetTransaction(ctx, id) + if storageerrors.IsNotFoundError(err) { + return nil, errorsutil.NewError(err, errors.Errorf("transaction %d not found", id)) + } + if err != nil { + return nil, err + } + + rt := transactionToRevert.Reverse() + rt.Metadata = ledger.MarkReverts(metadata.Metadata{}, transactionToRevert.ID) + + log, err := commander.exec(ctx, parameters, + ledger.TxToScriptData(ledger.TransactionData{ + Postings: rt.Postings, + Metadata: rt.Metadata, + }), + func(tx *ledger.Transaction, accountMetadata map[string]metadata.Metadata) *ledger.Log { + return ledger.NewRevertedTransactionLog(tx.Timestamp, transactionToRevert.ID, tx) + }) + if err != nil { + return nil, err + } + + commander.monitor.RevertedTransaction(ctx, log.Data.(ledger.RevertedTransactionLogPayload).RevertTransaction, tx) + + return log.Data.(ledger.RevertedTransactionLogPayload).RevertTransaction, nil +} + +func (commander *Commander) Close() { + commander.Batcher.Close() + commander.running.Wait() +} + +func (commander *Commander) chainLog(log *ledger.Log) *ledger.ChainedLog { + commander.mu.Lock() + defer commander.mu.Unlock() + + commander.lastLog = log.ChainLog(commander.lastLog) + return commander.lastLog +} + +func (commander *Commander) nextTXID() *big.Int { + commander.mu.Lock() + defer commander.mu.Unlock() + + ret := big.NewInt(0).Add(commander.lastTXID, big.NewInt(1)) + commander.lastTXID = ret + + return ret +} + +func (commander *Commander) DeleteMetadata(ctx context.Context, parameters Parameters, targetType string, targetID any, key string) error { + if targetType == "" { + return errorsutil.NewError(ErrValidation, errors.New("empty target type")) + } + if targetID == "" { + return errorsutil.NewError(ErrValidation, errors.New("empty target id")) + } + + execContext := newExecutionContext(commander, parameters) + _, err := execContext.run(ctx, func(executionContext *executionContext) (*ledger.ChainedLog, chan struct{}, error) { + var ( + log *ledger.Log + at = ledger.Now() + ) + switch targetType { + case ledger.MetaTargetTypeTransaction: + _, err := commander.store.GetTransaction(ctx, targetID.(*big.Int)) + if err != nil { + return nil, nil, err + } + log = ledger.NewDeleteMetadataLog(at, ledger.DeleteMetadataLogPayload{ + TargetType: ledger.MetaTargetTypeTransaction, + TargetID: targetID.(uint64), + Key: key, + }) + case ledger.MetaTargetTypeAccount: + log = ledger.NewDeleteMetadataLog(at, ledger.DeleteMetadataLogPayload{ + TargetType: ledger.MetaTargetTypeAccount, + TargetID: targetID.(string), + Key: key, + }) + default: + return nil, nil, errorsutil.NewError(ErrValidation, errors.Errorf("unknown target type '%s'", targetType)) + } + + return executionContext.AppendLog(ctx, log) + }) + if err != nil { + return err + } + + commander.monitor.DeletedMetadata(ctx, targetType, targetID, key) + + return nil +} diff --git a/components/ledger/internal/engine/command/commander_test.go b/components/ledger/internal/engine/command/commander_test.go new file mode 100644 index 000000000..43abf1639 --- /dev/null +++ b/components/ledger/internal/engine/command/commander_test.go @@ -0,0 +1,253 @@ +package command + +import ( + "context" + "math/big" + "testing" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/bus" + storageerrors "github.com/formancehq/ledger/internal/storage" + internaltesting "github.com/formancehq/ledger/internal/testing" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/pkg/errors" + "github.com/stretchr/testify/require" +) + +var ( + now = ledger.Now() +) + +type testCase struct { + name string + setup func(t *testing.T, r Store) + script string + reference string + expectedError error + expectedTx *ledger.Transaction + expectedLogs []*ledger.Log + parameters Parameters +} + +var testCases = []testCase{ + { + name: "nominal", + script: ` + send [GEM 100] ( + source = @world + destination = @mint + )`, + expectedTx: ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "mint", "GEM", big.NewInt(100)), + ), + expectedLogs: []*ledger.Log{ + ledger.NewTransactionLog( + ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "mint", "GEM", big.NewInt(100))), + map[string]metadata.Metadata{}, + ), + }, + }, + { + name: "no script", + script: ``, + expectedError: ErrNoScript, + }, + { + name: "invalid script", + script: `XXX`, + expectedError: ErrCompilationFailed, + }, + { + name: "set reference conflict", + setup: func(t *testing.T, store Store) { + tx := ledger.NewTransaction(). + WithPostings(ledger.NewPosting("world", "mint", "GEM", big.NewInt(100))). + WithReference("tx_ref") + log := ledger.NewTransactionLog(tx, nil) + err := store.InsertLogs(context.Background(), log.ChainLog(nil)) + require.NoError(t, err) + }, + script: ` + send [GEM 100] ( + source = @world + destination = @mint + )`, + reference: "tx_ref", + expectedError: ErrConflictError, + }, + { + name: "set reference", + script: ` + send [GEM 100] ( + source = @world + destination = @mint + )`, + reference: "tx_ref", + expectedTx: ledger.NewTransaction(). + WithPostings( + ledger.NewPosting("world", "mint", "GEM", big.NewInt(100)), + ). + WithReference("tx_ref"), + expectedLogs: []*ledger.Log{ + ledger.NewTransactionLog( + ledger.NewTransaction(). + WithPostings( + ledger.NewPosting("world", "mint", "GEM", big.NewInt(100)), + ). + WithReference("tx_ref"), + map[string]metadata.Metadata{}, + ), + }, + }, + { + name: "using idempotency", + script: ` + send [GEM 100] ( + source = @world + destination = @mint + )`, + reference: "tx_ref", + expectedTx: ledger.NewTransaction(). + WithPostings( + ledger.NewPosting("world", "mint", "GEM", big.NewInt(100)), + ), + expectedLogs: []*ledger.Log{ + ledger.NewTransactionLog( + ledger.NewTransaction(). + WithPostings( + ledger.NewPosting("world", "mint", "GEM", big.NewInt(100)), + ), + map[string]metadata.Metadata{}, + ).WithIdempotencyKey("testing"), + }, + setup: func(t *testing.T, r Store) { + log := ledger.NewTransactionLog( + ledger.NewTransaction(). + WithPostings( + ledger.NewPosting("world", "mint", "GEM", big.NewInt(100)), + ). + WithDate(now), + map[string]metadata.Metadata{}, + ).WithIdempotencyKey("testing") + err := r.InsertLogs(context.Background(), log.ChainLog(nil)) + require.NoError(t, err) + }, + parameters: Parameters{ + IdempotencyKey: "testing", + }, + }, +} + +func TestCreateTransaction(t *testing.T) { + t.Parallel() + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + + store := storageerrors.NewInMemoryStore() + ctx := logging.TestingContext() + + commander := New(store, NoOpLocker, NewCompiler(1024), NewReferencer(), bus.NewNoOpMonitor()) + go commander.Run(ctx) + defer commander.Close() + + if tc.setup != nil { + tc.setup(t, store) + } + ret, err := commander.CreateTransaction(ctx, tc.parameters, ledger.RunScript{ + Script: ledger.Script{ + Plain: tc.script, + }, + Timestamp: now, + Reference: tc.reference, + }) + + if tc.expectedError != nil { + require.True(t, errors.Is(err, tc.expectedError)) + } else { + require.NoError(t, err) + require.NotNil(t, ret) + tc.expectedTx.Timestamp = now + internaltesting.RequireEqual(t, tc.expectedTx, ret) + + for ind := range tc.expectedLogs { + expectedLog := tc.expectedLogs[ind] + switch v := expectedLog.Data.(type) { + case ledger.NewTransactionLogPayload: + v.Transaction.Timestamp = now + expectedLog.Data = v + } + expectedLog.Date = now + } + } + }) + } +} + +func TestRevert(t *testing.T) { + txID := big.NewInt(0) + store := storageerrors.NewInMemoryStore() + ctx := logging.TestingContext() + + log := ledger.NewTransactionLog( + ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ), + map[string]metadata.Metadata{}, + ).ChainLog(nil) + err := store.InsertLogs(context.Background(), log) + require.NoError(t, err) + + commander := New(store, NoOpLocker, NewCompiler(1024), NewReferencer(), bus.NewNoOpMonitor()) + go commander.Run(ctx) + defer commander.Close() + + _, err = commander.RevertTransaction(ctx, Parameters{}, txID) + require.NoError(t, err) +} + +func TestRevertWithAlreadyReverted(t *testing.T) { + + store := storageerrors.NewInMemoryStore() + ctx := logging.TestingContext() + + tx := ledger.NewTransaction().WithPostings(ledger.NewPosting("world", "bank", "USD", big.NewInt(100))) + err := store.InsertLogs(context.Background(), + ledger.NewTransactionLog(tx, map[string]metadata.Metadata{}).ChainLog(nil), + ledger.NewRevertedTransactionLog(ledger.Now(), tx.ID, ledger.NewTransaction()).ChainLog(nil), + ) + require.NoError(t, err) + + commander := New(store, NoOpLocker, NewCompiler(1024), NewReferencer(), bus.NewNoOpMonitor()) + go commander.Run(ctx) + defer commander.Close() + + _, err = commander.RevertTransaction(context.Background(), Parameters{}, tx.ID) + require.True(t, errors.Is(err, ErrAlreadyReverted)) +} + +func TestRevertWithRevertOccurring(t *testing.T) { + + store := storageerrors.NewInMemoryStore() + ctx := logging.TestingContext() + + tx := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ) + log := ledger.NewTransactionLog(tx, map[string]metadata.Metadata{}) + err := store.InsertLogs(ctx, log.ChainLog(nil)) + require.NoError(t, err) + + referencer := NewReferencer() + commander := New(store, NoOpLocker, NewCompiler(1024), referencer, bus.NewNoOpMonitor()) + go commander.Run(ctx) + defer commander.Close() + + referencer.take(referenceReverts, big.NewInt(0)) + + _, err = commander.RevertTransaction(ctx, Parameters{}, tx.ID) + require.True(t, errors.Is(err, ErrRevertOccurring)) +} diff --git a/components/ledger/internal/engine/command/compiler.go b/components/ledger/internal/engine/command/compiler.go new file mode 100644 index 000000000..832879c66 --- /dev/null +++ b/components/ledger/internal/engine/command/compiler.go @@ -0,0 +1,48 @@ +package command + +import ( + "context" + "crypto/sha256" + "encoding/base64" + + "github.com/bluele/gcache" + "github.com/formancehq/ledger/internal/machine/script/compiler" + "github.com/formancehq/ledger/internal/machine/vm" + "github.com/formancehq/ledger/internal/machine/vm/program" + "github.com/formancehq/stack/libs/go-libs/errorsutil" +) + +type Compiler struct { + cache gcache.Cache +} + +func (c *Compiler) Compile(ctx context.Context, script string) (*program.Program, error) { + + digest := sha256.New() + _, err := digest.Write([]byte(script)) + if err != nil { + return nil, errorsutil.NewError(vm.ErrCompilationFailed, err) + } + + cacheKey := base64.StdEncoding.EncodeToString(digest.Sum(nil)) + v, err := c.cache.Get(cacheKey) + if err == nil { + return v.(*program.Program), nil + } + + program, err := compiler.Compile(script) + if err != nil { + return nil, errorsutil.NewError(vm.ErrCompilationFailed, err) + } + _ = c.cache.Set(cacheKey, program) + + return program, nil +} + +func NewCompiler(maxCacheCount int) *Compiler { + return &Compiler{ + cache: gcache.New(maxCacheCount). + LFU(). + Build(), + } +} diff --git a/components/ledger/pkg/ledger/command/compiler_test.go b/components/ledger/internal/engine/command/compiler_test.go similarity index 100% rename from components/ledger/pkg/ledger/command/compiler_test.go rename to components/ledger/internal/engine/command/compiler_test.go diff --git a/components/ledger/internal/engine/command/context.go b/components/ledger/internal/engine/command/context.go new file mode 100644 index 000000000..dd2a5ea75 --- /dev/null +++ b/components/ledger/internal/engine/command/context.go @@ -0,0 +1,66 @@ +package command + +import ( + "context" + + ledger "github.com/formancehq/ledger/internal" + storageerrors "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/stack/libs/go-libs/logging" +) + +type executionContext struct { + commander *Commander + parameters Parameters +} + +func (e *executionContext) AppendLog(ctx context.Context, log *ledger.Log) (*ledger.ChainedLog, chan struct{}, error) { + if e.parameters.DryRun { + ret := make(chan struct{}) + close(ret) + return log.ChainLog(nil), ret, nil + } + + chainedLog := e.commander.chainLog(log) + logging.FromContext(ctx).WithFields(map[string]any{ + "id": chainedLog.ID, + }).Debugf("Appending log") + done := make(chan struct{}) + e.commander.Append(chainedLog, func() { + close(done) + }) + return chainedLog, done, nil +} + +func (e *executionContext) run(ctx context.Context, executor func(e *executionContext) (*ledger.ChainedLog, chan struct{}, error)) (*ledger.ChainedLog, error) { + if ik := e.parameters.IdempotencyKey; ik != "" { + if err := e.commander.referencer.take(referenceIks, ik); err != nil { + return nil, err + } + defer e.commander.referencer.release(referenceIks, ik) + + chainedLog, err := e.commander.store.ReadLogWithIdempotencyKey(ctx, ik) + if err == nil { + return chainedLog, nil + } + if err != nil && !storageerrors.IsNotFoundError(err) { + return nil, err + } + } + chainedLog, done, err := executor(e) + if err != nil { + return nil, err + } + <-done + logger := logging.FromContext(ctx).WithFields(map[string]any{ + "id": chainedLog.ID, + }) + logger.Debugf("Log inserted in database") + return chainedLog, nil +} + +func newExecutionContext(commander *Commander, parameters Parameters) *executionContext { + return &executionContext{ + commander: commander, + parameters: parameters, + } +} diff --git a/components/ledger/pkg/ledger/command/errors.go b/components/ledger/internal/engine/command/errors.go similarity index 100% rename from components/ledger/pkg/ledger/command/errors.go rename to components/ledger/internal/engine/command/errors.go diff --git a/components/ledger/pkg/ledger/command/lock.go b/components/ledger/internal/engine/command/lock.go similarity index 100% rename from components/ledger/pkg/ledger/command/lock.go rename to components/ledger/internal/engine/command/lock.go diff --git a/components/ledger/pkg/ledger/command/lock_test.go b/components/ledger/internal/engine/command/lock_test.go similarity index 100% rename from components/ledger/pkg/ledger/command/lock_test.go rename to components/ledger/internal/engine/command/lock_test.go diff --git a/components/ledger/pkg/ledger/command/reference.go b/components/ledger/internal/engine/command/reference.go similarity index 100% rename from components/ledger/pkg/ledger/command/reference.go rename to components/ledger/internal/engine/command/reference.go diff --git a/components/ledger/internal/engine/command/store.go b/components/ledger/internal/engine/command/store.go new file mode 100644 index 000000000..25569e56f --- /dev/null +++ b/components/ledger/internal/engine/command/store.go @@ -0,0 +1,19 @@ +package command + +import ( + "context" + "math/big" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/machine/vm" +) + +type Store interface { + vm.Store + InsertLogs(ctx context.Context, logs ...*ledger.ChainedLog) error + GetLastLog(ctx context.Context) (*ledger.ChainedLog, error) + GetLastTransaction(ctx context.Context) (*ledger.ExpandedTransaction, error) + ReadLogWithIdempotencyKey(ctx context.Context, key string) (*ledger.ChainedLog, error) + GetTransactionByReference(ctx context.Context, ref string) (*ledger.ExpandedTransaction, error) + GetTransaction(ctx context.Context, txID *big.Int) (*ledger.Transaction, error) +} diff --git a/components/ledger/internal/engine/ledger.go b/components/ledger/internal/engine/ledger.go new file mode 100644 index 000000000..111cd73ee --- /dev/null +++ b/components/ledger/internal/engine/ledger.go @@ -0,0 +1,110 @@ +package engine + +import ( + "context" + "math/big" + + "github.com/ThreeDotsLabs/watermill/message" + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/bus" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/pkg/errors" +) + +type Ledger struct { + commander *command.Commander + store *ledgerstore.Store +} + +func New( + store *ledgerstore.Store, + publisher message.Publisher, + compiler *command.Compiler, +) *Ledger { + var monitor bus.Monitor = bus.NewNoOpMonitor() + if publisher != nil { + monitor = bus.NewLedgerMonitor(publisher, store.Name()) + } + return &Ledger{ + commander: command.New( + store, + command.NewDefaultLocker(), + compiler, + command.NewReferencer(), + monitor, + ), + store: store, + } +} + +func (l *Ledger) Start(ctx context.Context) { + if err := l.commander.Init(ctx); err != nil { + panic(err) + } + go l.commander.Run(logging.ContextWithField(ctx, "component", "commander")) +} + +func (l *Ledger) Close(ctx context.Context) { + logging.FromContext(ctx).Debugf("Close commander") + l.commander.Close() +} + +func (l *Ledger) GetTransactions(ctx context.Context, q *ledgerstore.GetTransactionsQuery) (*api.Cursor[ledger.ExpandedTransaction], error) { + txs, err := l.store.GetTransactions(ctx, q) + return txs, errors.Wrap(err, "getting transactions") +} + +func (l *Ledger) CountTransactions(ctx context.Context, q *ledgerstore.GetTransactionsQuery) (uint64, error) { + count, err := l.store.CountTransactions(ctx, q) + return count, errors.Wrap(err, "counting transactions") +} + +func (l *Ledger) GetTransactionWithVolumes(ctx context.Context, query ledgerstore.GetTransactionQuery) (*ledger.ExpandedTransaction, error) { + tx, err := l.store.GetTransactionWithVolumes(ctx, query) + return tx, errors.Wrap(err, "getting transaction") +} + +func (l *Ledger) CountAccounts(ctx context.Context, a *ledgerstore.GetAccountsQuery) (uint64, error) { + count, err := l.store.CountAccounts(ctx, a) + return count, errors.Wrap(err, "counting accounts") +} + +func (l *Ledger) GetAccountsWithVolumes(ctx context.Context, a *ledgerstore.GetAccountsQuery) (*api.Cursor[ledger.ExpandedAccount], error) { + accounts, err := l.store.GetAccountsWithVolumes(ctx, a) + return accounts, errors.Wrap(err, "getting accounts") +} + +func (l *Ledger) GetAccountWithVolumes(ctx context.Context, q ledgerstore.GetAccountQuery) (*ledger.ExpandedAccount, error) { + accounts, err := l.store.GetAccountWithVolumes(ctx, q) + return accounts, errors.Wrap(err, "getting account") +} + +func (l *Ledger) GetAggregatedBalances(ctx context.Context, q *ledgerstore.GetAggregatedBalanceQuery) (ledger.BalancesByAssets, error) { + balances, err := l.store.GetAggregatedBalances(ctx, q) + return balances, errors.Wrap(err, "getting balances aggregated") +} + +func (l *Ledger) GetLogs(ctx context.Context, q *ledgerstore.GetLogsQuery) (*api.Cursor[ledger.ChainedLog], error) { + logs, err := l.store.GetLogs(ctx, q) + return logs, errors.Wrap(err, "getting logs") +} + +func (l *Ledger) CreateTransaction(ctx context.Context, parameters command.Parameters, data ledger.RunScript) (*ledger.Transaction, error) { + return l.commander.CreateTransaction(ctx, parameters, data) +} + +func (l *Ledger) RevertTransaction(ctx context.Context, parameters command.Parameters, id *big.Int) (*ledger.Transaction, error) { + return l.commander.RevertTransaction(ctx, parameters, id) +} + +func (l *Ledger) SaveMeta(ctx context.Context, parameters command.Parameters, targetType string, targetID any, m metadata.Metadata) error { + return l.commander.SaveMeta(ctx, parameters, targetType, targetID, m) +} + +func (l *Ledger) DeleteMetadata(ctx context.Context, parameters command.Parameters, targetType string, targetID any, key string) error { + return l.commander.DeleteMetadata(ctx, parameters, targetType, targetID, key) +} diff --git a/components/ledger/internal/engine/migrations.go b/components/ledger/internal/engine/migrations.go new file mode 100644 index 000000000..6d8810893 --- /dev/null +++ b/components/ledger/internal/engine/migrations.go @@ -0,0 +1,11 @@ +package engine + +import ( + "context" + + "github.com/formancehq/stack/libs/go-libs/migrations" +) + +func (l *Ledger) GetMigrationsInfo(ctx context.Context) ([]migrations.Info, error) { + return l.store.GetMigrationsInfo(ctx) +} diff --git a/components/ledger/internal/engine/module.go b/components/ledger/internal/engine/module.go new file mode 100644 index 000000000..74ab1b299 --- /dev/null +++ b/components/ledger/internal/engine/module.go @@ -0,0 +1,52 @@ +package engine + +import ( + "context" + + "github.com/ThreeDotsLabs/watermill/message" + "github.com/formancehq/ledger/internal/bus" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/driver" + "github.com/formancehq/stack/libs/go-libs/logging" + "go.uber.org/fx" +) + +type NumscriptCacheConfiguration struct { + MaxCount int +} + +type Configuration struct { + NumscriptCache NumscriptCacheConfiguration +} + +func Module(configuration Configuration) fx.Option { + return fx.Options( + fx.Provide(func( + storageDriver *driver.Driver, + publisher message.Publisher, + metricsRegistry metrics.GlobalRegistry, + logger logging.Logger, + ) *Resolver { + options := []option{ + WithMessagePublisher(publisher), + WithMetricsRegistry(metricsRegistry), + WithLogger(logger), + } + if configuration.NumscriptCache.MaxCount != 0 { + options = append(options, WithCompiler(command.NewCompiler(configuration.NumscriptCache.MaxCount))) + } + return NewResolver(storageDriver, options...) + }), + fx.Provide(fx.Annotate(bus.NewNoOpMonitor, fx.As(new(bus.Monitor)))), + fx.Provide(fx.Annotate(metrics.NewNoOpRegistry, fx.As(new(metrics.GlobalRegistry)))), + //TODO(gfyrag): Move in pkg/ledger package + fx.Invoke(func(lc fx.Lifecycle, resolver *Resolver) { + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return resolver.CloseLedgers(ctx) + }, + }) + }), + ) +} diff --git a/components/ledger/pkg/ledger/resolver.go b/components/ledger/internal/engine/resolver.go similarity index 90% rename from components/ledger/pkg/ledger/resolver.go rename to components/ledger/internal/engine/resolver.go index 24d426f91..7f2f25830 100644 --- a/components/ledger/pkg/ledger/resolver.go +++ b/components/ledger/internal/engine/resolver.go @@ -1,14 +1,14 @@ -package ledger +package engine import ( "context" "sync" "github.com/ThreeDotsLabs/watermill/message" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage/driver" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" + "github.com/formancehq/ledger/internal/engine/command" + "github.com/formancehq/ledger/internal/opentelemetry/metrics" + "github.com/formancehq/ledger/internal/storage/driver" + "github.com/formancehq/ledger/internal/storage/ledgerstore" "github.com/formancehq/stack/libs/go-libs/logging" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -105,7 +105,7 @@ func (r *Resolver) GetLedger(ctx context.Context, name string) (*Ledger, error) } } - ledger = New(name, store, r.publisher, r.compiler) + ledger = New(store, r.publisher, r.compiler) ledger.Start(logging.ContextWithLogger(context.Background(), r.logger)) r.ledgers[name] = ledger r.metricsRegistry.ActiveLedgers().Add(ctx, +1) diff --git a/components/ledger/internal/engine/stats.go b/components/ledger/internal/engine/stats.go new file mode 100644 index 000000000..7df6d12b2 --- /dev/null +++ b/components/ledger/internal/engine/stats.go @@ -0,0 +1,32 @@ +package engine + +import ( + "context" + + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/pkg/errors" +) + +type Stats struct { + Transactions uint64 `json:"transactions"` + Accounts uint64 `json:"accounts"` +} + +func (l *Ledger) Stats(ctx context.Context) (Stats, error) { + var stats Stats + + transactions, err := l.store.CountTransactions(ctx, ledgerstore.NewGetTransactionsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}))) + if err != nil { + return stats, errors.Wrap(err, "counting transactions") + } + + accounts, err := l.store.CountAccounts(ctx, ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}))) + if err != nil { + return stats, errors.Wrap(err, "counting accounts") + } + + return Stats{ + Transactions: transactions, + Accounts: accounts, + }, nil +} diff --git a/components/ledger/internal/engine/utils/batching/batcher.go b/components/ledger/internal/engine/utils/batching/batcher.go new file mode 100644 index 000000000..055f62e7d --- /dev/null +++ b/components/ledger/internal/engine/utils/batching/batcher.go @@ -0,0 +1,85 @@ +package batching + +import ( + "context" + "fmt" + "sync" + + "github.com/formancehq/ledger/internal/engine/utils/job" + "github.com/formancehq/stack/libs/go-libs/collectionutils" +) + +type OnBatchProcessed[T any] func(...T) + +func NoOpOnBatchProcessed[T any]() func(...T) { + return func(t ...T) {} +} + +type pending[T any] struct { + object T + callback func() +} + +type batcherJob[T any] struct { + items []*pending[T] +} + +func (b batcherJob[T]) String() string { + return fmt.Sprintf("processing %d items", len(b.items)) +} + +func (b batcherJob[T]) Terminated() { + for _, v := range b.items { + v.callback() + } +} + +type Batcher[T any] struct { + *job.Runner[batcherJob[T]] + pending []*pending[T] + mu sync.Mutex + maxBatchSize int +} + +func (s *Batcher[T]) Append(object T, callback func()) { + s.mu.Lock() + s.pending = append(s.pending, &pending[T]{ + callback: callback, + object: object, + }) + s.mu.Unlock() + s.Runner.Next() +} + +func (s *Batcher[T]) nextBatch() *batcherJob[T] { + s.mu.Lock() + defer s.mu.Unlock() + + if len(s.pending) == 0 { + return nil + } + if len(s.pending) > s.maxBatchSize { + batch := s.pending[:s.maxBatchSize] + s.pending = s.pending[s.maxBatchSize:] + return &batcherJob[T]{ + items: batch, + } + } + batch := s.pending + s.pending = make([]*pending[T], 0) + return &batcherJob[T]{ + items: batch, + } +} + +func NewBatcher[T any](runner func(context.Context, ...T) error, nbWorkers, maxBatchSize int) *Batcher[T] { + ret := &Batcher[T]{ + maxBatchSize: maxBatchSize, + } + ret.Runner = job.NewJobRunner[batcherJob[T]](func(ctx context.Context, job *batcherJob[T]) error { + return runner(ctx, collectionutils.Map(job.items, func(from *pending[T]) T { + return from.object + })...) + }, ret.nextBatch, nbWorkers) + return ret +} diff --git a/components/ledger/pkg/ledger/utils/job/jobs.go b/components/ledger/internal/engine/utils/job/jobs.go similarity index 100% rename from components/ledger/pkg/ledger/utils/job/jobs.go rename to components/ledger/internal/engine/utils/job/jobs.go diff --git a/components/ledger/pkg/ledger/utils/job/jobs_test.go b/components/ledger/internal/engine/utils/job/jobs_test.go similarity index 100% rename from components/ledger/pkg/ledger/utils/job/jobs_test.go rename to components/ledger/internal/engine/utils/job/jobs_test.go diff --git a/components/ledger/internal/log.go b/components/ledger/internal/log.go new file mode 100644 index 000000000..24369c96e --- /dev/null +++ b/components/ledger/internal/log.go @@ -0,0 +1,308 @@ +package ledger + +import ( + "crypto/sha256" + "encoding/json" + "math/big" + "reflect" + "strconv" + "strings" + + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/pkg/errors" +) + +type LogType int16 + +const ( + // TODO(gfyrag): Create dedicated log type for account and metadata + SetMetadataLogType LogType = iota // "SET_METADATA" + NewTransactionLogType // "NEW_TRANSACTION" + RevertedTransactionLogType // "REVERTED_TRANSACTION" + DeleteMetadataLogType +) + +func (l LogType) String() string { + switch l { + case SetMetadataLogType: + return "SET_METADATA" + case NewTransactionLogType: + return "NEW_TRANSACTION" + case RevertedTransactionLogType: + return "REVERTED_TRANSACTION" + case DeleteMetadataLogType: + return "DELETE_METADATA" + } + + return "" +} + +func LogTypeFromString(logType string) LogType { + switch logType { + case "SET_METADATA": + return SetMetadataLogType + case "NEW_TRANSACTION": + return NewTransactionLogType + case "REVERTED_TRANSACTION": + return RevertedTransactionLogType + case "DELETE_METADATA": + return DeleteMetadataLogType + } + + panic(errors.New("invalid log type")) +} + +// Needed in order to keep the compatibility with the openapi response for +// ListLogs. +func (lt LogType) MarshalJSON() ([]byte, error) { + return json.Marshal(lt.String()) +} + +func (lt *LogType) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + + *lt = LogTypeFromString(s) + + return nil +} + +type ChainedLog struct { + Log + ID *big.Int `json:"id"` + Projected bool `json:"-"` + Hash []byte `json:"hash"` +} + +func (l *ChainedLog) WithID(id uint64) *ChainedLog { + l.ID = big.NewInt(int64(id)) + return l +} + +func (l *ChainedLog) UnmarshalJSON(data []byte) error { + type auxLog ChainedLog + type log struct { + auxLog + Data json.RawMessage `json:"data"` + } + rawLog := log{} + if err := json.Unmarshal(data, &rawLog); err != nil { + return err + } + + var err error + rawLog.auxLog.Data, err = HydrateLog(rawLog.Type, rawLog.Data) + if err != nil { + return err + } + *l = ChainedLog(rawLog.auxLog) + return err +} + +func (l *ChainedLog) ComputeHash(previous *ChainedLog) { + digest := sha256.New() + enc := json.NewEncoder(digest) + if previous != nil { + if err := enc.Encode(previous.Hash); err != nil { + panic(err) + } + } + if err := enc.Encode(l); err != nil { + panic(err) + } + + l.Hash = digest.Sum(nil) +} + +type Log struct { + Type LogType `json:"type"` + Data any `json:"data"` + Date Time `json:"date"` + IdempotencyKey string `json:"idempotencyKey"` +} + +func (l *Log) WithDate(date Time) *Log { + l.Date = date + return l +} + +func (l *Log) WithIdempotencyKey(key string) *Log { + l.IdempotencyKey = key + return l +} + +func (l *Log) ChainLog(previous *ChainedLog) *ChainedLog { + ret := &ChainedLog{ + Log: *l, + ID: big.NewInt(0), + } + ret.ComputeHash(previous) + if previous != nil { + ret.ID = ret.ID.Add(previous.ID, big.NewInt(1)) + } + return ret +} + +type AccountMetadata map[string]metadata.Metadata + +type NewTransactionLogPayload struct { + Transaction *Transaction `json:"transaction"` + AccountMetadata AccountMetadata `json:"accountMetadata"` +} + +func NewTransactionLogWithDate(tx *Transaction, accountMetadata map[string]metadata.Metadata, time Time) *Log { + // Since the id is unique and the hash is a hash of the previous log, they + // will be filled at insertion time during the batch process. + return &Log{ + Type: NewTransactionLogType, + Date: time, + Data: NewTransactionLogPayload{ + Transaction: tx, + AccountMetadata: accountMetadata, + }, + } +} + +func NewTransactionLog(tx *Transaction, accountMetadata map[string]metadata.Metadata) *Log { + return NewTransactionLogWithDate(tx, accountMetadata, Now()) +} + +type SetMetadataLogPayload struct { + TargetType string `json:"targetType"` + TargetID any `json:"targetId"` + Metadata metadata.Metadata `json:"metadata"` +} + +func (s *SetMetadataLogPayload) UnmarshalJSON(data []byte) error { + type X struct { + TargetType string `json:"targetType"` + TargetID json.RawMessage `json:"targetId"` + Metadata metadata.Metadata `json:"metadata"` + } + x := X{} + err := json.Unmarshal(data, &x) + if err != nil { + return err + } + var id interface{} + switch strings.ToUpper(x.TargetType) { + case strings.ToUpper(MetaTargetTypeAccount): + id = "" + err = json.Unmarshal(x.TargetID, &id) + case strings.ToUpper(MetaTargetTypeTransaction): + id, err = strconv.ParseUint(string(x.TargetID), 10, 64) + default: + panic("unknown type") + } + if err != nil { + return err + } + + *s = SetMetadataLogPayload{ + TargetType: x.TargetType, + TargetID: id, + Metadata: x.Metadata, + } + return nil +} + +func NewSetMetadataLog(at Time, metadata SetMetadataLogPayload) *Log { + // Since the id is unique and the hash is a hash of the previous log, they + // will be filled at insertion time during the batch process. + return &Log{ + Type: SetMetadataLogType, + Date: at, + Data: metadata, + } +} + +type DeleteMetadataLogPayload struct { + TargetType string `json:"targetType"` + TargetID any `json:"targetId"` + Key string `json:"key"` +} + +func NewDeleteMetadataLog(at Time, payload DeleteMetadataLogPayload) *Log { + // Since the id is unique and the hash is a hash of the previous log, they + // will be filled at insertion time during the batch process. + return &Log{ + Type: DeleteMetadataLogType, + Date: at, + Data: payload, + } +} + +func NewSetMetadataOnAccountLog(at Time, account string, metadata metadata.Metadata) *Log { + return &Log{ + Type: SetMetadataLogType, + Date: at, + Data: SetMetadataLogPayload{ + TargetType: MetaTargetTypeAccount, + TargetID: account, + Metadata: metadata, + }, + } +} + +func NewSetMetadataOnTransactionLog(at Time, txID *big.Int, metadata metadata.Metadata) *Log { + return &Log{ + Type: SetMetadataLogType, + Date: at, + Data: SetMetadataLogPayload{ + TargetType: MetaTargetTypeTransaction, + TargetID: txID, + Metadata: metadata, + }, + } +} + +type RevertedTransactionLogPayload struct { + RevertedTransactionID *big.Int `json:"revertedTransactionID"` + RevertTransaction *Transaction `json:"transaction"` +} + +func NewRevertedTransactionLog(at Time, revertedTxID *big.Int, tx *Transaction) *Log { + return &Log{ + Type: RevertedTransactionLogType, + Date: at, + Data: RevertedTransactionLogPayload{ + RevertedTransactionID: revertedTxID, + RevertTransaction: tx, + }, + } +} + +func HydrateLog(_type LogType, data []byte) (any, error) { + var payload any + switch _type { + case NewTransactionLogType: + payload = &NewTransactionLogPayload{} + case SetMetadataLogType: + payload = &SetMetadataLogPayload{} + case RevertedTransactionLogType: + payload = &RevertedTransactionLogPayload{} + default: + panic("unknown type " + _type.String()) + } + err := json.Unmarshal(data, &payload) + if err != nil { + return nil, err + } + + return reflect.ValueOf(payload).Elem().Interface(), nil +} + +type Accounts map[string]Account + +func ChainLogs(logs ...*Log) []*ChainedLog { + var previous *ChainedLog + ret := make([]*ChainedLog, 0) + for _, log := range logs { + next := log.ChainLog(previous) + ret = append(ret, next) + previous = next + } + return ret +} diff --git a/components/ledger/pkg/machine/docs/instructions.md b/components/ledger/internal/machine/docs/instructions.md similarity index 100% rename from components/ledger/pkg/machine/docs/instructions.md rename to components/ledger/internal/machine/docs/instructions.md diff --git a/components/ledger/pkg/machine/docs/types.md b/components/ledger/internal/machine/docs/types.md similarity index 100% rename from components/ledger/pkg/machine/docs/types.md rename to components/ledger/internal/machine/docs/types.md diff --git a/components/ledger/internal/machine/examples/basic.go b/components/ledger/internal/machine/examples/basic.go new file mode 100644 index 000000000..24cd3b7ad --- /dev/null +++ b/components/ledger/internal/machine/examples/basic.go @@ -0,0 +1,81 @@ +package main + +import ( + "context" + "fmt" + "math/big" + + "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/machine/script/compiler" + vm2 "github.com/formancehq/ledger/internal/machine/vm" + "github.com/formancehq/stack/libs/go-libs/metadata" +) + +func main() { + program, err := compiler.Compile(` + // This is a comment + vars { + account $dest + } + send [COIN 99] ( + source = { + 15% from { + @alice + @bob + } + remaining from @bob + } + destination = $dest + )`) + if err != nil { + panic(err) + } + fmt.Print(program) + + m := vm2.NewMachine(*program) + m.Debug = true + + if err = m.SetVarsFromJSON(map[string]string{ + "dest": "charlie", + }); err != nil { + panic(err) + } + + initialVolumes := map[string]map[string]*big.Int{ + "alice": { + "COIN": big.NewInt(10), + }, + "bob": { + "COIN": big.NewInt(100), + }, + } + + store := vm2.StaticStore{} + for account, balances := range initialVolumes { + store[account] = &vm2.AccountWithBalances{ + Account: ledger.Account{ + Address: account, + Metadata: metadata.Metadata{}, + }, + Balances: balances, + } + } + + _, _, err = m.ResolveResources(context.Background(), vm2.EmptyStore) + if err != nil { + panic(err) + } + + err = m.ResolveBalances(context.Background(), store) + if err != nil { + panic(err) + } + + err = m.Execute() + if err != nil { + panic(err) + } + + fmt.Println(m.Postings) + fmt.Println(m.TxMeta) +} diff --git a/components/ledger/internal/machine/internal/account.go b/components/ledger/internal/machine/internal/account.go new file mode 100644 index 000000000..b7618b286 --- /dev/null +++ b/components/ledger/internal/machine/internal/account.go @@ -0,0 +1,21 @@ +package internal + +import ( + "fmt" + + ledger "github.com/formancehq/ledger/internal" +) + +type AccountAddress string + +func (AccountAddress) GetType() Type { return TypeAccount } +func (a AccountAddress) String() string { + return fmt.Sprintf("@%v", string(a)) +} + +func ValidateAccountAddress(acc AccountAddress) error { + if !ledger.AccountRegexp.MatchString(string(acc)) { + return fmt.Errorf("accounts should respect pattern %s", ledger.AccountPattern) + } + return nil +} diff --git a/components/ledger/pkg/machine/internal/address.go b/components/ledger/internal/machine/internal/address.go similarity index 100% rename from components/ledger/pkg/machine/internal/address.go rename to components/ledger/internal/machine/internal/address.go diff --git a/components/ledger/pkg/machine/internal/allotment.go b/components/ledger/internal/machine/internal/allotment.go similarity index 100% rename from components/ledger/pkg/machine/internal/allotment.go rename to components/ledger/internal/machine/internal/allotment.go diff --git a/components/ledger/pkg/machine/internal/allotment_test.go b/components/ledger/internal/machine/internal/allotment_test.go similarity index 100% rename from components/ledger/pkg/machine/internal/allotment_test.go rename to components/ledger/internal/machine/internal/allotment_test.go diff --git a/components/ledger/internal/machine/internal/asset.go b/components/ledger/internal/machine/internal/asset.go new file mode 100644 index 000000000..29f46fcde --- /dev/null +++ b/components/ledger/internal/machine/internal/asset.go @@ -0,0 +1,27 @@ +package internal + +import ( + "fmt" + + ledger "github.com/formancehq/ledger/internal" +) + +type Asset string + +func (Asset) GetType() Type { return TypeAsset } +func (a Asset) String() string { + return fmt.Sprintf("%v", string(a)) +} + +type HasAsset interface { + GetAsset() Asset +} + +func (a Asset) GetAsset() Asset { return a } + +func ValidateAsset(ass Asset) error { + if !ledger.AssetRegexp.MatchString(string(ass)) { + return fmt.Errorf("asset should respect pattern '%s'", ledger.AssetPattern) + } + return nil +} diff --git a/components/ledger/pkg/machine/internal/funding.go b/components/ledger/internal/machine/internal/funding.go similarity index 100% rename from components/ledger/pkg/machine/internal/funding.go rename to components/ledger/internal/machine/internal/funding.go diff --git a/components/ledger/pkg/machine/internal/funding_test.go b/components/ledger/internal/machine/internal/funding_test.go similarity index 100% rename from components/ledger/pkg/machine/internal/funding_test.go rename to components/ledger/internal/machine/internal/funding_test.go diff --git a/components/ledger/pkg/machine/internal/json.go b/components/ledger/internal/machine/internal/json.go similarity index 100% rename from components/ledger/pkg/machine/internal/json.go rename to components/ledger/internal/machine/internal/json.go diff --git a/components/ledger/pkg/machine/internal/json_test.go b/components/ledger/internal/machine/internal/json_test.go similarity index 100% rename from components/ledger/pkg/machine/internal/json_test.go rename to components/ledger/internal/machine/internal/json_test.go diff --git a/components/ledger/pkg/machine/internal/monetary.go b/components/ledger/internal/machine/internal/monetary.go similarity index 100% rename from components/ledger/pkg/machine/internal/monetary.go rename to components/ledger/internal/machine/internal/monetary.go diff --git a/components/ledger/pkg/machine/internal/number.go b/components/ledger/internal/machine/internal/number.go similarity index 100% rename from components/ledger/pkg/machine/internal/number.go rename to components/ledger/internal/machine/internal/number.go diff --git a/components/ledger/pkg/machine/internal/portion.go b/components/ledger/internal/machine/internal/portion.go similarity index 100% rename from components/ledger/pkg/machine/internal/portion.go rename to components/ledger/internal/machine/internal/portion.go diff --git a/components/ledger/pkg/machine/internal/portion_test.go b/components/ledger/internal/machine/internal/portion_test.go similarity index 100% rename from components/ledger/pkg/machine/internal/portion_test.go rename to components/ledger/internal/machine/internal/portion_test.go diff --git a/components/ledger/pkg/machine/internal/value.go b/components/ledger/internal/machine/internal/value.go similarity index 100% rename from components/ledger/pkg/machine/internal/value.go rename to components/ledger/internal/machine/internal/value.go diff --git a/components/ledger/internal/machine/machine.go b/components/ledger/internal/machine/machine.go new file mode 100644 index 000000000..7ca08dd33 --- /dev/null +++ b/components/ledger/internal/machine/machine.go @@ -0,0 +1,50 @@ +package machine + +import ( + "math/big" + + ledger "github.com/formancehq/ledger/internal" + vm2 "github.com/formancehq/ledger/internal/machine/vm" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/pkg/errors" +) + +type Result struct { + Postings ledger.Postings + Metadata metadata.Metadata + AccountMetadata map[string]metadata.Metadata +} + +func Run(m *vm2.Machine, script ledger.RunScript) (*Result, error) { + err := m.Execute() + if err != nil { + return nil, errors.Wrap(err, "script execution failed") + } + + result := Result{ + Postings: make([]ledger.Posting, len(m.Postings)), + Metadata: m.GetTxMetaJSON(), + AccountMetadata: m.GetAccountsMetaJSON(), + } + + for j, posting := range m.Postings { + result.Postings[j] = ledger.Posting{ + Source: posting.Source, + Destination: posting.Destination, + Amount: (*big.Int)(posting.Amount), + Asset: posting.Asset, + } + } + + for k, v := range script.Metadata { + _, ok := result.Metadata[k] + if ok { + return nil, errorsutil.NewError(vm2.ErrMetadataOverride, + errors.New("cannot override metadata from script")) + } + result.Metadata[k] = v + } + + return &result, nil +} diff --git a/components/ledger/internal/machine/machine_test.go b/components/ledger/internal/machine/machine_test.go new file mode 100644 index 000000000..5b6c45bc4 --- /dev/null +++ b/components/ledger/internal/machine/machine_test.go @@ -0,0 +1,407 @@ +package machine + +import ( + "context" + "errors" + "math/big" + "testing" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/machine/script/compiler" + vm2 "github.com/formancehq/ledger/internal/machine/vm" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/stretchr/testify/require" +) + +type testCase struct { + name string + script string + vars map[string]string + expectErrorCode error + expectResult Result + store vm2.Store + metadata metadata.Metadata +} + +var testCases = []testCase{ + { + name: "nominal", + script: ` + send [USD/2 99] ( + source = @world + destination = @user:001 + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "user:001", "USD/2", big.NewInt(99)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "not enough funds", + script: ` + send [USD/2 99] ( + source = @bank + destination = @user:001 + )`, + expectErrorCode: vm2.ErrInsufficientFund, + }, + { + name: "send $0", + script: ` + send [USD/2 0] ( + source = @alice + destination = @user:001 + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("alice", "user:001", "USD/2", big.NewInt(0)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "send $0 world", + script: ` + send [USD/2 0] ( + source = @world + destination = @user:001 + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "user:001", "USD/2", big.NewInt(0)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "send all available", + script: ` + send [USD/2 *] ( + source = @alice + destination = @user:001 + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("alice", "user:001", "USD/2", big.NewInt(0)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "with variable", + script: ` + vars { + account $dest + } + + send [CAD/2 42] ( + source = @world + destination = $dest + )`, + vars: map[string]string{ + "dest": "user:001", + }, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "user:001", "CAD/2", big.NewInt(42)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "using metadata", + store: vm2.StaticStore{ + "sales:001": &vm2.AccountWithBalances{ + Account: ledger.Account{ + Address: "sales:001", + Metadata: metadata.Metadata{ + "seller": "users:001", + }, + }, + Balances: map[string]*big.Int{ + "COIN": big.NewInt(100), + }, + }, + "users:001": &vm2.AccountWithBalances{ + Account: ledger.Account{ + Address: "sales:001", + Metadata: metadata.Metadata{ + "commission": "15.5%", + }, + }, + Balances: map[string]*big.Int{}, + }, + }, + script: ` + vars { + account $sale + account $seller = meta($sale, "seller") + portion $commission = meta($seller, "commission") + } + + send [COIN *] ( + source = $sale + destination = { + remaining to $seller + $commission to @platform + } + ) + `, + vars: map[string]string{ + "sale": "sales:001", + }, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("sales:001", "users:001", "COIN", big.NewInt(85)), + ledger.NewPosting("sales:001", "platform", "COIN", big.NewInt(15)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "defining metadata from input", + script: ` + send [USD/2 99] ( + source = @world + destination = @users:001 + )`, + metadata: metadata.Metadata{ + "priority": "low", + }, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "users:001", "USD/2", big.NewInt(99)), + }, + Metadata: metadata.Metadata{ + "priority": "low", + }, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "defining metadata from script", + script: ` + set_tx_meta("priority", "low") + send [USD/2 99] ( + source = @world + destination = @users:001 + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "users:001", "USD/2", big.NewInt(99)), + }, + Metadata: metadata.Metadata{ + "priority": "low", + }, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "override metadata from script", + script: ` + set_tx_meta("priority", "low") + send [USD/2 99] ( + source = @world + destination = @users:001 + )`, + metadata: metadata.Metadata{ + "priority": "low", + }, + expectErrorCode: vm2.ErrMetadataOverride, + }, + { + name: "set account meta", + script: ` + send [USD/2 99] ( + source = @world + destination = @users:001 + ) + set_account_meta(@alice, "aaa", "string meta") + set_account_meta(@alice, "bbb", 42) + set_account_meta(@alice, "ccc", COIN) + set_account_meta(@alice, "ddd", [COIN 30]) + set_account_meta(@alice, "eee", @bob) + `, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("world", "users:001", "USD/2", big.NewInt(99)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{ + "alice": { + "aaa": "string meta", + "bbb": "42", + "ccc": "COIN", + "ddd": "COIN 30", + "eee": "bob", + }, + }, + }, + }, + { + name: "balance function", + store: vm2.StaticStore{ + "users:001": { + Account: ledger.Account{ + Address: "users:001", + Metadata: metadata.Metadata{}, + }, + Balances: map[string]*big.Int{ + "COIN": big.NewInt(100), + }, + }, + }, + script: ` + vars { + monetary $bal = balance(@users:001, COIN) + } + send $bal ( + source = @users:001 + destination = @world + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("users:001", "world", "COIN", big.NewInt(100)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "overdraft", + script: ` + send [USD/2 100] ( + source = @users:001 allowing unbounded overdraft + destination = @users:002 + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("users:001", "users:002", "USD/2", big.NewInt(100)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "send amount 0", + store: vm2.StaticStore{ + "alice": { + Account: ledger.Account{ + Address: "alice", + Metadata: metadata.Metadata{}, + }, + Balances: map[string]*big.Int{}, + }, + }, + script: ` + send [USD 0] ( + source = @alice + destination = @bob + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("alice", "bob", "USD", big.NewInt(0)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "send all with balance 0", + store: vm2.StaticStore{ + "alice": { + Account: ledger.Account{ + Address: "alice", + Metadata: metadata.Metadata{}, + }, + Balances: map[string]*big.Int{}, + }, + }, + script: ` + send [USD *] ( + source = @alice + destination = @bob + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("alice", "bob", "USD", big.NewInt(0)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, + { + name: "send account balance of 0", + store: vm2.StaticStore{ + "alice": { + Account: ledger.Account{ + Address: "alice", + Metadata: metadata.Metadata{}, + }, + Balances: map[string]*big.Int{}, + }, + }, + script: ` + vars { + monetary $bal = balance(@alice, USD) + } + send $bal ( + source = @alice + destination = @bob + )`, + expectResult: Result{ + Postings: []ledger.Posting{ + ledger.NewPosting("alice", "bob", "USD", big.NewInt(0)), + }, + Metadata: metadata.Metadata{}, + AccountMetadata: map[string]metadata.Metadata{}, + }, + }, +} + +func TestMachine(t *testing.T) { + t.Parallel() + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + + if tc.store == nil { + tc.store = vm2.StaticStore{} + } + + program, err := compiler.Compile(tc.script) + require.NoError(t, err) + + m := vm2.NewMachine(*program) + require.NoError(t, m.SetVarsFromJSON(tc.vars)) + + _, _, err = m.ResolveResources(context.Background(), tc.store) + require.NoError(t, err) + require.NoError(t, m.ResolveBalances(context.Background(), tc.store)) + + result, err := Run(m, ledger.RunScript{ + Script: ledger.Script{ + Plain: tc.script, + Vars: tc.vars, + }, + Metadata: tc.metadata, + }) + if tc.expectErrorCode != nil { + require.True(t, errors.Is(err, tc.expectErrorCode)) + } else { + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, tc.expectResult, *result) + } + }) + } +} diff --git a/components/ledger/pkg/machine/script/NumScript.g4 b/components/ledger/internal/machine/script/NumScript.g4 similarity index 100% rename from components/ledger/pkg/machine/script/NumScript.g4 rename to components/ledger/internal/machine/script/NumScript.g4 diff --git a/components/ledger/pkg/machine/script/compiler/allotment.go b/components/ledger/internal/machine/script/compiler/allotment.go similarity index 75% rename from components/ledger/pkg/machine/script/compiler/allotment.go rename to components/ledger/internal/machine/script/compiler/allotment.go index 91edb6a59..9e7a0e4fa 100644 --- a/components/ledger/pkg/machine/script/compiler/allotment.go +++ b/components/ledger/internal/machine/script/compiler/allotment.go @@ -6,9 +6,9 @@ import ( "math/big" "github.com/antlr/antlr4/runtime/Go/antlr" - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/formancehq/ledger/pkg/machine/script/parser" - "github.com/formancehq/ledger/pkg/machine/vm/program" + internal2 "github.com/formancehq/ledger/internal/machine/internal" + "github.com/formancehq/ledger/internal/machine/script/parser" + program2 "github.com/formancehq/ledger/internal/machine/vm/program" ) func (p *parseVisitor) VisitAllotment(c antlr.ParserRuleContext, portions []parser.IAllotmentPortionContext) *CompileError { @@ -19,13 +19,13 @@ func (p *parseVisitor) VisitAllotment(c antlr.ParserRuleContext, portions []pars c := portions[i] switch c := c.(type) { case *parser.AllotmentPortionConstContext: - portion, err := internal.ParsePortionSpecific(c.GetText()) + portion, err := internal2.ParsePortionSpecific(c.GetText()) if err != nil { return LogicError(c, err) } rat := *portion.Specific total.Add(&rat, total) - addr, err := p.AllocateResource(program.Constant{Inner: *portion}) + addr, err := p.AllocateResource(program2.Constant{Inner: *portion}) if err != nil { return LogicError(c, err) } @@ -35,7 +35,7 @@ func (p *parseVisitor) VisitAllotment(c antlr.ParserRuleContext, portions []pars if err != nil { return err } - if ty != internal.TypePortion { + if ty != internal2.TypePortion { return LogicError(c, fmt.Errorf("wrong type: expected type portion for variable: %v", ty), ) @@ -47,7 +47,7 @@ func (p *parseVisitor) VisitAllotment(c antlr.ParserRuleContext, portions []pars errors.New("two uses of `remaining` in the same allocation"), ) } - addr, err := p.AllocateResource(program.Constant{Inner: internal.NewPortionRemaining()}) + addr, err := p.AllocateResource(program2.Constant{Inner: internal2.NewPortionRemaining()}) if err != nil { return LogicError(c, err) } @@ -75,10 +75,10 @@ func (p *parseVisitor) VisitAllotment(c antlr.ParserRuleContext, portions []pars errors.New("known portions are already equal to 100%"), ) } - err := p.PushInteger(internal.NewNumber(int64(len(portions)))) + err := p.PushInteger(internal2.NewNumber(int64(len(portions)))) if err != nil { return LogicError(c, err) } - p.AppendInstruction(program.OP_MAKE_ALLOTMENT) + p.AppendInstruction(program2.OP_MAKE_ALLOTMENT) return nil } diff --git a/components/ledger/internal/machine/script/compiler/compiler.go b/components/ledger/internal/machine/script/compiler/compiler.go new file mode 100644 index 000000000..0f72697f9 --- /dev/null +++ b/components/ledger/internal/machine/script/compiler/compiler.go @@ -0,0 +1,697 @@ +package compiler + +import ( + "fmt" + "sort" + "strings" + + "github.com/antlr/antlr4/runtime/Go/antlr" + internal2 "github.com/formancehq/ledger/internal/machine/internal" + parser2 "github.com/formancehq/ledger/internal/machine/script/parser" + program2 "github.com/formancehq/ledger/internal/machine/vm/program" + "github.com/pkg/errors" +) + +type parseVisitor struct { + errListener *ErrorListener + instructions []byte + // resources must not exceed 65536 elements + resources []program2.Resource + // sources store all source accounts + // a source can be also a destination of another posting + sources map[internal2.Address]struct{} + // varIdx maps name to resource index + varIdx map[string]internal2.Address + // needBalances store for each account, the set of assets needed + neededBalances map[internal2.Address]map[internal2.Address]struct{} +} + +// Allocates constants if it hasn't already been, +// and returns its resource address. +func (p *parseVisitor) findConstant(constant program2.Constant) (*internal2.Address, bool) { + for i := 0; i < len(p.resources); i++ { + if c, ok := p.resources[i].(program2.Constant); ok { + if internal2.ValueEquals(c.Inner, constant.Inner) { + addr := internal2.Address(i) + return &addr, true + } + } + } + return nil, false +} + +func (p *parseVisitor) AllocateResource(res program2.Resource) (*internal2.Address, error) { + if c, ok := res.(program2.Constant); ok { + idx, ok := p.findConstant(c) + if ok { + return idx, nil + } + } + if len(p.resources) >= 65536 { + return nil, errors.New("number of unique constants exceeded 65536") + } + p.resources = append(p.resources, res) + addr := internal2.NewAddress(uint16(len(p.resources) - 1)) + return &addr, nil +} + +func (p *parseVisitor) isWorld(addr internal2.Address) bool { + idx := int(addr) + if idx < len(p.resources) { + if c, ok := p.resources[idx].(program2.Constant); ok { + if acc, ok := c.Inner.(internal2.AccountAddress); ok { + if string(acc) == "world" { + return true + } + } + } + } + return false +} + +func (p *parseVisitor) VisitVariable(c parser2.IVariableContext, push bool) (internal2.Type, *internal2.Address, *CompileError) { + name := c.GetText()[1:] // strip '$' prefix + if idx, ok := p.varIdx[name]; ok { + res := p.resources[idx] + if push { + p.PushAddress(idx) + } + return res.GetType(), &idx, nil + } else { + return 0, nil, LogicError(c, errors.New("variable not declared")) + } +} + +func (p *parseVisitor) VisitExpr(c parser2.IExpressionContext, push bool) (internal2.Type, *internal2.Address, *CompileError) { + switch c := c.(type) { + case *parser2.ExprAddSubContext: + lhsType, lhsAddr, err := p.VisitExpr(c.GetLhs(), push) + if err != nil { + return 0, nil, err + } + switch lhsType { + case internal2.TypeNumber: + rhsType, _, err := p.VisitExpr(c.GetRhs(), push) + if err != nil { + return 0, nil, err + } + if rhsType != internal2.TypeNumber { + return 0, nil, LogicError(c, fmt.Errorf( + "tried to do an arithmetic operation with incompatible left and right-hand side operand types: %s and %s", + lhsType, rhsType)) + } + if push { + switch c.GetOp().GetTokenType() { + case parser2.NumScriptLexerOP_ADD: + p.AppendInstruction(program2.OP_IADD) + case parser2.NumScriptLexerOP_SUB: + p.AppendInstruction(program2.OP_ISUB) + } + } + return internal2.TypeNumber, nil, nil + case internal2.TypeMonetary: + rhsType, _, err := p.VisitExpr(c.GetRhs(), push) + if err != nil { + return 0, nil, err + } + if rhsType != internal2.TypeMonetary { + return 0, nil, LogicError(c, fmt.Errorf( + "tried to do an arithmetic operation with incompatible left and right-hand side operand types: %s and %s", + lhsType, rhsType)) + } + if push { + switch c.GetOp().GetTokenType() { + case parser2.NumScriptLexerOP_ADD: + p.AppendInstruction(program2.OP_MONETARY_ADD) + case parser2.NumScriptLexerOP_SUB: + p.AppendInstruction(program2.OP_MONETARY_SUB) + } + } + return internal2.TypeMonetary, lhsAddr, nil + default: + return 0, nil, LogicError(c, fmt.Errorf( + "tried to do an arithmetic operation with unsupported left-hand side operand type: %s", + lhsType)) + } + case *parser2.ExprLiteralContext: + return p.VisitLit(c.GetLit(), push) + case *parser2.ExprVariableContext: + return p.VisitVariable(c.GetVar_(), push) + default: + return 0, nil, InternalError(c) + } +} + +func (p *parseVisitor) VisitLit(c parser2.ILiteralContext, push bool) (internal2.Type, *internal2.Address, *CompileError) { + switch c := c.(type) { + case *parser2.LitAccountContext: + account := internal2.AccountAddress(c.GetText()[1:]) + addr, err := p.AllocateResource(program2.Constant{Inner: account}) + if err != nil { + return 0, nil, LogicError(c, err) + } + if push { + p.PushAddress(*addr) + } + return internal2.TypeAccount, addr, nil + case *parser2.LitAssetContext: + asset := internal2.Asset(c.GetText()) + addr, err := p.AllocateResource(program2.Constant{Inner: asset}) + if err != nil { + return 0, nil, LogicError(c, err) + } + if push { + p.PushAddress(*addr) + } + return internal2.TypeAsset, addr, nil + case *parser2.LitNumberContext: + number, err := internal2.ParseNumber(c.GetText()) + if err != nil { + return 0, nil, LogicError(c, err) + } + addr, err := p.AllocateResource(program2.Constant{Inner: number}) + if err != nil { + return 0, nil, LogicError(c, err) + } + if push { + p.PushAddress(*addr) + } + return internal2.TypeNumber, addr, nil + case *parser2.LitStringContext: + addr, err := p.AllocateResource(program2.Constant{ + Inner: internal2.String(strings.Trim(c.GetText(), `"`)), + }) + if err != nil { + return 0, nil, LogicError(c, err) + } + if push { + p.PushAddress(*addr) + } + return internal2.TypeString, addr, nil + case *parser2.LitPortionContext: + portion, err := internal2.ParsePortionSpecific(c.GetText()) + if err != nil { + return 0, nil, LogicError(c, err) + } + addr, err := p.AllocateResource(program2.Constant{Inner: *portion}) + if err != nil { + return 0, nil, LogicError(c, err) + } + if push { + p.PushAddress(*addr) + } + return internal2.TypePortion, addr, nil + case *parser2.LitMonetaryContext: + typ, assetAddr, compErr := p.VisitExpr(c.Monetary().GetAsset(), false) + if compErr != nil { + return 0, nil, compErr + } + if typ != internal2.TypeAsset { + return 0, nil, LogicError(c, fmt.Errorf( + "the expression in monetary literal should be of type '%s' instead of '%s'", + internal2.TypeAsset, typ)) + } + + amt, err := internal2.ParseMonetaryInt(c.Monetary().GetAmt().GetText()) + if err != nil { + return 0, nil, LogicError(c, err) + } + + var ( + monAddr *internal2.Address + alreadyAllocated bool + ) + for i, r := range p.resources { + switch v := r.(type) { + case program2.Monetary: + if v.Asset == *assetAddr && v.Amount.Equal(amt) { + alreadyAllocated = true + tmp := internal2.Address(uint16(i)) + monAddr = &tmp + break + } + } + } + if !alreadyAllocated { + monAddr, err = p.AllocateResource(program2.Monetary{ + Asset: *assetAddr, + Amount: amt, + }) + if err != nil { + return 0, nil, LogicError(c, err) + } + } + if push { + p.PushAddress(*monAddr) + } + return internal2.TypeMonetary, monAddr, nil + default: + return 0, nil, InternalError(c) + } +} + +func (p *parseVisitor) VisitMonetaryAll(c *parser2.SendContext, monAll parser2.IMonetaryAllContext) *CompileError { + assetType, assetAddr, compErr := p.VisitExpr(monAll.GetAsset(), false) + if compErr != nil { + return compErr + } + if assetType != internal2.TypeAsset { + return LogicError(c, fmt.Errorf( + "send monetary all: the expression should be of type 'asset' instead of '%s'", assetType)) + } + + switch c := c.GetSrc().(type) { + case *parser2.SrcContext: + accounts, _, _, compErr := p.VisitSource(c.Source(), func() { + p.PushAddress(*assetAddr) + }, true) + if compErr != nil { + return compErr + } + p.setNeededBalances(accounts, assetAddr) + + case *parser2.SrcAllotmentContext: + return LogicError(c, errors.New("cannot take all balance of an allotment source")) + } + return nil +} + +func (p *parseVisitor) VisitMonetary(c *parser2.SendContext, mon parser2.IExpressionContext) *CompileError { + monType, monAddr, compErr := p.VisitExpr(mon, false) + if compErr != nil { + return compErr + } + if monType != internal2.TypeMonetary { + return LogicError(c, fmt.Errorf( + "send monetary: the expression should be of type 'monetary' instead of '%s'", monType)) + } + + switch c := c.GetSrc().(type) { + case *parser2.SrcContext: + accounts, _, fallback, compErr := p.VisitSource(c.Source(), func() { + p.PushAddress(*monAddr) + p.AppendInstruction(program2.OP_ASSET) + }, false) + if compErr != nil { + return compErr + } + p.setNeededBalances(accounts, monAddr) + + if _, _, err := p.VisitExpr(mon, true); err != nil { + return err + } + + if err := p.TakeFromSource(fallback); err != nil { + return LogicError(c, err) + } + case *parser2.SrcAllotmentContext: + if _, _, err := p.VisitExpr(mon, true); err != nil { + return err + } + p.VisitAllotment(c.SourceAllotment(), c.SourceAllotment().GetPortions()) + p.AppendInstruction(program2.OP_ALLOC) + + sources := c.SourceAllotment().GetSources() + n := len(sources) + for i := 0; i < n; i++ { + accounts, _, fallback, compErr := p.VisitSource(sources[i], func() { + p.PushAddress(*monAddr) + p.AppendInstruction(program2.OP_ASSET) + }, false) + if compErr != nil { + return compErr + } + p.setNeededBalances(accounts, monAddr) + + if err := p.Bump(int64(i + 1)); err != nil { + return LogicError(c, err) + } + + if err := p.TakeFromSource(fallback); err != nil { + return LogicError(c, err) + } + } + + if err := p.PushInteger(internal2.NewNumber(int64(n))); err != nil { + return LogicError(c, err) + } + + p.AppendInstruction(program2.OP_FUNDING_ASSEMBLE) + } + return nil +} + +func (p *parseVisitor) setNeededBalances(accounts map[internal2.Address]struct{}, addr *internal2.Address) { + for acc := range accounts { + if b, ok := p.neededBalances[acc]; ok { + b[*addr] = struct{}{} + } else { + p.neededBalances[acc] = map[internal2.Address]struct{}{ + *addr: {}, + } + } + } +} + +func (p *parseVisitor) VisitSend(c *parser2.SendContext) *CompileError { + if monAll := c.GetMonAll(); monAll != nil { + if err := p.VisitMonetaryAll(c, monAll); err != nil { + return err + } + } else if mon := c.GetMon(); mon != nil { + if err := p.VisitMonetary(c, mon); err != nil { + return err + } + } + + if err := p.VisitDestination(c.GetDest()); err != nil { + return err + } + + return nil +} + +func (p *parseVisitor) VisitSetTxMeta(ctx *parser2.SetTxMetaContext) *CompileError { + _, _, compErr := p.VisitExpr(ctx.GetValue(), true) + if compErr != nil { + return compErr + } + + keyAddr, err := p.AllocateResource(program2.Constant{ + Inner: internal2.String(strings.Trim(ctx.GetKey().GetText(), `"`)), + }) + if err != nil { + return LogicError(ctx, err) + } + p.PushAddress(*keyAddr) + + p.AppendInstruction(program2.OP_TX_META) + + return nil +} + +func (p *parseVisitor) VisitSetAccountMeta(ctx *parser2.SetAccountMetaContext) *CompileError { + _, _, compErr := p.VisitExpr(ctx.GetValue(), true) + if compErr != nil { + return compErr + } + + keyAddr, err := p.AllocateResource(program2.Constant{ + Inner: internal2.String(strings.Trim(ctx.GetKey().GetText(), `"`)), + }) + if err != nil { + return LogicError(ctx, err) + } + p.PushAddress(*keyAddr) + + ty, accAddr, compErr := p.VisitExpr(ctx.GetAcc(), false) + if compErr != nil { + return compErr + } + if ty != internal2.TypeAccount { + return LogicError(ctx, fmt.Errorf( + "set_account_meta: expression is of type %s, and should be of type account", ty)) + } + p.PushAddress(*accAddr) + + p.AppendInstruction(program2.OP_ACCOUNT_META) + + return nil +} + +func (p *parseVisitor) VisitSaveFromAccount(c *parser2.SaveFromAccountContext) *CompileError { + var ( + typ internal2.Type + addr *internal2.Address + compErr *CompileError + ) + if monAll := c.GetMonAll(); monAll != nil { + typ, addr, compErr = p.VisitExpr(monAll.GetAsset(), false) + if compErr != nil { + return compErr + } + if typ != internal2.TypeAsset { + return LogicError(c, fmt.Errorf( + "save monetary all from account: the first expression should be of type 'asset' instead of '%s'", typ)) + } + } else if mon := c.GetMon(); mon != nil { + typ, addr, compErr = p.VisitExpr(mon, false) + if compErr != nil { + return compErr + } + if typ != internal2.TypeMonetary { + return LogicError(c, fmt.Errorf( + "save monetary from account: the first expression should be of type 'monetary' instead of '%s'", typ)) + } + } + p.PushAddress(*addr) + + typ, addr, compErr = p.VisitExpr(c.GetAcc(), false) + if compErr != nil { + return compErr + } + if typ != internal2.TypeAccount { + return LogicError(c, fmt.Errorf( + "save monetary from account: the second expression should be of type 'account' instead of '%s'", typ)) + } + p.PushAddress(*addr) + + p.AppendInstruction(program2.OP_SAVE) + + return nil +} + +func (p *parseVisitor) VisitPrint(ctx *parser2.PrintContext) *CompileError { + _, _, err := p.VisitExpr(ctx.GetExpr(), true) + if err != nil { + return err + } + + p.AppendInstruction(program2.OP_PRINT) + + return nil +} + +func (p *parseVisitor) VisitVars(c *parser2.VarListDeclContext) *CompileError { + if len(c.GetV()) > 32768 { + return LogicError(c, fmt.Errorf("number of variables exceeded %v", 32768)) + } + + for _, v := range c.GetV() { + name := v.GetName().GetText()[1:] + if _, ok := p.varIdx[name]; ok { + return LogicError(c, fmt.Errorf("duplicate variable $%s", name)) + } + var ty internal2.Type + switch v.GetTy().GetText() { + case "account": + ty = internal2.TypeAccount + case "asset": + ty = internal2.TypeAsset + case "number": + ty = internal2.TypeNumber + case "string": + ty = internal2.TypeString + case "monetary": + ty = internal2.TypeMonetary + case "portion": + ty = internal2.TypePortion + default: + return InternalError(c) + } + + var addr *internal2.Address + var err error + if v.GetOrig() == nil { + addr, err = p.AllocateResource(program2.Variable{Typ: ty, Name: name}) + if err != nil { + return &CompileError{ + Msg: errors.Wrap(err, + "allocating variable resource").Error(), + } + } + p.varIdx[name] = *addr + continue + } + + switch c := v.GetOrig().(type) { + case *parser2.OriginAccountMetaContext: + srcTy, src, compErr := p.VisitExpr(c.GetAccount(), false) + if compErr != nil { + return compErr + } + if srcTy != internal2.TypeAccount { + return LogicError(c, fmt.Errorf( + "variable $%s: type should be 'account' to pull account metadata", name)) + } + key := strings.Trim(c.GetKey().GetText(), `"`) + addr, err = p.AllocateResource(program2.VariableAccountMetadata{ + Typ: ty, + Name: name, + Account: *src, + Key: key, + }) + case *parser2.OriginAccountBalanceContext: + if ty != internal2.TypeMonetary { + return LogicError(c, fmt.Errorf( + "variable $%s: type should be 'monetary' to pull account balance", name)) + } + accTy, accAddr, compErr := p.VisitExpr(c.GetAccount(), false) + if compErr != nil { + return compErr + } + if accTy != internal2.TypeAccount { + return LogicError(c, fmt.Errorf( + "variable $%s: the first argument to pull account balance should be of type 'account'", name)) + } + + assTy, assAddr, compErr := p.VisitExpr(c.GetAsset(), false) + if compErr != nil { + return compErr + } + if assTy != internal2.TypeAsset { + return LogicError(c, fmt.Errorf( + "variable $%s: the second argument to pull account balance should be of type 'asset'", name)) + } + + addr, err = p.AllocateResource(program2.VariableAccountBalance{ + Name: name, + Account: *accAddr, + Asset: *assAddr, + }) + if err != nil { + return LogicError(c, err) + } + } + if err != nil { + return LogicError(c, err) + } + + p.varIdx[name] = *addr + } + + return nil +} + +func (p *parseVisitor) VisitScript(c parser2.IScriptContext) *CompileError { + switch c := c.(type) { + case *parser2.ScriptContext: + vars := c.GetVars() + if vars != nil { + switch c := vars.(type) { + case *parser2.VarListDeclContext: + if err := p.VisitVars(c); err != nil { + return err + } + default: + return InternalError(c) + } + } + + for _, stmt := range c.GetStmts() { + var err *CompileError + switch c := stmt.(type) { + case *parser2.PrintContext: + err = p.VisitPrint(c) + case *parser2.FailContext: + p.AppendInstruction(program2.OP_FAIL) + case *parser2.SendContext: + err = p.VisitSend(c) + case *parser2.SetTxMetaContext: + err = p.VisitSetTxMeta(c) + case *parser2.SetAccountMetaContext: + err = p.VisitSetAccountMeta(c) + case *parser2.SaveFromAccountContext: + err = p.VisitSaveFromAccount(c) + default: + return InternalError(c) + } + if err != nil { + return err + } + } + default: + return InternalError(c) + } + + return nil +} + +type CompileArtifacts struct { + Source string + Tokens []antlr.Token + Errors []CompileError + Program *program2.Program +} + +func CompileFull(input string) CompileArtifacts { + artifacts := CompileArtifacts{ + Source: input, + } + + errListener := &ErrorListener{} + + is := antlr.NewInputStream(input) + lexer := parser2.NewNumScriptLexer(is) + lexer.RemoveErrorListeners() + lexer.AddErrorListener(errListener) + + stream := antlr.NewCommonTokenStream(lexer, antlr.LexerDefaultTokenChannel) + p := parser2.NewNumScriptParser(stream) + p.RemoveErrorListeners() + p.AddErrorListener(errListener) + + p.BuildParseTrees = true + + tree := p.Script() + + artifacts.Tokens = stream.GetAllTokens() + artifacts.Errors = append(artifacts.Errors, errListener.Errors...) + + if len(errListener.Errors) != 0 { + return artifacts + } + + visitor := parseVisitor{ + errListener: errListener, + instructions: make([]byte, 0), + resources: make([]program2.Resource, 0), + varIdx: make(map[string]internal2.Address), + neededBalances: make(map[internal2.Address]map[internal2.Address]struct{}), + sources: map[internal2.Address]struct{}{}, + } + + err := visitor.VisitScript(tree) + if err != nil { + artifacts.Errors = append(artifacts.Errors, *err) + return artifacts + } + + sources := make(internal2.Addresses, 0) + for address := range visitor.sources { + sources = append(sources, address) + } + sort.Stable(sources) + + artifacts.Program = &program2.Program{ + Instructions: visitor.instructions, + Resources: visitor.resources, + NeededBalances: visitor.neededBalances, + Sources: sources, + } + + return artifacts +} + +func Compile(input string) (*program2.Program, error) { + artifacts := CompileFull(input) + if len(artifacts.Errors) > 0 { + err := CompileErrorList{ + Errors: artifacts.Errors, + Source: artifacts.Source, + } + return nil, &err + } + + return artifacts.Program, nil +} diff --git a/components/ledger/internal/machine/script/compiler/compiler_test.go b/components/ledger/internal/machine/script/compiler/compiler_test.go new file mode 100644 index 000000000..a6b3868a7 --- /dev/null +++ b/components/ledger/internal/machine/script/compiler/compiler_test.go @@ -0,0 +1,1711 @@ +package compiler + +import ( + "bytes" + "fmt" + "math/big" + "reflect" + "testing" + + internal2 "github.com/formancehq/ledger/internal/machine/internal" + program2 "github.com/formancehq/ledger/internal/machine/vm/program" + "github.com/stretchr/testify/require" +) + +type TestCase struct { + Case string + Expected CaseResult +} + +type CaseResult struct { + Instructions []byte + Resources []program2.Resource + Variables []string + Error string +} + +func test(t *testing.T, c TestCase) { + p, err := Compile(c.Case) + if c.Expected.Error != "" { + require.Error(t, err) + require.NotEmpty(t, err.Error()) + require.ErrorContains(t, err, c.Expected.Error) + return + } + require.NoError(t, err) + require.NotNil(t, p) + + if len(c.Expected.Instructions) > 0 && !bytes.Equal(p.Instructions, c.Expected.Instructions) { + t.Error(fmt.Errorf( + "unexpected instructions:\n%v\nhas: %+v\nwant:%+v", + *p, p.Instructions, c.Expected.Instructions)) + return + } else if len(p.Resources) != len(c.Expected.Resources) { + t.Error(fmt.Errorf( + "unexpected resources\n%v\nhas: \n%+v\nwant:\n%+v", + *p, p.Resources, c.Expected.Resources)) + return + } + + for i, expected := range c.Expected.Resources { + if !checkResourcesEqual(p.Resources[i], c.Expected.Resources[i]) { + t.Error(fmt.Errorf("%v: %v is not %v: %v", + p.Resources[i], reflect.TypeOf(p.Resources[i]).Name(), + expected, reflect.TypeOf(expected).Name(), + )) + t.Error(fmt.Errorf( + "unexpected resources\n%v\nhas: \n%+v\nwant:\n%+v", + *p, p.Resources, c.Expected.Resources)) + return + } + } +} + +func checkResourcesEqual(actual, expected program2.Resource) bool { + if reflect.TypeOf(actual) != reflect.TypeOf(expected) { + return false + } + switch res := actual.(type) { + case program2.Constant: + return internal2.ValueEquals(res.Inner, expected.(program2.Constant).Inner) + case program2.Variable: + e := expected.(program2.Variable) + return res.Typ == e.Typ && res.Name == e.Name + case program2.VariableAccountMetadata: + e := expected.(program2.VariableAccountMetadata) + return res.Account == e.Account && + res.Key == e.Key && + res.Typ == e.Typ + case program2.VariableAccountBalance: + e := expected.(program2.VariableAccountBalance) + return res.Account == e.Account && + res.Asset == e.Asset + case program2.Monetary: + e := expected.(program2.Monetary) + return res.Amount.Equal(e.Amount) && res.Asset == e.Asset + default: + panic(fmt.Errorf("invalid resource of type '%T'", res)) + } +} + +func TestSimplePrint(t *testing.T) { + test(t, TestCase{ + Case: "print 1", + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_PRINT, + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + }, + }, + }) +} + +func TestCompositeExpr(t *testing.T) { + test(t, TestCase{ + Case: "print 29 + 15 - 2", + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_APUSH, 01, 00, + program2.OP_IADD, + program2.OP_APUSH, 02, 00, + program2.OP_ISUB, + program2.OP_PRINT, + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.NewMonetaryInt(29)}, + program2.Constant{Inner: internal2.NewMonetaryInt(15)}, + program2.Constant{Inner: internal2.NewMonetaryInt(2)}, + }, + }, + }) +} + +func TestFail(t *testing.T) { + test(t, TestCase{ + Case: "fail", + Expected: CaseResult{ + Instructions: []byte{program2.OP_FAIL}, + Resources: []program2.Resource{}, + }, + }) +} + +func TestCRLF(t *testing.T) { + test(t, TestCase{ + Case: "print @a\r\nprint @b", + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_PRINT, + program2.OP_APUSH, 01, 00, + program2.OP_PRINT, + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.AccountAddress("a")}, + program2.Constant{Inner: internal2.AccountAddress("b")}, + }, + }, + }) +} + +func TestConstant(t *testing.T) { + user := internal2.AccountAddress("user:U001") + test(t, TestCase{ + Case: "print @user:U001", + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_PRINT, + }, + Resources: []program2.Resource{program2.Constant{Inner: user}}, + }, + }) +} + +func TestSetTxMeta(t *testing.T) { + test(t, TestCase{ + Case: ` + set_tx_meta("aaa", @platform) + set_tx_meta("bbb", GEM) + set_tx_meta("ccc", 42) + set_tx_meta("ddd", "test") + set_tx_meta("eee", [COIN 30]) + set_tx_meta("fff", 15%) + `, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_APUSH, 01, 00, + program2.OP_TX_META, + program2.OP_APUSH, 02, 00, + program2.OP_APUSH, 03, 00, + program2.OP_TX_META, + program2.OP_APUSH, 04, 00, + program2.OP_APUSH, 05, 00, + program2.OP_TX_META, + program2.OP_APUSH, 06, 00, + program2.OP_APUSH, 07, 00, + program2.OP_TX_META, + program2.OP_APUSH, 9, 00, + program2.OP_APUSH, 10, 00, + program2.OP_TX_META, + program2.OP_APUSH, 11, 00, + program2.OP_APUSH, 12, 00, + program2.OP_TX_META, + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.AccountAddress("platform")}, + program2.Constant{Inner: internal2.String("aaa")}, + program2.Constant{Inner: internal2.Asset("GEM")}, + program2.Constant{Inner: internal2.String("bbb")}, + program2.Constant{Inner: internal2.NewNumber(42)}, + program2.Constant{Inner: internal2.String("ccc")}, + program2.Constant{Inner: internal2.String("test")}, + program2.Constant{Inner: internal2.String("ddd")}, + program2.Constant{Inner: internal2.Asset("COIN")}, + program2.Monetary{Asset: 8, Amount: internal2.NewMonetaryInt(30)}, + program2.Constant{Inner: internal2.String("eee")}, + program2.Constant{Inner: internal2.Portion{ + Remaining: false, + Specific: big.NewRat(15, 100), + }}, + program2.Constant{Inner: internal2.String("fff")}, + }, + }, + }) +} + +func TestSetTxMetaVars(t *testing.T) { + test(t, TestCase{ + Case: ` + vars { + portion $commission + } + set_tx_meta("fee", $commission) + `, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_APUSH, 01, 00, + program2.OP_TX_META, + }, + Resources: []program2.Resource{ + program2.Variable{Typ: internal2.TypePortion, Name: "commission"}, + program2.Constant{Inner: internal2.String("fee")}, + }, + }, + }) +} + +func TestComments(t *testing.T) { + test(t, TestCase{ + Case: ` + /* This is a multi-line comment, it spans multiple lines + and /* doesn't choke on nested comments */ ! */ + vars { + account $a + } + // this is a single-line comment + print $a + `, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_PRINT, + }, + Resources: []program2.Resource{ + program2.Variable{Typ: internal2.TypeAccount, Name: "a"}, + }, + }, + }) +} + +func TestUndeclaredVariable(t *testing.T) { + test(t, TestCase{ + Case: "print $nope", + Expected: CaseResult{ + Error: "declared", + }, + }) +} + +func TestInvalidTypeInSendValue(t *testing.T) { + test(t, TestCase{ + Case: ` + send @a ( + source = { + @a + [GEM 2] + } + destination = @b + )`, + Expected: CaseResult{ + Error: "send monetary: the expression should be of type 'monetary' instead of 'account'", + }, + }) +} + +func TestInvalidTypeInSource(t *testing.T) { + test(t, TestCase{ + Case: ` + send [USD/2 99] ( + source = { + @a + [GEM 2] + } + destination = @b + )`, + Expected: CaseResult{ + Error: "wrong type", + }, + }) +} + +func TestDestinationAllotment(t *testing.T) { + test(t, TestCase{ + Case: `send [EUR/2 43] ( + source = @foo + destination = { + 1/8 to @bar + 7/8 to @baz + } + )`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 02, 00, // @foo + program2.OP_APUSH, 01, 00, // @foo, [EUR/2 43] + program2.OP_ASSET, // @foo, EUR/2 + program2.OP_APUSH, 03, 00, // @foo, EUR/2, 0 + program2.OP_MONETARY_NEW, // @foo, [EUR/2 0] + program2.OP_TAKE_ALL, // [EUR/2 @foo ] + program2.OP_APUSH, 01, 00, // [EUR/2 @foo ], [EUR/2 43] + program2.OP_TAKE, // [EUR/2 @foo ], [EUR/2 @foo 43] + program2.OP_APUSH, 04, 00, // [EUR/2 @foo ], [EUR/2 @foo 43] 1 + program2.OP_BUMP, // [EUR/2 @foo 43], [EUR/2 @foo ] + program2.OP_REPAY, // [EUR/2 @foo 43] + program2.OP_FUNDING_SUM, // [EUR/2 @foo 43], [EUR/2 43] + program2.OP_APUSH, 05, 00, // [EUR/2 @foo 43], [EUR/2 43], 7/8 + program2.OP_APUSH, 06, 00, // [EUR/2 @foo 43], [EUR/2 43], 7/8, 1/8 + program2.OP_APUSH, 07, 00, // [EUR/2 @foo 43], [EUR/2 43], 7/8, 1/8, 2 + program2.OP_MAKE_ALLOTMENT, // [EUR/2 @foo 43], [EUR/2 43], {1/8 : 7/8} + program2.OP_ALLOC, // [EUR/2 @foo 43], [EUR/2 37], [EUR/2 6] + program2.OP_APUSH, 07, 00, // [EUR/2 @foo 43], [EUR/2 37] [EUR/2 6], 2 + program2.OP_BUMP, // [EUR/2 37], [EUR/2 6], [EUR/2 @foo 43] + program2.OP_APUSH, 04, 00, // [EUR/2 37], [EUR/2 6], [EUR/2 @foo 43] 1 + program2.OP_BUMP, // [EUR/2 37], [EUR/2 @foo 43], [EUR/2 6] + program2.OP_TAKE, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2 @foo 6] + program2.OP_FUNDING_SUM, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2 @foo 6] [EUR/2 6] + program2.OP_TAKE, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2] [EUR/2 @foo 6] + program2.OP_APUSH, 8, 00, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2] [EUR/2 @foo 6], @bar + program2.OP_SEND, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2] + program2.OP_APUSH, 04, 00, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2] 1 + program2.OP_BUMP, // [EUR/2 37], [EUR/2], [EUR/2 @foo 37] + program2.OP_APUSH, 07, 00, // [EUR/2 37], [EUR/2], [EUR/2 @foo 37] 2 + program2.OP_FUNDING_ASSEMBLE, // [EUR/2 37], [EUR/2 @foo 37] + program2.OP_APUSH, 04, 00, // [EUR/2 37], [EUR/2 @foo 37], 1 + program2.OP_BUMP, // [EUR/2 @foo 37], [EUR/2 37] + program2.OP_TAKE, // [EUR/2], [EUR/2 @foo 37] + program2.OP_FUNDING_SUM, // [EUR/2], [EUR/2 @foo 37], [EUR/2 37] + program2.OP_TAKE, // [EUR/2], [EUR/2], [EUR/2 @foo 37] + program2.OP_APUSH, 9, 00, // [EUR/2], [EUR/2], [EUR/2 @foo 37], @baz + program2.OP_SEND, // [EUR/2], [EUR/2] + program2.OP_APUSH, 04, 00, // [EUR/2], [EUR/2], 1 + program2.OP_BUMP, // [EUR/2], [EUR/2] + program2.OP_APUSH, 07, 00, // [EUR/2], [EUR/2], 2 + program2.OP_FUNDING_ASSEMBLE, // [EUR/2] + program2.OP_REPAY, // + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.Asset("EUR/2")}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(43), + }, + program2.Constant{Inner: internal2.AccountAddress("foo")}, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.Portion{Specific: big.NewRat(7, 8)}}, + program2.Constant{Inner: internal2.Portion{Specific: big.NewRat(1, 8)}}, + program2.Constant{Inner: internal2.NewMonetaryInt(2)}, + program2.Constant{Inner: internal2.AccountAddress("bar")}, + program2.Constant{Inner: internal2.AccountAddress("baz")}, + }, + }, + }) +} + +func TestDestinationInOrder(t *testing.T) { + test(t, TestCase{ + Case: `send [COIN 50] ( + source = @a + destination = { + max [COIN 10] to @b + remaining to @c + } + )`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 02, 00, // @a + program2.OP_APUSH, 01, 00, // @a, [COIN 50] + program2.OP_ASSET, // @a, COIN + program2.OP_APUSH, 03, 00, // @a, COIN, 0 + program2.OP_MONETARY_NEW, // @a, [COIN 0] + program2.OP_TAKE_ALL, // [COIN @a ] + program2.OP_APUSH, 01, 00, // [COIN @a ], [COIN 50] + program2.OP_TAKE, // [COIN @a ], [COIN @a 50] + program2.OP_APUSH, 04, 00, // [COIN @a ], [COIN @a 50], 1 + program2.OP_BUMP, // [COIN @a 50], [COIN @a ] + program2.OP_REPAY, // [COIN @a 50] + program2.OP_FUNDING_SUM, // [COIN @a 50], [COIN 50] <- start of DestinationInOrder + program2.OP_ASSET, // [COIN @a 50], COIN + program2.OP_APUSH, 03, 00, // [COIN @a 50], COIN, 0 + program2.OP_MONETARY_NEW, // [COIN @a 50], [COIN 0] + program2.OP_APUSH, 04, 00, // [COIN @a 50], [COIN 0], 1 + program2.OP_BUMP, // [COIN 0], [COIN @a 50] + program2.OP_APUSH, 05, 00, // [COIN 0], [COIN @a 50], [COIN 10] <- start processing max subdestinations + program2.OP_TAKE_MAX, // [COIN 0], [COIN 0], [COIN @a 40], [COIN @a 10] + program2.OP_APUSH, 06, 00, // [COIN 0], [COIN 0], [COIN @a 40], [COIN @a 10], 2 + program2.OP_BUMP, // [COIN 0], [COIN @a 40], [COIN @a 10], [COIN 0] + program2.OP_DELETE, // [COIN 0], [COIN @a 40], [COIN @a 10] + program2.OP_FUNDING_SUM, // [COIN 0], [COIN @a 40], [COIN @a 10], [COIN 10] + program2.OP_TAKE, // [COIN 0], [COIN @a 40], [COIN], [COIN @a 10] + program2.OP_APUSH, 07, 00, // [COIN 0], [COIN @a 40], [COIN], [COIN @a 10], @b + program2.OP_SEND, // [COIN 0], [COIN @a 40], [COIN] + program2.OP_FUNDING_SUM, // [COIN 0], [COIN @a 40], [COIN], [COIN 0] + program2.OP_APUSH, 8, 00, // [COIN 0], [COIN @a 40], [COIN], [COIN 0], 3 + program2.OP_BUMP, // [COIN @a 40], [COIN], [COIN 0], [COIN 0] + program2.OP_MONETARY_ADD, // [COIN @a 40], [COIN], [COIN 0] + program2.OP_APUSH, 04, 00, // [COIN @a 40], [COIN], [COIN 0], 1 + program2.OP_BUMP, // [COIN @a 40], [COIN 0], [COIN] + program2.OP_APUSH, 06, 00, // [COIN @a 40], [COIN 0], [COIN] 2 + program2.OP_BUMP, // [COIN 0], [COIN], [COIN @a 40] + program2.OP_APUSH, 06, 00, // [COIN 0], [COIN], [COIN @a 40], 2 + program2.OP_FUNDING_ASSEMBLE, // [COIN 0], [COIN @a 40] + program2.OP_FUNDING_REVERSE, // [COIN 0], [COIN @a 40] <- start processing remaining subdestination + program2.OP_APUSH, 04, 00, // [COIN 0], [COIN @a 40], 1 + program2.OP_BUMP, // [COIN @a 40], [COIN 0] + program2.OP_TAKE, // [COIN @a 40], [COIN] + program2.OP_FUNDING_REVERSE, // [COIN @a 40], [COIN] + program2.OP_APUSH, 04, 00, // [COIN @a 40], [COIN], 1 + program2.OP_BUMP, // [COIN], [COIN @a 40] + program2.OP_FUNDING_REVERSE, // [COIN], [COIN @a 40] + program2.OP_FUNDING_SUM, // [COIN], [COIN @a 40], [COIN 40] + program2.OP_TAKE, // [COIN], [COIN], [COIN @a 40] + program2.OP_APUSH, 9, 00, // [COIN], [COIN], [COIN @a 40], @c + program2.OP_SEND, // [COIN], [COIN] + program2.OP_APUSH, 04, 00, // [COIN], [COIN], 1 + program2.OP_BUMP, // [COIN], [COIN] + program2.OP_APUSH, 06, 00, // [COIN], [COIN], 2 + program2.OP_FUNDING_ASSEMBLE, // [COIN] + program2.OP_REPAY, // + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.Asset("COIN")}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(50), + }, + program2.Constant{Inner: internal2.AccountAddress("a")}, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(10), + }, + program2.Constant{Inner: internal2.NewMonetaryInt(2)}, + program2.Constant{Inner: internal2.AccountAddress("b")}, + program2.Constant{Inner: internal2.NewMonetaryInt(3)}, + program2.Constant{Inner: internal2.AccountAddress("c")}, + }, + }, + }) +} + +func TestAllocationPercentages(t *testing.T) { + test(t, TestCase{ + Case: `send [EUR/2 43] ( + source = @foo + destination = { + 12.5% to @bar + 37.5% to @baz + 50% to @qux + } + )`, + Expected: CaseResult{ + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.Asset("EUR/2")}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(43), + }, + program2.Constant{Inner: internal2.AccountAddress("foo")}, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.Portion{Specific: big.NewRat(1, 2)}}, + program2.Constant{Inner: internal2.Portion{Specific: big.NewRat(3, 8)}}, + program2.Constant{Inner: internal2.Portion{Specific: big.NewRat(1, 8)}}, + program2.Constant{Inner: internal2.NewMonetaryInt(3)}, + program2.Constant{Inner: internal2.AccountAddress("bar")}, + program2.Constant{Inner: internal2.NewMonetaryInt(2)}, + program2.Constant{Inner: internal2.AccountAddress("baz")}, + program2.Constant{Inner: internal2.AccountAddress("qux")}, + }, + }, + }) +} + +func TestSend(t *testing.T) { + script := ` + send [EUR/2 99] ( + source = @alice + destination = @bob + )` + alice := internal2.AccountAddress("alice") + bob := internal2.AccountAddress("bob") + test(t, TestCase{ + Case: script, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 02, 00, // @alice + program2.OP_APUSH, 01, 00, // @alice, [EUR/2 99] + program2.OP_ASSET, // @alice, EUR/2 + program2.OP_APUSH, 03, 00, // @alice, EUR/2, 0 + program2.OP_MONETARY_NEW, // @alice, [EUR/2 0] + program2.OP_TAKE_ALL, // [EUR/2 @alice ] + program2.OP_APUSH, 01, 00, // [EUR/2 @alice ], [EUR/2 99] + program2.OP_TAKE, // [EUR/2 @alice ], [EUR/2 @alice 99] + program2.OP_APUSH, 04, 00, // [EUR/2 @alice ], [EUR/2 @alice 99], 1 + program2.OP_BUMP, // [EUR/2 @alice 99], [EUR/2 @alice ] + program2.OP_REPAY, // [EUR/2 @alice 99] + program2.OP_FUNDING_SUM, // [EUR/2 @alice 99], [EUR/2 99] + program2.OP_TAKE, // [EUR/2], [EUR/2 @alice 99] + program2.OP_APUSH, 05, 00, // [EUR/2], [EUR/2 @alice 99], @bob + program2.OP_SEND, // [EUR/2] + program2.OP_REPAY, // + }, Resources: []program2.Resource{ + program2.Constant{Inner: internal2.Asset("EUR/2")}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(99), + }, + program2.Constant{Inner: alice}, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: bob}}, + }, + }) +} + +func TestSendAll(t *testing.T) { + test(t, TestCase{ + Case: `send [EUR/2 *] ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 01, 00, // @alice + program2.OP_APUSH, 00, 00, // @alice, EUR/2 + program2.OP_APUSH, 02, 00, // @alice, EUR/2, 0 + program2.OP_MONETARY_NEW, // @alice, [EUR/2 0] + program2.OP_TAKE_ALL, // [EUR/2 @alice ] + program2.OP_FUNDING_SUM, // [EUR/2 @alice ], [EUR/2 ] + program2.OP_TAKE, // [EUR/2], [EUR/2 @alice ] + program2.OP_APUSH, 03, 00, // [EUR/2], [EUR/2 @alice ], @b + program2.OP_SEND, // [EUR/2] + program2.OP_REPAY, // + }, Resources: []program2.Resource{ + program2.Constant{Inner: internal2.Asset("EUR/2")}, + program2.Constant{Inner: internal2.AccountAddress("alice")}, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.AccountAddress("bob")}}, + }, + }) +} + +func TestMetadata(t *testing.T) { + test(t, TestCase{ + Case: ` + vars { + account $sale + account $seller = meta($sale, "seller") + portion $commission = meta($seller, "commission") + } + send [EUR/2 53] ( + source = $sale + destination = { + $commission to @platform + remaining to $seller + } + )`, + Expected: CaseResult{ + Resources: []program2.Resource{ + program2.Variable{Typ: internal2.TypeAccount, Name: "sale"}, + program2.VariableAccountMetadata{ + Typ: internal2.TypeAccount, + Account: internal2.NewAddress(0), + Key: "seller", + }, + program2.VariableAccountMetadata{ + Typ: internal2.TypePortion, + Account: internal2.NewAddress(1), + Key: "commission", + }, + program2.Constant{Inner: internal2.Asset("EUR/2")}, + program2.Monetary{ + Asset: 3, + Amount: internal2.NewMonetaryInt(53), + }, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.NewPortionRemaining()}, + program2.Constant{Inner: internal2.NewMonetaryInt(2)}, + program2.Constant{Inner: internal2.AccountAddress("platform")}, + }, + }, + }) +} + +func TestSyntaxError(t *testing.T) { + test(t, TestCase{ + Case: "print fail", + Expected: CaseResult{ + Error: "mismatched input", + }, + }) +} + +func TestLogicError(t *testing.T) { + test(t, TestCase{ + Case: `send [EUR/2 200] ( + source = 200 + destination = @bob + )`, + Expected: CaseResult{ + Error: "expected", + }, + }) +} + +func TestPreventTakeAllFromWorld(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM *] ( + source = @world + destination = @foo + )`, + Expected: CaseResult{ + Error: "cannot", + }, + }) +} + +func TestPreventAddToBottomlessSource(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 1000] ( + source = { + @a + @world + @c + } + destination = @out + )`, + Expected: CaseResult{ + Error: "world", + }, + }) +} + +func TestPreventAddToBottomlessSource2(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 1000] ( + source = { + { + @a + @world + } + { + @b + @world + } + } + destination = @out + )`, + Expected: CaseResult{ + Error: "world", + }, + }) +} + +func TestPreventSourceAlreadyEmptied(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 1000] ( + source = { + { + @a + @b + } + @a + } + destination = @out + )`, + Expected: CaseResult{ + Error: "empt", + }, + }) +} + +func TestPreventTakeAllFromAllocation(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM *] ( + source = { + 50% from @a + 50% from @b + } + destination = @out + )`, + Expected: CaseResult{ + Error: "all", + }, + }) +} + +func TestWrongTypeSourceMax(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 15] ( + source = { + max @foo from @bar + @world + } + destination = @baz + )`, + Expected: CaseResult{ + Error: "type", + }, + }) +} + +func TestOverflowingAllocation(t *testing.T) { + t.Run(">100%", func(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 15] ( + source = @world + destination = { + 2/3 to @a + 2/3 to @b + } + )`, + Expected: CaseResult{ + Error: "100%", + }, + }) + }) + + t.Run("=100% + remaining", func(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 15] ( + source = @world + destination = { + 1/2 to @a + 1/2 to @b + remaining to @c + } + )`, + Expected: CaseResult{ + Error: "100%", + }, + }) + }) + + t.Run(">100% + remaining", func(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 15] ( + source = @world + destination = { + 2/3 to @a + 1/2 to @b + remaining to @c + } + )`, + Expected: CaseResult{ + Error: "100%", + }, + }) + }) + + t.Run("const remaining + remaining", func(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 15] ( + source = @world + destination = { + 2/3 to @a + remaining to @b + remaining to @c + } + )`, + Expected: CaseResult{ + Error: "`remaining` in the same", + }, + }) + }) + + t.Run("dyn remaining + remaining", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + portion $p + } + send [GEM 15] ( + source = @world + destination = { + $p to @a + remaining to @b + remaining to @c + } + )`, + Expected: CaseResult{ + Error: "`remaining` in the same", + }, + }) + }) + + t.Run(">100% + remaining + variable", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + portion $prop + } + send [GEM 15] ( + source = @world + destination = { + 1/2 to @a + 2/3 to @b + remaining to @c + $prop to @d + } + )`, + Expected: CaseResult{ + Error: "100%", + }, + }) + }) + + t.Run("variable - remaining", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + portion $prop + } + send [GEM 15] ( + source = @world + destination = { + 2/3 to @a + $prop to @b + } + )`, + Expected: CaseResult{ + Error: "100%", + }, + }) + }) +} + +func TestAllocationWrongDestination(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 15] ( + source = @world + destination = [GEM 10] + )`, + Expected: CaseResult{ + Error: "account", + }, + }) + test(t, TestCase{ + Case: `send [GEM 15] ( + source = @world + destination = { + 2/3 to @a + 1/3 to [GEM 10] + } + )`, + Expected: CaseResult{ + Error: "account", + }, + }) +} + +func TestAllocationInvalidPortion(t *testing.T) { + test(t, TestCase{ + Case: `vars { + account $p + } + send [GEM 15] ( + source = @world + destination = { + 10% to @a + $p to @b + } + )`, + Expected: CaseResult{ + Error: "type", + }, + }) +} + +func TestOverdraftOnWorld(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 15] ( + source = @world allowing overdraft up to [GEM 10] + destination = @foo + )`, + Expected: CaseResult{ + Error: "overdraft", + }, + }) +} + +func TestOverdraftWrongType(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 15] ( + source = @foo allowing overdraft up to @baz + destination = @bar + )`, + Expected: CaseResult{ + Error: "type", + }, + }) +} + +func TestDestinationInOrderWrongType(t *testing.T) { + test(t, TestCase{ + Case: `send [GEM 15] ( + source = @foo + destination = { + max @bar to @baz + remaining to @qux + } + )`, + Expected: CaseResult{ + Error: "type", + }, + }) +} + +func TestSetAccountMeta(t *testing.T) { + t.Run("all types", func(t *testing.T) { + test(t, TestCase{ + Case: ` + set_account_meta(@alice, "aaa", @platform) + set_account_meta(@alice, "bbb", GEM) + set_account_meta(@alice, "ccc", 42) + set_account_meta(@alice, "ddd", "test") + set_account_meta(@alice, "eee", [COIN 30]) + set_account_meta(@alice, "fff", 15%) + `, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_APUSH, 01, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ACCOUNT_META, + program2.OP_APUSH, 03, 00, + program2.OP_APUSH, 04, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ACCOUNT_META, + program2.OP_APUSH, 05, 00, + program2.OP_APUSH, 06, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ACCOUNT_META, + program2.OP_APUSH, 7, 00, + program2.OP_APUSH, 8, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ACCOUNT_META, + program2.OP_APUSH, 10, 00, + program2.OP_APUSH, 11, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ACCOUNT_META, + program2.OP_APUSH, 12, 00, + program2.OP_APUSH, 13, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ACCOUNT_META, + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.AccountAddress("platform")}, + program2.Constant{Inner: internal2.String("aaa")}, + program2.Constant{Inner: internal2.AccountAddress("alice")}, + program2.Constant{Inner: internal2.Asset("GEM")}, + program2.Constant{Inner: internal2.String("bbb")}, + program2.Constant{Inner: internal2.NewNumber(42)}, + program2.Constant{Inner: internal2.String("ccc")}, + program2.Constant{Inner: internal2.String("test")}, + program2.Constant{Inner: internal2.String("ddd")}, + program2.Constant{Inner: internal2.Asset("COIN")}, + program2.Monetary{ + Asset: 9, + Amount: internal2.NewMonetaryInt(30), + }, + program2.Constant{Inner: internal2.String("eee")}, + program2.Constant{Inner: internal2.Portion{ + Remaining: false, + Specific: big.NewRat(15, 100), + }}, + program2.Constant{Inner: internal2.String("fff")}, + }, + }, + }) + }) + + t.Run("with vars", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + account $acc + } + send [EUR/2 100] ( + source = @world + destination = $acc + ) + set_account_meta($acc, "fees", 1%)`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 03, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ASSET, + program2.OP_APUSH, 04, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 02, 00, + program2.OP_TAKE_MAX, + program2.OP_APUSH, 05, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_APUSH, 03, 00, + program2.OP_APUSH, 06, 00, + program2.OP_BUMP, + program2.OP_TAKE_ALWAYS, + program2.OP_APUSH, 06, 00, + program2.OP_FUNDING_ASSEMBLE, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 00, 00, + program2.OP_SEND, + program2.OP_REPAY, + program2.OP_APUSH, 07, 00, + program2.OP_APUSH, 8, 00, + program2.OP_APUSH, 00, 00, + program2.OP_ACCOUNT_META, + }, + Resources: []program2.Resource{ + program2.Variable{Typ: internal2.TypeAccount, Name: "acc"}, + program2.Constant{Inner: internal2.Asset("EUR/2")}, + program2.Monetary{ + Asset: 1, + Amount: internal2.NewMonetaryInt(100), + }, + program2.Constant{Inner: internal2.AccountAddress("world")}, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.NewMonetaryInt(2)}, + program2.Constant{Inner: internal2.Portion{ + Remaining: false, + Specific: big.NewRat(1, 100), + }}, + program2.Constant{Inner: internal2.String("fees")}, + }, + }, + }) + }) + + t.Run("errors", func(t *testing.T) { + test(t, TestCase{ + Case: `set_account_meta(@alice, "fees")`, + Expected: CaseResult{ + Error: "mismatched input", + }, + }) + test(t, TestCase{ + Case: `set_account_meta("test")`, + Expected: CaseResult{ + Error: "mismatched input", + }, + }) + test(t, TestCase{ + Case: `set_account_meta(@alice, "t1", "t2", "t3")`, + Expected: CaseResult{ + Error: "mismatched input", + }, + }) + test(t, TestCase{ + Case: `vars { + portion $p + } + set_account_meta($p, "fees", 1%)`, + Expected: CaseResult{ + Error: "should be of type account", + }, + }) + }) +} + +func TestVariableBalance(t *testing.T) { + t.Run("simplest", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + monetary $bal = balance(@alice, COIN) + } + send $bal ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ASSET, + program2.OP_APUSH, 03, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 02, 00, + program2.OP_TAKE, + program2.OP_APUSH, 04, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 05, 00, + program2.OP_SEND, + program2.OP_REPAY, + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.AccountAddress("alice")}, + program2.Constant{Inner: internal2.Asset("COIN")}, + program2.VariableAccountBalance{Account: 0, Asset: 1}, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.AccountAddress("bob")}, + }, + }, + }) + }) + + t.Run("with account variable", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + account $acc + monetary $bal = balance($acc, COIN) + } + send $bal ( + source = @world + destination = @alice + )`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 03, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ASSET, + program2.OP_APUSH, 04, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 02, 00, + program2.OP_TAKE_MAX, + program2.OP_APUSH, 05, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_APUSH, 03, 00, + program2.OP_APUSH, 06, 00, + program2.OP_BUMP, + program2.OP_TAKE_ALWAYS, + program2.OP_APUSH, 06, 00, + program2.OP_FUNDING_ASSEMBLE, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 07, 00, + program2.OP_SEND, + program2.OP_REPAY, + }, + Resources: []program2.Resource{ + program2.Variable{Typ: internal2.TypeAccount, Name: "acc"}, + program2.Constant{Inner: internal2.Asset("COIN")}, + program2.VariableAccountBalance{Account: 0, Asset: 1}, + program2.Constant{Inner: internal2.AccountAddress("world")}, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.NewMonetaryInt(2)}, + program2.Constant{Inner: internal2.AccountAddress("alice")}, + }, + }, + }) + }) + + t.Run("error variable type", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + account $bal = balance(@alice, COIN) + } + send $bal ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Error: "variable $bal: type should be 'monetary' to pull account balance", + }, + }) + }) + + t.Run("error no asset", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + monetary $bal = balance(@alice) + } + send $bal ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Error: "mismatched input", + }, + }) + }) + + t.Run("error too many arguments", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + monetary $bal = balance(@alice, USD, COIN) + } + send $bal ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Error: "mismatched input ',' expecting ')'", + }, + }) + }) + + t.Run("error wrong type for account", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + monetary $bal = balance(USD, COIN) + } + send $bal ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Error: "variable $bal: the first argument to pull account balance should be of type 'account'", + }, + }) + }) + + t.Run("error wrong type for asset", func(t *testing.T) { + test(t, TestCase{ + Case: `vars { + monetary $bal = balance(@alice, @bob) + } + send $bal ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Error: "variable $bal: the second argument to pull account balance should be of type 'asset'", + }, + }) + }) + + t.Run("error not in variables", func(t *testing.T) { + test(t, TestCase{ + Case: `send balance(@alice, COIN) ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Error: "mismatched input 'balance'", + }, + }) + }) +} + +func TestVariableAsset(t *testing.T) { + script := `vars { + asset $ass + monetary $bal = balance(@alice, $ass) + } + + send [$ass *] ( + source = @alice + destination = @bob + ) + + send [$ass 1] ( + source = @bob + destination = @alice + ) + + send $bal ( + source = @alice + destination = @bob + )` + + test(t, TestCase{ + Case: script, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 01, 00, + program2.OP_APUSH, 00, 00, + program2.OP_APUSH, 03, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 04, 00, + program2.OP_SEND, + program2.OP_REPAY, + program2.OP_APUSH, 04, 00, + program2.OP_APUSH, 05, 00, + program2.OP_ASSET, + program2.OP_APUSH, 03, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 05, 00, + program2.OP_TAKE, + program2.OP_APUSH, 06, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 01, 00, + program2.OP_SEND, + program2.OP_REPAY, + program2.OP_APUSH, 01, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ASSET, + program2.OP_APUSH, 03, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 02, 00, + program2.OP_TAKE, + program2.OP_APUSH, 06, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 04, 00, + program2.OP_SEND, + program2.OP_REPAY, + }, + Resources: []program2.Resource{ + program2.Variable{Typ: internal2.TypeAsset, Name: "ass"}, + program2.Constant{Inner: internal2.AccountAddress("alice")}, + program2.VariableAccountBalance{ + Name: "bal", + Account: 1, + Asset: 0, + }, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.AccountAddress("bob")}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(1), + }, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + }, + }, + }) +} + +func TestPrint(t *testing.T) { + script := `print 1 + 2 + 3` + test(t, TestCase{ + Case: script, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_APUSH, 01, 00, + program2.OP_IADD, + program2.OP_APUSH, 02, 00, + program2.OP_IADD, + program2.OP_PRINT, + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.NewMonetaryInt(2)}, + program2.Constant{Inner: internal2.NewMonetaryInt(3)}, + }, + }, + }) +} + +func TestSendWithArithmetic(t *testing.T) { + t.Run("nominal", func(t *testing.T) { + script := ` + vars { + asset $ass + monetary $mon + } + send [EUR 1] + $mon + [$ass 3] - [EUR 4] ( + source = @a + destination = @b + )` + + test(t, TestCase{ + Case: script, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 06, 00, + program2.OP_APUSH, 03, 00, + program2.OP_ASSET, + program2.OP_APUSH, 07, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 03, 00, + program2.OP_APUSH, 01, 00, + program2.OP_MONETARY_ADD, + program2.OP_APUSH, 04, 00, + program2.OP_MONETARY_ADD, + program2.OP_APUSH, 05, 00, + program2.OP_MONETARY_SUB, + program2.OP_TAKE, + program2.OP_APUSH, 8, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 9, 00, + program2.OP_SEND, + program2.OP_REPAY, + }, + Resources: []program2.Resource{ + program2.Variable{ + Typ: internal2.TypeAsset, + Name: "ass", + }, + program2.Variable{ + Typ: internal2.TypeMonetary, + Name: "mon", + }, + program2.Constant{Inner: internal2.Asset("EUR")}, + program2.Monetary{ + Asset: 2, + Amount: internal2.NewMonetaryInt(1), + }, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(3), + }, + program2.Monetary{ + Asset: 2, + Amount: internal2.NewMonetaryInt(4), + }, + program2.Constant{Inner: internal2.AccountAddress("a")}, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.AccountAddress("b")}, + }, + }, + }) + }) + + t.Run("error incompatible types", func(t *testing.T) { + script := `send [EUR 1] + 2 ( + source = @world + destination = @bob + )` + + test(t, TestCase{ + Case: script, + Expected: CaseResult{ + Instructions: []byte{}, + Resources: []program2.Resource{}, + Error: "tried to do an arithmetic operation with incompatible left and right-hand side operand types: monetary and number", + }, + }) + }) + + t.Run("error incompatible types var", func(t *testing.T) { + script := ` + vars { + number $nb + } + send [EUR 1] - $nb ( + source = @world + destination = @bob + )` + + test(t, TestCase{ + Case: script, + Expected: CaseResult{ + Instructions: []byte{}, + Resources: []program2.Resource{}, + Error: "tried to do an arithmetic operation with incompatible left and right-hand side operand types: monetary and number", + }, + }) + }) +} + +func TestSaveFromAccount(t *testing.T) { + t.Run("simple", func(t *testing.T) { + test(t, TestCase{ + Case: ` + save [EUR 10] from @alice + + send [EUR 20] ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 01, 00, + program2.OP_APUSH, 02, 00, + program2.OP_SAVE, + program2.OP_APUSH, 02, 00, + program2.OP_APUSH, 03, 00, + program2.OP_ASSET, + program2.OP_APUSH, 04, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 03, 00, + program2.OP_TAKE, + program2.OP_APUSH, 05, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 06, 00, + program2.OP_SEND, + program2.OP_REPAY, + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.Asset("EUR")}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(10), + }, + program2.Constant{Inner: internal2.AccountAddress("alice")}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(20), + }, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.AccountAddress("bob")}, + }, + }, + }) + }) + + t.Run("save all", func(t *testing.T) { + test(t, TestCase{ + Case: ` + save [EUR *] from @alice + + send [EUR 20] ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_APUSH, 01, 00, + program2.OP_SAVE, + program2.OP_APUSH, 01, 00, + program2.OP_APUSH, 02, 00, + program2.OP_ASSET, + program2.OP_APUSH, 03, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 02, 00, + program2.OP_TAKE, + program2.OP_APUSH, 04, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 05, 00, + program2.OP_SEND, + program2.OP_REPAY, + }, + Resources: []program2.Resource{ + program2.Constant{Inner: internal2.Asset("EUR")}, + program2.Constant{Inner: internal2.AccountAddress("alice")}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(20), + }, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.AccountAddress("bob")}, + }, + }, + }) + }) + + t.Run("with asset var", func(t *testing.T) { + test(t, TestCase{ + Case: ` + vars { + asset $ass + } + + save [$ass 10] from @alice + + send [$ass 20] ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 01, 00, + program2.OP_APUSH, 02, 00, + program2.OP_SAVE, + program2.OP_APUSH, 02, 00, + program2.OP_APUSH, 03, 00, + program2.OP_ASSET, + program2.OP_APUSH, 04, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 03, 00, + program2.OP_TAKE, + program2.OP_APUSH, 05, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 06, 00, + program2.OP_SEND, + program2.OP_REPAY, + }, + Resources: []program2.Resource{ + program2.Variable{Typ: internal2.TypeAsset, Name: "ass"}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(10), + }, + program2.Constant{Inner: internal2.AccountAddress("alice")}, + program2.Monetary{ + Asset: 0, + Amount: internal2.NewMonetaryInt(20), + }, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.AccountAddress("bob")}, + }, + }, + }) + }) + + t.Run("with monetary var", func(t *testing.T) { + test(t, TestCase{ + Case: ` + vars { + monetary $mon + } + + save $mon from @alice + + send [EUR 20] ( + source = @alice + destination = @bob + )`, + Expected: CaseResult{ + Instructions: []byte{ + program2.OP_APUSH, 00, 00, + program2.OP_APUSH, 01, 00, + program2.OP_SAVE, + program2.OP_APUSH, 01, 00, + program2.OP_APUSH, 03, 00, + program2.OP_ASSET, + program2.OP_APUSH, 04, 00, + program2.OP_MONETARY_NEW, + program2.OP_TAKE_ALL, + program2.OP_APUSH, 03, 00, + program2.OP_TAKE, + program2.OP_APUSH, 05, 00, + program2.OP_BUMP, + program2.OP_REPAY, + program2.OP_FUNDING_SUM, + program2.OP_TAKE, + program2.OP_APUSH, 06, 00, + program2.OP_SEND, + program2.OP_REPAY, + }, + Resources: []program2.Resource{ + program2.Variable{Typ: internal2.TypeMonetary, Name: "mon"}, + program2.Constant{Inner: internal2.AccountAddress("alice")}, + program2.Constant{Inner: internal2.Asset("EUR")}, + program2.Monetary{ + Asset: 2, + Amount: internal2.NewMonetaryInt(20), + }, + program2.Constant{Inner: internal2.NewMonetaryInt(0)}, + program2.Constant{Inner: internal2.NewMonetaryInt(1)}, + program2.Constant{Inner: internal2.AccountAddress("bob")}, + }, + }, + }) + }) + + t.Run("error wrong type monetary", func(t *testing.T) { + test(t, TestCase{ + Case: ` + save 30 from @alice + `, + Expected: CaseResult{ + Instructions: []byte{}, + Resources: []program2.Resource{}, + Error: "save monetary from account: the first expression should be of type 'monetary' instead of 'number'", + }, + }) + }) + + t.Run("error wrong type account", func(t *testing.T) { + test(t, TestCase{ + Case: ` + save [EUR 30] from ALICE + `, + Expected: CaseResult{ + Instructions: []byte{}, + Resources: []program2.Resource{}, + Error: "save monetary from account: the second expression should be of type 'account' instead of 'asset'", + }, + }) + }) +} diff --git a/components/ledger/pkg/machine/script/compiler/destination.go b/components/ledger/internal/machine/script/compiler/destination.go similarity index 90% rename from components/ledger/pkg/machine/script/compiler/destination.go rename to components/ledger/internal/machine/script/compiler/destination.go index fbc5bf8a0..255f3b8f1 100644 --- a/components/ledger/pkg/machine/script/compiler/destination.go +++ b/components/ledger/internal/machine/script/compiler/destination.go @@ -3,9 +3,9 @@ package compiler import ( "errors" - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/formancehq/ledger/pkg/machine/script/parser" - "github.com/formancehq/ledger/pkg/machine/vm/program" + internal2 "github.com/formancehq/ledger/internal/machine/internal" + "github.com/formancehq/ledger/internal/machine/script/parser" + "github.com/formancehq/ledger/internal/machine/vm/program" ) func (p *parseVisitor) VisitDestination(c parser.IDestinationContext) *CompileError { @@ -26,7 +26,7 @@ func (p *parseVisitor) VisitDestinationRecursive(c parser.IDestinationContext) * if err != nil { return err } - if ty != internal.TypeAccount { + if ty != internal2.TypeAccount { return LogicError(c, errors.New("wrong type: expected account as destination"), ) @@ -41,7 +41,7 @@ func (p *parseVisitor) VisitDestinationRecursive(c parser.IDestinationContext) * // initialize the `kept` accumulator p.AppendInstruction(program.OP_FUNDING_SUM) p.AppendInstruction(program.OP_ASSET) - err := p.PushInteger(internal.NewNumber(0)) + err := p.PushInteger(internal2.NewNumber(0)) if err != nil { return LogicError(c, err) } @@ -57,7 +57,7 @@ func (p *parseVisitor) VisitDestinationRecursive(c parser.IDestinationContext) * if compErr != nil { return compErr } - if ty != internal.TypeMonetary { + if ty != internal2.TypeMonetary { return LogicError(c, errors.New("wrong type: expected monetary as max")) } p.AppendInstruction(program.OP_TAKE_MAX) @@ -84,7 +84,7 @@ func (p *parseVisitor) VisitDestinationRecursive(c parser.IDestinationContext) * if err != nil { return LogicError(c, err) } - err = p.PushInteger(internal.NewNumber(2)) + err = p.PushInteger(internal2.NewNumber(2)) if err != nil { return LogicError(c, err) } @@ -110,7 +110,7 @@ func (p *parseVisitor) VisitDestinationRecursive(c parser.IDestinationContext) * if err != nil { return LogicError(c, err) } - err = p.PushInteger(internal.NewNumber(2)) + err = p.PushInteger(internal2.NewNumber(2)) if err != nil { return LogicError(c, err) } @@ -169,7 +169,7 @@ func (p *parseVisitor) VisitAllocDestination(dests []parser.IKeptOrDestinationCo if err != nil { return LogicError(dest, err) } - err = p.PushInteger(internal.NewNumber(2)) + err = p.PushInteger(internal2.NewNumber(2)) if err != nil { return LogicError(dest, err) } diff --git a/components/ledger/pkg/machine/script/compiler/error.go b/components/ledger/internal/machine/script/compiler/error.go similarity index 100% rename from components/ledger/pkg/machine/script/compiler/error.go rename to components/ledger/internal/machine/script/compiler/error.go diff --git a/components/ledger/pkg/machine/script/compiler/error_test.go b/components/ledger/internal/machine/script/compiler/error_test.go similarity index 100% rename from components/ledger/pkg/machine/script/compiler/error_test.go rename to components/ledger/internal/machine/script/compiler/error_test.go diff --git a/components/ledger/internal/machine/script/compiler/program.go b/components/ledger/internal/machine/script/compiler/program.go new file mode 100644 index 000000000..460f22c32 --- /dev/null +++ b/components/ledger/internal/machine/script/compiler/program.go @@ -0,0 +1,36 @@ +package compiler + +import ( + internal2 "github.com/formancehq/ledger/internal/machine/internal" + program2 "github.com/formancehq/ledger/internal/machine/vm/program" +) + +func (p *parseVisitor) AppendInstruction(instruction byte) { + p.instructions = append(p.instructions, instruction) +} + +func (p *parseVisitor) PushAddress(addr internal2.Address) { + p.instructions = append(p.instructions, program2.OP_APUSH) + bytes := addr.ToBytes() + p.instructions = append(p.instructions, bytes...) +} + +func (p *parseVisitor) PushInteger(val internal2.Number) error { + addr, err := p.AllocateResource(program2.Constant{Inner: val}) + if err != nil { + return err + } + p.instructions = append(p.instructions, program2.OP_APUSH) + bytes := addr.ToBytes() + p.instructions = append(p.instructions, bytes...) + return nil +} + +func (p *parseVisitor) Bump(n int64) error { + err := p.PushInteger(internal2.NewNumber(n)) + if err != nil { + return err + } + p.instructions = append(p.instructions, program2.OP_BUMP) + return nil +} diff --git a/components/ledger/pkg/machine/script/compiler/source.go b/components/ledger/internal/machine/script/compiler/source.go similarity index 84% rename from components/ledger/pkg/machine/script/compiler/source.go rename to components/ledger/internal/machine/script/compiler/source.go index 1e5d95da6..e6af5c67f 100644 --- a/components/ledger/pkg/machine/script/compiler/source.go +++ b/components/ledger/internal/machine/script/compiler/source.go @@ -4,16 +4,16 @@ import ( "errors" "fmt" - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/formancehq/ledger/pkg/machine/script/parser" - "github.com/formancehq/ledger/pkg/machine/vm/program" + internal2 "github.com/formancehq/ledger/internal/machine/internal" + "github.com/formancehq/ledger/internal/machine/script/parser" + "github.com/formancehq/ledger/internal/machine/vm/program" ) -type FallbackAccount internal.Address +type FallbackAccount internal2.Address // VisitValueAwareSource returns the resource addresses of all the accounts -func (p *parseVisitor) VisitValueAwareSource(c parser.IValueAwareSourceContext, pushAsset func(), monAddr *internal.Address) (map[internal.Address]struct{}, *CompileError) { - neededAccounts := map[internal.Address]struct{}{} +func (p *parseVisitor) VisitValueAwareSource(c parser.IValueAwareSourceContext, pushAsset func(), monAddr *internal2.Address) (map[internal2.Address]struct{}, *CompileError) { + neededAccounts := map[internal2.Address]struct{}{} isAll := monAddr == nil switch c := c.(type) { case *parser.SrcContext: @@ -58,7 +58,7 @@ func (p *parseVisitor) VisitValueAwareSource(c parser.IValueAwareSourceContext, return nil, LogicError(c, err) } } - err := p.PushInteger(internal.NewNumber(int64(n))) + err := p.PushInteger(internal2.NewNumber(int64(n))) if err != nil { return nil, LogicError(c, err) } @@ -84,13 +84,13 @@ func (p *parseVisitor) TakeFromSource(fallback *FallbackAccount) error { return err } p.AppendInstruction(program.OP_REPAY) - p.PushAddress(internal.Address(*fallback)) + p.PushAddress(internal2.Address(*fallback)) err = p.Bump(2) if err != nil { return err } p.AppendInstruction(program.OP_TAKE_ALWAYS) - err = p.PushInteger(internal.NewNumber(2)) + err = p.PushInteger(internal2.NewNumber(2)) if err != nil { return err } @@ -101,9 +101,9 @@ func (p *parseVisitor) TakeFromSource(fallback *FallbackAccount) error { // VisitSource returns the resource addresses of all the accounts, // the addresses of accounts already emptied, // and possibly a fallback account if the source has an unbounded overdraft allowance or contains @world -func (p *parseVisitor) VisitSource(c parser.ISourceContext, pushAsset func(), isAll bool) (map[internal.Address]struct{}, map[internal.Address]struct{}, *FallbackAccount, *CompileError) { - neededAccounts := map[internal.Address]struct{}{} - emptiedAccounts := map[internal.Address]struct{}{} +func (p *parseVisitor) VisitSource(c parser.ISourceContext, pushAsset func(), isAll bool) (map[internal2.Address]struct{}, map[internal2.Address]struct{}, *FallbackAccount, *CompileError) { + neededAccounts := map[internal2.Address]struct{}{} + emptiedAccounts := map[internal2.Address]struct{}{} var fallback *FallbackAccount switch c := c.(type) { case *parser.SrcAccountContext: @@ -111,7 +111,7 @@ func (p *parseVisitor) VisitSource(c parser.ISourceContext, pushAsset func(), is if compErr != nil { return nil, nil, nil, compErr } - if ty != internal.TypeAccount { + if ty != internal2.TypeAccount { return nil, nil, nil, LogicError(c, errors.New("wrong type: expected account or allocation as destination")) } if p.isWorld(*accAddr) { @@ -123,7 +123,7 @@ func (p *parseVisitor) VisitSource(c parser.ISourceContext, pushAsset func(), is if overdraft == nil { // no overdraft: use zero monetary pushAsset() - err := p.PushInteger(internal.NewNumber(0)) + err := p.PushInteger(internal2.NewNumber(0)) if err != nil { return nil, nil, nil, LogicError(c, err) } @@ -139,13 +139,13 @@ func (p *parseVisitor) VisitSource(c parser.ISourceContext, pushAsset func(), is if compErr != nil { return nil, nil, nil, compErr } - if ty != internal.TypeMonetary { + if ty != internal2.TypeMonetary { return nil, nil, nil, LogicError(c, errors.New("wrong type: expected monetary")) } p.AppendInstruction(program.OP_TAKE_ALL) case *parser.SrcAccountOverdraftUnboundedContext: pushAsset() - err := p.PushInteger(internal.NewNumber(0)) + err := p.PushInteger(internal2.NewNumber(0)) if err != nil { return nil, nil, nil, LogicError(c, err) } @@ -171,7 +171,7 @@ func (p *parseVisitor) VisitSource(c parser.ISourceContext, pushAsset func(), is if compErr != nil { return nil, nil, nil, compErr } - if ty != internal.TypeMonetary { + if ty != internal2.TypeMonetary { return nil, nil, nil, LogicError(c, errors.New("wrong type: expected monetary as max")) } for k, v := range accounts { @@ -184,13 +184,13 @@ func (p *parseVisitor) VisitSource(c parser.ISourceContext, pushAsset func(), is } p.AppendInstruction(program.OP_REPAY) if subsourceFallback != nil { - p.PushAddress(internal.Address(*subsourceFallback)) + p.PushAddress(internal2.Address(*subsourceFallback)) err := p.Bump(2) if err != nil { return nil, nil, nil, LogicError(c, err) } p.AppendInstruction(program.OP_TAKE_ALL) - err = p.PushInteger(internal.NewNumber(2)) + err = p.PushInteger(internal2.NewNumber(2)) if err != nil { return nil, nil, nil, LogicError(c, err) } @@ -224,7 +224,7 @@ func (p *parseVisitor) VisitSource(c parser.ISourceContext, pushAsset func(), is emptiedAccounts[k] = v } } - err := p.PushInteger(internal.NewNumber(int64(n))) + err := p.PushInteger(internal2.NewNumber(int64(n))) if err != nil { return nil, nil, nil, LogicError(c, err) } diff --git a/components/ledger/pkg/machine/script/generate.go b/components/ledger/internal/machine/script/generate.go similarity index 100% rename from components/ledger/pkg/machine/script/generate.go rename to components/ledger/internal/machine/script/generate.go diff --git a/components/ledger/pkg/machine/script/generate.sh b/components/ledger/internal/machine/script/generate.sh similarity index 100% rename from components/ledger/pkg/machine/script/generate.sh rename to components/ledger/internal/machine/script/generate.sh diff --git a/components/ledger/pkg/machine/script/parser/NumScript.interp b/components/ledger/internal/machine/script/parser/NumScript.interp similarity index 100% rename from components/ledger/pkg/machine/script/parser/NumScript.interp rename to components/ledger/internal/machine/script/parser/NumScript.interp diff --git a/components/ledger/pkg/machine/script/parser/NumScript.tokens b/components/ledger/internal/machine/script/parser/NumScript.tokens similarity index 100% rename from components/ledger/pkg/machine/script/parser/NumScript.tokens rename to components/ledger/internal/machine/script/parser/NumScript.tokens diff --git a/components/ledger/pkg/machine/script/parser/NumScriptLexer.interp b/components/ledger/internal/machine/script/parser/NumScriptLexer.interp similarity index 100% rename from components/ledger/pkg/machine/script/parser/NumScriptLexer.interp rename to components/ledger/internal/machine/script/parser/NumScriptLexer.interp diff --git a/components/ledger/pkg/machine/script/parser/NumScriptLexer.tokens b/components/ledger/internal/machine/script/parser/NumScriptLexer.tokens similarity index 100% rename from components/ledger/pkg/machine/script/parser/NumScriptLexer.tokens rename to components/ledger/internal/machine/script/parser/NumScriptLexer.tokens diff --git a/components/ledger/pkg/machine/script/parser/numscript_base_listener.go b/components/ledger/internal/machine/script/parser/numscript_base_listener.go similarity index 100% rename from components/ledger/pkg/machine/script/parser/numscript_base_listener.go rename to components/ledger/internal/machine/script/parser/numscript_base_listener.go diff --git a/components/ledger/pkg/machine/script/parser/numscript_lexer.go b/components/ledger/internal/machine/script/parser/numscript_lexer.go similarity index 100% rename from components/ledger/pkg/machine/script/parser/numscript_lexer.go rename to components/ledger/internal/machine/script/parser/numscript_lexer.go diff --git a/components/ledger/pkg/machine/script/parser/numscript_listener.go b/components/ledger/internal/machine/script/parser/numscript_listener.go similarity index 100% rename from components/ledger/pkg/machine/script/parser/numscript_listener.go rename to components/ledger/internal/machine/script/parser/numscript_listener.go diff --git a/components/ledger/pkg/machine/script/parser/numscript_parser.go b/components/ledger/internal/machine/script/parser/numscript_parser.go similarity index 100% rename from components/ledger/pkg/machine/script/parser/numscript_parser.go rename to components/ledger/internal/machine/script/parser/numscript_parser.go diff --git a/components/ledger/pkg/machine/vm/errors.go b/components/ledger/internal/machine/vm/errors.go similarity index 100% rename from components/ledger/pkg/machine/vm/errors.go rename to components/ledger/internal/machine/vm/errors.go diff --git a/components/ledger/internal/machine/vm/machine.go b/components/ledger/internal/machine/vm/machine.go new file mode 100644 index 000000000..f53e4500e --- /dev/null +++ b/components/ledger/internal/machine/vm/machine.go @@ -0,0 +1,644 @@ +/* +Provides `Machine`, which executes programs and outputs postings. +1: Create New Machine +2: Set Variables (with `internal.Value`s or JSON) +3: Resolve Resources (answer requests on channel) +4: Resolve Balances (answer requests on channel) +6: Execute +*/ +package vm + +import ( + "context" + "encoding/binary" + "fmt" + "math/big" + + ledger "github.com/formancehq/ledger/internal" + internal "github.com/formancehq/ledger/internal/machine/internal" + program2 "github.com/formancehq/ledger/internal/machine/vm/program" + "github.com/formancehq/stack/libs/go-libs/errorsutil" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/logrusorgru/aurora" + "github.com/pkg/errors" +) + +type Machine struct { + P uint + Program program2.Program + Vars map[string]internal.Value + UnresolvedResources []program2.Resource + Resources []internal.Value // Constants and Variables + UnresolvedResourceBalances map[string]int + resolveCalled bool + Balances map[internal.AccountAddress]map[internal.Asset]*internal.MonetaryInt // keeps track of balances throughout execution + setBalanceCalled bool + Stack []internal.Value + Postings []Posting // accumulates postings throughout execution + TxMeta map[string]internal.Value // accumulates transaction meta throughout execution + AccountsMeta map[internal.AccountAddress]map[string]internal.Value // accumulates accounts meta throughout execution + Printer func(chan internal.Value) + printChan chan internal.Value + Debug bool +} + +type Posting struct { + Source string `json:"source"` + Destination string `json:"destination"` + Amount *internal.MonetaryInt `json:"amount"` + Asset string `json:"asset"` +} + +type Metadata map[string]any + +func NewMachine(p program2.Program) *Machine { + printChan := make(chan internal.Value) + + m := Machine{ + Program: p, + UnresolvedResources: p.Resources, + Resources: make([]internal.Value, 0), + printChan: printChan, + Printer: StdOutPrinter, + Postings: make([]Posting, 0), + TxMeta: map[string]internal.Value{}, + AccountsMeta: map[internal.AccountAddress]map[string]internal.Value{}, + UnresolvedResourceBalances: map[string]int{}, + } + + return &m +} + +func StdOutPrinter(c chan internal.Value) { + for v := range c { + fmt.Println("OUT:", v) + } +} + +func (m *Machine) GetTxMetaJSON() metadata.Metadata { + meta := metadata.Metadata{} + for k, v := range m.TxMeta { + var err error + meta[k], err = internal.NewStringFromValue(v) + if err != nil { + panic(err) + } + } + return meta +} + +func (m *Machine) GetAccountsMetaJSON() map[string]metadata.Metadata { + res := make(map[string]metadata.Metadata) + for account, meta := range m.AccountsMeta { + for k, v := range meta { + if _, ok := res[string(account)]; !ok { + res[string(account)] = metadata.Metadata{} + } + + var err error + res[string(account)][k], err = internal.NewStringFromValue(v) + if err != nil { + panic(err) + } + } + } + + return res +} + +func (m *Machine) getResource(addr internal.Address) (*internal.Value, bool) { + a := int(addr) + if a >= len(m.Resources) { + return nil, false + } + return &m.Resources[a], true +} + +func (m *Machine) withdrawAll(account internal.AccountAddress, asset internal.Asset, overdraft *internal.MonetaryInt) (*internal.Funding, error) { + if accBalances, ok := m.Balances[account]; ok { + if balance, ok := accBalances[asset]; ok { + amountTaken := internal.Zero + balanceWithOverdraft := balance.Add(overdraft) + if balanceWithOverdraft.Gt(internal.Zero) { + amountTaken = balanceWithOverdraft + accBalances[asset] = overdraft.Neg() + } + + return &internal.Funding{ + Asset: asset, + Parts: []internal.FundingPart{{ + Account: account, + Amount: amountTaken, + }}, + }, nil + } + } + return nil, fmt.Errorf("missing %v balance from %v", asset, account) +} + +func (m *Machine) withdrawAlways(account internal.AccountAddress, mon internal.Monetary) (*internal.Funding, error) { + if accBalance, ok := m.Balances[account]; ok { + if balance, ok := accBalance[mon.Asset]; ok { + accBalance[mon.Asset] = balance.Sub(mon.Amount) + return &internal.Funding{ + Asset: mon.Asset, + Parts: []internal.FundingPart{{ + Account: account, + Amount: mon.Amount, + }}, + }, nil + } + } + return nil, fmt.Errorf("missing %v balance from %v", mon.Asset, account) +} + +func (m *Machine) credit(account internal.AccountAddress, funding internal.Funding) { + if account == "world" { + return + } + if accBalance, ok := m.Balances[account]; ok { + if _, ok := accBalance[funding.Asset]; ok { + for _, part := range funding.Parts { + balance := accBalance[funding.Asset] + accBalance[funding.Asset] = balance.Add(part.Amount) + } + } + } +} + +func (m *Machine) repay(funding internal.Funding) { + for _, part := range funding.Parts { + if part.Account == "world" { + continue + } + balance := m.Balances[part.Account][funding.Asset] + m.Balances[part.Account][funding.Asset] = balance.Add(part.Amount) + } +} + +func (m *Machine) tick() (bool, error) { + op := m.Program.Instructions[m.P] + + if m.Debug { + fmt.Println("STATE ---------------------------------------------------------------------") + fmt.Printf(" %v\n", aurora.Blue(m.Stack)) + fmt.Printf(" %v\n", aurora.Cyan(m.Balances)) + fmt.Printf(" %v\n", program2.OpcodeName(op)) + } + + switch op { + case program2.OP_APUSH: + bytes := m.Program.Instructions[m.P+1 : m.P+3] + v, ok := m.getResource(internal.Address(binary.LittleEndian.Uint16(bytes))) + if !ok { + return true, ErrResourceNotFound + } + m.Stack = append(m.Stack, *v) + m.P += 2 + + case program2.OP_BUMP: + n := big.Int(*pop[internal.Number](m)) + idx := len(m.Stack) - int(n.Uint64()) - 1 + v := m.Stack[idx] + m.Stack = append(m.Stack[:idx], m.Stack[idx+1:]...) + m.Stack = append(m.Stack, v) + + case program2.OP_DELETE: + n := m.popValue() + if n.GetType() == internal.TypeFunding { + return true, errorsutil.NewError(ErrInvalidScript, + errors.Errorf("wrong type: want: %v, got: %v", n.GetType(), internal.TypeFunding)) + } + + case program2.OP_IADD: + b := pop[internal.Number](m) + a := pop[internal.Number](m) + m.pushValue(a.Add(b)) + + case program2.OP_ISUB: + b := pop[internal.Number](m) + a := pop[internal.Number](m) + m.pushValue(a.Sub(b)) + + case program2.OP_PRINT: + a := m.popValue() + m.printChan <- a + + case program2.OP_FAIL: + return true, ErrScriptFailed + + case program2.OP_ASSET: + v := m.popValue() + switch v := v.(type) { + case internal.Asset: + m.pushValue(v) + case internal.Monetary: + m.pushValue(v.Asset) + case internal.Funding: + m.pushValue(v.Asset) + default: + return true, errorsutil.NewError(ErrInvalidScript, + errors.Errorf("wrong type for op asset: %v", v.GetType())) + } + + case program2.OP_MONETARY_NEW: + amount := pop[internal.Number](m) + asset := pop[internal.Asset](m) + m.pushValue(internal.Monetary{ + Asset: asset, + Amount: amount, + }) + + case program2.OP_MONETARY_ADD: + b := pop[internal.Monetary](m) + a := pop[internal.Monetary](m) + if a.Asset != b.Asset { + return true, errorsutil.NewError(ErrInvalidScript, + errors.Errorf("cannot add different assets: %v and %v", a.Asset, b.Asset)) + } + m.pushValue(internal.Monetary{ + Asset: a.Asset, + Amount: a.Amount.Add(b.Amount), + }) + + case program2.OP_MONETARY_SUB: + b := pop[internal.Monetary](m) + a := pop[internal.Monetary](m) + if a.Asset != b.Asset { + return true, fmt.Errorf("%s", program2.OpcodeName(op)) + } + m.pushValue(internal.Monetary{ + Asset: a.Asset, + Amount: a.Amount.Sub(b.Amount), + }) + + case program2.OP_MAKE_ALLOTMENT: + n := pop[internal.Number](m) + portions := make([]internal.Portion, n.Uint64()) + for i := uint64(0); i < n.Uint64(); i++ { + p := pop[internal.Portion](m) + portions[i] = p + } + allotment, err := internal.NewAllotment(portions) + if err != nil { + return true, errorsutil.NewError(ErrInvalidScript, err) + } + m.pushValue(*allotment) + + case program2.OP_TAKE_ALL: + overdraft := pop[internal.Monetary](m) + account := pop[internal.AccountAddress](m) + funding, err := m.withdrawAll(account, overdraft.Asset, overdraft.Amount) + if err != nil { + return true, errorsutil.NewError(ErrInvalidScript, err) + } + m.pushValue(*funding) + + case program2.OP_TAKE_ALWAYS: + mon := pop[internal.Monetary](m) + account := pop[internal.AccountAddress](m) + funding, err := m.withdrawAlways(account, mon) + if err != nil { + return true, errorsutil.NewError(ErrInvalidScript, err) + } + m.pushValue(*funding) + + case program2.OP_TAKE: + mon := pop[internal.Monetary](m) + funding := pop[internal.Funding](m) + if funding.Asset != mon.Asset { + return true, errorsutil.NewError(ErrInvalidScript, + errors.Errorf("cannot take from different assets: %v and %v", funding.Asset, mon.Asset)) + } + result, remainder, err := funding.Take(mon.Amount) + if err != nil { + return true, errorsutil.NewError(ErrInsufficientFund, err) + } + m.pushValue(remainder) + m.pushValue(result) + + case program2.OP_TAKE_MAX: + mon := pop[internal.Monetary](m) + if mon.Amount.Ltz() { + return true, fmt.Errorf( + "cannot send a monetary with a negative amount: [%s %s]", + string(mon.Asset), mon.Amount) + } + funding := pop[internal.Funding](m) + if funding.Asset != mon.Asset { + return true, errorsutil.NewError(ErrInvalidScript, + errors.Errorf("cannot take from different assets: %v and %v", funding.Asset, mon.Asset)) + } + missing := internal.Zero + total := funding.Total() + if mon.Amount.Gt(total) { + missing = mon.Amount.Sub(total) + } + m.pushValue(internal.Monetary{ + Asset: mon.Asset, + Amount: missing, + }) + result, remainder := funding.TakeMax(mon.Amount) + m.pushValue(remainder) + m.pushValue(result) + + case program2.OP_FUNDING_ASSEMBLE: + num := pop[internal.Number](m) + n := int(num.Uint64()) + if n == 0 { + return true, errorsutil.NewError(ErrInvalidScript, + errors.New("cannot assemble zero fundings")) + } + first := pop[internal.Funding](m) + result := internal.Funding{ + Asset: first.Asset, + } + fundings_rev := make([]internal.Funding, n) + fundings_rev[0] = first + for i := 1; i < n; i++ { + f := pop[internal.Funding](m) + if f.Asset != result.Asset { + return true, errorsutil.NewError(ErrInvalidScript, + errors.Errorf("cannot assemble different assets: %v and %v", f.Asset, result.Asset)) + } + fundings_rev[i] = f + } + for i := 0; i < n; i++ { + res, err := result.Concat(fundings_rev[n-1-i]) + if err != nil { + return true, errorsutil.NewError(ErrInvalidScript, err) + } + result = res + } + m.pushValue(result) + + case program2.OP_FUNDING_SUM: + funding := pop[internal.Funding](m) + sum := funding.Total() + m.pushValue(funding) + m.pushValue(internal.Monetary{ + Asset: funding.Asset, + Amount: sum, + }) + + case program2.OP_FUNDING_REVERSE: + funding := pop[internal.Funding](m) + result := funding.Reverse() + m.pushValue(result) + + case program2.OP_ALLOC: + allotment := pop[internal.Allotment](m) + monetary := pop[internal.Monetary](m) + total := monetary.Amount + parts := allotment.Allocate(total) + for i := len(parts) - 1; i >= 0; i-- { + m.pushValue(internal.Monetary{ + Asset: monetary.Asset, + Amount: parts[i], + }) + } + + case program2.OP_REPAY: + m.repay(pop[internal.Funding](m)) + + case program2.OP_SEND: + dest := pop[internal.AccountAddress](m) + funding := pop[internal.Funding](m) + m.credit(dest, funding) + for _, part := range funding.Parts { + src := part.Account + amt := part.Amount + m.Postings = append(m.Postings, Posting{ + Source: string(src), + Destination: string(dest), + Asset: string(funding.Asset), + Amount: amt, + }) + } + + case program2.OP_TX_META: + k := pop[internal.String](m) + v := m.popValue() + m.TxMeta[string(k)] = v + + case program2.OP_ACCOUNT_META: + a := pop[internal.AccountAddress](m) + k := pop[internal.String](m) + v := m.popValue() + if m.AccountsMeta[a] == nil { + m.AccountsMeta[a] = map[string]internal.Value{} + } + m.AccountsMeta[a][string(k)] = v + + case program2.OP_SAVE: + a := pop[internal.AccountAddress](m) + v := m.popValue() + switch v := v.(type) { + case internal.Asset: + m.Balances[a][v] = internal.Zero + case internal.Monetary: + m.Balances[a][v.Asset] = m.Balances[a][v.Asset].Sub(v.Amount) + default: + panic(fmt.Errorf("invalid value type: %T", v)) + } + + default: + return true, errorsutil.NewError(ErrInvalidScript, + errors.Errorf("invalid opcode: %v", op)) + } + + m.P += 1 + + if int(m.P) >= len(m.Program.Instructions) { + return true, nil + } + + return false, nil +} + +func (m *Machine) Execute() error { + go m.Printer(m.printChan) + defer close(m.printChan) + + if len(m.Resources) != len(m.UnresolvedResources) { + return ErrResourcesNotInitialized + } else if m.Balances == nil { + return ErrBalancesNotInitialized + } + + for { + finished, err := m.tick() + if finished { + if err == nil && len(m.Stack) != 0 { + return errorsutil.NewError(ErrInvalidScript, + errors.New("stack not empty after execution")) + } else { + return err + } + } + } +} + +type BalanceRequest struct { + Account string + Asset string + Response chan *internal.MonetaryInt + Error error +} + +func (m *Machine) ResolveBalances(ctx context.Context, store Store) error { + if len(m.Resources) != len(m.UnresolvedResources) { + return errors.New("tried to resolve balances before resources") + } + if m.setBalanceCalled { + return errors.New("tried to call ResolveBalances twice") + } + m.setBalanceCalled = true + m.Balances = make(map[internal.AccountAddress]map[internal.Asset]*internal.MonetaryInt) + + for address, resourceIndex := range m.UnresolvedResourceBalances { + monetary := m.Resources[resourceIndex].(internal.Monetary) + balance, err := store.GetBalance(ctx, address, string(monetary.Asset)) + if err != nil { + return err + } + if balance.Cmp(ledger.Zero) < 0 { + return errorsutil.NewError(ErrNegativeMonetaryAmount, fmt.Errorf( + "tried to request the balance of account %s for asset %s: received %s: monetary amounts must be non-negative", + address, monetary.Asset, balance)) + } + monetary.Amount = internal.NewMonetaryIntFromBigInt(balance) + m.Resources[resourceIndex] = monetary + } + + // for every account that we need balances of, check if it's there + for addr, neededAssets := range m.Program.NeededBalances { + account, ok := m.getResource(addr) + if !ok { + return errors.New("invalid program (resolve balances: invalid address of account)") + } + accountAddress := (*account).(internal.AccountAddress) + m.Balances[accountAddress] = make(map[internal.Asset]*internal.MonetaryInt) + // for every asset, send request + for addr := range neededAssets { + mon, ok := m.getResource(addr) + if !ok { + return errors.New("invalid program (resolve balances: invalid address of monetary)") + } + + asset := (*mon).(internal.HasAsset).GetAsset() + if string(accountAddress) == "world" { + m.Balances[accountAddress][asset] = internal.Zero + continue + } + + balance, err := store.GetBalance(ctx, string(accountAddress), string(asset)) + if err != nil { + return errors.Wrap(err, fmt.Sprintf("could not get balance for account %q", addr)) + } + + m.Balances[accountAddress][asset] = internal.NewMonetaryIntFromBigInt(balance) + } + } + return nil +} + +func (m *Machine) ResolveResources(ctx context.Context, store Store) ([]string, []string, error) { + //TODO(gfyrag): Is that really required? Feel like defensive programming. + if m.resolveCalled { + return nil, nil, errors.New("tried to call ResolveResources twice") + } + + m.resolveCalled = true + involvedAccountsMap := make(map[internal.Address]string) + for len(m.Resources) != len(m.UnresolvedResources) { + idx := len(m.Resources) + res := m.UnresolvedResources[idx] + var val internal.Value + switch res := res.(type) { + case program2.Constant: + val = res.Inner + if val.GetType() == internal.TypeAccount { + involvedAccountsMap[internal.Address(idx)] = string(val.(internal.AccountAddress)) + } + case program2.Variable: + var ok bool + val, ok = m.Vars[res.Name] + if !ok { + return nil, nil, fmt.Errorf("missing variable '%s'", res.Name) + } + if val.GetType() == internal.TypeAccount { + involvedAccountsMap[internal.Address(idx)] = string(val.(internal.AccountAddress)) + } + case program2.VariableAccountMetadata: + acc, _ := m.getResource(res.Account) + addr := string((*acc).(internal.AccountAddress)) + + account, err := store.GetAccount(ctx, addr) + if err != nil { + return nil, nil, err + } + + metadata, ok := account.Metadata[res.Key] + if !ok { + return nil, nil, errorsutil.NewError(ErrResourceResolutionMissingMetadata, errors.New( + fmt.Sprintf("missing key %v in metadata for account %s", res.Key, addr))) + } + + val, err = internal.NewValueFromString(res.Typ, metadata) + if err != nil { + return nil, nil, err + } + case program2.VariableAccountBalance: + acc, _ := m.getResource(res.Account) + address := string((*acc).(internal.AccountAddress)) + involvedAccountsMap[internal.Address(idx)] = address + m.UnresolvedResourceBalances[address] = idx + + ass, ok := m.getResource(res.Asset) + if !ok { + return nil, nil, fmt.Errorf( + "variable '%s': tried to request account balance of an asset which has not yet been solved", + res.Name) + } + if (*ass).GetType() != internal.TypeAsset { + return nil, nil, fmt.Errorf( + "variable '%s': tried to request account balance for an asset on wrong entity: %v instead of asset", + res.Name, (*ass).GetType()) + } + + val = internal.Monetary{ + Asset: (*ass).(internal.Asset), + } + case program2.Monetary: + ass, _ := m.getResource(res.Asset) + val = internal.Monetary{ + Asset: (*ass).(internal.Asset), + Amount: res.Amount, + } + default: + panic(fmt.Errorf("type %T not implemented", res)) + } + m.Resources = append(m.Resources, val) + } + + involvedAccounts := make([]string, 0) + involvedSources := make([]string, 0) + for _, accountAddress := range involvedAccountsMap { + involvedAccounts = append(involvedAccounts, accountAddress) + } + for _, machineAddress := range m.Program.Sources { + involvedSources = append(involvedSources, involvedAccountsMap[machineAddress]) + } + + return involvedAccounts, involvedSources, nil +} + +func (m *Machine) SetVarsFromJSON(vars map[string]string) error { + v, err := m.Program.ParseVariablesJSON(vars) + if err != nil { + return errorsutil.NewError(ErrInvalidVars, err) + } + m.Vars = v + return nil +} diff --git a/components/ledger/internal/machine/vm/machine_kept_test.go b/components/ledger/internal/machine/vm/machine_kept_test.go new file mode 100644 index 000000000..b6ff67822 --- /dev/null +++ b/components/ledger/internal/machine/vm/machine_kept_test.go @@ -0,0 +1,118 @@ +package vm + +import ( + "testing" + + internal2 "github.com/formancehq/ledger/internal/machine/internal" +) + +func TestKeptDestinationAllotment(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [GEM 100] ( + source = { + @a + @world + } + destination = { + 50% kept + 25% to @x + 25% to @y + } + )`) + tc.setBalance("a", "GEM", 1) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(1), + Source: "a", + Destination: "x", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(24), + Source: "world", + Destination: "x", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(25), + Source: "world", + Destination: "y", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestKeptComplex(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [GEM 100] ( + source = { + @foo + @bar + @baz + } + destination = { + 50% to { + max [GEM 8] to { + 50% kept + 25% to @arst + 25% kept + } + remaining to @thing + } + 20% to @qux + 5% kept + remaining to @quz + } + )`) + tc.setBalance("foo", "GEM", 20) + tc.setBalance("bar", "GEM", 40) + tc.setBalance("baz", "GEM", 40) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(2), + Source: "foo", + Destination: "arst", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(18), + Source: "foo", + Destination: "thing", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(24), + Source: "bar", + Destination: "thing", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(16), + Source: "bar", + Destination: "qux", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(4), + Source: "baz", + Destination: "qux", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(25), + Source: "baz", + Destination: "quz", + }, + }, + Error: nil, + } + test(t, tc) +} diff --git a/components/ledger/pkg/machine/vm/machine_overdraft_test.go b/components/ledger/internal/machine/vm/machine_overdraft_test.go similarity index 82% rename from components/ledger/pkg/machine/vm/machine_overdraft_test.go rename to components/ledger/internal/machine/vm/machine_overdraft_test.go index e15bb15ed..a285f76a1 100644 --- a/components/ledger/pkg/machine/vm/machine_overdraft_test.go +++ b/components/ledger/internal/machine/vm/machine_overdraft_test.go @@ -3,7 +3,7 @@ package vm import ( "testing" - "github.com/formancehq/ledger/pkg/machine/internal" + internal2 "github.com/formancehq/ledger/internal/machine/internal" ) func TestOverdraftNotEnough(t *testing.T) { @@ -14,7 +14,7 @@ func TestOverdraftNotEnough(t *testing.T) { )`) tc.setBalance("foo", "GEM", 89) tc.expected = CaseResult{ - Printed: []internal.Value{}, + Printed: []internal2.Value{}, Postings: []Posting{}, Error: ErrInsufficientFund, } @@ -29,11 +29,11 @@ func TestOverdraftEnough(t *testing.T) { )`) tc.setBalance("foo", "GEM", 90) tc.expected = CaseResult{ - Printed: []internal.Value{}, + Printed: []internal2.Value{}, Postings: []Posting{ { Asset: "GEM", - Amount: internal.NewMonetaryInt(100), + Amount: internal2.NewMonetaryInt(100), Source: "foo", Destination: "world", }, @@ -51,11 +51,11 @@ func TestOverdraftUnbounded(t *testing.T) { )`) tc.setBalance("foo", "GEM", 90) tc.expected = CaseResult{ - Printed: []internal.Value{}, + Printed: []internal2.Value{}, Postings: []Posting{ { Asset: "GEM", - Amount: internal.NewMonetaryInt(1000), + Amount: internal2.NewMonetaryInt(1000), Source: "foo", Destination: "world", }, @@ -81,23 +81,23 @@ func TestOverdraftSourceAllotmentSuccess(t *testing.T) { tc.setBalance("bar", "GEM", 20) tc.setBalance("baz", "GEM", 0) tc.expected = CaseResult{ - Printed: []internal.Value{}, + Printed: []internal2.Value{}, Postings: []Posting{ { Asset: "GEM", - Amount: internal.NewMonetaryInt(50), + Amount: internal2.NewMonetaryInt(50), Source: "foo", Destination: "world", }, { Asset: "GEM", - Amount: internal.NewMonetaryInt(40), + Amount: internal2.NewMonetaryInt(40), Source: "bar", Destination: "world", }, { Asset: "GEM", - Amount: internal.NewMonetaryInt(10), + Amount: internal2.NewMonetaryInt(10), Source: "baz", Destination: "world", }, @@ -125,29 +125,29 @@ func TestOverdraftSourceInOrderSuccess(t *testing.T) { tc.setBalance("baz", "GEM", 0) tc.setBalance("qux", "GEM", 0) tc.expected = CaseResult{ - Printed: []internal.Value{}, + Printed: []internal2.Value{}, Postings: []Posting{ { Asset: "GEM", - Amount: internal.NewMonetaryInt(10), + Amount: internal2.NewMonetaryInt(10), Source: "foo", Destination: "world", }, { Asset: "GEM", - Amount: internal.NewMonetaryInt(20), + Amount: internal2.NewMonetaryInt(20), Source: "bar", Destination: "world", }, { Asset: "GEM", - Amount: internal.NewMonetaryInt(20), + Amount: internal2.NewMonetaryInt(20), Source: "baz", Destination: "world", }, { Asset: "GEM", - Amount: internal.NewMonetaryInt(50), + Amount: internal2.NewMonetaryInt(50), Source: "qux", Destination: "world", }, @@ -174,23 +174,23 @@ func TestOverdraftBalanceTracking(t *testing.T) { `) tc.setBalance("foo", "GEM", 0) tc.expected = CaseResult{ - Printed: []internal.Value{}, + Printed: []internal2.Value{}, Postings: []Posting{ { Asset: "GEM", - Amount: internal.NewMonetaryInt(100), + Amount: internal2.NewMonetaryInt(100), Source: "foo", Destination: "world", }, { Asset: "GEM", - Amount: internal.NewMonetaryInt(200), + Amount: internal2.NewMonetaryInt(200), Source: "foo", Destination: "world", }, { Asset: "GEM", - Amount: internal.NewMonetaryInt(300), + Amount: internal2.NewMonetaryInt(300), Source: "foo", Destination: "world", }, @@ -212,17 +212,17 @@ func TestWorldIsUnbounded(t *testing.T) { ) `) tc.expected = CaseResult{ - Printed: []internal.Value{}, + Printed: []internal2.Value{}, Postings: []Posting{ { Asset: "GEM", - Amount: internal.NewMonetaryInt(100), + Amount: internal2.NewMonetaryInt(100), Source: "world", Destination: "foo", }, { Asset: "GEM", - Amount: internal.NewMonetaryInt(200), + Amount: internal2.NewMonetaryInt(200), Source: "world", Destination: "foo", }, @@ -248,7 +248,7 @@ func TestOverdraftComplexFailure(t *testing.T) { tc.setBalance("bar", "GEM", 20) tc.setBalance("baz", "GEM", 0) tc.expected = CaseResult{ - Printed: []internal.Value{}, + Printed: []internal2.Value{}, Postings: []Posting{}, Error: ErrInsufficientFund, } @@ -263,7 +263,7 @@ func TestNegativeBalance(t *testing.T) { )`) tc.setBalance("foo", "GEM", -50) tc.expected = CaseResult{ - Printed: []internal.Value{}, + Printed: []internal2.Value{}, Postings: []Posting{}, Error: ErrInsufficientFund, } diff --git a/components/ledger/internal/machine/vm/machine_test.go b/components/ledger/internal/machine/vm/machine_test.go new file mode 100644 index 000000000..12968644f --- /dev/null +++ b/components/ledger/internal/machine/vm/machine_test.go @@ -0,0 +1,2132 @@ +package vm + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "sync" + "testing" + + ledger "github.com/formancehq/ledger/internal" + internal2 "github.com/formancehq/ledger/internal/machine/internal" + "github.com/formancehq/ledger/internal/machine/script/compiler" + "github.com/formancehq/ledger/internal/machine/vm/program" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + DEBUG bool = false +) + +type CaseResult struct { + Printed []internal2.Value + Postings []Posting + Metadata map[string]internal2.Value + Error error + ErrorContains string +} + +type TestCase struct { + program *program.Program + vars map[string]string + meta map[string]metadata.Metadata + balances map[string]map[string]*internal2.MonetaryInt + expected CaseResult +} + +func NewTestCase() TestCase { + return TestCase{ + vars: make(map[string]string), + meta: make(map[string]metadata.Metadata), + balances: make(map[string]map[string]*internal2.MonetaryInt), + expected: CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{}, + Metadata: make(map[string]internal2.Value), + Error: nil, + }, + } +} + +func (c *TestCase) compile(t *testing.T, code string) { + p, err := compiler.Compile(code) + if err != nil { + t.Fatalf("compile error: %v", err) + return + } + c.program = p +} + +func (c *TestCase) setVarsFromJSON(t *testing.T, str string) { + var jsonVars map[string]string + err := json.Unmarshal([]byte(str), &jsonVars) + require.NoError(t, err) + c.vars = jsonVars +} + +func (c *TestCase) setBalance(account, asset string, amount int64) { + if _, ok := c.balances[account]; !ok { + c.balances[account] = make(map[string]*internal2.MonetaryInt) + } + c.balances[account][asset] = internal2.NewMonetaryInt(amount) +} + +func test(t *testing.T, testCase TestCase) { + testImpl(t, testCase.program, testCase.expected, func(m *Machine) error { + if err := m.SetVarsFromJSON(testCase.vars); err != nil { + return err + } + + store := StaticStore{} + for account, balances := range testCase.balances { + store[account] = &AccountWithBalances{ + Account: ledger.Account{ + Address: account, + Metadata: testCase.meta[account], + }, + Balances: func() map[string]*big.Int { + ret := make(map[string]*big.Int) + for asset, balance := range balances { + ret[asset] = (*big.Int)(balance) + } + return ret + }(), + } + } + + _, _, err := m.ResolveResources(context.Background(), store) + if err != nil { + return err + } + + err = m.ResolveBalances(context.Background(), store) + if err != nil { + return err + } + + return m.Execute() + }) +} + +func testImpl(t *testing.T, prog *program.Program, expected CaseResult, exec func(*Machine) error) { + printed := []internal2.Value{} + + var wg sync.WaitGroup + wg.Add(1) + + require.NotNil(t, prog) + + m := NewMachine(*prog) + m.Debug = DEBUG + m.Printer = func(c chan internal2.Value) { + for v := range c { + printed = append(printed, v) + } + wg.Done() + } + + err := exec(m) + if expected.Error != nil { + require.True(t, errors.Is(err, expected.Error), "got wrong error, want: %v, got: %v", expected.Error, err) + if expected.ErrorContains != "" { + require.ErrorContains(t, err, expected.ErrorContains) + } + } else { + require.NoError(t, err) + } + if err != nil { + return + } + + if expected.Postings == nil { + expected.Postings = make([]Posting, 0) + } + if expected.Metadata == nil { + expected.Metadata = make(map[string]internal2.Value) + } + + assert.Equalf(t, expected.Postings, m.Postings, "unexpected postings output: %v", m.Postings) + assert.Equalf(t, expected.Metadata, m.TxMeta, "unexpected metadata output: %v", m.TxMeta) + + wg.Wait() + + assert.Equalf(t, expected.Printed, printed, "unexpected metadata output: %v", printed) +} + +func TestFail(t *testing.T) { + tc := NewTestCase() + tc.compile(t, "fail") + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{}, + Error: ErrScriptFailed, + } + test(t, tc) +} + +func TestPrint(t *testing.T) { + tc := NewTestCase() + tc.compile(t, "print 29 + 15 - 2") + mi := internal2.MonetaryInt(*big.NewInt(42)) + tc.expected = CaseResult{ + Printed: []internal2.Value{&mi}, + Postings: []Posting{}, + Error: nil, + } + test(t, tc) +} + +func TestSend(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [EUR/2 100] ( + source=@alice + destination=@bob + )`) + tc.setBalance("alice", "EUR/2", 100) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "EUR/2", + Amount: internal2.NewMonetaryInt(100), + Source: "alice", + Destination: "bob", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestVariables(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `vars { + account $rider + account $driver + string $description + number $nb + asset $ass + } + send [$ass 999] ( + source=$rider + destination=$driver + ) + set_tx_meta("description", $description) + set_tx_meta("ride", $nb)`) + tc.vars = map[string]string{ + "rider": "users:001", + "driver": "users:002", + "description": "midnight ride", + "nb": "1", + "ass": "EUR/2", + } + tc.setBalance("users:001", "EUR/2", 1000) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "EUR/2", + Amount: internal2.NewMonetaryInt(999), + Source: "users:001", + Destination: "users:002", + }, + }, + Metadata: map[string]internal2.Value{ + "description": internal2.String("midnight ride"), + "ride": internal2.NewMonetaryInt(1), + }, + Error: nil, + } +} + +func TestVariablesJSON(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `vars { + account $rider + account $driver + string $description + number $nb + asset $ass + } + send [$ass 999] ( + source=$rider + destination=$driver + ) + set_tx_meta("description", $description) + set_tx_meta("ride", $nb)`) + tc.setVarsFromJSON(t, `{ + "rider": "users:001", + "driver": "users:002", + "description": "midnight ride", + "nb": "1", + "ass": "EUR/2" + }`) + tc.setBalance("users:001", "EUR/2", 1000) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "EUR/2", + Amount: internal2.NewMonetaryInt(999), + Source: "users:001", + Destination: "users:002", + }, + }, + Metadata: map[string]internal2.Value{ + "description": internal2.String("midnight ride"), + "ride": internal2.NewMonetaryInt(1), + }, + Error: nil, + } + test(t, tc) +} + +func TestSource(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `vars { + account $balance + account $payment + account $seller + } + send [GEM 15] ( + source = { + $balance + $payment + } + destination = $seller + )`) + tc.setVarsFromJSON(t, `{ + "balance": "users:001", + "payment": "payments:001", + "seller": "users:002" + }`) + tc.setBalance("users:001", "GEM", 3) + tc.setBalance("payments:001", "GEM", 12) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(3), + Source: "users:001", + Destination: "users:002", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(12), + Source: "payments:001", + Destination: "users:002", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestAllocation(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `vars { + account $rider + account $driver + } + send [GEM 15] ( + source = $rider + destination = { + 80% to $driver + 8% to @a + 12% to @b + } + )`) + tc.setVarsFromJSON(t, `{ + "rider": "users:001", + "driver": "users:002" + }`) + tc.setBalance("users:001", "GEM", 15) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(13), + Source: "users:001", + Destination: "users:002", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(1), + Source: "users:001", + Destination: "a", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(1), + Source: "users:001", + Destination: "b", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestDynamicAllocation(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `vars { + portion $p + } + send [GEM 15] ( + source = @a + destination = { + 80% to @b + $p to @c + remaining to @d + } + )`) + tc.setVarsFromJSON(t, `{ + "p": "15%" + }`) + tc.setBalance("a", "GEM", 15) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(13), + Source: "a", + Destination: "b", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(2), + Source: "a", + Destination: "c", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestSendAll(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [USD/2 *] ( + source = @users:001 + destination = @platform + )`) + tc.setBalance("users:001", "USD/2", 17) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD/2", + Amount: internal2.NewMonetaryInt(17), + Source: "users:001", + Destination: "platform", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestSendAllMulti(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [USD/2 *] ( + source = { + @users:001:wallet + @users:001:credit + } + destination = @platform + ) + `) + tc.setBalance("users:001:wallet", "USD/2", 19) + tc.setBalance("users:001:credit", "USD/2", 22) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD/2", + Amount: internal2.NewMonetaryInt(19), + Source: "users:001:wallet", + Destination: "platform", + }, + { + Asset: "USD/2", + Amount: internal2.NewMonetaryInt(22), + Source: "users:001:credit", + Destination: "platform", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestInsufficientFunds(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `vars { + account $balance + account $payment + account $seller + } + send [GEM 16] ( + source = { + $balance + $payment + } + destination = $seller + )`) + tc.setVarsFromJSON(t, `{ + "balance": "users:001", + "payment": "payments:001", + "seller": "users:002" + }`) + tc.setBalance("users:001", "GEM", 3) + tc.setBalance("payments:001", "GEM", 12) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{}, + Error: ErrInsufficientFund, + } + test(t, tc) +} + +func TestWorldSource(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [GEM 15] ( + source = { + @a + @world + } + destination = @b + )`) + tc.setBalance("a", "GEM", 1) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(1), + Source: "a", + Destination: "b", + }, + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(14), + Source: "world", + Destination: "b", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestNoEmptyPostings(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [GEM 2] ( + source = @world + destination = { + 90% to @a + 10% to @b + } + )`) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "GEM", + Amount: internal2.NewMonetaryInt(2), + Source: "world", + Destination: "a", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestEmptyPostings(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [GEM *] ( + source = @foo + destination = @bar + )`) + tc.setBalance("foo", "GEM", 0) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Source: "foo", + Destination: "bar", + Amount: internal2.NewMonetaryInt(0), + Asset: "GEM", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestAllocateDontTakeTooMuch(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [CREDIT 200] ( + source = { + @users:001 + @users:002 + } + destination = { + 1/2 to @foo + 1/2 to @bar + } + )`) + tc.setBalance("users:001", "CREDIT", 100) + tc.setBalance("users:002", "CREDIT", 110) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "CREDIT", + Amount: internal2.NewMonetaryInt(100), + Source: "users:001", + Destination: "foo", + }, + { + Asset: "CREDIT", + Amount: internal2.NewMonetaryInt(100), + Source: "users:002", + Destination: "bar", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestMetadata(t *testing.T) { + //commission, _ := internal.NewPortionSpecific(*big.NewRat(125, 1000)) + tc := NewTestCase() + tc.compile(t, `vars { + account $sale + account $seller = meta($sale, "seller") + portion $commission = meta($seller, "commission") + } + send [EUR/2 100] ( + source = $sale + destination = { + remaining to $seller + $commission to @platform + } + )`) + tc.setVarsFromJSON(t, `{ + "sale": "sales:042" + }`) + tc.meta = map[string]metadata.Metadata{ + "sales:042": { + "seller": "users:053", + }, + "users:053": { + "commission": "12.5%", + }, + } + tc.setBalance("sales:042", "EUR/2", 2500) + tc.setBalance("users:053", "EUR/2", 500) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "EUR/2", + Amount: internal2.NewMonetaryInt(88), + Source: "sales:042", + Destination: "users:053", + }, + { + Asset: "EUR/2", + Amount: internal2.NewMonetaryInt(12), + Source: "sales:042", + Destination: "platform", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestTrackBalances(t *testing.T) { + tc := NewTestCase() + tc.compile(t, ` + send [COIN 50] ( + source = @world + destination = @a + ) + send [COIN 100] ( + source = @a + destination = @b + )`) + tc.setBalance("a", "COIN", 50) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(50), + Source: "world", + Destination: "a", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(100), + Source: "a", + Destination: "b", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestTrackBalances2(t *testing.T) { + tc := NewTestCase() + tc.compile(t, ` + send [COIN 50] ( + source = @a + destination = @z + ) + send [COIN 50] ( + source = @a + destination = @z + )`) + tc.setBalance("a", "COIN", 60) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{}, + Error: ErrInsufficientFund, + } + test(t, tc) +} + +func TestTrackBalances3(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [COIN *] ( + source = @foo + destination = { + max [COIN 1000] to @bar + remaining kept + } + ) + send [COIN *] ( + source = @foo + destination = @bar + )`) + tc.setBalance("foo", "COIN", 2000) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(1000), + Source: "foo", + Destination: "bar", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(1000), + Source: "foo", + Destination: "bar", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestSourceAllotment(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [COIN 100] ( + source = { + 60% from @a + 35.5% from @b + 4.5% from @c + } + destination = @d + )`) + tc.setBalance("a", "COIN", 100) + tc.setBalance("b", "COIN", 100) + tc.setBalance("c", "COIN", 100) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(61), + Source: "a", + Destination: "d", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(35), + Source: "b", + Destination: "d", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(4), + Source: "c", + Destination: "d", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestSourceOverlapping(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [COIN 99] ( + source = { + 15% from { + @b + @a + } + 30% from @a + remaining from @a + } + destination = @world + )`) + tc.setBalance("a", "COIN", 99) + tc.setBalance("b", "COIN", 3) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(3), + Source: "b", + Destination: "world", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(96), + Source: "a", + Destination: "world", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestSourceComplex(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `vars { + monetary $max + } + send [COIN 200] ( + source = { + 50% from { + max [COIN 4] from @a + @b + @c + } + remaining from max $max from @d + } + destination = @platform + )`) + tc.setVarsFromJSON(t, `{ + "max": "COIN 120" + }`) + tc.setBalance("a", "COIN", 1000) + tc.setBalance("b", "COIN", 40) + tc.setBalance("c", "COIN", 1000) + tc.setBalance("d", "COIN", 1000) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(4), + Source: "a", + Destination: "platform", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(40), + Source: "b", + Destination: "platform", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(56), + Source: "c", + Destination: "platform", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(100), + Source: "d", + Destination: "platform", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestDestinationComplex(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `send [COIN 100] ( + source = @world + destination = { + 20% to @a + 20% kept + 60% to { + max [COIN 10] to @b + remaining to @c + } + } + )`) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(20), + Source: "world", + Destination: "a", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(10), + Source: "world", + Destination: "b", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(50), + Source: "world", + Destination: "c", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestNeededBalances(t *testing.T) { + p, err := compiler.Compile(`vars { + account $a + } + send [GEM 15] ( + source = { + $a + @b + @world + } + destination = @c + )`) + + if err != nil { + t.Fatalf("did not expect error on Compile, got: %v", err) + } + + m := NewMachine(*p) + + err = m.SetVarsFromJSON(map[string]string{ + "a": "a", + }) + if err != nil { + t.Fatalf("did not expect error on SetVars, got: %v", err) + } + _, _, err = m.ResolveResources(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.ResolveBalances(context.Background(), EmptyStore) + require.NoError(t, err) +} + +func TestSetTxMeta(t *testing.T) { + p, err := compiler.Compile(` + set_tx_meta("aaa", @platform) + set_tx_meta("bbb", GEM) + set_tx_meta("ccc", 45) + set_tx_meta("ddd", "hello") + set_tx_meta("eee", [COIN 30]) + set_tx_meta("fff", 15%) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + _, _, err = m.ResolveResources(context.Background(), EmptyStore) + require.NoError(t, err) + err = m.ResolveBalances(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.Execute() + require.NoError(t, err) + + expectedMeta := map[string]string{ + "aaa": "platform", + "bbb": "GEM", + "ccc": "45", + "ddd": "hello", + "eee": "COIN 30", + "fff": "3/20", + } + + resMeta := m.GetTxMetaJSON() + assert.Equal(t, 6, len(resMeta)) + + for key, val := range resMeta { + assert.Equal(t, string(expectedMeta[key]), val) + } +} + +func TestSetAccountMeta(t *testing.T) { + t.Run("all types", func(t *testing.T) { + p, err := compiler.Compile(` + set_account_meta(@platform, "aaa", @platform) + set_account_meta(@platform, "bbb", GEM) + set_account_meta(@platform, "ccc", 45) + set_account_meta(@platform, "ddd", "hello") + set_account_meta(@platform, "eee", [COIN 30]) + set_account_meta(@platform, "fff", 15%)`) + require.NoError(t, err) + + m := NewMachine(*p) + + _, _, err = m.ResolveResources(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.ResolveBalances(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.Execute() + require.NoError(t, err) + + expectedMeta := metadata.Metadata{ + "aaa": "platform", + "bbb": "GEM", + "ccc": "45", + "ddd": "hello", + "eee": "COIN 30", + "fff": "3/20", + } + + resMeta := m.GetAccountsMetaJSON() + assert.Equal(t, 1, len(resMeta)) + + for acc, meta := range resMeta { + assert.Equal(t, "platform", acc) + assert.Equal(t, 6, len(meta)) + for key, val := range meta { + assert.Equal(t, expectedMeta[key], val) + } + } + }) + + t.Run("with vars", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + account $acc + } + send [EUR/2 100] ( + source = @world + destination = $acc + ) + set_account_meta($acc, "fees", 1%) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "acc": "test", + })) + + _, _, err = m.ResolveResources(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.ResolveBalances(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.Execute() + require.NoError(t, err) + + expectedMeta := map[string]json.RawMessage{ + "fees": json.RawMessage("1/100"), + } + + resMeta := m.GetAccountsMetaJSON() + assert.Equal(t, 1, len(resMeta)) + + for acc, meta := range resMeta { + assert.Equal(t, "test", acc) + assert.Equal(t, 1, len(meta)) + for key, val := range meta { + assert.Equal(t, string(expectedMeta[key]), val) + } + } + }) +} + +func TestVariableBalance(t *testing.T) { + script := ` + vars { + monetary $initial = balance(@A, USD/2) + } + send [USD/2 100] ( + source = { + @A + @C + } + destination = { + max $initial to @B + remaining to @D + } + )` + + t.Run("1", func(t *testing.T) { + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("A", "USD/2", 40) + tc.setBalance("C", "USD/2", 90) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD/2", + Amount: internal2.NewMonetaryInt(40), + Source: "A", + Destination: "B", + }, + { + Asset: "USD/2", + Amount: internal2.NewMonetaryInt(60), + Source: "C", + Destination: "D", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("2", func(t *testing.T) { + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("A", "USD/2", 400) + tc.setBalance("C", "USD/2", 90) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD/2", + Amount: internal2.NewMonetaryInt(100), + Source: "A", + Destination: "B", + }, + }, + Error: nil, + } + test(t, tc) + }) + + script = ` + vars { + account $acc + monetary $initial = balance($acc, USD/2) + } + send [USD/2 100] ( + source = { + $acc + @C + } + destination = { + max $initial to @B + remaining to @D + } + )` + + t.Run("3", func(t *testing.T) { + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("A", "USD/2", 40) + tc.setBalance("C", "USD/2", 90) + tc.setVarsFromJSON(t, `{"acc": "A"}`) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD/2", + Amount: internal2.NewMonetaryInt(40), + Source: "A", + Destination: "B", + }, + { + Asset: "USD/2", + Amount: internal2.NewMonetaryInt(60), + Source: "C", + Destination: "D", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("4", func(t *testing.T) { + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("A", "USD/2", 400) + tc.setBalance("C", "USD/2", 90) + tc.setVarsFromJSON(t, `{"acc": "A"}`) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD/2", + Amount: internal2.NewMonetaryInt(100), + Source: "A", + Destination: "B", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("5", func(t *testing.T) { + tc := NewTestCase() + tc.compile(t, ` + vars { + monetary $max = balance(@maxAcc, COIN) + } + send [COIN 200] ( + source = { + 50% from { + max [COIN 4] from @a + @b + @c + } + remaining from max $max from @d + } + destination = @platform + )`) + tc.setBalance("maxAcc", "COIN", 120) + tc.setBalance("a", "COIN", 1000) + tc.setBalance("b", "COIN", 40) + tc.setBalance("c", "COIN", 1000) + tc.setBalance("d", "COIN", 1000) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(4), + Source: "a", + Destination: "platform", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(40), + Source: "b", + Destination: "platform", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(56), + Source: "c", + Destination: "platform", + }, + { + Asset: "COIN", + Amount: internal2.NewMonetaryInt(100), + Source: "d", + Destination: "platform", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("send negative monetary", func(t *testing.T) { + tc := NewTestCase() + script = ` + vars { + monetary $amount = balance(@world, USD/2) + } + send $amount ( + source = @A + destination = @B + )` + tc.compile(t, script) + tc.setBalance("world", "USD/2", -40) + tc.expected = CaseResult{ + Error: ErrNegativeMonetaryAmount, + ErrorContains: "must be non-negative", + } + test(t, tc) + }) +} + +func TestVariablesParsing(t *testing.T) { + t.Run("account", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + account $acc + } + set_tx_meta("account", $acc) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "acc": "valid:acc", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "acc": "invalid-acc", + })) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "acc": "valid:acc", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "acc": "invalid-acc", + })) + }) + + t.Run("asset", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + asset $ass + } + set_tx_meta("asset", $ass) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "ass": "USD/2", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "ass": "USD-2", + })) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "ass": "USD/2", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "ass": "USD-2", + })) + }) + + t.Run("monetary", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + monetary $mon + } + set_tx_meta("monetary", $mon) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "mon": "EUR/2 100", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "mon": "invalid-asset 100", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "mon": "EUR/2", + })) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "mon": "EUR/2 100", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "mon": "invalid-asset 100", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "mon": "EUR/2 null", + })) + }) + + t.Run("portion", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + portion $por + } + set_tx_meta("portion", $por) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "por": "1/2", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "por": "", + })) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "por": "1/2", + })) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "por": "50%", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "por": "3/2", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "por": "200%", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "por": "", + })) + }) + + t.Run("string", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + string $str + } + set_tx_meta("string", $str) + `) + require.NoError(t, err) + + m := NewMachine(*p) + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "str": "valid string", + })) + }) + + t.Run("number", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + number $nbr + } + set_tx_meta("number", $nbr) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + require.NoError(t, m.SetVarsFromJSON(map[string]string{ + "nbr": "100", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "nbr": "string", + })) + + require.Error(t, m.SetVarsFromJSON(map[string]string{ + "nbr": `nil`, + })) + }) + + t.Run("missing variable", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + number $nbr + string $str + } + set_tx_meta("number", $nbr) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + require.ErrorContains(t, m.SetVarsFromJSON(map[string]string{ + "nbr": "100", + }), "missing variable $str") + }) + + t.Run("extraneous variable SetVars", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + number $nbr + } + set_tx_meta("number", $nbr) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + require.ErrorContains(t, m.SetVarsFromJSON(map[string]string{ + "nbr": "100", + "nbr2": "100", + }), "extraneous variable $nbr2") + }) + + t.Run("extraneous variable SetVarsFromJSON", func(t *testing.T) { + p, err := compiler.Compile(` + vars { + number $nbr + } + set_tx_meta("number", $nbr) + `) + require.NoError(t, err) + + m := NewMachine(*p) + + require.ErrorContains(t, m.SetVarsFromJSON(map[string]string{ + "nbr": `100`, + "nbr2": `100`, + }), "extraneous variable $nbr2") + }) +} + +func TestVariablesErrors(t *testing.T) { + tc := NewTestCase() + tc.compile(t, `vars { + monetary $mon + } + send $mon ( + source = @alice + destination = @bob + )`) + tc.setBalance("alice", "COIN", 10) + tc.vars = map[string]string{ + "mon": "COIN -1", + } + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{}, + Error: ErrInvalidVars, + ErrorContains: "negative amount", + } + test(t, tc) +} + +func TestSetVarsFromJSON(t *testing.T) { + + type testCase struct { + name string + script string + expectedError error + vars map[string]string + } + for _, tc := range []testCase{ + { + name: "missing var", + script: `vars { + account $dest + } + send [COIN 99] ( + source = @world + destination = $dest + )`, + expectedError: fmt.Errorf("missing variable $dest"), + }, + { + name: "invalid format for account", + script: `vars { + account $dest + } + send [COIN 99] ( + source = @world + destination = $dest + )`, + vars: map[string]string{ + "dest": "invalid-acc", + }, + expectedError: fmt.Errorf("invalid JSON value for variable $dest of type account: value invalid-acc: accounts should respect pattern ^[a-zA-Z_]+[a-zA-Z0-9_:]*$"), + }, + } { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + p, err := compiler.Compile(tc.script) + require.NoError(t, err) + + m := NewMachine(*p) + err = m.SetVarsFromJSON(tc.vars) + if tc.expectedError != nil { + require.Error(t, err) + //TODO(gfyrag): refine error handling of SetVars/ResolveResources/ResolveBalances + require.Equal(t, tc.expectedError.Error(), err.Error()) + } else { + require.Nil(t, err) + } + }) + } +} + +func TestResolveResources(t *testing.T) { + + type testCase struct { + name string + script string + expectedError error + vars map[string]string + } + for _, tc := range []testCase{ + { + name: "missing metadata", + script: `vars { + account $sale + account $seller = meta($sale, "seller") + } + send [COIN *] ( + source = $sale + destination = $seller + )`, + vars: map[string]string{ + "sale": "sales:042", + }, + expectedError: ErrResourceResolutionMissingMetadata, + }, + } { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + p, err := compiler.Compile(tc.script) + require.NoError(t, err) + + m := NewMachine(*p) + require.NoError(t, m.SetVarsFromJSON(tc.vars)) + _, _, err = m.ResolveResources(context.Background(), EmptyStore) + if tc.expectedError != nil { + require.Error(t, err) + require.True(t, errors.Is(err, tc.expectedError)) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestResolveBalances(t *testing.T) { + + type testCase struct { + name string + script string + expectedError error + vars map[string]string + store Store + } + for _, tc := range []testCase{ + { + name: "balance function with negative balance", + store: StaticStore{ + "users:001": &AccountWithBalances{ + Account: ledger.Account{ + Address: "users:001", + Metadata: metadata.Metadata{}, + }, + Balances: map[string]*big.Int{ + "COIN": big.NewInt(-100), + }, + }, + }, + script: ` + vars { + monetary $bal = balance(@users:001, COIN) + } + send $bal ( + source = @users:001 + destination = @world + )`, + expectedError: ErrNegativeMonetaryAmount, + }, + } { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + p, err := compiler.Compile(tc.script) + require.NoError(t, err) + + m := NewMachine(*p) + require.NoError(t, m.SetVarsFromJSON(tc.vars)) + _, _, err = m.ResolveResources(context.Background(), EmptyStore) + require.NoError(t, err) + + store := tc.store + if store == nil { + store = EmptyStore + } + + err = m.ResolveBalances(context.Background(), store) + if tc.expectedError != nil { + require.Error(t, err) + require.True(t, errors.Is(err, tc.expectedError)) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMachine(t *testing.T) { + p, err := compiler.Compile(` + vars { + account $dest + } + send [COIN 99] ( + source = @world + destination = $dest + )`) + require.NoError(t, err) + + t.Run("with debug", func(t *testing.T) { + m := NewMachine(*p) + m.Debug = true + + err = m.SetVarsFromJSON(map[string]string{ + "dest": "charlie", + }) + require.NoError(t, err) + + _, _, err := m.ResolveResources(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.ResolveBalances(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.Execute() + require.NoError(t, err) + }) + + t.Run("err resources", func(t *testing.T) { + m := NewMachine(*p) + err := m.Execute() + require.True(t, errors.Is(err, ErrResourcesNotInitialized)) + }) + + t.Run("err balances not initialized", func(t *testing.T) { + m := NewMachine(*p) + + err = m.SetVarsFromJSON(map[string]string{ + "dest": "charlie", + }) + require.NoError(t, err) + + _, _, err := m.ResolveResources(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.Execute() + require.True(t, errors.Is(err, ErrBalancesNotInitialized)) + }) + + t.Run("err resolve resources twice", func(t *testing.T) { + m := NewMachine(*p) + + err = m.SetVarsFromJSON(map[string]string{ + "dest": "charlie", + }) + require.NoError(t, err) + + _, _, err := m.ResolveResources(context.Background(), EmptyStore) + require.NoError(t, err) + + _, _, err = m.ResolveResources(context.Background(), EmptyStore) + require.ErrorContains(t, err, "tried to call ResolveResources twice") + }) + + t.Run("err balances before resources", func(t *testing.T) { + m := NewMachine(*p) + + err := m.ResolveBalances(context.Background(), EmptyStore) + require.ErrorContains(t, err, "tried to resolve balances before resources") + }) + + t.Run("err resolve balances twice", func(t *testing.T) { + m := NewMachine(*p) + + err = m.SetVarsFromJSON(map[string]string{ + "dest": "charlie", + }) + require.NoError(t, err) + + _, _, err := m.ResolveResources(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.ResolveBalances(context.Background(), EmptyStore) + require.NoError(t, err) + + err = m.ResolveBalances(context.Background(), EmptyStore) + require.ErrorContains(t, err, "tried to call ResolveBalances twice") + }) + + t.Run("err missing var", func(t *testing.T) { + m := NewMachine(*p) + + _, _, err := m.ResolveResources(context.Background(), EmptyStore) + require.Error(t, err) + }) +} + +func TestVariableAsset(t *testing.T) { + script := ` + vars { + asset $ass + monetary $bal = balance(@alice, $ass) + } + + send [$ass 15] ( + source = { + @alice + @bob + } + destination = @swap + ) + + send [$ass *] ( + source = @swap + destination = { + max $bal to @alice_2 + remaining to @bob_2 + } + )` + + tc := NewTestCase() + tc.compile(t, script) + tc.vars = map[string]string{ + "ass": "USD", + } + tc.setBalance("alice", "USD", 10) + tc.setBalance("bob", "USD", 10) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(10), + Source: "alice", + Destination: "swap", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(5), + Source: "bob", + Destination: "swap", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(10), + Source: "swap", + Destination: "alice_2", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(5), + Source: "swap", + Destination: "bob_2", + }, + }, + Error: nil, + } + test(t, tc) +} + +func TestSaveFromAccount(t *testing.T) { + t.Run("simple", func(t *testing.T) { + script := ` + save [USD 10] from @alice + + send [USD 30] ( + source = { + @alice + @world + } + destination = @bob + )` + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("alice", "USD", 20) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(10), + Source: "alice", + Destination: "bob", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(20), + Source: "world", + Destination: "bob", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("save all", func(t *testing.T) { + script := ` + save [USD *] from @alice + + send [USD 30] ( + source = { + @alice + @world + } + destination = @bob + )` + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("alice", "USD", 20) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(0), + Source: "alice", + Destination: "bob", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(30), + Source: "world", + Destination: "bob", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("save more than balance", func(t *testing.T) { + script := ` + save [USD 30] from @alice + + send [USD 30] ( + source = { + @alice + @world + } + destination = @bob + )` + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("alice", "USD", 20) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(0), + Source: "alice", + Destination: "bob", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(30), + Source: "world", + Destination: "bob", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("with asset var", func(t *testing.T) { + script := ` + vars { + asset $ass + } + save [$ass 10] from @alice + + send [$ass 30] ( + source = { + @alice + @world + } + destination = @bob + )` + tc := NewTestCase() + tc.compile(t, script) + tc.vars = map[string]string{ + "ass": "USD", + } + tc.setBalance("alice", "USD", 20) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(10), + Source: "alice", + Destination: "bob", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(20), + Source: "world", + Destination: "bob", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("with monetary var", func(t *testing.T) { + script := ` + vars { + monetary $mon + } + + save $mon from @alice + + send [USD 30] ( + source = { + @alice + @world + } + destination = @bob + )` + tc := NewTestCase() + tc.compile(t, script) + tc.vars = map[string]string{ + "mon": "USD 10", + } + tc.setBalance("alice", "USD", 20) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(10), + Source: "alice", + Destination: "bob", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(20), + Source: "world", + Destination: "bob", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("multi postings", func(t *testing.T) { + script := ` + send [USD 10] ( + source = @alice + destination = @bob + ) + + save [USD 5] from @alice + + send [USD 30] ( + source = { + @alice + @world + } + destination = @bob + )` + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("alice", "USD", 20) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(10), + Source: "alice", + Destination: "bob", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(5), + Source: "alice", + Destination: "bob", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(25), + Source: "world", + Destination: "bob", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("save a different asset", func(t *testing.T) { + script := ` + save [COIN 100] from @alice + + send [USD 30] ( + source = { + @alice + @world + } + destination = @bob + )` + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("alice", "COIN", 100) + tc.setBalance("alice", "USD", 20) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{ + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(20), + Source: "alice", + Destination: "bob", + }, + { + Asset: "USD", + Amount: internal2.NewMonetaryInt(10), + Source: "world", + Destination: "bob", + }, + }, + Error: nil, + } + test(t, tc) + }) + + t.Run("negative amount", func(t *testing.T) { + script := ` + vars { + monetary $amt = balance(@A, USD) + } + save $amt from @A` + tc := NewTestCase() + tc.compile(t, script) + tc.setBalance("A", "USD", -100) + tc.expected = CaseResult{ + Printed: []internal2.Value{}, + Postings: []Posting{}, + Error: ErrNegativeMonetaryAmount, + } + test(t, tc) + }) +} diff --git a/components/ledger/pkg/machine/vm/program/instructions.go b/components/ledger/internal/machine/vm/program/instructions.go similarity index 100% rename from components/ledger/pkg/machine/vm/program/instructions.go rename to components/ledger/internal/machine/vm/program/instructions.go diff --git a/components/ledger/internal/machine/vm/program/program.go b/components/ledger/internal/machine/vm/program/program.go new file mode 100644 index 000000000..73f75ba1c --- /dev/null +++ b/components/ledger/internal/machine/vm/program/program.go @@ -0,0 +1,112 @@ +package program + +import ( + "encoding/binary" + "fmt" + + internal2 "github.com/formancehq/ledger/internal/machine/internal" + "github.com/pkg/errors" +) + +type Program struct { + Instructions []byte + Resources []Resource + Sources []internal2.Address + NeededBalances map[internal2.Address]map[internal2.Address]struct{} +} + +func (p Program) String() string { + out := "Program:\nINSTRUCTIONS\n" + for i := 0; i < len(p.Instructions); i++ { + out += fmt.Sprintf("%02d----- ", i) + switch p.Instructions[i] { + case OP_APUSH: + out += "OP_APUSH " + address := binary.LittleEndian.Uint16(p.Instructions[i+1 : i+3]) + out += fmt.Sprintf("#%d\n", address) + i += 2 + default: + out += OpcodeName(p.Instructions[i]) + "\n" + } + } + + out += fmt.Sprintln("RESOURCES") + i := 0 + for i = 0; i < len(p.Resources); i++ { + out += fmt.Sprintf("%02d ", i) + out += fmt.Sprintf("%v\n", p.Resources[i]) + } + return out +} + +func (p *Program) ParseVariables(vars map[string]internal2.Value) (map[string]internal2.Value, error) { + variables := make(map[string]internal2.Value) + for _, res := range p.Resources { + if variable, ok := res.(Variable); ok { + if val, ok := vars[variable.Name]; ok && val.GetType() == variable.Typ { + variables[variable.Name] = val + switch val.GetType() { + case internal2.TypeAccount: + if err := internal2.ValidateAccountAddress(val.(internal2.AccountAddress)); err != nil { + return nil, errors.Wrapf(err, "invalid variable $%s value '%s'", + variable.Name, string(val.(internal2.AccountAddress))) + } + case internal2.TypeAsset: + if err := internal2.ValidateAsset(val.(internal2.Asset)); err != nil { + return nil, errors.Wrapf(err, "invalid variable $%s value '%s'", + variable.Name, string(val.(internal2.Asset))) + } + case internal2.TypeMonetary: + if err := internal2.ParseMonetary(val.(internal2.Monetary)); err != nil { + return nil, errors.Wrapf(err, "invalid variable $%s value '%s'", + variable.Name, val.(internal2.Monetary).String()) + } + case internal2.TypePortion: + if err := internal2.ValidatePortionSpecific(val.(internal2.Portion)); err != nil { + return nil, errors.Wrapf(err, "invalid variable $%s value '%s'", + variable.Name, val.(internal2.Portion).String()) + } + case internal2.TypeString: + case internal2.TypeNumber: + default: + return nil, fmt.Errorf("unsupported type for variable $%s: %s", + variable.Name, val.GetType()) + } + delete(vars, variable.Name) + } else if val, ok := vars[variable.Name]; ok && val.GetType() != variable.Typ { + return nil, fmt.Errorf("wrong type for variable $%s: %s instead of %s", + variable.Name, variable.Typ, val.GetType()) + } else { + return nil, fmt.Errorf("missing variable $%s", variable.Name) + } + } + } + for name := range vars { + return nil, fmt.Errorf("extraneous variable $%s", name) + } + return variables, nil +} + +func (p *Program) ParseVariablesJSON(vars map[string]string) (map[string]internal2.Value, error) { + variables := make(map[string]internal2.Value) + for _, res := range p.Resources { + if param, ok := res.(Variable); ok { + data, ok := vars[param.Name] + if !ok { + return nil, fmt.Errorf("missing variable $%s", param.Name) + } + val, err := internal2.NewValueFromString(param.Typ, data) + if err != nil { + return nil, fmt.Errorf( + "invalid JSON value for variable $%s of type %v: %w", + param.Name, param.Typ, err) + } + variables[param.Name] = val + delete(vars, param.Name) + } + } + for name := range vars { + return nil, fmt.Errorf("extraneous variable $%s", name) + } + return variables, nil +} diff --git a/components/ledger/pkg/machine/vm/program/program_test.go b/components/ledger/internal/machine/vm/program/program_test.go similarity index 80% rename from components/ledger/pkg/machine/vm/program/program_test.go rename to components/ledger/internal/machine/vm/program/program_test.go index 8abaa13de..12303e0d9 100644 --- a/components/ledger/pkg/machine/vm/program/program_test.go +++ b/components/ledger/internal/machine/vm/program/program_test.go @@ -3,7 +3,7 @@ package program_test import ( "testing" - "github.com/formancehq/ledger/pkg/machine/script/compiler" + "github.com/formancehq/ledger/internal/machine/script/compiler" "github.com/stretchr/testify/require" ) diff --git a/components/ledger/internal/machine/vm/program/resource.go b/components/ledger/internal/machine/vm/program/resource.go new file mode 100644 index 000000000..3e591592d --- /dev/null +++ b/components/ledger/internal/machine/vm/program/resource.go @@ -0,0 +1,59 @@ +package program + +import ( + "fmt" + + internal2 "github.com/formancehq/ledger/internal/machine/internal" +) + +type Resource interface { + GetType() internal2.Type +} + +type Constant struct { + Inner internal2.Value +} + +func (c Constant) GetType() internal2.Type { return c.Inner.GetType() } +func (c Constant) String() string { return fmt.Sprintf("%v", c.Inner) } + +type Variable struct { + Typ internal2.Type + Name string +} + +func (p Variable) GetType() internal2.Type { return p.Typ } +func (p Variable) String() string { return fmt.Sprintf("<%v %v>", p.Typ, p.Name) } + +type VariableAccountMetadata struct { + Typ internal2.Type + Name string + Account internal2.Address + Key string +} + +func (m VariableAccountMetadata) GetType() internal2.Type { return m.Typ } +func (m VariableAccountMetadata) String() string { + return fmt.Sprintf("<%v %v meta(%v, %v)>", m.Typ, m.Name, m.Account, m.Key) +} + +type VariableAccountBalance struct { + Name string + Account internal2.Address + Asset internal2.Address +} + +func (a VariableAccountBalance) GetType() internal2.Type { return internal2.TypeMonetary } +func (a VariableAccountBalance) String() string { + return fmt.Sprintf("<%v %v balance(%v, %v)>", internal2.TypeMonetary, a.Name, a.Account, a.Asset) +} + +type Monetary struct { + Asset internal2.Address + Amount *internal2.MonetaryInt +} + +func (a Monetary) GetType() internal2.Type { return internal2.TypeMonetary } +func (a Monetary) String() string { + return fmt.Sprintf("<%v [%v %v]>", internal2.TypeMonetary, a.Asset, a.Amount) +} diff --git a/components/ledger/internal/machine/vm/program/resource_test.go b/components/ledger/internal/machine/vm/program/resource_test.go new file mode 100644 index 000000000..90c1f8127 --- /dev/null +++ b/components/ledger/internal/machine/vm/program/resource_test.go @@ -0,0 +1,37 @@ +package program + +import ( + "testing" + + internal2 "github.com/formancehq/ledger/internal/machine/internal" + "github.com/stretchr/testify/require" +) + +func TestResource(t *testing.T) { + c := Constant{ + Inner: internal2.NewMonetaryInt(0), + } + c.GetType() + require.Equal(t, "0", c.String()) + + v := Variable{ + Typ: internal2.TypeAccount, + Name: "acc", + } + require.Equal(t, "", v.String()) + + vab := VariableAccountBalance{ + Name: "name", + Account: internal2.Address(0), + Asset: internal2.Address(1), + } + require.Equal(t, "", vab.String()) + + vam := VariableAccountMetadata{ + Typ: internal2.TypeMonetary, + Name: "name", + Account: internal2.Address(0), + Key: "key", + } + require.Equal(t, "", vam.String()) +} diff --git a/components/ledger/pkg/machine/vm/stack.go b/components/ledger/internal/machine/vm/stack.go similarity index 87% rename from components/ledger/pkg/machine/vm/stack.go rename to components/ledger/internal/machine/vm/stack.go index 7236f094b..81d3bacb3 100644 --- a/components/ledger/pkg/machine/vm/stack.go +++ b/components/ledger/internal/machine/vm/stack.go @@ -3,7 +3,7 @@ package vm import ( "fmt" - "github.com/formancehq/ledger/pkg/machine/internal" + "github.com/formancehq/ledger/internal/machine/internal" ) func (m *Machine) popValue() internal.Value { diff --git a/components/ledger/internal/machine/vm/store.go b/components/ledger/internal/machine/vm/store.go new file mode 100644 index 000000000..455218d4d --- /dev/null +++ b/components/ledger/internal/machine/vm/store.go @@ -0,0 +1,65 @@ +package vm + +import ( + "context" + "math/big" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/stack/libs/go-libs/metadata" +) + +type Store interface { + GetBalance(ctx context.Context, address, asset string) (*big.Int, error) + GetAccount(ctx context.Context, address string) (*ledger.Account, error) +} + +type emptyStore struct{} + +func (e *emptyStore) GetBalance(ctx context.Context, address, asset string) (*big.Int, error) { + return new(big.Int), nil +} + +func (e *emptyStore) GetAccount(ctx context.Context, address string) (*ledger.Account, error) { + return &ledger.Account{ + Address: address, + Metadata: metadata.Metadata{}, + }, nil +} + +var _ Store = (*emptyStore)(nil) + +var EmptyStore = &emptyStore{} + +type AccountWithBalances struct { + ledger.Account + Balances map[string]*big.Int +} + +type StaticStore map[string]*AccountWithBalances + +func (s StaticStore) GetBalance(ctx context.Context, address, asset string) (*big.Int, error) { + account, ok := s[address] + if !ok { + return new(big.Int), nil + } + balance, ok := account.Balances[asset] + if !ok { + return new(big.Int), nil + } + + return balance, nil +} + +func (s StaticStore) GetAccount(ctx context.Context, address string) (*ledger.Account, error) { + account, ok := s[address] + if !ok { + return &ledger.Account{ + Address: address, + Metadata: metadata.Metadata{}, + }, nil + } + + return &account.Account, nil +} + +var _ Store = StaticStore{} diff --git a/components/ledger/internal/metadata.go b/components/ledger/internal/metadata.go new file mode 100644 index 000000000..177e7f640 --- /dev/null +++ b/components/ledger/internal/metadata.go @@ -0,0 +1,37 @@ +package ledger + +import ( + "math/big" + + "github.com/formancehq/stack/libs/go-libs/metadata" +) + +const ( + formanceNamespace = "com.formance.spec/" + revertKey = "state/reverts" + + MetaTargetTypeAccount = "ACCOUNT" + MetaTargetTypeTransaction = "TRANSACTION" +) + +func SpecMetadata(name string) string { + return formanceNamespace + name +} + +func MarkReverts(m metadata.Metadata, txID *big.Int) metadata.Metadata { + return m.Merge(RevertMetadata(txID)) +} + +func RevertMetadataSpecKey() string { + return SpecMetadata(revertKey) +} + +func ComputeMetadata(key, value string) metadata.Metadata { + return metadata.Metadata{ + key: value, + } +} + +func RevertMetadata(tx *big.Int) metadata.Metadata { + return ComputeMetadata(RevertMetadataSpecKey(), tx.String()) +} diff --git a/components/ledger/pkg/core/numscript.go b/components/ledger/internal/numscript.go similarity index 99% rename from components/ledger/pkg/core/numscript.go rename to components/ledger/internal/numscript.go index 062a30517..bac95b377 100644 --- a/components/ledger/pkg/core/numscript.go +++ b/components/ledger/internal/numscript.go @@ -1,4 +1,4 @@ -package core +package ledger import ( "fmt" diff --git a/components/ledger/internal/opentelemetry/metrics/metrics.go b/components/ledger/internal/opentelemetry/metrics/metrics.go new file mode 100644 index 000000000..1cc65dea0 --- /dev/null +++ b/components/ledger/internal/opentelemetry/metrics/metrics.go @@ -0,0 +1,89 @@ +package metrics + +import ( + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" +) + +type GlobalRegistry interface { + APILatencies() metric.Int64Histogram + StatusCodes() metric.Int64Counter + ActiveLedgers() metric.Int64UpDownCounter +} + +type globalRegistry struct { + // API Latencies + apiLatencies metric.Int64Histogram + statusCodes metric.Int64Counter + activeLedgers metric.Int64UpDownCounter +} + +func RegisterGlobalRegistry(meterProvider metric.MeterProvider) (GlobalRegistry, error) { + meter := meterProvider.Meter("global") + + apiLatencies, err := meter.Int64Histogram( + "ledger.api.time", + metric.WithUnit("ms"), + metric.WithDescription("Latency of API calls"), + ) + if err != nil { + return nil, err + } + + statusCodes, err := meter.Int64Counter( + "ledger.api.status", + metric.WithUnit("1"), + metric.WithDescription("Status codes of API calls"), + ) + if err != nil { + return nil, err + } + + activeLedgers, err := meter.Int64UpDownCounter( + "ledger.api.ledgers", + metric.WithUnit("1"), + metric.WithDescription("Number of active ledgers"), + ) + if err != nil { + return nil, err + } + + return &globalRegistry{ + apiLatencies: apiLatencies, + statusCodes: statusCodes, + activeLedgers: activeLedgers, + }, nil +} + +func (gm *globalRegistry) APILatencies() metric.Int64Histogram { + return gm.apiLatencies +} + +func (gm *globalRegistry) StatusCodes() metric.Int64Counter { + return gm.statusCodes +} + +func (gm *globalRegistry) ActiveLedgers() metric.Int64UpDownCounter { + return gm.activeLedgers +} + +type noOpRegistry struct{} + +func NewNoOpRegistry() *noOpRegistry { + return &noOpRegistry{} +} + +func (nm *noOpRegistry) APILatencies() metric.Int64Histogram { + histogram, _ := noop.NewMeterProvider().Meter("ledger").Int64Histogram("api_latencies") + return histogram +} + +func (nm *noOpRegistry) StatusCodes() metric.Int64Counter { + counter, _ := noop.NewMeterProvider().Meter("ledger").Int64Counter("status_codes") + return counter +} + +func (nm *noOpRegistry) ActiveLedgers() metric.Int64UpDownCounter { + counter, _ := noop.NewMeterProvider().Meter("ledger").Int64UpDownCounter("active_ledgers") + return counter +} diff --git a/components/ledger/pkg/opentelemetry/tracer/tracer.go b/components/ledger/internal/opentelemetry/tracer/tracer.go similarity index 100% rename from components/ledger/pkg/opentelemetry/tracer/tracer.go rename to components/ledger/internal/opentelemetry/tracer/tracer.go diff --git a/components/ledger/pkg/core/posting.go b/components/ledger/internal/posting.go similarity index 91% rename from components/ledger/pkg/core/posting.go rename to components/ledger/internal/posting.go index 35e41a308..c93cd6a17 100644 --- a/components/ledger/pkg/core/posting.go +++ b/components/ledger/internal/posting.go @@ -1,4 +1,4 @@ -package core +package ledger import ( "database/sql/driver" @@ -16,13 +16,6 @@ type Posting struct { Asset string `json:"asset"` } -func (p Posting) hashString(buf *buffer) { - buf.writeString(p.Source) - buf.writeString(p.Destination) - buf.write(p.Amount.Bytes()) - buf.writeString(p.Asset) -} - func NewPosting(source string, destination string, asset string, amount *big.Int) Posting { return Posting{ Source: source, diff --git a/components/ledger/pkg/core/posting_test.go b/components/ledger/internal/posting_test.go similarity index 98% rename from components/ledger/pkg/core/posting_test.go rename to components/ledger/internal/posting_test.go index 3693172fc..13114815c 100644 --- a/components/ledger/pkg/core/posting_test.go +++ b/components/ledger/internal/posting_test.go @@ -1,4 +1,4 @@ -package core +package ledger import ( "math/big" diff --git a/components/ledger/pkg/core/script.go b/components/ledger/internal/script.go similarity index 96% rename from components/ledger/pkg/core/script.go rename to components/ledger/internal/script.go index 30f412ff7..f6840973f 100644 --- a/components/ledger/pkg/core/script.go +++ b/components/ledger/internal/script.go @@ -1,4 +1,4 @@ -package core +package ledger import ( "github.com/formancehq/stack/libs/go-libs/metadata" diff --git a/components/ledger/internal/storage/driver/cli.go b/components/ledger/internal/storage/driver/cli.go new file mode 100644 index 000000000..424f5392d --- /dev/null +++ b/components/ledger/internal/storage/driver/cli.go @@ -0,0 +1,67 @@ +package driver + +import ( + "context" + "io" + "time" + + storage2 "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/stack/libs/go-libs/health" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/uptrace/bun" + "go.uber.org/fx" +) + +// TODO(gfyrag): maybe move flag handling inside cmd/internal (as telemetry flags) +// Or make the inverse (move analytics flags to pkg/analytics) +// IMO, flags are more easily discoverable if located inside cmd/ +func InitCLIFlags(cmd *cobra.Command) { + cmd.PersistentFlags().Int(storage2.StoreWorkerMaxPendingSize, 0, "Max pending size for store worker") + cmd.PersistentFlags().Int(storage2.StoreWorkerMaxWriteChanSize, 1024, "Max write channel size for store worker") + cmd.PersistentFlags().String(storage2.StoragePostgresConnectionStringFlag, "postgresql://localhost/postgres", "Postgres connection string") + cmd.PersistentFlags().Int(storage2.StoragePostgresMaxIdleConnsFlag, 20, "Max idle connections to database") + cmd.PersistentFlags().Duration(storage2.StoragePostgresConnMaxIdleTimeFlag, time.Minute, "Max idle time of idle connections") + cmd.PersistentFlags().Int(storage2.StoragePostgresMaxOpenConns, 20, "Max open connections") +} + +type PostgresConfig struct { + ConnString string +} + +type ModuleConfig struct { + PostgresConnectionOptions storage2.ConnectionOptions + Debug bool +} + +func CLIModule(v *viper.Viper, output io.Writer, debug bool) fx.Option { + + options := make([]fx.Option, 0) + options = append(options, fx.Provide(func(logger logging.Logger) (*bun.DB, error) { + configuration := storage2.ConnectionOptionsFromFlags(v, output, debug) + logger.WithField("config", configuration).Infof("Opening connection to database...") + return storage2.OpenSQLDB(configuration) + })) + options = append(options, fx.Provide(func(db *bun.DB) (*Driver, error) { + return New(db), nil + })) + options = append(options, health.ProvideHealthCheck(func(db *bun.DB) health.NamedCheck { + return health.NewNamedCheck("postgres", health.CheckFn(db.PingContext)) + })) + + options = append(options, fx.Invoke(func(db *bun.DB, driver *Driver, lifecycle fx.Lifecycle, logger logging.Logger) error { + lifecycle.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + logger.Infof("Initializing database...") + return driver.Initialize(ctx) + }, + OnStop: func(ctx context.Context) error { + logger.Infof("Closing database...") + return db.Close() + }, + }) + return nil + })) + return fx.Options(options...) +} diff --git a/components/ledger/pkg/storage/driver/driver.go b/components/ledger/internal/storage/driver/driver.go similarity index 76% rename from components/ledger/pkg/storage/driver/driver.go rename to components/ledger/internal/storage/driver/driver.go index 0a415cf42..701df0df0 100644 --- a/components/ledger/pkg/storage/driver/driver.go +++ b/components/ledger/internal/storage/driver/driver.go @@ -7,11 +7,12 @@ import ( "fmt" "sync" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - systemstore "github.com/formancehq/ledger/pkg/storage/systemstore" + "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/systemstore" "github.com/formancehq/stack/libs/go-libs/logging" "github.com/pkg/errors" + "github.com/uptrace/bun" "go.nhat.io/otelsql" ) @@ -38,6 +39,7 @@ func init() { pgxSqlDriver.driverName = "pgx" } +// todo: since se use pq, this is probably useless func InstrumentalizeSQLDriver() { // otelsql has a function Register which wrap the underlying driver, but does not mirror driver.NamedValuedChecker interface of the underlying driver // pgx implements this interface and just return nil @@ -65,7 +67,7 @@ func InstrumentalizeSQLDriver() { } type Driver struct { - db *storage.Database + db *bun.DB systemStore *systemstore.Store lock sync.Mutex } @@ -74,17 +76,8 @@ func (d *Driver) GetSystemStore() *systemstore.Store { return d.systemStore } -func (d *Driver) newStore(ctx context.Context, name string) (*ledgerstore.Store, error) { - schema, err := d.db.Schema(name) - if err != nil { - return nil, errors.Wrap(err, "opening schema") - } - - if err = schema.Create(ctx); err != nil { - return nil, err - } - - store, err := ledgerstore.New(schema, func(ctx context.Context) error { +func (d *Driver) newStore(name string) (*ledgerstore.Store, error) { + store, err := ledgerstore.New(d.db, name, func(ctx context.Context) error { return d.GetSystemStore().DeleteLedger(ctx, name) }) if err != nil { @@ -114,7 +107,7 @@ func (d *Driver) CreateLedgerStore(ctx context.Context, name string) (*ledgersto return nil, err } - store, err := d.newStore(ctx, name) + store, err := d.newStore(name) if err != nil { return nil, err } @@ -136,26 +129,23 @@ func (d *Driver) GetLedgerStore(ctx context.Context, name string) (*ledgerstore. return nil, storage.ErrStoreNotFound } - return d.newStore(ctx, name) + return d.newStore(name) } func (d *Driver) Initialize(ctx context.Context) error { logging.FromContext(ctx).Debugf("Initialize driver") - if err := d.db.Initialize(ctx); err != nil { - return err - } - - systemSchema, err := d.db.Schema(SystemSchema) + _, err := d.db.ExecContext(ctx, "create extension if not exists pgcrypto") if err != nil { - return err + return storage.PostgresError(err) } - if err := systemSchema.Create(ctx); err != nil { - return err + _, err = d.db.ExecContext(ctx, fmt.Sprintf(`create schema if not exists "%s"`, SystemSchema)) + if err != nil { + return storage.PostgresError(err) } - d.systemStore = systemstore.NewStore(systemSchema) + d.systemStore = systemstore.NewStore(d.db) if err := d.systemStore.Initialize(ctx); err != nil { return err @@ -164,7 +154,7 @@ func (d *Driver) Initialize(ctx context.Context) error { return nil } -func New(db *storage.Database) *Driver { +func New(db *bun.DB) *Driver { return &Driver{ db: db, } diff --git a/components/ledger/pkg/storage/driver/driver_test.go b/components/ledger/internal/storage/driver/driver_test.go similarity index 89% rename from components/ledger/pkg/storage/driver/driver_test.go rename to components/ledger/internal/storage/driver/driver_test.go index c06da668d..03adbdac4 100644 --- a/components/ledger/pkg/storage/driver/driver_test.go +++ b/components/ledger/internal/storage/driver/driver_test.go @@ -5,8 +5,8 @@ import ( "os" "testing" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/storagetesting" + "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/storagetesting" "github.com/formancehq/stack/libs/go-libs/logging" "github.com/formancehq/stack/libs/go-libs/pgtesting" "github.com/stretchr/testify/require" diff --git a/components/ledger/pkg/storage/errors.go b/components/ledger/internal/storage/errors.go similarity index 100% rename from components/ledger/pkg/storage/errors.go rename to components/ledger/internal/storage/errors.go diff --git a/components/ledger/pkg/storage/flags.go b/components/ledger/internal/storage/flags.go similarity index 97% rename from components/ledger/pkg/storage/flags.go rename to components/ledger/internal/storage/flags.go index 351dfb922..670cc1fa1 100644 --- a/components/ledger/pkg/storage/flags.go +++ b/components/ledger/internal/storage/flags.go @@ -19,7 +19,6 @@ func ConnectionOptionsFromFlags(v *viper.Viper, output io.Writer, debug bool) Co return ConnectionOptions{ DatabaseSourceName: v.GetString(StoragePostgresConnectionStringFlag), Debug: debug, - Trace: debug, Writer: output, MaxIdleConns: v.GetInt(StoragePostgresMaxIdleConnsFlag), ConnMaxIdleTime: v.GetDuration(StoragePostgresConnMaxIdleTimeFlag), diff --git a/components/ledger/internal/storage/inmemory.go b/components/ledger/internal/storage/inmemory.go new file mode 100644 index 000000000..f12289e62 --- /dev/null +++ b/components/ledger/internal/storage/inmemory.go @@ -0,0 +1,124 @@ +package storage + +import ( + "context" + "math/big" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/stack/libs/go-libs/collectionutils" + "github.com/formancehq/stack/libs/go-libs/metadata" +) + +type InMemoryStore struct { + logs []*ledger.ChainedLog + transactions []*ledger.ExpandedTransaction + accounts []*ledger.Account +} + +func (m *InMemoryStore) GetTransactionByReference(ctx context.Context, ref string) (*ledger.ExpandedTransaction, error) { + filtered := collectionutils.Filter(m.transactions, func(transaction *ledger.ExpandedTransaction) bool { + return transaction.Reference == ref + }) + if len(filtered) == 0 { + return nil, ErrNotFound + } + return filtered[0], nil +} + +func (m *InMemoryStore) GetTransaction(ctx context.Context, txID *big.Int) (*ledger.Transaction, error) { + filtered := collectionutils.Filter(m.transactions, func(transaction *ledger.ExpandedTransaction) bool { + return transaction.ID.Cmp(txID) == 0 + }) + if len(filtered) == 0 { + return nil, ErrNotFound + } + return &filtered[0].Transaction, nil +} + +func (m *InMemoryStore) GetLastLog(ctx context.Context) (*ledger.ChainedLog, error) { + if len(m.logs) == 0 { + return nil, nil + } + return m.logs[len(m.logs)-1], nil +} + +func (m *InMemoryStore) GetBalance(ctx context.Context, address, asset string) (*big.Int, error) { + balance := new(big.Int) + for _, log := range m.logs { + switch payload := log.Data.(type) { + case ledger.NewTransactionLogPayload: + postings := payload.Transaction.Postings + for _, posting := range postings { + if posting.Asset != asset { + continue + } + if posting.Source == address { + balance = balance.Sub(balance, posting.Amount) + } + if posting.Destination == address { + balance = balance.Add(balance, posting.Amount) + } + } + } + } + return balance, nil +} + +func (m *InMemoryStore) GetAccount(ctx context.Context, address string) (*ledger.Account, error) { + account := collectionutils.Filter(m.accounts, func(account *ledger.Account) bool { + return account.Address == address + }) + if len(account) == 0 { + return &ledger.Account{ + Address: address, + Metadata: metadata.Metadata{}, + }, nil + } + return account[0], nil +} + +func (m *InMemoryStore) ReadLogWithIdempotencyKey(ctx context.Context, key string) (*ledger.ChainedLog, error) { + first := collectionutils.First(m.logs, func(log *ledger.ChainedLog) bool { + return log.IdempotencyKey == key + }) + if first == nil { + return nil, ErrNotFound + } + return first, nil +} + +func (m *InMemoryStore) InsertLogs(ctx context.Context, logs ...*ledger.ChainedLog) error { + m.logs = append(m.logs, logs...) + for _, log := range logs { + switch payload := log.Data.(type) { + case ledger.NewTransactionLogPayload: + m.transactions = append(m.transactions, &ledger.ExpandedTransaction{ + Transaction: *payload.Transaction, + // TODO + PreCommitVolumes: nil, + PostCommitVolumes: nil, + }) + case ledger.RevertedTransactionLogPayload: + tx := collectionutils.Filter(m.transactions, func(transaction *ledger.ExpandedTransaction) bool { + return transaction.ID.Cmp(payload.RevertedTransactionID) == 0 + })[0] + tx.Reverted = true + case ledger.SetMetadataLogPayload: + } + } + + return nil +} + +func (m *InMemoryStore) GetLastTransaction(ctx context.Context) (*ledger.ExpandedTransaction, error) { + if len(m.transactions) == 0 { + return nil, ErrNotFound + } + return m.transactions[len(m.transactions)-1], nil +} + +func NewInMemoryStore() *InMemoryStore { + return &InMemoryStore{ + logs: []*ledger.ChainedLog{}, + } +} diff --git a/components/ledger/internal/storage/ledgerstore/accounts.go b/components/ledger/internal/storage/ledgerstore/accounts.go new file mode 100644 index 000000000..4d7035566 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/accounts.go @@ -0,0 +1,202 @@ +package ledgerstore + +import ( + "context" + "errors" + "fmt" + "regexp" + + ledger "github.com/formancehq/ledger/internal" + storageerrors "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/pointer" + "github.com/uptrace/bun" +) + +func (store *Store) buildAccountQuery(q PITFilterWithVolumes, query *bun.SelectQuery) *bun.SelectQuery { + query = query. + DistinctOn("accounts.address"). + Column("accounts.address"). + ColumnExpr("coalesce(metadata, '{}'::jsonb) as metadata"). + Table("accounts"). + Apply(filterPIT(q.PIT, "insertion_date")). + Order("accounts.address", "revision desc") + + if q.PIT == nil { + query = query.Join("left join accounts_metadata on accounts_metadata.address = accounts.address") + } else { + query = query.Join("left join accounts_metadata on accounts_metadata.address = accounts.address and accounts_metadata.date < ?", q.PIT) + } + + if q.ExpandVolumes { + query = query. + ColumnExpr("volumes.*"). + Join("join get_account_aggregated_volumes(accounts.address, ?) volumes on true", q.PIT) + } + + if q.ExpandEffectiveVolumes { + query = query. + ColumnExpr("effective_volumes.*"). + Join("join get_account_aggregated_effective_volumes(accounts.address, ?) effective_volumes on true", q.PIT) + } + + return query +} + +func (store *Store) accountQueryContext(qb query.Builder) (string, []any, error) { + metadataRegex := regexp.MustCompile("metadata\\[(.+)\\]") + balanceRegex := regexp.MustCompile("balance\\[(.*)\\]") + + return qb.Build(query.ContextFn(func(key, operator string, value any) (string, []any, error) { + switch { + case key == "address": + // TODO: Should allow comparison operator only if segments not used + if operator != "$match" { + return "", nil, errors.New("'address' column can only be used with $match") + } + switch address := value.(type) { + case string: + return filterAccountAddress(address, "accounts.address"), nil, nil + default: + return "", nil, fmt.Errorf("unexpected type %T for column 'address'", address) + } + case metadataRegex.Match([]byte(key)): + if operator != "$match" { + return "", nil, errors.New("'account' column can only be used with $match") + } + match := metadataRegex.FindAllStringSubmatch(key, 3) + + return "metadata @> ?", []any{map[string]any{ + match[0][1]: value, + }}, nil + case balanceRegex.Match([]byte(key)): + match := balanceRegex.FindAllStringSubmatch(key, 2) + + return fmt.Sprintf(`( + select balance_from_volumes(post_commit_volumes) + from moves + where asset = ? and account_address = accounts.address + order by seq desc + limit 1 + ) < ?`), []any{match[0][1], value}, nil + case key == "balance": + return fmt.Sprintf(`( + select balance_from_volumes(post_commit_volumes) + from moves + where account_address = accounts.address + order by seq desc + limit 1 + ) < ?`), nil, nil + default: + return "", nil, fmt.Errorf("unknown key '%s' when building query", key) + } + })) +} + +func (store *Store) buildAccountListQuery(selectQuery *bun.SelectQuery, q *GetAccountsQuery) *bun.SelectQuery { + selectQuery = store.buildAccountQuery(q.Options.Options, selectQuery) + + if q.Options.QueryBuilder != nil { + where, args, err := store.accountQueryContext(q.Options.QueryBuilder) + if err != nil { + // TODO: handle error + panic(err) + } + return selectQuery.Where(where, args...) + } + + return selectQuery +} + +func (store *Store) GetAccountsWithVolumes(ctx context.Context, q *GetAccountsQuery) (*api.Cursor[ledger.ExpandedAccount], error) { + return paginateWithOffset[PaginatedQueryOptions[PITFilterWithVolumes], ledger.ExpandedAccount](store, ctx, + (*paginate.OffsetPaginatedQuery[PaginatedQueryOptions[PITFilterWithVolumes]])(q), + func(query *bun.SelectQuery) *bun.SelectQuery { + return store.buildAccountListQuery(query, q) + }, + ) +} + +func (store *Store) GetAccount(ctx context.Context, address string) (*ledger.Account, error) { + account, err := fetch[*ledger.Account](store, ctx, func(query *bun.SelectQuery) *bun.SelectQuery { + return query. + ColumnExpr("accounts.address"). + ColumnExpr("coalesce(metadata, '{}'::jsonb) as metadata"). + Table("accounts"). + Join("left join accounts_metadata on accounts_metadata.address = accounts.address"). + Where("accounts.address = ?", address). + Order("revision desc"). + Limit(1) + }) + if err != nil { + if storageerrors.IsNotFoundError(err) { + return pointer.For(ledger.NewAccount(address)), nil + } + return nil, err + } + return account, nil +} + +func (store *Store) GetAccountWithVolumes(ctx context.Context, q GetAccountQuery) (*ledger.ExpandedAccount, error) { + account, err := fetch[*ledger.ExpandedAccount](store, ctx, func(query *bun.SelectQuery) *bun.SelectQuery { + query = store.buildAccountQuery(q.PITFilterWithVolumes, query). + Where("accounts.address = ?", q.Addr). + Limit(1) + + return query + }) + if err != nil { + if storageerrors.IsNotFoundError(err) { + return pointer.For(ledger.NewExpandedAccount(q.Addr)), nil + } + return nil, err + } + return account, nil +} + +func (store *Store) CountAccounts(ctx context.Context, q *GetAccountsQuery) (uint64, error) { + return count(store, ctx, func(query *bun.SelectQuery) *bun.SelectQuery { + return store.buildAccountListQuery(query, q) + }) +} + +type GetAccountQuery struct { + PITFilterWithVolumes + Addr string +} + +func (q GetAccountQuery) WithPIT(pit ledger.Time) GetAccountQuery { + q.PIT = &pit + + return q +} + +func (q GetAccountQuery) WithExpandVolumes() GetAccountQuery { + q.ExpandVolumes = true + + return q +} + +func (q GetAccountQuery) WithExpandEffectiveVolumes() GetAccountQuery { + q.ExpandEffectiveVolumes = true + + return q +} + +func NewGetAccountQuery(addr string) GetAccountQuery { + return GetAccountQuery{ + Addr: addr, + } +} + +type GetAccountsQuery paginate.OffsetPaginatedQuery[PaginatedQueryOptions[PITFilterWithVolumes]] + +func NewGetAccountsQuery(opts PaginatedQueryOptions[PITFilterWithVolumes]) *GetAccountsQuery { + return &GetAccountsQuery{ + PageSize: opts.PageSize, + Order: paginate.OrderAsc, + Options: opts, + } +} diff --git a/components/ledger/internal/storage/ledgerstore/accounts_test.go b/components/ledger/internal/storage/ledgerstore/accounts_test.go new file mode 100644 index 000000000..f55a391ca --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/accounts_test.go @@ -0,0 +1,314 @@ +package ledgerstore_test + +import ( + "context" + "math/big" + "testing" + "time" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/query" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/stretchr/testify/require" +) + +func TestGetAccounts(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.ChainLogs( + ledger.NewTransactionLog( + ledger.NewTransaction(). + WithPostings(ledger.NewPosting("world", "account:1", "USD", big.NewInt(100))). + WithDate(now), + map[string]metadata.Metadata{ + "account:1": { + "category": "4", + }, + }, + ).WithDate(now), + ledger.NewSetMetadataOnAccountLog(ledger.Now(), "account:1", metadata.Metadata{"category": "1"}).WithDate(now.Add(time.Minute)), + ledger.NewSetMetadataOnAccountLog(ledger.Now(), "account:2", metadata.Metadata{"category": "2"}).WithDate(now.Add(2*time.Minute)), + ledger.NewSetMetadataOnAccountLog(ledger.Now(), "account:3", metadata.Metadata{"category": "3"}).WithDate(now.Add(3*time.Minute)), + ledger.NewSetMetadataOnAccountLog(ledger.Now(), "orders:1", metadata.Metadata{"foo": "bar"}).WithDate(now.Add(3*time.Minute)), + ledger.NewSetMetadataOnAccountLog(ledger.Now(), "orders:2", metadata.Metadata{"foo": "bar"}).WithDate(now.Add(3*time.Minute)), + ledger.NewTransactionLog( + ledger.NewTransaction(). + WithPostings(ledger.NewPosting("world", "account:1", "USD", big.NewInt(100))). + WithIDUint64(1). + WithDate(now.Add(4*time.Minute)), + map[string]metadata.Metadata{}, + ).WithDate(now.Add(100*time.Millisecond)), + ledger.NewTransactionLog( + ledger.NewTransaction(). + WithPostings(ledger.NewPosting("account:1", "bank", "USD", big.NewInt(50))). + WithDate(now.Add(3*time.Minute)). + WithIDUint64(2), + map[string]metadata.Metadata{}, + ).WithDate(now.Add(200*time.Millisecond)), + )..., + )) + + t.Run("list all", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}))) + require.NoError(t, err) + require.Len(t, accounts.Data, 7) + }) + + t.Run("list using metadata", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("metadata[category]", "1")), + )) + require.NoError(t, err) + require.Len(t, accounts.Data, 1) + }) + + t.Run("list before date", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{ + PITFilter: ledgerstore.PITFilter{ + PIT: &now, + }, + }))) + require.NoError(t, err) + require.Len(t, accounts.Data, 2) + }) + + t.Run("list with volumes", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{ + ExpandVolumes: true, + }).WithQueryBuilder(query.Match("address", "account:1")))) + require.NoError(t, err) + require.Len(t, accounts.Data, 1) + require.Equal(t, ledger.VolumesByAssets{ + "USD": ledger.NewVolumesInt64(200, 50), + }, accounts.Data[0].Volumes) + }) + + t.Run("list with volumes using PIT", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{ + PITFilter: ledgerstore.PITFilter{ + PIT: &now, + }, + ExpandVolumes: true, + }).WithQueryBuilder(query.Match("address", "account:1")))) + require.NoError(t, err) + require.Len(t, accounts.Data, 1) + require.Equal(t, ledger.VolumesByAssets{ + "USD": ledger.NewVolumesInt64(100, 0), + }, accounts.Data[0].Volumes) + }) + + t.Run("list with effective volumes", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{ + ExpandEffectiveVolumes: true, + }).WithQueryBuilder(query.Match("address", "account:1")))) + require.NoError(t, err) + require.Len(t, accounts.Data, 1) + require.Equal(t, ledger.VolumesByAssets{ + "USD": ledger.NewVolumesInt64(200, 50), + }, accounts.Data[0].EffectiveVolumes) + }) + + t.Run("list with effective volumes using PIT", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{ + PITFilter: ledgerstore.PITFilter{ + PIT: &now, + }, + ExpandEffectiveVolumes: true, + }).WithQueryBuilder(query.Match("address", "account:1")))) + require.NoError(t, err) + require.Len(t, accounts.Data, 1) + require.Equal(t, ledger.VolumesByAssets{ + "USD": ledger.NewVolumesInt64(100, 0), + }, accounts.Data[0].EffectiveVolumes) + }) + + t.Run("list using filter on address", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("address", "account:")), + )) + require.NoError(t, err) + require.Len(t, accounts.Data, 3) + }) + t.Run("list using filter on multiple address", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder( + query.Or( + query.Match("address", "account:1"), + query.Match("address", "orders:"), + ), + ), + )) + require.NoError(t, err) + require.Len(t, accounts.Data, 3) + }) + t.Run("list using filter on balances", func(t *testing.T) { + accounts, err := store.GetAccountsWithVolumes(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Lt("balance[USD]", 0)), + )) + require.NoError(t, err) + require.Len(t, accounts.Data, 1) // world + }) +} + +func TestUpdateAccountsMetadata(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + + metadata := metadata.Metadata{ + "foo": "bar", + } + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.NewSetMetadataOnAccountLog(ledger.Now(), "bank", metadata).ChainLog(nil), + ), "account insertion should not fail") + + account, err := store.GetAccountWithVolumes(context.Background(), ledgerstore.NewGetAccountQuery("bank")) + require.NoError(t, err, "account retrieval should not fail") + + require.Equal(t, "bank", account.Address, "account address should match") + require.Equal(t, metadata, account.Metadata, "account metadata should match") +} + +func TestGetAccount(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.ChainLogs( + ledger.NewTransactionLog(ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "multi", "USD/2", big.NewInt(100)), + ).WithDate(now), map[string]metadata.Metadata{}), + ledger.NewSetMetadataLog(now.Add(time.Minute), ledger.SetMetadataLogPayload{ + TargetType: ledger.MetaTargetTypeAccount, + TargetID: "multi", + Metadata: metadata.Metadata{ + "category": "gold", + }, + }), + )..., + )) + + t.Run("find account", func(t *testing.T) { + account, err := store.GetAccountWithVolumes(context.Background(), ledgerstore.NewGetAccountQuery("multi")) + require.NoError(t, err) + require.Equal(t, ledger.ExpandedAccount{ + Account: ledger.Account{ + Address: "multi", + Metadata: metadata.Metadata{ + "category": "gold", + }, + }, + }, *account) + }) + + t.Run("find account with volumes", func(t *testing.T) { + account, err := store.GetAccountWithVolumes(context.Background(), ledgerstore.NewGetAccountQuery("multi"). + WithExpandVolumes()) + require.NoError(t, err) + require.Equal(t, ledger.ExpandedAccount{ + Account: ledger.Account{ + Address: "multi", + Metadata: metadata.Metadata{ + "category": "gold", + }, + }, + Volumes: ledger.VolumesByAssets{ + "USD/2": ledger.NewVolumesInt64(100, 0), + }, + }, *account) + }) + + t.Run("find account with effective volumes", func(t *testing.T) { + account, err := store.GetAccountWithVolumes(context.Background(), ledgerstore.NewGetAccountQuery("multi"). + WithExpandEffectiveVolumes()) + require.NoError(t, err) + require.Equal(t, ledger.ExpandedAccount{ + Account: ledger.Account{ + Address: "multi", + Metadata: metadata.Metadata{ + "category": "gold", + }, + }, + EffectiveVolumes: ledger.VolumesByAssets{ + "USD/2": ledger.NewVolumesInt64(100, 0), + }, + }, *account) + }) + + t.Run("find account using pit", func(t *testing.T) { + account, err := store.GetAccountWithVolumes(context.Background(), ledgerstore.NewGetAccountQuery("multi").WithPIT(now)) + require.NoError(t, err) + require.Equal(t, ledger.ExpandedAccount{ + Account: ledger.Account{ + Address: "multi", + Metadata: metadata.Metadata{}, + }, + Volumes: ledger.VolumesByAssets{}, + }, *account) + }) + + t.Run("not existent account", func(t *testing.T) { + account, err := store.GetAccountWithVolumes(context.Background(), ledgerstore.NewGetAccountQuery("account_not_existing")) + require.NoError(t, err) + require.NotNil(t, account) + }) +} + +func TestGetAccountWithVolumes(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + + require.NoError(t, insertTransactions(context.Background(), store, + *ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "multi", "USD/2", big.NewInt(100)), + ), + )) + + accountWithVolumes, err := store.GetAccountWithVolumes(context.Background(), + ledgerstore.NewGetAccountQuery("multi").WithExpandVolumes()) + require.NoError(t, err) + require.Equal(t, &ledger.ExpandedAccount{ + Account: ledger.Account{ + Address: "multi", + Metadata: metadata.Metadata{}, + }, + Volumes: map[string]*ledger.Volumes{ + "USD/2": ledger.NewEmptyVolumes().WithInputInt64(100), + }, + }, accountWithVolumes) +} + +func TestUpdateAccountMetadata(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.NewSetMetadataOnAccountLog(ledger.Now(), "central_bank", metadata.Metadata{ + "foo": "bar", + }).ChainLog(nil), + )) + + account, err := store.GetAccountWithVolumes(context.Background(), ledgerstore.NewGetAccountQuery("central_bank")) + require.NoError(t, err) + require.EqualValues(t, "bar", account.Metadata["foo"]) +} + +func TestCountAccounts(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + + require.NoError(t, insertTransactions(context.Background(), store, + *ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "central_bank", "USD/2", big.NewInt(100)), + ), + )) + + countAccounts, err := store.CountAccounts(context.Background(), ledgerstore.NewGetAccountsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}))) + require.NoError(t, err) + require.EqualValues(t, 2, countAccounts) // world + central_bank +} diff --git a/components/ledger/internal/storage/ledgerstore/balances.go b/components/ledger/internal/storage/ledgerstore/balances.go new file mode 100644 index 000000000..068e477b1 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/balances.go @@ -0,0 +1,84 @@ +package ledgerstore + +import ( + "context" + "errors" + "fmt" + "math/big" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + "github.com/uptrace/bun" +) + +// todo: should return a cursor? +func (store *Store) GetAggregatedBalances(ctx context.Context, q *GetAggregatedBalanceQuery) (ledger.BalancesByAssets, error) { + + type Temp struct { + Aggregated ledger.VolumesByAssets `bun:"aggregated,type:jsonb"` + } + return fetchAndMap[*Temp, ledger.BalancesByAssets](store, ctx, + func(temp *Temp) ledger.BalancesByAssets { + return temp.Aggregated.Balances() + }, + func(selectQuery *bun.SelectQuery) *bun.SelectQuery { + moves := store.db. + NewSelect(). + Table(MovesTableName). + ColumnExpr("distinct on (moves.account_address, moves.asset) moves.*"). + Order("account_address", "asset", "moves.seq desc"). + Apply(filterPIT(q.Options.Options.PIT, "insertion_date")) // todo(gfyrag): expose capability to use effective_date + + if q.Options.QueryBuilder != nil { + subQuery, args, err := q.Options.QueryBuilder.Build(query.ContextFn(func(key, operator string, value any) (string, []any, error) { + switch { + case key == "address": + // TODO: Should allow comparison operator only if segments not used + if operator != "$match" { + return "", nil, errors.New("'address' column can only be used with $match") + } + switch address := value.(type) { + case string: + return filterAccountAddress(address, "account_address"), nil, nil + default: + return "", nil, fmt.Errorf("unexpected type %T for column 'address'", address) + } + default: + return "", nil, fmt.Errorf("unknown key '%s' when building query", key) + } + })) + if err != nil { + panic(err) + } + moves = moves.Where(subQuery, args...) + } + + return selectQuery. + With("moves", moves). + TableExpr("moves"). + ColumnExpr("volumes_to_jsonb((moves.asset, (sum((moves.post_commit_volumes).inputs), sum((moves.post_commit_volumes).outputs))::volumes)) as aggregated"). + Group("moves.asset") + }) +} + +func (store *Store) GetBalance(ctx context.Context, address, asset string) (*big.Int, error) { + type Temp struct { + Balance *big.Int `bun:"balance,type:numeric"` + } + return fetchAndMap[*Temp, *big.Int](store, ctx, func(temp *Temp) *big.Int { + return temp.Balance + }, func(query *bun.SelectQuery) *bun.SelectQuery { + return query.TableExpr("get_account_balance(?, ?) as balance", address, asset) + }) +} + +type GetAggregatedBalanceQuery paginate.OffsetPaginatedQuery[PaginatedQueryOptions[PITFilter]] + +func NewGetAggregatedBalancesQuery(options PaginatedQueryOptions[PITFilter]) *GetAggregatedBalanceQuery { + return &GetAggregatedBalanceQuery{ + PageSize: options.PageSize, + Order: paginate.OrderAsc, + Options: options, + } +} diff --git a/components/ledger/internal/storage/ledgerstore/balances_test.go b/components/ledger/internal/storage/ledgerstore/balances_test.go new file mode 100644 index 000000000..5de91a529 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/balances_test.go @@ -0,0 +1,67 @@ +package ledgerstore_test + +import ( + "context" + "math/big" + "testing" + "time" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/query" + internaltesting "github.com/formancehq/ledger/internal/testing" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/stretchr/testify/require" +) + +func TestGetBalancesAggregated(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "users:1", "USD", big.NewInt(1)), + ledger.NewPosting("world", "users:2", "USD", big.NewInt(199)), + ).WithDate(now) + + tx2 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "users:1", "USD", big.NewInt(1)), + ledger.NewPosting("world", "users:2", "USD", big.NewInt(199)), + ).WithDate(now.Add(time.Minute)).WithIDUint64(1) + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.ChainLogs( + ledger.NewTransactionLog(tx1, map[string]metadata.Metadata{}).WithDate(tx1.Timestamp), + ledger.NewTransactionLog(tx2, map[string]metadata.Metadata{}).WithDate(tx2.Timestamp), + )...)) + + t.Run("aggregate on all", func(t *testing.T) { + q := ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilter{}).WithPageSize(10) + cursor, err := store.GetAggregatedBalances(context.Background(), ledgerstore.NewGetAggregatedBalancesQuery(q)) + require.NoError(t, err) + internaltesting.RequireEqual(t, ledger.BalancesByAssets{ + "USD": big.NewInt(0), + }, cursor) + }) + t.Run("filter on address", func(t *testing.T) { + ret, err := store.GetAggregatedBalances(context.Background(), ledgerstore.NewGetAggregatedBalancesQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilter{}). + WithQueryBuilder(query.Match("address", "users:")). + WithPageSize(10), + )) + require.NoError(t, err) + require.Equal(t, ledger.BalancesByAssets{ + "USD": big.NewInt(400), + }, ret) + }) + t.Run("using pit", func(t *testing.T) { + ret, err := store.GetAggregatedBalances(context.Background(), ledgerstore.NewGetAggregatedBalancesQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilter{ + PIT: &now, + }). + WithQueryBuilder(query.Match("address", "users:")). + WithPageSize(10))) + require.NoError(t, err) + require.Equal(t, ledger.BalancesByAssets{ + "USD": big.NewInt(200), + }, ret) + }) +} diff --git a/components/ledger/internal/storage/ledgerstore/logs.go b/components/ledger/internal/storage/ledgerstore/logs.go new file mode 100644 index 000000000..253a7d561 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/logs.go @@ -0,0 +1,172 @@ +package ledgerstore + +import ( + "context" + "database/sql/driver" + "encoding/json" + "fmt" + "math/big" + + ledger "github.com/formancehq/ledger/internal" + storageerrors "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/lib/pq" + "github.com/pkg/errors" + "github.com/uptrace/bun" +) + +const ( + LogTableName = "logs" +) + +type Logs struct { + bun.BaseModel `bun:"logs,alias:logs"` + + ID *paginate.BigInt `bun:"id,unique,type:numeric"` + Type string `bun:"type,type:log_type"` + Hash []byte `bun:"hash,type:bytea"` + Date ledger.Time `bun:"date,type:timestamptz"` + Data []byte `bun:"data,type:jsonb"` + IdempotencyKey string `bun:"idempotency_key,type:varchar(256),unique"` +} + +func (log *Logs) ToCore() *ledger.ChainedLog { + payload, err := ledger.HydrateLog(ledger.LogTypeFromString(log.Type), log.Data) + if err != nil { + panic(errors.Wrap(err, "hydrating log data")) + } + + return &ledger.ChainedLog{ + Log: ledger.Log{ + Type: ledger.LogTypeFromString(log.Type), + Data: payload, + Date: log.Date.UTC(), + IdempotencyKey: log.IdempotencyKey, + }, + ID: (*big.Int)(log.ID), + Hash: log.Hash, + } +} + +type RawMessage json.RawMessage + +func (j RawMessage) Value() (driver.Value, error) { + if j == nil { + return nil, nil + } + return string(j), nil +} + +func (store *Store) logsQueryBuilder(q PaginatedQueryOptions[any]) func(*bun.SelectQuery) *bun.SelectQuery { + return func(selectQuery *bun.SelectQuery) *bun.SelectQuery { + selectQuery = selectQuery.Table(LogTableName) + + if q.QueryBuilder != nil { + subQuery, args, err := q.QueryBuilder.Build(query.ContextFn(func(key, operator string, value any) (string, []any, error) { + switch { + case key == "date": + return fmt.Sprintf("%s %s ?", key, query.DefaultComparisonOperatorsMapping[operator]), []any{value}, nil + default: + return "", nil, fmt.Errorf("unknown key '%s' when building query", key) + } + })) + if err != nil { + panic(err) + } + selectQuery = selectQuery.Where(subQuery, args...) + } + + return selectQuery + } +} + +func (store *Store) InsertLogs(ctx context.Context, activeLogs ...*ledger.ChainedLog) error { + return store.withTransaction(ctx, func(tx bun.Tx) error { + // Beware: COPY query is not supported by bun if the pgx driver is used. + stmt, err := tx.Prepare(pq.CopyInSchema( + store.name, + LogTableName, + "id", "type", "hash", "date", "data", "idempotency_key", + )) + if err != nil { + return storageerrors.PostgresError(err) + } + + ls := make([]Logs, len(activeLogs)) + for i, chainedLogs := range activeLogs { + data, err := json.Marshal(chainedLogs.Data) + if err != nil { + return errors.Wrap(err, "marshaling log data") + } + + ls[i] = Logs{ + ID: (*paginate.BigInt)(chainedLogs.ID), + Type: chainedLogs.Type.String(), + Hash: chainedLogs.Hash, + Date: chainedLogs.Date, + Data: data, + IdempotencyKey: chainedLogs.IdempotencyKey, + } + + _, err = stmt.Exec(ls[i].ID, ls[i].Type, ls[i].Hash, ls[i].Date, RawMessage(ls[i].Data), chainedLogs.IdempotencyKey) + if err != nil { + return storageerrors.PostgresError(err) + } + } + + _, err = stmt.Exec() + if err != nil { + return storageerrors.PostgresError(err) + } + + return stmt.Close() + }) +} + +func (store *Store) GetLastLog(ctx context.Context) (*ledger.ChainedLog, error) { + return fetchAndMap[*Logs, *ledger.ChainedLog](store, ctx, (*Logs).ToCore, + func(query *bun.SelectQuery) *bun.SelectQuery { + return query. + Table(LogTableName). + OrderExpr("id desc"). + Limit(1) + }) +} + +func (store *Store) GetLogs(ctx context.Context, q *GetLogsQuery) (*api.Cursor[ledger.ChainedLog], error) { + logs, err := paginateWithColumn[PaginatedQueryOptions[any], Logs](store, ctx, + (*paginate.ColumnPaginatedQuery[PaginatedQueryOptions[any]])(q), + store.logsQueryBuilder(q.Options), + ) + if err != nil { + return nil, err + } + + return api.MapCursor(logs, func(from Logs) ledger.ChainedLog { + return *from.ToCore() + }), nil +} + +func (store *Store) ReadLogWithIdempotencyKey(ctx context.Context, key string) (*ledger.ChainedLog, error) { + return fetchAndMap[*Logs, *ledger.ChainedLog](store, ctx, (*Logs).ToCore, + func(query *bun.SelectQuery) *bun.SelectQuery { + return query. + Table(LogTableName). + OrderExpr("id desc"). + Limit(1). + Where("idempotency_key = ?", key) + }) +} + +type GetLogsQuery paginate.ColumnPaginatedQuery[PaginatedQueryOptions[any]] + +func NewGetLogsQuery(options PaginatedQueryOptions[any]) *GetLogsQuery { + return &GetLogsQuery{ + PageSize: options.PageSize, + Column: "id", + Order: paginate.OrderDesc, + Options: options, + } +} diff --git a/components/ledger/internal/storage/ledgerstore/logs_test.go b/components/ledger/internal/storage/ledgerstore/logs_test.go new file mode 100644 index 000000000..f9dfaf6e9 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/logs_test.go @@ -0,0 +1,321 @@ +package ledgerstore_test + +import ( + "context" + "fmt" + "math/big" + "testing" + "time" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/stretchr/testify/require" +) + +func TestGetLastLog(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + lastLog, err := store.GetLastLog(context.Background()) + require.True(t, storage.IsNotFoundError(err)) + require.Nil(t, lastLog) + tx1 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(0), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "world", + Destination: "central_bank", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Reference: "tx1", + Timestamp: now.Add(-3 * time.Hour), + }, + }, + PostCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(100), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(100), + Output: big.NewInt(0), + }, + }, + }, + PreCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(0), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(0), + }, + }, + }, + } + + logTx := ledger.NewTransactionLog(&tx1.Transaction, map[string]metadata.Metadata{}).ChainLog(nil) + appendLog(t, store, logTx) + + lastLog, err = store.GetLastLog(context.Background()) + require.NoError(t, err) + require.NotNil(t, lastLog) + + require.Equal(t, tx1.Postings, lastLog.Data.(ledger.NewTransactionLogPayload).Transaction.Postings) + require.Equal(t, tx1.Reference, lastLog.Data.(ledger.NewTransactionLogPayload).Transaction.Reference) + require.Equal(t, tx1.Timestamp, lastLog.Data.(ledger.NewTransactionLogPayload).Transaction.Timestamp) +} + +func TestReadLogWithIdempotencyKey(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + + logTx := ledger.NewTransactionLog( + ledger.NewTransaction(). + WithPostings( + ledger.NewPosting("world", "bank", "USD", big.NewInt(100)), + ), + map[string]metadata.Metadata{}, + ) + log := logTx.WithIdempotencyKey("test") + + ret := appendLog(t, store, log.ChainLog(nil)) + + lastLog, err := store.ReadLogWithIdempotencyKey(context.Background(), "test") + require.NoError(t, err) + require.NotNil(t, lastLog) + require.Equal(t, *ret, *lastLog) +} + +func TestGetLogs(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(0), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "world", + Destination: "central_bank", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Reference: "tx1", + Timestamp: now.Add(-3 * time.Hour), + }, + }, + PostCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(100), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(100), + Output: big.NewInt(0), + }, + }, + }, + PreCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(0), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(0), + }, + }, + }, + } + tx2 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(1), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "world", + Destination: "central_bank", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Reference: "tx2", + Timestamp: now.Add(-2 * time.Hour), + }, + }, + PostCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(200), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(200), + Output: big.NewInt(0), + }, + }, + }, + PreCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(100), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(100), + Output: big.NewInt(0), + }, + }, + }, + } + tx3 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(2), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "central_bank", + Destination: "users:1", + Amount: big.NewInt(1), + Asset: "USD", + }, + }, + Reference: "tx3", + Metadata: metadata.Metadata{ + "priority": "high", + }, + Timestamp: now.Add(-1 * time.Hour), + }, + }, + PreCommitVolumes: ledger.AccountsAssetsVolumes{ + "central_bank": { + "USD": { + Input: big.NewInt(200), + Output: big.NewInt(0), + }, + }, + "users:1": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(0), + }, + }, + }, + PostCommitVolumes: ledger.AccountsAssetsVolumes{ + "central_bank": { + "USD": { + Input: big.NewInt(200), + Output: big.NewInt(1), + }, + }, + "users:1": { + "USD": { + Input: big.NewInt(1), + Output: big.NewInt(0), + }, + }, + }, + } + + var previousLog *ledger.ChainedLog + for _, tx := range []ledger.ExpandedTransaction{tx1, tx2, tx3} { + newLog := ledger.NewTransactionLog(&tx.Transaction, map[string]metadata.Metadata{}). + WithDate(tx.Timestamp). + ChainLog(previousLog) + appendLog(t, store, newLog) + previousLog = newLog + } + + cursor, err := store.GetLogs(context.Background(), ledgerstore.NewGetLogsQuery(ledgerstore.NewPaginatedQueryOptions[any](nil))) + require.NoError(t, err) + require.Equal(t, paginate.QueryDefaultPageSize, cursor.PageSize) + + require.Equal(t, 3, len(cursor.Data)) + require.Equal(t, big.NewInt(2), cursor.Data[0].ID) + require.Equal(t, tx3.Postings, cursor.Data[0].Data.(ledger.NewTransactionLogPayload).Transaction.Postings) + require.Equal(t, tx3.Reference, cursor.Data[0].Data.(ledger.NewTransactionLogPayload).Transaction.Reference) + require.Equal(t, tx3.Timestamp, cursor.Data[0].Data.(ledger.NewTransactionLogPayload).Transaction.Timestamp) + + cursor, err = store.GetLogs(context.Background(), ledgerstore.NewGetLogsQuery(ledgerstore.NewPaginatedQueryOptions[any](nil).WithPageSize(1))) + require.NoError(t, err) + // Should get only the first log. + require.Equal(t, 1, cursor.PageSize) + require.Equal(t, big.NewInt(2), cursor.Data[0].ID) + + cursor, err = store.GetLogs(context.Background(), ledgerstore.NewGetLogsQuery(ledgerstore.NewPaginatedQueryOptions[any](nil). + WithQueryBuilder(query.And( + query.Gte("date", now.Add(-2*time.Hour)), + query.Lt("date", now.Add(-time.Hour)), + )). + WithPageSize(10), + )) + require.NoError(t, err) + require.Equal(t, 10, cursor.PageSize) + // Should get only the second log, as StartTime is inclusive and EndTime exclusive. + require.Len(t, cursor.Data, 1) + require.Equal(t, big.NewInt(1), cursor.Data[0].ID) +} + +func TestGetBalance(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + + const ( + batchNumber = 100 + batchSize = 10 + input = 100 + output = 10 + ) + + logs := make([]*ledger.ChainedLog, 0) + var previousLog *ledger.ChainedLog + for i := 0; i < batchNumber; i++ { + for j := 0; j < batchSize; j++ { + chainedLog := ledger.NewTransactionLog( + ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", fmt.Sprintf("account:%d", j), "EUR/2", big.NewInt(input)), + ledger.NewPosting(fmt.Sprintf("account:%d", j), "starbucks", "EUR/2", big.NewInt(output)), + ).WithIDUint64(uint64(i*batchSize+j)), + map[string]metadata.Metadata{}, + ).ChainLog(previousLog) + logs = append(logs, chainedLog) + previousLog = chainedLog + } + } + err := store.InsertLogs(context.Background(), logs...) + require.NoError(t, err) + + balance, err := store.GetBalance(context.Background(), "account:1", "EUR/2") + require.NoError(t, err) + require.Equal(t, big.NewInt((input-output)*batchNumber), balance) +} diff --git a/components/ledger/internal/storage/ledgerstore/main_test.go b/components/ledger/internal/storage/ledgerstore/main_test.go new file mode 100644 index 000000000..57be485d4 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/main_test.go @@ -0,0 +1,59 @@ +package ledgerstore_test + +import ( + "context" + "os" + "testing" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/driver" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/formancehq/stack/libs/go-libs/pgtesting" + "github.com/google/uuid" + "github.com/stretchr/testify/require" +) + +func TestMain(m *testing.M) { + if err := pgtesting.CreatePostgresServer(); err != nil { + logging.Error(err) + os.Exit(1) + } + + code := m.Run() + if err := pgtesting.DestroyPostgresServer(); err != nil { + logging.Error(err) + } + os.Exit(code) +} + +func newLedgerStore(t *testing.T) *ledgerstore.Store { + t.Helper() + + pgServer := pgtesting.NewPostgresDatabase(t) + db, err := storage.OpenSQLDB(storage.ConnectionOptions{ + DatabaseSourceName: pgServer.ConnString(), + Debug: testing.Verbose(), + }, + //&explainHook{}, + ) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, db.Close()) + }) + + ctx := logging.TestingContext() + driver := driver.New(db) + require.NoError(t, driver.Initialize(ctx)) + ledgerStore, err := driver.CreateLedgerStore(ctx, uuid.NewString()) + require.NoError(t, err) + + return ledgerStore +} + +func appendLog(t *testing.T, store *ledgerstore.Store, log *ledger.ChainedLog) *ledger.ChainedLog { + err := store.InsertLogs(context.Background(), log) + require.NoError(t, err) + return log +} diff --git a/components/ledger/internal/storage/ledgerstore/migrations.go b/components/ledger/internal/storage/ledgerstore/migrations.go new file mode 100644 index 000000000..c1d89cd4d --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/migrations.go @@ -0,0 +1,89 @@ +package ledgerstore + +import ( + "context" + _ "embed" + "fmt" + + "github.com/formancehq/stack/libs/go-libs/migrations" + "github.com/pkg/errors" + "github.com/uptrace/bun" +) + +func (store *Store) getMigrator() *migrations.Migrator { + migrator := migrations.NewMigrator(migrations.WithSchema(store.Name(), true)) + registerMigrations(migrator, store.name) + return migrator +} + +func (store *Store) Migrate(ctx context.Context) (bool, error) { + migrator := store.getMigrator() + + if err := migrator.Up(ctx, store.db); err != nil { + return false, err + } + + // TODO: Update migrations package to return modifications + return false, nil +} + +func (store *Store) GetMigrationsInfo(ctx context.Context) ([]migrations.Info, error) { + return store.getMigrator().GetMigrations(ctx, store.db) +} + +//go:embed migrations/0-init-schema.sql +var initSchema string + +func registerMigrations(migrator *migrations.Migrator, name string) { + migrator.RegisterMigrations( + migrations.Migration{ + Name: "Init schema", + UpWithContext: func(ctx context.Context, tx bun.Tx) error { + + needV1Upgrade := false + row := tx.QueryRowContext(ctx, `select exists ( + select from pg_tables + where schemaname = ? and tablename = 'log' + )`, name) + if row.Err() != nil { + return row.Err() + } + var ret string + if err := row.Scan(&ret); err != nil { + panic(err) + } + needV1Upgrade = ret != "false" + + oldSchemaRenamed := fmt.Sprintf(name + oldSchemaRenameSuffix) + if needV1Upgrade { + _, err := tx.ExecContext(ctx, fmt.Sprintf(`alter schema "%s" rename to "%s"`, name, oldSchemaRenamed)) + if err != nil { + return errors.Wrap(err, "renaming old schema") + } + _, err = tx.ExecContext(ctx, fmt.Sprintf(`create schema if not exists "%s"`, name)) + if err != nil { + return errors.Wrap(err, "creating new schema") + } + } + + _, err := tx.ExecContext(ctx, initSchema) + if err != nil { + return errors.Wrap(err, "initializing new schema") + } + + if needV1Upgrade { + if err := migrateLogs(ctx, oldSchemaRenamed, name, tx); err != nil { + return errors.Wrap(err, "migrating logs") + } + + _, err = tx.ExecContext(ctx, fmt.Sprintf(`create table goose_db_version as table "%s".goose_db_version with no data`, oldSchemaRenamed)) + if err != nil { + return err + } + } + + return nil + }, + }, + ) +} diff --git a/components/ledger/internal/storage/ledgerstore/migrations/0-init-schema.sql b/components/ledger/internal/storage/ledgerstore/migrations/0-init-schema.sql new file mode 100644 index 000000000..6d03402ba --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/migrations/0-init-schema.sql @@ -0,0 +1,611 @@ +/** + Some utils + */ +create aggregate aggregate_objects(jsonb) ( + sfunc = jsonb_concat, + stype = jsonb, + initcond = '{}' +); + +create function first_agg (anyelement, anyelement) + returns anyelement + language sql + immutable + strict + parallel safe +as $$ + select $1 +$$; + +create aggregate first (anyelement) ( + sfunc = first_agg, + stype = anyelement, + parallel = safe +); + +create function array_distinct(anyarray) + returns anyarray + language sql + immutable +as $$ + select array_agg(distinct x) + from unnest($1) t(x); +$$; + +/** Define types **/ +create type account_with_volumes as ( + address varchar, + metadata jsonb, + volumes jsonb +); + +create type volumes as ( + inputs numeric, + outputs numeric +); + +create type volumes_with_asset as ( + asset varchar, + volumes volumes +); + +/** Define tables **/ +create table transactions ( + id numeric not null primary key, + timestamp timestamp without time zone not null, + reference varchar, + reverted_at timestamp without time zone, + postings varchar not null +); + +create table transactions_metadata ( + transaction_id numeric not null references transactions(id), + revision numeric default 0 not null, + date timestamp not null, + metadata jsonb not null default '{}'::jsonb, + + primary key (transaction_id, revision) +); + +create table accounts ( + address varchar primary key, + address_array jsonb not null, + insertion_date timestamp not null +); + +create table accounts_metadata ( + address varchar references accounts(address), + metadata jsonb default '{}'::jsonb, + revision numeric default 0, + date timestamp +); + +create table moves ( + seq serial not null primary key , + transaction_id numeric not null references transactions(id), + account_address varchar not null, + account_address_array jsonb not null, + asset varchar not null, + amount numeric not null, + insertion_date timestamp not null, + effective_date timestamp not null, + post_commit_volumes volumes not null, + post_commit_effective_volumes volumes default null, + is_source boolean not null +); + +create type log_type as enum ( + 'NEW_TRANSACTION', + 'REVERTED_TRANSACTION', + 'SET_METADATA', + 'DELETE_METADATA' +); + +create table logs ( + id numeric not null primary key, + type log_type not null, + hash bytea not null, + date timestamp not null, + data jsonb not null, + idempotency_key varchar(255) +); + +/** Define index **/ + +create function balance_from_volumes(v volumes) + returns numeric + language sql + immutable +as $$ + select v.inputs - v.outputs +$$; + +/** Index required for write part */ +create index moves_range_dates on moves (account_address, asset, effective_date); + +/** Index requires for read */ +create index transactions_date on transactions (timestamp); +create index transactions_metadata_metadata on transactions_metadata using gin (metadata); +--create unique index transactions_revisions on transactions_metadata(id desc, revision desc); + +create index moves_account_address on moves (account_address); +create index moves_account_address_array on moves using gin (account_address_array jsonb_ops); +create index moves_account_address_array_length on moves (jsonb_array_length(account_address_array)); +create index moves_date on moves (effective_date); +create index moves_asset on moves (asset); +create index moves_balance on moves (balance_from_volumes(post_commit_volumes)); +create index moves_post_commit_volumes on moves(account_address, asset, seq); +create index moves_effective_post_commit_volumes on moves(account_address, asset, effective_date desc, seq desc); +create index moves_transactions_id on moves (transaction_id); + +create index accounts_address_array on accounts using gin (address_array jsonb_ops); +create index accounts_address_array_length on accounts (jsonb_array_length(address_array)); + +create unique index accounts_metadata_revisions on accounts_metadata(address asc, revision desc); + +/** Define write functions **/ +create function insert_new_account(_address varchar, _date timestamp) + returns bool + language plpgsql +as $$ + declare + _account accounts; + begin + insert into accounts(address, address_array, insertion_date) + values (_address, to_json(string_to_array(_address, ':')), _date) + on conflict do nothing + returning * into _account; + + return _account is not null; + end; +$$; + +create function get_account(_account_address varchar, _before timestamp default null) + returns setof accounts_metadata + language sql + stable +as $$ + select distinct on (address) * + from accounts_metadata t + where (_before is null or t.date <= _before) + and t.address = _account_address + order by address, revision desc + limit 1; +$$; + +create function get_transaction(_id numeric, _before timestamp default null) + returns setof transactions + language sql + stable +as $$ + select * + from transactions t + where (_before is null or t.timestamp <= _before) and t.id = _id + order by id desc + limit 1; +$$; + +-- a simple 'select distinct asset from moves' would be more simple +-- but Postgres is extremely inefficient with distinct +-- so the query implementation use a "hack" to emulate skip scan feature which Postgres lack natively +-- see https://wiki.postgresql.org/wiki/Loose_indexscan for more information +create function get_all_assets() + returns setof varchar + language sql +as $$ + with recursive t as ( + select min(asset) as asset + from moves + union all + select ( + select min(asset) + from moves + where asset > t.asset + ) + from t + where t.asset is not null + ) + select asset from t where asset is not null + union all + select null where exists(select 1 from moves where asset is null) +$$; + +create function get_latest_move_for_account_and_asset(_account_address varchar, _asset varchar, _before timestamp default null) + returns setof moves + language sql + stable +as $$ + select * + from moves s + where (_before is null or s.effective_date <= _before) and s.account_address = _account_address and s.asset = _asset + order by effective_date desc, seq desc + limit 1; +$$; + +create function update_account_metadata(_address varchar, _metadata jsonb, _date timestamp) + returns void + language sql +as $$ + select insert_new_account(_address, _date); + + insert into accounts_metadata (address, metadata, date, revision) + ( + select _address, accounts_metadata.metadata || _metadata, _date, accounts_metadata.revision + 1 + from accounts_metadata + where address = _address + order by revision desc + limit 1 + ) + union all -- if no metdata + select _address, _metadata, _date, 0 + limit 1; +$$; + +create function delete_account_metadata(_address varchar, _key varchar, _date timestamp) + returns void + language sql +as $$ + insert into accounts_metadata (address, metadata, date, revision) + select _address, accounts_metadata.metadata - _key, _date, accounts_metadata.revision + 1 + from accounts_metadata + where address = _address + order by revision desc + limit 1 +$$; + +create function update_transaction_metadata(_id numeric, _metadata jsonb, _date timestamp) + returns void + language sql +as $$ + insert into transactions_metadata (transaction_id, metadata, date, revision) + ( + select originalTX.transaction_id, + originalTX.metadata || _metadata, + _date, + originalTX.revision + 1 + from transactions_metadata originalTX + where transaction_id = _id + order by revision desc + limit 1 + ) + union all ( + select _id, '{}'::jsonb, null, -1 + ) + limit 1 +$$; + +create function delete_transaction_metadata(_id numeric, _key varchar, _date timestamp) + returns void + language sql +as $$ + insert into transactions_metadata (transaction_id, metadata, date, revision) + select originalTX.transaction_id, + originalTX.metadata - _key, + _date, + originalTX.revision + 1 + from transactions_metadata originalTX + where transaction_id = _id + order by revision desc + limit 1; +$$; + +create function revert_transaction(_id numeric, _date timestamp) + returns void + language sql +as $$ + update transactions + set reverted_at = _date + where id = _id; +$$; + +create or replace function insert_move(_transaction_id numeric, _insertion_date timestamp without time zone, + _effective_date timestamp without time zone, _account_address varchar, _asset varchar, _amount numeric, _is_source bool, _new_account bool) + returns void + language plpgsql +as $$ + declare + _post_commit_volumes volumes = (0, 0)::volumes; + _effective_post_commit_volumes volumes = (0, 0)::volumes; + _seq numeric; + begin + + -- todo: lock if we enable parallelism + -- perform * + -- from accounts + -- where address = _account_address + -- for update; + + if not _new_account then + select (post_commit_volumes).inputs, (post_commit_volumes).outputs into _post_commit_volumes + from moves + where account_address = _account_address + and asset = _asset + order by seq desc + limit 1; + + if not found then + _post_commit_volumes = (0, 0)::volumes; + _effective_post_commit_volumes = (0, 0)::volumes; + else + select (post_commit_effective_volumes).inputs, (post_commit_effective_volumes).outputs into _effective_post_commit_volumes + from moves + where account_address = _account_address + and asset = _asset and effective_date <= _effective_date + order by effective_date desc, seq desc + limit 1; + end if; + end if; + + if _is_source then + _post_commit_volumes.outputs = _post_commit_volumes.outputs + _amount; + _effective_post_commit_volumes.outputs = _effective_post_commit_volumes.outputs + _amount; + else + _post_commit_volumes.inputs = _post_commit_volumes.inputs + _amount; + _effective_post_commit_volumes.inputs = _effective_post_commit_volumes.inputs + _amount; + end if; + + insert into moves ( + insertion_date, + effective_date, + account_address, + asset, + transaction_id, + amount, + is_source, + account_address_array, + post_commit_volumes, + post_commit_effective_volumes + ) values (_insertion_date, _effective_date, _account_address, _asset, _transaction_id, + _amount, _is_source, (select to_json(string_to_array(_account_address, ':'))), + _post_commit_volumes, _effective_post_commit_volumes) + returning seq into _seq; + + if not _new_account then + update moves + set post_commit_effective_volumes = ( + (post_commit_effective_volumes).inputs + case when _is_source then 0 else _amount end, + (post_commit_effective_volumes).outputs + case when _is_source then _amount else 0 end + ) + where account_address = _account_address and asset = _asset and effective_date > _effective_date; + + update moves + set post_commit_effective_volumes = ( + (post_commit_effective_volumes).inputs + case when _is_source then 0 else _amount end, + (post_commit_effective_volumes).outputs + case when _is_source then _amount else 0 end + ) + where account_address = _account_address and asset = _asset and effective_date = _effective_date and seq > _seq; + end if; + end; +$$; + +create function insert_posting(_transaction_id numeric, _insertion_date timestamp without time zone, _effective_date timestamp without time zone, posting jsonb) + returns void + language plpgsql +as $$ + declare + source_created bool; + destination_created bool; + begin + select insert_new_account(posting->>'source', _insertion_date) into source_created; + select insert_new_account(posting->>'destination', _insertion_date) into destination_created; + + -- todo: sometimes the balance is known at commit time (for sources != world), we need to forward the value to populate the pre_commit_aggregated_input and output + perform insert_move(_transaction_id, _insertion_date, _effective_date, + posting->>'source', posting->>'asset', (posting->>'amount')::numeric, true, source_created); + perform insert_move(_transaction_id, _insertion_date, _effective_date, + posting->>'destination', posting->>'asset', (posting->>'amount')::numeric, false, destination_created); + end; +$$; + +-- todo: maybe we could avoid plpgsql functions +create function insert_transaction(data jsonb, _date timestamp without time zone) + returns void + language plpgsql +as $$ + declare + posting jsonb; + begin + insert into transactions (id, timestamp, reference, postings) + values ((data->>'id')::numeric, + (data->>'timestamp')::timestamp without time zone, + data->>'reference', + jsonb_pretty(data->'postings')); + + for posting in (select jsonb_array_elements(data->'postings')) loop + -- todo: sometimes the balance is known at commit time (for sources != world), we need to forward the value to populate the pre_commit_aggregated_input and output + perform insert_posting((data->>'id')::numeric, _date, (data->>'timestamp')::timestamp without time zone, posting); + end loop; + + if data->'metadata' is not null and data->>'metadata' <> '()' then + insert into transactions_metadata (transaction_id, revision, date, metadata) values ( + (data->>'id')::numeric, + 0, + (data->>'timestamp')::timestamp without time zone, + coalesce(data->'metadata', '{}'::jsonb) + ); + end if; + end +$$; + +create function handle_log() returns trigger + security definer + language plpgsql +as $$ + declare + _key varchar; + _value jsonb; + begin + if new.type = 'NEW_TRANSACTION' then + perform insert_transaction(new.data->'transaction', new.date); + for _key, _value in (select * from jsonb_each_text(new.data->'accountMetadata')) loop + perform update_account_metadata(_key, _value, (new.data->'transaction'->>'timestamp')::timestamp); + end loop; + end if; + if new.type = 'REVERTED_TRANSACTION' then + perform insert_transaction(new.data->'transaction', new.date); + perform revert_transaction((new.data->>'revertedTransactionID')::numeric, (new.data->'transaction'->>'timestamp')::timestamp); + end if; + if new.type = 'SET_METADATA' then + if new.data->>'targetType' = 'TRANSACTION' then + perform update_transaction_metadata((new.data->>'targetId')::numeric, new.data->'metadata', new.date); + else + perform update_account_metadata((new.data->>'targetId')::varchar, new.data ->'metadata', new.date); + end if; + end if; + if new.type = 'DELETE_METADATA' then + if new.data->>'targetType' = 'TRANSACTION' then + perform delete_transaction_metadata((new.data->>'targetId')::numeric, new.data->>'key', new.date); + else + perform delete_account_metadata((new.data->>'targetId')::varchar, new.data ->>'key', new.date); + end if; + end if; + + return new; + end; +$$; + +/** Define the trigger which populate table in response to new logs **/ +create trigger insert_log after insert on logs + for each row execute procedure handle_log(); + +create or replace function get_all_account_effective_volumes(_account varchar, _before timestamp default null) + returns setof volumes_with_asset + language sql + stable +as $$ + with + all_assets as ( + select v.v as asset + from get_all_assets() v + ), + moves as ( + select m.* + from all_assets assets + join lateral ( + select * + from moves s + where (_before is null or s.effective_date <= _before) and s.account_address = _account and s.asset = assets.asset + order by effective_date desc, seq desc + limit 1 + ) m on true + ) + select moves.asset, moves.post_commit_effective_volumes + from moves +$$; + +create or replace function get_all_account_volumes(_account varchar, _before timestamp default null) + returns setof volumes_with_asset + language sql + stable +as $$ + with + all_assets as ( + select v.v as asset + from get_all_assets() v + ), + moves as ( + select m.* + from all_assets assets + join lateral ( + select * + from moves s + where (_before is null or s.insertion_date <= _before) and s.account_address = _account and s.asset = assets.asset + order by seq desc + limit 1 + ) m on true + ) + select moves.asset, moves.post_commit_volumes + from moves +$$; + +create function volumes_to_jsonb(v volumes_with_asset) + returns jsonb + language sql + immutable +as $$ + select ('{"' || v.asset || '": {"input": ' || (v.volumes).inputs || ', "output": ' || (v.volumes).outputs || '}}')::jsonb +$$; + +create function get_account_aggregated_effective_volumes(_account_address varchar, _before timestamp default null) + returns jsonb + language sql + stable +as $$ + select aggregate_objects(volumes_to_jsonb(volumes_with_asset)) + from get_all_account_effective_volumes(_account_address, _before := _before) volumes_with_asset +$$; + +create function get_account_aggregated_volumes(_account_address varchar, _before timestamp default null) + returns jsonb + language sql + stable + parallel safe +as $$ + select aggregate_objects(volumes_to_jsonb(volumes_with_asset)) + from get_all_account_volumes(_account_address, _before := _before) volumes_with_asset +$$; + +create function get_account_balance(_account varchar, _asset varchar, _before timestamp default null) + returns numeric + language sql + stable +as $$ + select (post_commit_volumes).inputs - (post_commit_volumes).outputs + from moves s + where (_before is null or s.effective_date <= _before) and s.account_address = _account and s.asset = _asset + order by seq desc + limit 1 +$$; + +create function aggregate_ledger_volumes( + _before timestamp default null, + _accounts varchar[] default null, + _assets varchar[] default null +) + returns setof volumes_with_asset + language sql + stable +as $$ + with + moves as ( + select distinct on (m.account_address, m.asset) m.* + from moves m + where (_before is null or m.effective_date <= _before) and + (_accounts is null or account_address = any(_accounts)) and + (_assets is null or asset = any(_assets)) + order by account_address, asset, m.seq desc + ) + select v.asset, (sum((v.post_commit_effective_volumes).inputs), sum((v.post_commit_effective_volumes).outputs)) + from moves v + group by v.asset +$$; + +create function get_aggregated_effective_volumes_for_transaction(tx transactions) returns jsonb + stable + language sql +as +$$ +select aggregate_objects(jsonb_build_object(data.account_address, data.aggregated)) +from ( + select distinct on (move.account_address, move.asset) move.account_address, + volumes_to_jsonb((move.asset, first(move.post_commit_effective_volumes))) as aggregated + from moves move + where move.transaction_id = tx.id + group by move.account_address, move.asset +) data +$$; + +create function get_aggregated_volumes_for_transaction(tx transactions) returns jsonb + stable + language sql +as +$$ +select aggregate_objects(jsonb_build_object(data.account_address, data.aggregated)) +from ( + select distinct on (move.account_address, move.asset) move.account_address, + volumes_to_jsonb((move.asset, first(move.post_commit_volumes))) as aggregated + from moves move + where move.transaction_id = tx.id + group by move.account_address, move.asset +) data +$$; diff --git a/components/ledger/internal/storage/ledgerstore/migrations_v1.go b/components/ledger/internal/storage/ledgerstore/migrations_v1.go new file mode 100644 index 000000000..bca7f14ba --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/migrations_v1.go @@ -0,0 +1,200 @@ +package ledgerstore + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/lib/pq" + "github.com/pkg/errors" + "github.com/uptrace/bun" +) + +var ( + batchSize uint64 = 10000 + oldSchemaRenameSuffix = "_save_v2_0_0" +) + +type LogV1 struct { + ID uint64 `bun:"id,unique,type:bigint"` + Type string `bun:"type,type:varchar"` + Hash string `bun:"hash,type:varchar"` + Date ledger.Time `bun:"date,type:timestamptz"` + Data json.RawMessage `bun:"data,type:jsonb"` +} + +func readLogsRange( + ctx context.Context, + schema string, + sqlTx bun.Tx, + idMin, idMax uint64, +) ([]LogV1, error) { + rawLogs := make([]LogV1, 0) + if err := sqlTx. + NewSelect(). + Table(fmt.Sprintf(`%s.log`, schema)). + Where("id >= ?", idMin). + Where("id < ?", idMax). + Scan(ctx, &rawLogs); err != nil { + return nil, err + } + + return rawLogs, nil +} + +func convertMetadata(ret map[string]any) map[string]any { + oldMetadata := ret["metadata"].(map[string]any) + newMetadata := make(map[string]string) + for k, v := range oldMetadata { + switch v := v.(type) { + case map[string]any: + if len(v) == 2 && v["type"] != nil && v["value"] != nil { + switch v["type"] { + case "asset", "string", "account": + newMetadata[k] = v["value"].(string) + case "monetary": + newMetadata[k] = fmt.Sprintf("%s %d", + v["value"].(map[string]any)["asset"].(string), + int(v["value"].(map[string]any)["amount"].(float64)), + ) + case "portion": + newMetadata[k] = v["value"].(map[string]any)["specific"].(string) + case "number": + newMetadata[k] = fmt.Sprint(v["value"]) + } + } else { + newMetadata[k] = fmt.Sprint(v) + } + default: + newMetadata[k] = fmt.Sprint(v) + } + } + ret["metadata"] = newMetadata + + return ret +} + +func convertTransaction(ret map[string]any) map[string]any { + ret = convertMetadata(ret) + ret["id"] = ret["txid"] + delete(ret, "txid") + + return ret +} + +func (l *LogV1) ToLogsV2() (Logs, error) { + logType := ledger.LogTypeFromString(l.Type) + + ret := make(map[string]any) + if err := json.Unmarshal(l.Data, &ret); err != nil { + panic(err) + } + + var data any + switch logType { + case ledger.NewTransactionLogType: + data = map[string]any{ + "transaction": convertTransaction(ret), + "accountMetadata": map[string]any{}, + } + case ledger.SetMetadataLogType: + data = convertMetadata(ret) + case ledger.RevertedTransactionLogType: + data = l.Data + default: + panic("unknown type " + logType.String()) + } + + asJson, err := json.Marshal(data) + if err != nil { + panic(err) + } + + return Logs{ + ID: (*paginate.BigInt)(big.NewInt(int64(l.ID))), + Type: logType.String(), + Hash: []byte(l.Hash), + Date: l.Date, + Data: asJson, + }, nil +} + +func batchLogs( + ctx context.Context, + schema string, + sqlTx bun.Tx, + logs []Logs, +) error { + // Beware: COPY query is not supported by bun if the pgx driver is used. + stmt, err := sqlTx.PrepareContext(ctx, pq.CopyInSchema( + schema, + "logs", + "id", "type", "hash", "date", "data", + )) + if err != nil { + return err + } + + for _, l := range logs { + _, err = stmt.ExecContext(ctx, l.ID, l.Type, l.Hash, l.Date, RawMessage(l.Data)) + if err != nil { + return err + } + } + + _, err = stmt.ExecContext(ctx) + if err != nil { + return err + } + + err = stmt.Close() + if err != nil { + return err + } + + return nil +} + +func migrateLogs( + ctx context.Context, + schemaV1Name string, + schemaV2Name string, + sqlTx bun.Tx, +) error { + + var idMin uint64 + var idMax = idMin + batchSize + for { + logs, err := readLogsRange(ctx, schemaV1Name, sqlTx, idMin, idMax) + if err != nil { + return errors.Wrap(err, "reading logs from old table") + } + + if len(logs) == 0 { + break + } + + logsV2 := make([]Logs, 0, len(logs)) + for _, l := range logs { + logV2, err := l.ToLogsV2() + if err != nil { + return err + } + + logsV2 = append(logsV2, logV2) + } + + err = batchLogs(ctx, schemaV2Name, sqlTx, logsV2) + if err != nil { + return err + } + + idMin = idMax + idMax = idMin + batchSize + } + + return nil +} diff --git a/components/ledger/internal/storage/ledgerstore/store.go b/components/ledger/internal/storage/ledgerstore/store.go new file mode 100644 index 000000000..9cc0f3583 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/store.go @@ -0,0 +1,77 @@ +package ledgerstore + +import ( + "context" + "database/sql" + "fmt" + + "github.com/formancehq/ledger/internal/storage" + _ "github.com/jackc/pgx/v5/stdlib" + "github.com/pkg/errors" + "github.com/uptrace/bun" +) + +type Store struct { + db *bun.DB + onDelete func(ctx context.Context) error + + isInitialized bool + name string +} + +func (store *Store) Name() string { + return store.name +} + +func (store *Store) GetDatabase() *bun.DB { + return store.db +} + +func (store *Store) Delete(ctx context.Context) error { + _, err := store.db.ExecContext(ctx, "delete schema ? cascade", store.name) + if err != nil { + return err + } + return errors.Wrap(store.onDelete(ctx), "deleting ledger store") +} + +func (store *Store) IsInitialized() bool { + return store.isInitialized +} + +func (store *Store) prepareTransaction(ctx context.Context) (bun.Tx, error) { + txOptions := &sql.TxOptions{} + + tx, err := store.db.BeginTx(ctx, txOptions) + if err != nil { + return tx, err + } + if _, err := tx.Exec(fmt.Sprintf(`set search_path = "%s"`, store.Name())); err != nil { + return tx, err + } + return tx, nil +} + +func (store *Store) withTransaction(ctx context.Context, callback func(tx bun.Tx) error) error { + tx, err := store.prepareTransaction(ctx) + if err != nil { + return err + } + if err := callback(tx); err != nil { + _ = tx.Rollback() + return storage.PostgresError(err) + } + return tx.Commit() +} + +func New( + db *bun.DB, + name string, + onDelete func(ctx context.Context) error, +) (*Store, error) { + return &Store{ + db: db, + name: name, + onDelete: onDelete, + }, nil +} diff --git a/components/ledger/internal/storage/ledgerstore/store_test.go b/components/ledger/internal/storage/ledgerstore/store_test.go new file mode 100644 index 000000000..a336af022 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/store_test.go @@ -0,0 +1,35 @@ +package ledgerstore_test + +import ( + "context" + "testing" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/stack/libs/go-libs/collectionutils" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/stretchr/testify/require" +) + +func TestInitializeStore(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + + modified, err := store.Migrate(context.Background()) + require.NoError(t, err) + require.False(t, modified) + + migrationInfos, err := store.GetMigrationsInfo(context.Background()) + require.NoError(t, err) + require.Len(t, migrationInfos, 1) +} + +// TODO: remove that +func insertTransactions(ctx context.Context, s *ledgerstore.Store, txs ...ledger.Transaction) error { + var previous *ledger.ChainedLog + logs := collectionutils.Map(txs, func(from ledger.Transaction) *ledger.ChainedLog { + previous = ledger.NewTransactionLog(&from, map[string]metadata.Metadata{}).ChainLog(previous) + return previous + }) + return s.InsertLogs(ctx, logs...) +} diff --git a/components/ledger/internal/storage/ledgerstore/transactions.go b/components/ledger/internal/storage/ledgerstore/transactions.go new file mode 100644 index 000000000..b0d6e286a --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/transactions.go @@ -0,0 +1,322 @@ +package ledgerstore + +import ( + "context" + "database/sql/driver" + "encoding/json" + "errors" + "fmt" + "math/big" + "regexp" + "strings" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/uptrace/bun" +) + +const ( + MovesTableName = "moves" +) + +type Transaction struct { + bun.BaseModel `bun:"transactions,alias:transactions"` + + ID *paginate.BigInt `bun:"id,type:numeric"` + Timestamp ledger.Time `bun:"timestamp,type:timestamp without time zone"` + Reference string `bun:"reference,type:varchar,unique,nullzero"` + Postings []ledger.Posting `bun:"postings,type:jsonb"` + Metadata metadata.Metadata `bun:"metadata,type:jsonb,default:'{}'"` + PostCommitEffectiveVolumes ledger.AccountsAssetsVolumes `bun:"post_commit_effective_volumes,type:jsonb"` + PostCommitVolumes ledger.AccountsAssetsVolumes `bun:"post_commit_volumes,type:jsonb"` + RevertedAt *ledger.Time `bun:"reverted_at"` + LastUpdate *ledger.Time `bun:"last_update"` +} + +func (t *Transaction) toCore() *ledger.ExpandedTransaction { + var ( + preCommitEffectiveVolumes ledger.AccountsAssetsVolumes + preCommitVolumes ledger.AccountsAssetsVolumes + ) + if t.PostCommitEffectiveVolumes != nil { + preCommitEffectiveVolumes = t.PostCommitEffectiveVolumes.Copy() + for _, posting := range t.Postings { + preCommitEffectiveVolumes.AddOutput(posting.Source, posting.Asset, big.NewInt(0).Neg(posting.Amount)) + preCommitEffectiveVolumes.AddInput(posting.Destination, posting.Asset, big.NewInt(0).Neg(posting.Amount)) + } + } + if t.PostCommitVolumes != nil { + preCommitVolumes = t.PostCommitVolumes.Copy() + for _, posting := range t.Postings { + preCommitVolumes.AddOutput(posting.Source, posting.Asset, big.NewInt(0).Neg(posting.Amount)) + preCommitVolumes.AddInput(posting.Destination, posting.Asset, big.NewInt(0).Neg(posting.Amount)) + } + } + return &ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + TransactionData: ledger.TransactionData{ + Reference: t.Reference, + Metadata: t.Metadata, + Timestamp: t.Timestamp, + Postings: t.Postings, + }, + ID: (*big.Int)(t.ID), + Reverted: t.RevertedAt != nil && !t.RevertedAt.IsZero(), + }, + PreCommitEffectiveVolumes: preCommitEffectiveVolumes, + PostCommitEffectiveVolumes: t.PostCommitEffectiveVolumes, + PreCommitVolumes: preCommitVolumes, + PostCommitVolumes: t.PostCommitVolumes, + } +} + +type account string + +var _ driver.Valuer = account("") + +func (m1 account) Value() (driver.Value, error) { + ret, err := json.Marshal(strings.Split(string(m1), ":")) + if err != nil { + return nil, err + } + return string(ret), nil +} + +// Scan - Implement the database/sql scanner interface +func (m1 *account) Scan(value interface{}) error { + if value == nil { + return nil + } + v, err := driver.String.ConvertValue(value) + if err != nil { + return err + } + + array := make([]string, 0) + switch vv := v.(type) { + case []uint8: + err = json.Unmarshal(vv, &array) + case string: + err = json.Unmarshal([]byte(vv), &array) + default: + panic("not handled type") + } + if err != nil { + return err + } + *m1 = account(strings.Join(array, ":")) + return nil +} + +func (store *Store) buildTransactionQuery(p PITFilterWithVolumes, query *bun.SelectQuery) *bun.SelectQuery { + + selectMetadata := query.NewSelect(). + Table("transactions_metadata"). + Where("transactions.id = transactions_metadata.transaction_id"). + Order("revision desc"). + Limit(1) + + if p.PIT != nil && !p.PIT.IsZero() { + selectMetadata = selectMetadata.Where("date <= ?", p.PIT) + } + + query = query. + Table("transactions"). + ColumnExpr("distinct on(transactions.id) transactions.*, transactions_metadata.metadata"). + Join("join moves m on transactions.id = m.transaction_id"). + Join(fmt.Sprintf(`left join lateral (%s) as transactions_metadata on true`, selectMetadata.String())) + + if p.PIT != nil && !p.PIT.IsZero() { + query = query. + Where("timestamp <= ?", p.PIT). + ColumnExpr(fmt.Sprintf("case when reverted_at is not null and reverted_at > '%s' then null else reverted_at end", p.PIT.Format(ledger.DateFormat))) + } + + if p.ExpandEffectiveVolumes { + query = query.ColumnExpr("get_aggregated_effective_volumes_for_transaction(transactions) as post_commit_effective_volumes") + } + if p.ExpandVolumes { + query = query.ColumnExpr("get_aggregated_volumes_for_transaction(transactions) as post_commit_volumes") + } + return query +} + +func (store *Store) transactionQueryContext(qb query.Builder) (string, []any, error) { + metadataRegex := regexp.MustCompile("metadata\\[(.+)\\]") + + return qb.Build(query.ContextFn(func(key, operator string, value any) (string, []any, error) { + switch { + case key == "reference" || key == "timestamp": + return fmt.Sprintf("%s %s ?", key, query.DefaultComparisonOperatorsMapping[operator]), []any{value}, nil + case key == "account": + // TODO: Should allow comparison operator only if segments not used + if operator != "$match" { + return "", nil, errors.New("'account' column can only be used with $match") + } + switch address := value.(type) { + case string: + return filterAccountAddress(address, "m.account_address"), nil, nil + default: + return "", nil, fmt.Errorf("unexpected type %T for column 'account'", address) + } + case key == "source": + // TODO: Should allow comparison operator only if segments not used + if operator != "$match" { + return "", nil, errors.New("'source' column can only be used with $match") + } + switch address := value.(type) { + case string: + return fmt.Sprintf("(%s) and m.is_source", filterAccountAddress(address, "m.account_address")), nil, nil + default: + return "", nil, fmt.Errorf("unexpected type %T for column 'source'", address) + } + case key == "destination": + // TODO: Should allow comparison operator only if segments not used + if operator != "$match" { + return "", nil, errors.New("'destination' column can only be used with $match") + } + switch address := value.(type) { + case string: + return fmt.Sprintf("(%s) and not m.is_source", filterAccountAddress(address, "m.account_address")), nil, nil + default: + return "", nil, fmt.Errorf("unexpected type %T for column 'destination'", address) + } + case metadataRegex.Match([]byte(key)): + if operator != "$match" { + return "", nil, errors.New("'account' column can only be used with $match") + } + match := metadataRegex.FindAllStringSubmatch(key, 3) + + return "metadata @> ?", []any{map[string]any{ + match[0][1]: value, + }}, nil + default: + return "", nil, fmt.Errorf("unknown key '%s' when building query", key) + } + })) +} + +func (store *Store) buildTransactionListQuery(selectQuery *bun.SelectQuery, q PaginatedQueryOptions[PITFilterWithVolumes]) *bun.SelectQuery { + + selectQuery = store.buildTransactionQuery(q.Options, selectQuery) + + if q.QueryBuilder != nil { + where, args, err := store.transactionQueryContext(q.QueryBuilder) + if err != nil { + // TODO: handle error + panic(err) + } + return selectQuery.Where(where, args...) + } + + return selectQuery +} + +func (store *Store) GetTransactions(ctx context.Context, q *GetTransactionsQuery) (*api.Cursor[ledger.ExpandedTransaction], error) { + transactions, err := paginateWithColumn[PaginatedQueryOptions[PITFilterWithVolumes], Transaction](store, ctx, + (*paginate.ColumnPaginatedQuery[PaginatedQueryOptions[PITFilterWithVolumes]])(q), + func(query *bun.SelectQuery) *bun.SelectQuery { + return store.buildTransactionListQuery(query, q.Options) + }, + ) + if err != nil { + return nil, err + } + return api.MapCursor(transactions, func(from Transaction) ledger.ExpandedTransaction { + return *from.toCore() + }), nil +} + +func (store *Store) CountTransactions(ctx context.Context, q *GetTransactionsQuery) (uint64, error) { + return count(store, ctx, func(query *bun.SelectQuery) *bun.SelectQuery { + return store.buildTransactionListQuery(query, q.Options) + }) +} + +func (store *Store) GetTransactionWithVolumes(ctx context.Context, filter GetTransactionQuery) (*ledger.ExpandedTransaction, error) { + return fetchAndMap[*Transaction, *ledger.ExpandedTransaction](store, ctx, + (*Transaction).toCore, + func(query *bun.SelectQuery) *bun.SelectQuery { + return store.buildTransactionQuery(filter.PITFilterWithVolumes, query). + Where("transactions.id = ?", filter.ID). + Limit(1) + }) +} + +func (store *Store) GetTransaction(ctx context.Context, txId *big.Int) (*ledger.Transaction, error) { + return fetch[*ledger.Transaction](store, ctx, + func(query *bun.SelectQuery) *bun.SelectQuery { + return query. + Table("transactions"). + ColumnExpr(`transactions.id, transactions.reference, transactions.postings, transactions.timestamp, transactions.reverted_at, tm.metadata`). + Join("left join transactions_metadata tm on tm.transaction_id = transactions.id"). + Where("transactions.id = ?", (*paginate.BigInt)(txId)). + Order("tm.revision desc"). + Limit(1) + }) +} + +func (store *Store) GetTransactionByReference(ctx context.Context, ref string) (*ledger.ExpandedTransaction, error) { + return fetchAndMap[*Transaction, *ledger.ExpandedTransaction](store, ctx, + (*Transaction).toCore, + func(query *bun.SelectQuery) *bun.SelectQuery { + return query. + Table("transactions"). + ColumnExpr(`transactions.id, transactions.reference, transactions.postings, transactions.timestamp, transactions.reverted_at, tm.metadata`). + Join("left join transactions_metadata tm on tm.transaction_id = transactions.id"). + Where("transactions.reference = ?", ref). + Order("tm.revision desc"). + Limit(1) + }) +} + +func (store *Store) GetLastTransaction(ctx context.Context) (*ledger.ExpandedTransaction, error) { + return fetchAndMap[*Transaction, *ledger.ExpandedTransaction](store, ctx, + (*Transaction).toCore, + func(query *bun.SelectQuery) *bun.SelectQuery { + return query. + Table("transactions"). + ColumnExpr(`transactions.id, transactions.reference, transactions.postings, transactions.timestamp, transactions.reverted_at, tm.metadata`). + Join("left join transactions_metadata tm on tm.transaction_id = transactions.id"). + Order("transactions.id desc", "tm.revision desc"). + Limit(1) + }) +} + +type GetTransactionsQuery paginate.ColumnPaginatedQuery[PaginatedQueryOptions[PITFilterWithVolumes]] + +func NewGetTransactionsQuery(options PaginatedQueryOptions[PITFilterWithVolumes]) *GetTransactionsQuery { + return &GetTransactionsQuery{ + PageSize: options.PageSize, + Column: "id", + Order: paginate.OrderDesc, + Options: options, + } +} + +type GetTransactionQuery struct { + PITFilterWithVolumes + ID *big.Int +} + +func (q GetTransactionQuery) WithExpandVolumes() GetTransactionQuery { + q.ExpandVolumes = true + + return q +} + +func (q GetTransactionQuery) WithExpandEffectiveVolumes() GetTransactionQuery { + q.ExpandEffectiveVolumes = true + + return q +} + +func NewGetTransactionQuery(id *big.Int) GetTransactionQuery { + return GetTransactionQuery{ + PITFilterWithVolumes: PITFilterWithVolumes{}, + ID: id, + } +} diff --git a/components/ledger/internal/storage/ledgerstore/transactions_test.go b/components/ledger/internal/storage/ledgerstore/transactions_test.go new file mode 100644 index 000000000..e6cafa4a6 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/transactions_test.go @@ -0,0 +1,1023 @@ +package ledgerstore_test + +import ( + "context" + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/formancehq/stack/libs/go-libs/pointer" + "math/big" + "testing" + "time" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage/ledgerstore" + "github.com/formancehq/ledger/internal/storage/query" + internaltesting "github.com/formancehq/ledger/internal/testing" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/stretchr/testify/require" +) + +func expandLogs(logs ...*ledger.Log) []ledger.ExpandedTransaction { + ret := make([]ledger.ExpandedTransaction, 0) + accumulatedVolumes := ledger.AccountsAssetsVolumes{} + + appendTx := func(tx *ledger.Transaction) { + expandedTx := &ledger.ExpandedTransaction{ + Transaction: *tx, + } + for _, posting := range tx.Postings { + expandedTx.PreCommitVolumes.AddInput(posting.Destination, posting.Asset, accumulatedVolumes.GetVolumes(posting.Destination, posting.Asset).Input) + expandedTx.PreCommitVolumes.AddOutput(posting.Destination, posting.Asset, accumulatedVolumes.GetVolumes(posting.Destination, posting.Asset).Output) + expandedTx.PreCommitVolumes.AddOutput(posting.Source, posting.Asset, accumulatedVolumes.GetVolumes(posting.Source, posting.Asset).Output) + expandedTx.PreCommitVolumes.AddInput(posting.Source, posting.Asset, accumulatedVolumes.GetVolumes(posting.Source, posting.Asset).Input) + } + for _, posting := range tx.Postings { + accumulatedVolumes.AddOutput(posting.Source, posting.Asset, posting.Amount) + accumulatedVolumes.AddInput(posting.Destination, posting.Asset, posting.Amount) + } + for _, posting := range tx.Postings { + expandedTx.PostCommitVolumes.AddInput(posting.Destination, posting.Asset, accumulatedVolumes.GetVolumes(posting.Destination, posting.Asset).Input) + expandedTx.PostCommitVolumes.AddOutput(posting.Destination, posting.Asset, accumulatedVolumes.GetVolumes(posting.Destination, posting.Asset).Output) + expandedTx.PostCommitVolumes.AddOutput(posting.Source, posting.Asset, accumulatedVolumes.GetVolumes(posting.Source, posting.Asset).Output) + expandedTx.PostCommitVolumes.AddInput(posting.Source, posting.Asset, accumulatedVolumes.GetVolumes(posting.Source, posting.Asset).Input) + } + ret = append(ret, *expandedTx) + } + + for _, log := range logs { + switch payload := log.Data.(type) { + case ledger.NewTransactionLogPayload: + appendTx(payload.Transaction) + case ledger.RevertedTransactionLogPayload: + appendTx(payload.RevertTransaction) + ret[payload.RevertedTransactionID.Uint64()].Reverted = true + case ledger.SetMetadataLogPayload: + ret[payload.TargetID.(*big.Int).Uint64()].Metadata = ret[payload.TargetID.(*big.Int).Uint64()].Metadata.Merge(payload.Metadata) + } + } + + return ret +} + +func Reverse[T any](values ...T) []T { + ret := make([]T, len(values)) + for i := 0; i < len(values)/2; i++ { + ret[i], ret[len(values)-i-1] = values[len(values)-i-1], values[i] + } + if len(values)%2 == 1 { + ret[(len(values)-1)/2] = values[(len(values)-1)/2] + } + return ret +} + +func TestGetTransactionWithVolumes(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + ctx := logging.TestingContext() + + tx1 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(0), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "world", + Destination: "central_bank", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Reference: "tx1", + Timestamp: now.Add(-3 * time.Hour), + }, + }, + PostCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(100), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(100), + Output: big.NewInt(0), + }, + }, + }, + PreCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(0), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(0), + }, + }, + }, + } + tx2 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(1), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "world", + Destination: "central_bank", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Reference: "tx2", + Timestamp: now.Add(-2 * time.Hour), + }, + }, + PostCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(200), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(200), + Output: big.NewInt(0), + }, + }, + }, + PreCommitVolumes: ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(100), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(100), + Output: big.NewInt(0), + }, + }, + }, + } + + require.NoError(t, insertTransactions(ctx, store, tx1.Transaction, tx2.Transaction)) + + tx, err := store.GetTransactionWithVolumes(ctx, ledgerstore.NewGetTransactionQuery(tx1.ID). + WithExpandVolumes(). + WithExpandEffectiveVolumes()) + require.NoError(t, err) + require.Equal(t, tx1.Postings, tx.Postings) + require.Equal(t, tx1.Reference, tx.Reference) + require.Equal(t, tx1.Timestamp, tx.Timestamp) + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(100), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(100), + Output: big.NewInt(0), + }, + }, + }, tx.PostCommitVolumes) + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(0), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(0), + }, + }, + }, tx.PreCommitVolumes) + + tx, err = store.GetTransactionWithVolumes(ctx, ledgerstore.NewGetTransactionQuery(tx2.ID). + WithExpandVolumes(). + WithExpandEffectiveVolumes()) + require.Equal(t, tx2.Postings, tx.Postings) + require.Equal(t, tx2.Reference, tx.Reference) + require.Equal(t, tx2.Timestamp, tx.Timestamp) + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(200), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(200), + Output: big.NewInt(0), + }, + }, + }, tx.PostCommitVolumes) + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "world": { + "USD": { + Input: big.NewInt(0), + Output: big.NewInt(100), + }, + }, + "central_bank": { + "USD": { + Input: big.NewInt(100), + Output: big.NewInt(0), + }, + }, + }, tx.PreCommitVolumes) +} + +func TestGetTransaction(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.Transaction{ + ID: big.NewInt(0), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "world", + Destination: "central_bank", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Reference: "tx1", + Timestamp: now.Add(-3 * time.Hour), + }, + } + tx2 := ledger.Transaction{ + ID: big.NewInt(1), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "world", + Destination: "central_bank", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Reference: "tx2", + Timestamp: now.Add(-2 * time.Hour), + }, + } + + require.NoError(t, insertTransactions(context.Background(), store, tx1, tx2)) + + tx, err := store.GetTransaction(context.Background(), tx1.ID) + require.NoError(t, err) + require.Equal(t, tx1.Postings, tx.Postings) + require.Equal(t, tx1.Reference, tx.Reference) + require.Equal(t, tx1.Timestamp, tx.Timestamp) +} + +func TestGetTransactionByReference(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.Transaction{ + ID: big.NewInt(0), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "world", + Destination: "central_bank", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Reference: "tx1", + Timestamp: now.Add(-3 * time.Hour), + }, + } + tx2 := ledger.Transaction{ + ID: big.NewInt(1), + TransactionData: ledger.TransactionData{ + Postings: []ledger.Posting{ + { + Source: "world", + Destination: "central_bank", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Reference: "tx2", + Timestamp: now.Add(-2 * time.Hour), + }, + } + + require.NoError(t, insertTransactions(context.Background(), store, tx1, tx2)) + + tx, err := store.GetTransactionByReference(context.Background(), "tx1") + require.NoError(t, err) + require.Equal(t, tx1.Postings, tx.Postings) + require.Equal(t, tx1.Reference, tx.Reference) + require.Equal(t, tx1.Timestamp, tx.Timestamp) +} + +func TestInsertTransactions(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + t.Run("success inserting transaction", func(t *testing.T) { + tx1 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(0), + TransactionData: ledger.TransactionData{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "alice", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Timestamp: now.Add(-3 * time.Hour), + Metadata: metadata.Metadata{}, + }, + }, + PreCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + "alice": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + }, + PostCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(100), + }, + "alice": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithInputInt64(100), + }, + }, + } + + err := insertTransactions(context.Background(), store, tx1.Transaction) + require.NoError(t, err, "inserting transaction should not fail") + + tx, err := store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(big.NewInt(0)). + WithExpandVolumes()) + internaltesting.RequireEqual(t, tx1, *tx) + }) + + t.Run("success inserting multiple transactions", func(t *testing.T) { + tx2 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(1), + TransactionData: ledger.TransactionData{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "polo", + Amount: big.NewInt(200), + Asset: "USD", + }, + }, + Timestamp: now.Add(-2 * time.Hour), + Metadata: metadata.Metadata{}, + }, + }, + PreCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(100), + }, + "polo": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + }, + PostCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(300), + }, + "polo": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithInputInt64(200), + }, + }, + } + + tx3 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(2), + TransactionData: ledger.TransactionData{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "gfyrag", + Amount: big.NewInt(150), + Asset: "USD", + }, + }, + Timestamp: now.Add(-1 * time.Hour), + Metadata: metadata.Metadata{}, + }, + }, + PreCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(300), + }, + "gfyrag": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + }, + PostCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(450), + }, + "gfyrag": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithInputInt64(150), + }, + }, + } + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.NewTransactionLog(&tx2.Transaction, map[string]metadata.Metadata{}).ChainLog(nil).WithID(2), + ledger.NewTransactionLog(&tx3.Transaction, map[string]metadata.Metadata{}).ChainLog(nil).WithID(3), + )) + + tx, err := store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(big.NewInt(1)).WithExpandVolumes()) + require.NoError(t, err, "getting transaction should not fail") + internaltesting.RequireEqual(t, tx2, *tx) + + tx, err = store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(big.NewInt(2)).WithExpandVolumes()) + require.NoError(t, err, "getting transaction should not fail") + internaltesting.RequireEqual(t, tx3, *tx) + }) +} + +func TestCountTransactions(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(0), + TransactionData: ledger.TransactionData{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "alice", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Timestamp: now.Add(-3 * time.Hour), + Metadata: metadata.Metadata{}, + }, + }, + PreCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + "alice": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + }, + PostCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(100), + }, + "alice": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithInputInt64(100), + }, + }, + } + tx2 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(1), + TransactionData: ledger.TransactionData{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "polo", + Amount: big.NewInt(200), + Asset: "USD", + }, + }, + Timestamp: now.Add(-2 * time.Hour), + Metadata: metadata.Metadata{}, + }, + }, + PreCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(100), + }, + "polo": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + }, + PostCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(300), + }, + "polo": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithInputInt64(200), + }, + }, + } + + tx3 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(2), + TransactionData: ledger.TransactionData{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "gfyrag", + Amount: big.NewInt(150), + Asset: "USD", + }, + }, + Timestamp: now.Add(-1 * time.Hour), + Metadata: metadata.Metadata{}, + }, + }, + PreCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(300), + }, + "gfyrag": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + }, + PostCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(450), + }, + "gfyrag": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithInputInt64(150), + }, + }, + } + + err := insertTransactions(context.Background(), store, tx1.Transaction, tx2.Transaction, tx3.Transaction) + require.NoError(t, err, "inserting transaction should not fail") + + count, err := store.CountTransactions(context.Background(), ledgerstore.NewGetTransactionsQuery(ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}))) + require.NoError(t, err, "counting transactions should not fail") + require.Equal(t, uint64(3), count, "count should be equal") +} + +func TestUpdateTransactionsMetadata(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(0), + TransactionData: ledger.TransactionData{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "alice", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Timestamp: now.Add(-3 * time.Hour), + Metadata: metadata.Metadata{}, + }, + }, + PreCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + "alice": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + }, + PostCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(100), + }, + "alice": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithInputInt64(100), + }, + }, + } + tx2 := ledger.ExpandedTransaction{ + Transaction: ledger.Transaction{ + ID: big.NewInt(1), + TransactionData: ledger.TransactionData{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "polo", + Amount: big.NewInt(200), + Asset: "USD", + }, + }, + Timestamp: now.Add(-2 * time.Hour), + Metadata: metadata.Metadata{}, + }, + }, + PreCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(100), + }, + "polo": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes(), + }, + }, + PostCommitVolumes: map[string]ledger.VolumesByAssets{ + "world": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithOutputInt64(300), + }, + "polo": map[string]*ledger.Volumes{ + "USD": ledger.NewEmptyVolumes().WithInputInt64(200), + }, + }, + } + + err := insertTransactions(context.Background(), store, tx1.Transaction, tx2.Transaction) + require.NoError(t, err, "inserting transaction should not fail") + + err = store.InsertLogs(context.Background(), + ledger.NewSetMetadataOnTransactionLog(ledger.Now(), tx1.ID, metadata.Metadata{"foo1": "bar2"}).ChainLog(nil).WithID(3), + ledger.NewSetMetadataOnTransactionLog(ledger.Now(), tx2.ID, metadata.Metadata{"foo2": "bar2"}).ChainLog(nil).WithID(4), + ) + require.NoError(t, err, "updating multiple transaction metadata should not fail") + + tx, err := store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(big.NewInt(0)).WithExpandVolumes().WithExpandEffectiveVolumes()) + require.NoError(t, err, "getting transaction should not fail") + require.Equal(t, tx.Metadata, metadata.Metadata{"foo1": "bar2"}, "metadata should be equal") + + tx, err = store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(big.NewInt(1)).WithExpandVolumes().WithExpandEffectiveVolumes()) + require.NoError(t, err, "getting transaction should not fail") + require.Equal(t, tx.Metadata, metadata.Metadata{"foo2": "bar2"}, "metadata should be equal") +} + +func TestDeleteTransactionsMetadata(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.Transaction{ + ID: big.NewInt(0), + TransactionData: ledger.TransactionData{ + Postings: ledger.Postings{ + { + Source: "world", + Destination: "alice", + Amount: big.NewInt(100), + Asset: "USD", + }, + }, + Timestamp: now.Add(-3 * time.Hour), + Metadata: metadata.Metadata{}, + }, + } + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.NewTransactionLog(&tx1, map[string]metadata.Metadata{}).ChainLog(nil).WithID(1), + ledger.NewSetMetadataOnTransactionLog(ledger.Now(), tx1.ID, metadata.Metadata{"foo1": "bar1", "foo2": "bar2"}).ChainLog(nil).WithID(2), + )) + + tx, err := store.GetTransaction(context.Background(), tx1.ID) + require.NoError(t, err) + require.Equal(t, tx.Metadata, metadata.Metadata{"foo1": "bar1", "foo2": "bar2"}) + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.NewDeleteMetadataLog(ledger.Now(), ledger.DeleteMetadataLogPayload{ + TargetType: ledger.MetaTargetTypeTransaction, + TargetID: tx1.ID, + Key: "foo1", + }).ChainLog(nil).WithID(3), + )) + + tx, err = store.GetTransaction(context.Background(), tx1.ID) + require.NoError(t, err) + require.Equal(t, metadata.Metadata{"foo2": "bar2"}, tx.Metadata) +} + +func TestInsertTransactionInPast(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD/2", big.NewInt(100)), + ).WithDate(now) + + tx2 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("bank", "user1", "USD/2", big.NewInt(50)), + ).WithDate(now.Add(time.Hour)).WithIDUint64(1) + + // Insert in past must modify pre/post commit volumes of tx2 + tx3 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("bank", "user2", "USD/2", big.NewInt(50)), + ).WithDate(now.Add(30 * time.Minute)).WithIDUint64(2) + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.NewTransactionLog(tx1, map[string]metadata.Metadata{}).ChainLog(nil).WithID(1), + ledger.NewTransactionLog(tx2, map[string]metadata.Metadata{}).ChainLog(nil).WithID(2), + ledger.NewTransactionLog(tx3, map[string]metadata.Metadata{}).ChainLog(nil).WithID(3), + )) + + tx2FromDatabase, err := store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(tx2.ID).WithExpandVolumes().WithExpandEffectiveVolumes()) + require.NoError(t, err) + + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 50), + }, + "user1": { + "USD/2": ledger.NewVolumesInt64(0, 0), + }, + }, tx2FromDatabase.PreCommitEffectiveVolumes) + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 100), + }, + "user1": { + "USD/2": ledger.NewVolumesInt64(50, 0), + }, + }, tx2FromDatabase.PostCommitEffectiveVolumes) +} + +func TestInsertTransactionInPastInOneBatch(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD/2", big.NewInt(100)), + ).WithDate(now) + + tx2 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("bank", "user1", "USD/2", big.NewInt(50)), + ).WithDate(now.Add(time.Hour)).WithIDUint64(1) + + // Insert in past must modify pre/post commit volumes of tx2 + tx3 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("bank", "user2", "USD/2", big.NewInt(50)), + ).WithDate(now.Add(30 * time.Minute)).WithIDUint64(2) + + require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2, *tx3)) + + tx2FromDatabase, err := store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(tx2.ID).WithExpandVolumes().WithExpandEffectiveVolumes()) + require.NoError(t, err) + + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 50), + }, + "user1": { + "USD/2": ledger.NewVolumesInt64(0, 0), + }, + }, tx2FromDatabase.PreCommitEffectiveVolumes) + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 100), + }, + "user1": { + "USD/2": ledger.NewVolumesInt64(50, 0), + }, + }, tx2FromDatabase.PostCommitEffectiveVolumes) +} + +func TestInsertTwoTransactionAtSameDateInSameBatch(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD/2", big.NewInt(100)), + ).WithDate(now.Add(-time.Hour)) + + tx2 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("bank", "user1", "USD/2", big.NewInt(10)), + ).WithDate(now).WithIDUint64(1) + + tx3 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("bank", "user2", "USD/2", big.NewInt(10)), + ).WithDate(now).WithIDUint64(2) + + require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2, *tx3)) + + tx2FromDatabase, err := store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(tx2.ID).WithExpandVolumes().WithExpandEffectiveVolumes()) + require.NoError(t, err) + + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 10), + }, + "user1": { + "USD/2": ledger.NewVolumesInt64(10, 0), + }, + }, tx2FromDatabase.PostCommitVolumes) + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 0), + }, + "user1": { + "USD/2": ledger.NewVolumesInt64(0, 0), + }, + }, tx2FromDatabase.PreCommitVolumes) + + tx3FromDatabase, err := store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(tx3.ID).WithExpandVolumes().WithExpandEffectiveVolumes()) + require.NoError(t, err) + + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 10), + }, + "user2": { + "USD/2": ledger.NewVolumesInt64(0, 0), + }, + }, tx3FromDatabase.PreCommitVolumes) + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 20), + }, + "user2": { + "USD/2": ledger.NewVolumesInt64(10, 0), + }, + }, tx3FromDatabase.PostCommitVolumes) +} + +func TestInsertTwoTransactionAtSameDateInTwoBatch(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + + tx1 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("world", "bank", "USD/2", big.NewInt(100)), + ).WithDate(now.Add(-time.Hour)) + + tx2 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("bank", "user1", "USD/2", big.NewInt(10)), + ).WithDate(now).WithIDUint64(1) + + require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2)) + + tx3 := ledger.NewTransaction().WithPostings( + ledger.NewPosting("bank", "user2", "USD/2", big.NewInt(10)), + ).WithDate(now).WithIDUint64(2) + + require.NoError(t, store.InsertLogs(context.Background(), + ledger.NewTransactionLog(tx3, map[string]metadata.Metadata{}).ChainLog(nil).WithID(3), + )) + + tx3FromDatabase, err := store.GetTransactionWithVolumes(context.Background(), ledgerstore.NewGetTransactionQuery(tx3.ID).WithExpandVolumes().WithExpandEffectiveVolumes()) + require.NoError(t, err) + + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 10), + }, + "user2": { + "USD/2": ledger.NewVolumesInt64(0, 0), + }, + }, tx3FromDatabase.PreCommitVolumes) + internaltesting.RequireEqual(t, ledger.AccountsAssetsVolumes{ + "bank": { + "USD/2": ledger.NewVolumesInt64(100, 20), + }, + "user2": { + "USD/2": ledger.NewVolumesInt64(10, 0), + }, + }, tx3FromDatabase.PostCommitVolumes) +} + +func TestListTransactions(t *testing.T) { + t.Parallel() + store := newLedgerStore(t) + now := ledger.Now() + ctx := logging.TestingContext() + + tx1 := ledger.NewTransaction(). + WithIDUint64(0). + WithPostings( + ledger.NewPosting("world", "alice", "USD", big.NewInt(100)), + ). + WithMetadata(metadata.Metadata{"category": "1"}). + WithDate(now.Add(-3 * time.Hour)) + tx2 := ledger.NewTransaction(). + WithIDUint64(1). + WithPostings( + ledger.NewPosting("world", "bob", "USD", big.NewInt(100)), + ). + WithMetadata(metadata.Metadata{"category": "2"}). + WithDate(now.Add(-2 * time.Hour)) + tx3 := ledger.NewTransaction(). + WithIDUint64(2). + WithPostings( + ledger.NewPosting("world", "users:marley", "USD", big.NewInt(100)), + ). + WithMetadata(metadata.Metadata{"category": "3"}). + WithDate(now.Add(-time.Hour)) + tx4 := ledger.NewTransaction(). + WithIDUint64(3). + WithPostings( + ledger.NewPosting("users:marley", "world", "USD", big.NewInt(100)), + ). + WithDate(now) + + logs := []*ledger.Log{ + ledger.NewTransactionLog(tx1, map[string]metadata.Metadata{}), + ledger.NewTransactionLog(tx2, map[string]metadata.Metadata{}), + ledger.NewTransactionLog(tx3, map[string]metadata.Metadata{}), + ledger.NewRevertedTransactionLog(ledger.Now(), tx3.ID, tx4), + ledger.NewSetMetadataOnTransactionLog(ledger.Now(), tx3.ID, metadata.Metadata{ + "additional_metadata": "true", + }), + } + + require.NoError(t, store.InsertLogs(ctx, ledger.ChainLogs(logs...)...)) + + type testCase struct { + name string + query ledgerstore.PaginatedQueryOptions[ledgerstore.PITFilterWithVolumes] + expected *api.Cursor[ledger.ExpandedTransaction] + } + testCases := []testCase{ + { + name: "nominal", + query: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}), + expected: &api.Cursor[ledger.ExpandedTransaction]{ + PageSize: 15, + HasMore: false, + Data: Reverse(expandLogs(logs...)...), + }, + }, + { + name: "address filter", + query: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("account", "bob")), + expected: &api.Cursor[ledger.ExpandedTransaction]{ + PageSize: 15, + HasMore: false, + Data: expandLogs(logs...)[1:2], + }, + }, + { + name: "address filter using segment", + query: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("account", "users:")), + expected: &api.Cursor[ledger.ExpandedTransaction]{ + PageSize: 15, + HasMore: false, + Data: Reverse(expandLogs(logs...)[2:]...), + }, + }, + { + name: "filter using metadata", + query: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}). + WithQueryBuilder(query.Match("metadata[category]", "2")), + expected: &api.Cursor[ledger.ExpandedTransaction]{ + PageSize: 15, + HasMore: false, + Data: expandLogs(logs...)[1:2], + }, + }, + { + name: "using point in time", + query: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{ + PITFilter: ledgerstore.PITFilter{ + PIT: pointer.For(now.Add(-time.Hour)), + }, + }), + expected: &api.Cursor[ledger.ExpandedTransaction]{ + PageSize: 15, + HasMore: false, + Data: Reverse(expandLogs(logs[:3]...)...), + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + tc.query.Options.ExpandVolumes = true + tc.query.Options.ExpandEffectiveVolumes = false + cursor, err := store.GetTransactions(ctx, ledgerstore.NewGetTransactionsQuery(tc.query)) + require.NoError(t, err) + internaltesting.RequireEqual(t, *tc.expected, *cursor) + + count, err := store.CountTransactions(ctx, ledgerstore.NewGetTransactionsQuery(tc.query)) + require.NoError(t, err) + require.EqualValues(t, len(tc.expected.Data), count) + }) + } +} diff --git a/components/ledger/internal/storage/ledgerstore/utils.go b/components/ledger/internal/storage/ledgerstore/utils.go new file mode 100644 index 000000000..217280211 --- /dev/null +++ b/components/ledger/internal/storage/ledgerstore/utils.go @@ -0,0 +1,171 @@ +package ledgerstore + +import ( + "context" + "fmt" + "reflect" + "strings" + + ledger "github.com/formancehq/ledger/internal" + "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/ledger/internal/storage/query" + "github.com/formancehq/stack/libs/go-libs/api" + "github.com/uptrace/bun" +) + +func fetch[T any](s *Store, ctx context.Context, builders ...func(query *bun.SelectQuery) *bun.SelectQuery) (T, error) { + var ret T + ret = reflect.New(reflect.TypeOf(ret).Elem()).Interface().(T) + err := s.withTransaction(ctx, func(tx bun.Tx) error { + query := s.db.NewSelect().Conn(tx) + for _, builder := range builders { + query = query.Apply(builder) + } + if query.GetTableName() == "" && query.GetModel() == nil { + //query = query.Model(ret) + } + + return storage.PostgresError(query.Scan(ctx, ret)) + }) + return ret, err +} + +func fetchAndMap[T any, TO any](s *Store, ctx context.Context, + mapper func(T) TO, + builders ...func(query *bun.SelectQuery) *bun.SelectQuery) (TO, error) { + ret, err := fetch[T](s, ctx, builders...) + if err != nil { + var zero TO + return zero, storage.PostgresError(err) + } + return mapper(ret), nil +} + +func paginateWithOffset[FILTERS any, RETURN any](s *Store, ctx context.Context, + q *paginate.OffsetPaginatedQuery[FILTERS], builders ...func(query *bun.SelectQuery) *bun.SelectQuery) (*api.Cursor[RETURN], error) { + tx, err := s.prepareTransaction(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + var ret RETURN + query := s.db.NewSelect().Conn(tx) + for _, builder := range builders { + query = query.Apply(builder) + } + if query.GetModel() == nil && query.GetTableName() == "" { + query = query.Model(ret) + } + + return paginate.UsingOffset[FILTERS, RETURN](ctx, query, *q) +} + +func paginateWithColumn[FILTERS any, RETURN any](s *Store, ctx context.Context, q *paginate.ColumnPaginatedQuery[FILTERS], builders ...func(query *bun.SelectQuery) *bun.SelectQuery) (*api.Cursor[RETURN], error) { + tx, err := s.prepareTransaction(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + query := s.db.NewSelect().Conn(tx) + for _, builder := range builders { + query = query.Apply(builder) + } + + return paginate.UsingColumn[FILTERS, RETURN](ctx, query, *q) +} + +func count(s *Store, ctx context.Context, builders ...func(query *bun.SelectQuery) *bun.SelectQuery) (uint64, error) { + var ( + count int + err error + ) + if err := s.withTransaction(ctx, func(tx bun.Tx) error { + query := s.db.NewSelect() + for _, builder := range builders { + query = query.Apply(builder) + } + count, err = s.db.NewSelect(). + TableExpr("(" + query.String() + ") data"). + Conn(tx). + Count(ctx) + return err + }); err != nil { + return 0, err + } + return uint64(count), nil +} + +func filterAccountAddress(address, key string) string { + parts := make([]string, 0) + src := strings.Split(address, ":") + + needSegmentCheck := false + for _, segment := range src { + needSegmentCheck = segment == "" + if needSegmentCheck { + break + } + } + + if needSegmentCheck { + parts = append(parts, fmt.Sprintf("jsonb_array_length(%s_array) = %d", key, len(src))) + + for i, segment := range src { + if len(segment) == 0 { + continue + } + parts = append(parts, fmt.Sprintf("%s_array @@ ('$[%d] == \"%s\"')::jsonpath", key, i, segment)) + } + } else { + parts = append(parts, fmt.Sprintf("%s = '%s'", key, address)) + } + + return strings.Join(parts, " and ") +} + +func filterPIT(pit *ledger.Time, column string) func(query *bun.SelectQuery) *bun.SelectQuery { + return func(query *bun.SelectQuery) *bun.SelectQuery { + if pit == nil || pit.IsZero() { + return query + } + return query.Where(fmt.Sprintf("%s <= ?", column), pit) + } +} + +type PaginatedQueryOptions[T any] struct { + QueryBuilder query.Builder `json:"qb"` + PageSize uint64 `json:"pageSize"` + Options T `json:"options"` +} + +func (opts PaginatedQueryOptions[T]) WithQueryBuilder(qb query.Builder) PaginatedQueryOptions[T] { + opts.QueryBuilder = qb + + return opts +} + +func (opts PaginatedQueryOptions[T]) WithPageSize(pageSize uint64) PaginatedQueryOptions[T] { + opts.PageSize = pageSize + + return opts +} + +func NewPaginatedQueryOptions[T any](options T) PaginatedQueryOptions[T] { + return PaginatedQueryOptions[T]{ + Options: options, + PageSize: paginate.QueryDefaultPageSize, + } +} + +type PITFilter struct { + PIT *ledger.Time `json:"pit"` +} + +type PITFilterWithVolumes struct { + PITFilter + ExpandVolumes bool `json:"volumes"` + ExpandEffectiveVolumes bool `json:"effectiveVolumes"` +} diff --git a/components/ledger/internal/storage/paginate/bigint.go b/components/ledger/internal/storage/paginate/bigint.go new file mode 100644 index 000000000..29d4693a8 --- /dev/null +++ b/components/ledger/internal/storage/paginate/bigint.go @@ -0,0 +1,92 @@ +package paginate + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" + "fmt" + "math/big" +) + +type BigInt big.Int + +func (i *BigInt) MarshalJSON() ([]byte, error) { + return json.Marshal(i.ToMathBig()) +} + +func (i *BigInt) UnmarshalJSON(bytes []byte) error { + v, err := i.FromString(string(bytes)) + if err != nil { + return err + } + *i = *v + return nil +} + +func NewInt() *BigInt { + return new(BigInt) +} +func newBigint(x *big.Int) *BigInt { + return (*BigInt)(x) +} + +// same as NewBigint() +func FromMathBig(x *big.Int) *BigInt { + return (*BigInt)(x) +} + +func FromInt64(x int64) *BigInt { + return FromMathBig(big.NewInt(x)) +} + +func (i *BigInt) FromString(x string) (*BigInt, error) { + if x == "" { + return FromInt64(0), nil + } + a := big.NewInt(0) + b, ok := a.SetString(x, 10) + + if !ok { + return nil, fmt.Errorf("cannot create Int from string") + } + + return newBigint(b), nil +} + +func (b *BigInt) Value() (driver.Value, error) { + return (*big.Int)(b).String(), nil +} + +func (b *BigInt) Set(v *BigInt) *BigInt { + return (*BigInt)((*big.Int)(b).Set((*big.Int)(v))) +} + +func (b *BigInt) Sub(x *BigInt, y *BigInt) *BigInt { + return (*BigInt)((*big.Int)(b).Sub((*big.Int)(x), (*big.Int)(y))) +} + +func (b *BigInt) Scan(value interface{}) error { + + var i sql.NullString + + if err := i.Scan(value); err != nil { + return err + } + + if _, ok := (*big.Int)(b).SetString(i.String, 10); ok { + return nil + } + + return fmt.Errorf("Error converting type %T into Bigint", value) +} + +func (b *BigInt) ToMathBig() *big.Int { + return (*big.Int)(b) +} + +func (i *BigInt) Cmp(bottom *BigInt) int { + return (*big.Int)(i).Cmp((*big.Int)(bottom)) +} + +var _ json.Unmarshaler = (*BigInt)(nil) +var _ json.Marshaler = (*BigInt)(nil) diff --git a/components/ledger/internal/storage/paginate/main_test.go b/components/ledger/internal/storage/paginate/main_test.go new file mode 100644 index 000000000..20bab814d --- /dev/null +++ b/components/ledger/internal/storage/paginate/main_test.go @@ -0,0 +1,22 @@ +package paginate_test + +import ( + "os" + "testing" + + "github.com/formancehq/stack/libs/go-libs/logging" + "github.com/formancehq/stack/libs/go-libs/pgtesting" +) + +func TestMain(m *testing.M) { + if err := pgtesting.CreatePostgresServer(); err != nil { + logging.Error(err) + os.Exit(1) + } + + code := m.Run() + if err := pgtesting.DestroyPostgresServer(); err != nil { + logging.Error(err) + } + os.Exit(code) +} diff --git a/components/ledger/internal/storage/paginate/pagination.go b/components/ledger/internal/storage/paginate/pagination.go new file mode 100644 index 000000000..b05411162 --- /dev/null +++ b/components/ledger/internal/storage/paginate/pagination.go @@ -0,0 +1,99 @@ +package paginate + +import ( + "encoding/base64" + "encoding/json" + "math/big" +) + +const ( + OrderAsc = iota + OrderDesc + + QueryDefaultPageSize = 15 +) + +type Order int + +func (o Order) String() string { + switch o { + case OrderAsc: + return "ASC" + case OrderDesc: + return "DESC" + } + panic("should not happen") +} + +func (o Order) Reverse() Order { + return (o + 1) % 2 +} + +type ColumnPaginatedQuery[OPTIONS any] struct { + PageSize uint64 `json:"pageSize"` + Bottom *big.Int `json:"bottom"` + Column string `json:"column"` + PaginationID *big.Int `json:"paginationID"` + Order Order `json:"order"` + Options OPTIONS `json:"filters"` + Reverse bool `json:"reverse"` +} + +func (q *ColumnPaginatedQuery[PAYLOAD]) EncodeAsCursor() string { + return encodeCursor(q) +} + +func (a *ColumnPaginatedQuery[PAYLOAD]) WithPageSize(pageSize uint64) *ColumnPaginatedQuery[PAYLOAD] { + if pageSize != 0 { + a.PageSize = pageSize + } + + return a +} + +type OffsetPaginatedQuery[OPTIONS any] struct { + Offset uint64 `json:"offset"` + Order Order `json:"order"` + PageSize uint64 `json:"pageSize"` + Options OPTIONS `json:"filters"` +} + +func (q *OffsetPaginatedQuery[PAYLOAD]) EncodeAsCursor() string { + return encodeCursor(q) +} + +func (a *OffsetPaginatedQuery[PAYLOAD]) WithPageSize(pageSize uint64) *OffsetPaginatedQuery[PAYLOAD] { + if pageSize != 0 { + a.PageSize = pageSize + } + + return a +} + +func encodeCursor[T any](v *T) string { + if v == nil { + return "" + } + return EncodeCursor(*v) +} + +func EncodeCursor[T any](v T) string { + data, err := json.Marshal(v) + if err != nil { + panic(err) + } + return base64.RawURLEncoding.EncodeToString(data) +} + +func UnmarshalCursor(v string, to any) error { + res, err := base64.RawURLEncoding.DecodeString(v) + if err != nil { + return err + } + + if err := json.Unmarshal(res, &to); err != nil { + return err + } + + return nil +} diff --git a/components/ledger/pkg/storage/ledgerstore/pagination_column.go b/components/ledger/internal/storage/paginate/pagination_column.go similarity index 78% rename from components/ledger/pkg/storage/ledgerstore/pagination_column.go rename to components/ledger/internal/storage/paginate/pagination_column.go index 5d004c350..1860e1f90 100644 --- a/components/ledger/pkg/storage/ledgerstore/pagination_column.go +++ b/components/ledger/internal/storage/paginate/pagination_column.go @@ -1,23 +1,22 @@ -package ledgerstore +package paginate import ( "context" "fmt" + "math/big" "reflect" "strings" - storageerrors "github.com/formancehq/ledger/pkg/storage" + storageerrors "github.com/formancehq/ledger/internal/storage" "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/pointer" "github.com/uptrace/bun" ) func UsingColumn[FILTERS any, ENTITY any](ctx context.Context, - builder func(filters FILTERS, models *[]ENTITY) *bun.SelectQuery, + sb *bun.SelectQuery, query ColumnPaginatedQuery[FILTERS]) (*api.Cursor[ENTITY], error) { ret := make([]ENTITY, 0) - sb := builder(query.Filters, &ret) sb = sb.Limit(int(query.PageSize) + 1) // Fetch one additional item to find the next token order := query.Order if query.Reverse { @@ -43,7 +42,7 @@ func UsingColumn[FILTERS any, ENTITY any](ctx context.Context, } } - if err := sb.Scan(ctx); err != nil { + if err := sb.Scan(ctx, &ret); err != nil { return nil, storageerrors.PostgresError(err) } var ( @@ -60,14 +59,14 @@ func UsingColumn[FILTERS any, ENTITY any](ctx context.Context, } var ( - paginationIDs = make([]uint64, 0) + paginationIDs = make([]*BigInt, 0) ) for _, t := range ret { paginationID := reflect.ValueOf(t). Field(paginatedColumnIndex). - Interface().(uint64) + Interface().(*BigInt) if query.Bottom == nil { - query.Bottom = &paginationID + query.Bottom = (*big.Int)(paginationID) } paginationIDs = append(paginationIDs, paginationID) } @@ -91,17 +90,17 @@ func UsingColumn[FILTERS any, ENTITY any](ctx context.Context, if hasMore { cp := query - cp.PaginationID = pointer.For(paginationIDs[len(paginationIDs)-2]) + cp.PaginationID = (*big.Int)(paginationIDs[len(paginationIDs)-2]) previous = &cp } } else { if hasMore { cp := query - cp.PaginationID = pointer.For(paginationIDs[len(paginationIDs)-1]) + cp.PaginationID = (*big.Int)(paginationIDs[len(paginationIDs)-1]) next = &cp } if query.PaginationID != nil { - if (query.Order == OrderAsc && *query.PaginationID > *query.Bottom) || (query.Order == OrderDesc && *query.PaginationID < *query.Bottom) { + if (query.Order == OrderAsc && query.PaginationID.Cmp(query.Bottom) > 0) || (query.Order == OrderDesc && query.PaginationID.Cmp(query.Bottom) < 0) { cp := query cp.Reverse = true previous = &cp diff --git a/components/ledger/internal/storage/paginate/pagination_column_test.go b/components/ledger/internal/storage/paginate/pagination_column_test.go new file mode 100644 index 000000000..2acaf5bae --- /dev/null +++ b/components/ledger/internal/storage/paginate/pagination_column_test.go @@ -0,0 +1,343 @@ +package paginate_test + +import ( + "context" + "math/big" + "testing" + + "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/stack/libs/go-libs/pgtesting" + "github.com/stretchr/testify/require" +) + +func TestColumnPagination(t *testing.T) { + t.Parallel() + + pgServer := pgtesting.NewPostgresDatabase(t) + db, err := storage.OpenSQLDB(storage.ConnectionOptions{ + DatabaseSourceName: pgServer.ConnString(), + Debug: testing.Verbose(), + }) + require.NoError(t, err) + + _, err = db.Exec(` + CREATE TABLE "models" (id int, pair boolean); + `) + require.NoError(t, err) + + type model struct { + ID *paginate.BigInt `bun:"id,type:numeric"` + Pair bool `bun:"pair"` + } + + models := make([]model, 0) + for i := 0; i < 100; i++ { + models = append(models, model{ + ID: (*paginate.BigInt)(big.NewInt(int64(i))), + Pair: i%2 == 0, + }) + } + + _, err = db.NewInsert(). + Model(&models). + Exec(context.Background()) + require.NoError(t, err) + + type testCase struct { + name string + query paginate.ColumnPaginatedQuery[bool] + expectedNext *paginate.ColumnPaginatedQuery[bool] + expectedPrevious *paginate.ColumnPaginatedQuery[bool] + expectedNumberOfItems int64 + } + testCases := []testCase{ + { + name: "asc first page", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + Order: paginate.OrderAsc, + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(10)), + Order: paginate.OrderAsc, + Bottom: big.NewInt(int64(0)), + }, + expectedNumberOfItems: 10, + }, + { + name: "asc second page using next cursor", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(10)), + Order: paginate.OrderAsc, + Bottom: big.NewInt(int64(0)), + }, + expectedPrevious: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + Order: paginate.OrderAsc, + Bottom: big.NewInt(int64(0)), + PaginationID: big.NewInt(int64(10)), + Reverse: true, + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(20)), + Order: paginate.OrderAsc, + Bottom: big.NewInt(int64(0)), + }, + expectedNumberOfItems: 10, + }, + { + name: "asc last page using next cursor", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(90)), + Order: paginate.OrderAsc, + Bottom: big.NewInt(int64(0)), + }, + expectedPrevious: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + Order: paginate.OrderAsc, + PaginationID: big.NewInt(int64(90)), + Bottom: big.NewInt(int64(0)), + Reverse: true, + }, + expectedNumberOfItems: 10, + }, + { + name: "desc first page", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + Order: paginate.OrderDesc, + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(99)), + Column: "id", + PaginationID: big.NewInt(int64(89)), + Order: paginate.OrderDesc, + }, + expectedNumberOfItems: 10, + }, + { + name: "desc second page using next cursor", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(99)), + Column: "id", + PaginationID: big.NewInt(int64(89)), + Order: paginate.OrderDesc, + }, + expectedPrevious: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(99)), + Column: "id", + PaginationID: big.NewInt(int64(89)), + Order: paginate.OrderDesc, + Reverse: true, + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(99)), + Column: "id", + PaginationID: big.NewInt(int64(79)), + Order: paginate.OrderDesc, + }, + expectedNumberOfItems: 10, + }, + { + name: "desc last page using next cursor", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(99)), + Column: "id", + PaginationID: big.NewInt(int64(9)), + Order: paginate.OrderDesc, + }, + expectedPrevious: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(99)), + Column: "id", + PaginationID: big.NewInt(int64(9)), + Order: paginate.OrderDesc, + Reverse: true, + }, + expectedNumberOfItems: 10, + }, + { + name: "asc first page using previous cursor", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(0)), + Column: "id", + PaginationID: big.NewInt(int64(10)), + Order: paginate.OrderAsc, + Reverse: true, + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(0)), + Column: "id", + PaginationID: big.NewInt(int64(10)), + Order: paginate.OrderAsc, + }, + expectedNumberOfItems: 10, + }, + { + name: "desc first page using previous cursor", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(99)), + Column: "id", + PaginationID: big.NewInt(int64(89)), + Order: paginate.OrderDesc, + Reverse: true, + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Bottom: big.NewInt(int64(99)), + Column: "id", + PaginationID: big.NewInt(int64(89)), + Order: paginate.OrderDesc, + }, + expectedNumberOfItems: 10, + }, + { + name: "asc first page with filter", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + Order: paginate.OrderAsc, + Options: true, + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(20)), + Order: paginate.OrderAsc, + Options: true, + Bottom: big.NewInt(int64(0)), + }, + expectedNumberOfItems: 10, + }, + { + name: "asc second page with filter", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(20)), + Order: paginate.OrderAsc, + Options: true, + Bottom: big.NewInt(int64(0)), + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(40)), + Order: paginate.OrderAsc, + Options: true, + Bottom: big.NewInt(int64(0)), + }, + expectedPrevious: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(20)), + Order: paginate.OrderAsc, + Options: true, + Bottom: big.NewInt(int64(0)), + Reverse: true, + }, + expectedNumberOfItems: 10, + }, + { + name: "desc first page with filter", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + Order: paginate.OrderDesc, + Options: true, + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(78)), + Order: paginate.OrderDesc, + Options: true, + Bottom: big.NewInt(int64(98)), + }, + expectedNumberOfItems: 10, + }, + { + name: "desc second page with filter", + query: paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(78)), + Order: paginate.OrderDesc, + Options: true, + Bottom: big.NewInt(int64(98)), + }, + expectedNext: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(58)), + Order: paginate.OrderDesc, + Options: true, + Bottom: big.NewInt(int64(98)), + }, + expectedPrevious: &paginate.ColumnPaginatedQuery[bool]{ + PageSize: 10, + Column: "id", + PaginationID: big.NewInt(int64(78)), + Order: paginate.OrderDesc, + Options: true, + Bottom: big.NewInt(int64(98)), + Reverse: true, + }, + expectedNumberOfItems: 10, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + models := make([]model, 0) + query := db.NewSelect().Model(&models).Column("id") + if tc.query.Options { + query = query.Where("pair = ?", true) + } + cursor, err := paginate.UsingColumn[bool, model](context.Background(), query, tc.query) + require.NoError(t, err) + + if tc.expectedNext == nil { + require.Empty(t, cursor.Next) + } else { + require.NotEmpty(t, cursor.Next) + + q := paginate.ColumnPaginatedQuery[bool]{} + require.NoError(t, paginate.UnmarshalCursor(cursor.Next, &q)) + require.EqualValues(t, *tc.expectedNext, q) + } + + if tc.expectedPrevious == nil { + require.Empty(t, cursor.Previous) + } else { + require.NotEmpty(t, cursor.Previous) + + q := paginate.ColumnPaginatedQuery[bool]{} + require.NoError(t, paginate.UnmarshalCursor(cursor.Previous, &q)) + require.EqualValues(t, *tc.expectedPrevious, q) + } + }) + } +} diff --git a/components/ledger/pkg/storage/ledgerstore/pagination_offset.go b/components/ledger/internal/storage/paginate/pagination_offset.go similarity index 98% rename from components/ledger/pkg/storage/ledgerstore/pagination_offset.go rename to components/ledger/internal/storage/paginate/pagination_offset.go index b20ab7be9..9630b3d01 100644 --- a/components/ledger/pkg/storage/ledgerstore/pagination_offset.go +++ b/components/ledger/internal/storage/paginate/pagination_offset.go @@ -1,4 +1,4 @@ -package ledgerstore +package paginate import ( "context" diff --git a/components/ledger/internal/storage/paginate/pagination_offset_test.go b/components/ledger/internal/storage/paginate/pagination_offset_test.go new file mode 100644 index 000000000..24abfed0d --- /dev/null +++ b/components/ledger/internal/storage/paginate/pagination_offset_test.go @@ -0,0 +1,170 @@ +package paginate_test + +import ( + "context" + "testing" + + "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/paginate" + "github.com/formancehq/stack/libs/go-libs/pgtesting" + "github.com/stretchr/testify/require" +) + +func TestOffsetPagination(t *testing.T) { + t.Parallel() + + pgServer := pgtesting.NewPostgresDatabase(t) + db, err := storage.OpenSQLDB(storage.ConnectionOptions{ + DatabaseSourceName: pgServer.ConnString(), + Debug: testing.Verbose(), + }) + require.NoError(t, err) + + _, err = db.Exec(` + CREATE TABLE "models" (id int, pair boolean); + `) + require.NoError(t, err) + + type model struct { + ID uint64 `bun:"id"` + Pair bool `bun:"pair"` + } + + models := make([]model, 0) + for i := 0; i < 100; i++ { + models = append(models, model{ + ID: uint64(i), + Pair: i%2 == 0, + }) + } + + _, err = db.NewInsert(). + Model(&models). + Exec(context.Background()) + require.NoError(t, err) + + type testCase struct { + name string + query paginate.OffsetPaginatedQuery[bool] + expectedNext *paginate.OffsetPaginatedQuery[bool] + expectedPrevious *paginate.OffsetPaginatedQuery[bool] + expectedNumberOfItems uint64 + } + testCases := []testCase{ + { + name: "asc first page", + query: paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Order: paginate.OrderAsc, + }, + expectedNext: &paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Offset: 10, + Order: paginate.OrderAsc, + }, + expectedNumberOfItems: 10, + }, + { + name: "asc second page using next cursor", + query: paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Offset: 10, + Order: paginate.OrderAsc, + }, + expectedPrevious: &paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Order: paginate.OrderAsc, + Offset: 0, + }, + expectedNext: &paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Order: paginate.OrderAsc, + Offset: 20, + }, + expectedNumberOfItems: 10, + }, + { + name: "asc last page using next cursor", + query: paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Offset: 90, + Order: paginate.OrderAsc, + }, + expectedPrevious: &paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Order: paginate.OrderAsc, + Offset: 80, + }, + expectedNumberOfItems: 10, + }, + { + name: "asc last page partial", + query: paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Offset: 95, + Order: paginate.OrderAsc, + }, + expectedPrevious: &paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Order: paginate.OrderAsc, + Offset: 85, + }, + expectedNumberOfItems: 10, + }, + { + name: "asc fist page partial", + query: paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Offset: 5, + Order: paginate.OrderAsc, + }, + expectedPrevious: &paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Order: paginate.OrderAsc, + Offset: 0, + }, + expectedNext: &paginate.OffsetPaginatedQuery[bool]{ + PageSize: 10, + Order: paginate.OrderAsc, + Offset: 15, + }, + expectedNumberOfItems: 10, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + + query := db.NewSelect().Model(&models).Column("id") + if tc.query.Options { + query = query.Where("pair = ?", true) + } + cursor, err := paginate.UsingOffset[bool, model]( + context.Background(), + query, + tc.query) + require.NoError(t, err) + + if tc.expectedNext == nil { + require.Empty(t, cursor.Next) + } else { + require.NotEmpty(t, cursor.Next) + + q := paginate.OffsetPaginatedQuery[bool]{} + require.NoError(t, paginate.UnmarshalCursor(cursor.Next, &q)) + require.EqualValues(t, *tc.expectedNext, q) + } + + if tc.expectedPrevious == nil { + require.Empty(t, cursor.Previous) + } else { + require.NotEmpty(t, cursor.Previous) + + q := paginate.OffsetPaginatedQuery[bool]{} + require.NoError(t, paginate.UnmarshalCursor(cursor.Previous, &q)) + require.EqualValues(t, *tc.expectedPrevious, q) + } + }) + } +} diff --git a/components/ledger/internal/storage/query/expression.go b/components/ledger/internal/storage/query/expression.go new file mode 100644 index 000000000..47a2eb052 --- /dev/null +++ b/components/ledger/internal/storage/query/expression.go @@ -0,0 +1,223 @@ +package query + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/pkg/errors" +) + +type Context interface { + BuildMatcher(key, operator string, value any) (string, []any, error) +} +type ContextFn func(key, operator string, value any) (string, []any, error) + +func (fn ContextFn) BuildMatcher(key, operator string, value any) (string, []any, error) { + return fn(key, operator, value) +} + +type Builder interface { + Build(Context) (string, []any, error) +} + +type set struct { + operator string + items []Builder +} + +var _ Builder = (*set)(nil) + +func (set set) Build(ctx Context) (string, []any, error) { + clauses := make([]string, 0) + args := make([]any, 0) + for _, builder := range set.items { + clause, clauseArgs, err := builder.Build(ctx) + if err != nil { + return "", nil, err + } + clauses = append(clauses, clause) + args = append(args, clauseArgs...) + } + return "(" + strings.Join(clauses, fmt.Sprintf(") %s (", set.operator)) + ")", args, nil +} + +type keyValue struct { + operator string + key string + value any +} + +var _ Builder = (*keyValue)(nil) + +func (k keyValue) Build(ctx Context) (string, []any, error) { + return ctx.BuildMatcher(k.key, k.operator, k.value) +} + +type not struct { + expression Builder +} + +var _ Builder = (*not)(nil) + +func (n not) Build(context Context) (string, []any, error) { + sub, args, err := n.expression.Build(context) + if err != nil { + return "", nil, err + } + return fmt.Sprintf("not (%s)", sub), args, nil +} + +func Not(expr Builder) not { + return not{ + expression: expr, + } +} + +func Match(key string, value any) keyValue { + return keyValue{ + operator: "$match", + key: key, + value: value, + } +} + +func Or(items ...Builder) set { + return set{ + operator: "or", + items: items, + } +} + +func And(items ...Builder) set { + return set{ + operator: "and", + items: items, + } +} + +func Lt(key string, value any) keyValue { + return keyValue{ + operator: "$lt", + key: key, + value: value, + } +} + +func Lte(key string, value any) keyValue { + return keyValue{ + operator: "$lte", + key: key, + value: value, + } +} + +func Gt(key string, value any) keyValue { + return keyValue{ + operator: "$gt", + key: key, + value: value, + } +} + +func Gte(key string, value any) keyValue { + return keyValue{ + operator: "$gte", + key: key, + value: value, + } +} + +func singleKey(m map[string]any) (string, any, error) { + switch { + case len(m) == 0: + return "", nil, fmt.Errorf("expected single key, found none") + case len(m) > 1: + return "", nil, fmt.Errorf("expected single key, found more then one") + default: + var ( + key string + value any + ) + for key, value = range m { + } + return key, value, nil + } +} + +func parseSet(operator string, value any) (set, error) { + set := set{ + operator: operator[1:], + } + switch value := value.(type) { + case []any: + for ind, sub := range value { + switch sub := sub.(type) { + case map[string]any: + subExpression, err := mapMapToExpression(sub) + if err != nil { + return set, err + } + set.items = append(set.items, subExpression) + default: + return set, fmt.Errorf("unexpected type %T when decoding %s clause at index %d", value, operator, ind) + } + } + return set, nil + default: + return set, fmt.Errorf("unexpected type %T", value) + } +} + +func parseKeyValue(operator string, m any) (keyValue, error) { + kv := keyValue{ + operator: operator, + } + switch m := m.(type) { + case map[string]any: + key, value, err := singleKey(m) + if err != nil { + return kv, err + } + kv.key = key + kv.value = value + return kv, nil + default: + return kv, fmt.Errorf("unexpected type %T", m) + } +} + +func mapMapToExpression(m map[string]any) (Builder, error) { + operator, value, err := singleKey(m) + if err != nil { + return nil, err + } + switch operator { + case "$and", "$or": + and, err := parseSet(operator, value) + if err != nil { + return nil, errors.Wrap(err, "parsing $and") + } + return and, nil + case "$match", "$gte", "$lte", "$gt", "$lt": + match, err := parseKeyValue(operator, value) + if err != nil { + return nil, errors.Wrapf(err, "parsing %s", operator) + } + return match, nil + default: + return nil, fmt.Errorf("unexpected operator %s", operator) + } +} + +func ParseJSON(data string) (Builder, error) { + if len(data) == 0 { + return nil, nil + } + m := make(map[string]any) + if err := json.Unmarshal([]byte(data), &m); err != nil { + panic(err) + } + + return mapMapToExpression(m) +} diff --git a/components/ledger/internal/storage/query/expression_test.go b/components/ledger/internal/storage/query/expression_test.go new file mode 100644 index 000000000..8057630b3 --- /dev/null +++ b/components/ledger/internal/storage/query/expression_test.go @@ -0,0 +1,41 @@ +package query + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseExpression(t *testing.T) { + json := `{ + "$and": [ + { + "$match": { + "account": "accounts::pending" + } + }, + { + "$or": [ + { + "$gte": { + "balance": 1000 + } + }, + { + "$match": { + "metadata[category]": "gold" + } + } + ] + } + ] +}` + expr, err := ParseJSON(json) + require.NoError(t, err) + + _, _, err = expr.Build(ContextFn(func(key, operator string, value any) (string, []any, error) { + return fmt.Sprintf("%s %s ?", key, DefaultComparisonOperatorsMapping[operator]), []any{value}, nil + })) + require.NoError(t, err) +} diff --git a/components/ledger/internal/storage/query/mapping.go b/components/ledger/internal/storage/query/mapping.go new file mode 100644 index 000000000..366a29508 --- /dev/null +++ b/components/ledger/internal/storage/query/mapping.go @@ -0,0 +1,9 @@ +package query + +var DefaultComparisonOperatorsMapping = map[string]string{ + "$match": "=", + "$gte": ">=", + "$gt": ">", + "$lte": "<=", + "$lt": "<", +} diff --git a/components/ledger/pkg/storage/storagetesting/storage.go b/components/ledger/internal/storage/storagetesting/storage.go similarity index 82% rename from components/ledger/pkg/storage/storagetesting/storage.go rename to components/ledger/internal/storage/storagetesting/storage.go index c3eaac89b..e9fe2fafb 100644 --- a/components/ledger/pkg/storage/storagetesting/storage.go +++ b/components/ledger/internal/storage/storagetesting/storage.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/driver" + "github.com/formancehq/ledger/internal/storage" + "github.com/formancehq/ledger/internal/storage/driver" "github.com/formancehq/stack/libs/go-libs/pgtesting" "github.com/stretchr/testify/require" ) @@ -27,7 +27,7 @@ func StorageDriver(t pgtesting.TestingT) *driver.Driver { db.Close() }) - d := driver.New(storage.NewDatabase(db)) + d := driver.New(db) require.NoError(t, d.Initialize(context.Background())) diff --git a/components/ledger/internal/storage/systemstore/configuration.go b/components/ledger/internal/storage/systemstore/configuration.go new file mode 100644 index 000000000..def2efe22 --- /dev/null +++ b/components/ledger/internal/storage/systemstore/configuration.go @@ -0,0 +1,60 @@ +package systemstore + +import ( + "context" + + ledger "github.com/formancehq/ledger/internal" + storageerrors "github.com/formancehq/ledger/internal/storage" + "github.com/uptrace/bun" +) + +type configuration struct { + bun.BaseModel `bun:"_system.configuration,alias:configuration"` + + Key string `bun:"key,type:varchar(255),pk"` // Primary key + Value string `bun:"value,type:text"` + AddedAt ledger.Time `bun:"addedAt,type:timestamp"` +} + +func (s *Store) CreateConfigurationTable(ctx context.Context) error { + _, err := s.db.NewCreateTable(). + Model((*configuration)(nil)). + IfNotExists(). + Exec(ctx) + + return storageerrors.PostgresError(err) +} + +func (s *Store) GetConfiguration(ctx context.Context, key string) (string, error) { + query := s.db.NewSelect(). + Model((*configuration)(nil)). + Column("value"). + Where("key = ?", key). + Limit(1). + String() + + row := s.db.QueryRowContext(ctx, query) + if row.Err() != nil { + return "", storageerrors.PostgresError(row.Err()) + } + var value string + if err := row.Scan(&value); err != nil { + return "", storageerrors.PostgresError(err) + } + + return value, nil +} + +func (s *Store) InsertConfiguration(ctx context.Context, key, value string) error { + config := &configuration{ + Key: key, + Value: value, + AddedAt: ledger.Now(), + } + + _, err := s.db.NewInsert(). + Model(config). + Exec(ctx) + + return storageerrors.PostgresError(err) +} diff --git a/components/ledger/internal/storage/systemstore/ledgers.go b/components/ledger/internal/storage/systemstore/ledgers.go new file mode 100644 index 000000000..a2f3b2582 --- /dev/null +++ b/components/ledger/internal/storage/systemstore/ledgers.go @@ -0,0 +1,101 @@ +package systemstore + +import ( + "context" + + ledger "github.com/formancehq/ledger/internal" + storageerrors "github.com/formancehq/ledger/internal/storage" + "github.com/pkg/errors" + "github.com/uptrace/bun" +) + +type Ledgers struct { + bun.BaseModel `bun:"_system.ledgers,alias:ledgers"` + + Ledger string `bun:"ledger,type:varchar(255),pk"` // Primary key + AddedAt ledger.Time `bun:"addedat,type:timestamp"` +} + +func (s *Store) CreateLedgersTable(ctx context.Context) error { + _, err := s.db.NewCreateTable(). + Model((*Ledgers)(nil)). + IfNotExists(). + Exec(ctx) + + return storageerrors.PostgresError(err) +} + +func (s *Store) ListLedgers(ctx context.Context) ([]string, error) { + query := s.db.NewSelect(). + Model((*Ledgers)(nil)). + Column("ledger"). + String() + + rows, err := s.db.QueryContext(ctx, query) + if err != nil { + return nil, storageerrors.PostgresError(err) + } + defer rows.Close() + + res := make([]string, 0) + for rows.Next() { + var ledger string + if err := rows.Scan(&ledger); err != nil { + return nil, storageerrors.PostgresError(err) + } + res = append(res, ledger) + } + return res, nil +} + +func (s *Store) DeleteLedger(ctx context.Context, name string) error { + _, err := s.db.NewDelete(). + Model((*Ledgers)(nil)). + Where("ledger = ?", name). + Exec(ctx) + + return errors.Wrap(storageerrors.PostgresError(err), "delete ledger from system store") +} + +func (s *Store) Register(ctx context.Context, ledgerName string) (bool, error) { + l := &Ledgers{ + Ledger: ledgerName, + AddedAt: ledger.Now(), + } + + ret, err := s.db.NewInsert(). + Model(l). + Ignore(). + Exec(ctx) + if err != nil { + return false, storageerrors.PostgresError(err) + } + + affected, err := ret.RowsAffected() + if err != nil { + return false, storageerrors.PostgresError(err) + } + + return affected > 0, nil +} + +func (s *Store) Exists(ctx context.Context, ledger string) (bool, error) { + query := s.db.NewSelect(). + Model((*Ledgers)(nil)). + Column("ledger"). + Where("ledger = ?", ledger). + String() + + ret := s.db.QueryRowContext(ctx, query) + if ret.Err() != nil { + return false, nil + } + + var t string + _ = ret.Scan(&t) // Trigger close + + if t == "" { + return false, nil + } + return true, nil +} diff --git a/components/ledger/internal/storage/systemstore/store.go b/components/ledger/internal/storage/systemstore/store.go new file mode 100644 index 000000000..2aaae497a --- /dev/null +++ b/components/ledger/internal/storage/systemstore/store.go @@ -0,0 +1,24 @@ +package systemstore + +import ( + "context" + + "github.com/formancehq/ledger/internal/storage" + "github.com/uptrace/bun" +) + +type Store struct { + db *bun.DB +} + +func NewStore(db *bun.DB) *Store { + return &Store{db: db} +} + +func (s *Store) Initialize(ctx context.Context) error { + if err := s.CreateLedgersTable(ctx); err != nil { + return storage.PostgresError(err) + } + + return storage.PostgresError(s.CreateConfigurationTable(ctx)) +} diff --git a/components/ledger/internal/storage/utils.go b/components/ledger/internal/storage/utils.go new file mode 100644 index 000000000..c2721a8c3 --- /dev/null +++ b/components/ledger/internal/storage/utils.go @@ -0,0 +1,58 @@ +package storage + +import ( + "database/sql" + "fmt" + "io" + "time" + + "github.com/formancehq/stack/libs/go-libs/bun/bundebug" + "github.com/uptrace/bun" + "github.com/uptrace/bun/dialect/pgdialect" + "github.com/uptrace/bun/extra/bunotel" +) + +type ConnectionOptions struct { + DatabaseSourceName string + Debug bool + Writer io.Writer + MaxIdleConns int + MaxOpenConns int + ConnMaxIdleTime time.Duration +} + +func (opts ConnectionOptions) String() string { + return fmt.Sprintf("dsn=%s, debug=%v, max-idle-conns=%d, max-open-conns=%d, conn-max-idle-time=%s", + opts.DatabaseSourceName, opts.Debug, opts.MaxIdleConns, opts.MaxOpenConns, opts.ConnMaxIdleTime) +} + +func OpenSQLDB(options ConnectionOptions, hooks ...bun.QueryHook) (*bun.DB, error) { + sqldb, err := sql.Open("postgres", options.DatabaseSourceName) + if err != nil { + return nil, err + } + if options.MaxIdleConns != 0 { + sqldb.SetMaxIdleConns(options.MaxIdleConns) + } + if options.ConnMaxIdleTime != 0 { + sqldb.SetConnMaxIdleTime(options.ConnMaxIdleTime) + } + if options.MaxOpenConns != 0 { + sqldb.SetMaxOpenConns(options.MaxOpenConns) + } + + db := bun.NewDB(sqldb, pgdialect.New(), bun.WithDiscardUnknownColumns()) + if options.Debug { + db.AddQueryHook(bundebug.NewQueryHook()) + } + db.AddQueryHook(bunotel.NewQueryHook()) + for _, hook := range hooks { + db.AddQueryHook(hook) + } + + if err := db.Ping(); err != nil { + return nil, err + } + + return db, nil +} diff --git a/components/ledger/internal/testing/compare.go b/components/ledger/internal/testing/compare.go new file mode 100644 index 000000000..0e978c8c2 --- /dev/null +++ b/components/ledger/internal/testing/compare.go @@ -0,0 +1,20 @@ +package testing + +import ( + "math/big" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" +) + +func bigIntComparer(v1 *big.Int, v2 *big.Int) bool { + return v1.String() == v2.String() +} + +func RequireEqual(t *testing.T, expected, actual any) { + t.Helper() + if diff := cmp.Diff(expected, actual, cmp.Comparer(bigIntComparer)); diff != "" { + require.Failf(t, "Content not matching", diff) + } +} diff --git a/components/ledger/pkg/core/time.go b/components/ledger/internal/time.go similarity index 98% rename from components/ledger/pkg/core/time.go rename to components/ledger/internal/time.go index 41abca40e..1361aee20 100644 --- a/components/ledger/pkg/core/time.go +++ b/components/ledger/internal/time.go @@ -1,4 +1,4 @@ -package core +package ledger import ( "database/sql/driver" @@ -21,7 +21,7 @@ func (t *Time) Scan(src interface{}) (err error) { switch src := src.(type) { case time.Time: *t = Time{ - Time: src, + Time: src.UTC(), } return nil case string: diff --git a/components/ledger/internal/transaction.go b/components/ledger/internal/transaction.go new file mode 100644 index 000000000..b96173f07 --- /dev/null +++ b/components/ledger/internal/transaction.go @@ -0,0 +1,116 @@ +package ledger + +import ( + "math/big" + + "github.com/formancehq/stack/libs/go-libs/metadata" +) + +type Transactions struct { + Transactions []TransactionData `json:"transactions"` +} + +type TransactionData struct { + Postings Postings `json:"postings"` + Metadata metadata.Metadata `json:"metadata"` + Timestamp Time `json:"timestamp"` + Reference string `json:"reference"` +} + +func (d TransactionData) WithPostings(postings ...Posting) TransactionData { + d.Postings = append(d.Postings, postings...) + return d +} + +func NewTransactionData() TransactionData { + return TransactionData{ + Metadata: metadata.Metadata{}, + } +} + +func (t *TransactionData) Reverse() TransactionData { + postings := make(Postings, len(t.Postings)) + copy(postings, t.Postings) + postings.Reverse() + + return TransactionData{ + Postings: postings, + } +} + +func (d TransactionData) WithDate(now Time) TransactionData { + d.Timestamp = now + + return d +} + +type Transaction struct { + TransactionData + ID *big.Int `json:"id"` + Reverted bool `json:"reverted"` +} + +func (t *Transaction) WithPostings(postings ...Posting) *Transaction { + t.TransactionData = t.TransactionData.WithPostings(postings...) + return t +} + +func (t *Transaction) WithReference(ref string) *Transaction { + t.Reference = ref + return t +} + +func (t *Transaction) WithDate(ts Time) *Transaction { + t.Timestamp = ts + return t +} + +func (t *Transaction) WithIDUint64(id uint64) *Transaction { + t.ID = big.NewInt(int64(id)) + return t +} + +func (t *Transaction) WithID(id *big.Int) *Transaction { + t.ID = id + return t +} + +func (t *Transaction) WithMetadata(m metadata.Metadata) *Transaction { + t.Metadata = m + return t +} + +func NewTransaction() *Transaction { + return &Transaction{ + ID: big.NewInt(0), + TransactionData: NewTransactionData(). + WithDate(Now()), + } +} + +type ExpandedTransaction struct { + Transaction + PreCommitVolumes AccountsAssetsVolumes `json:"preCommitVolumes,omitempty"` + PostCommitVolumes AccountsAssetsVolumes `json:"postCommitVolumes,omitempty"` + PreCommitEffectiveVolumes AccountsAssetsVolumes `json:"preCommitEffectiveVolumes,omitempty"` + PostCommitEffectiveVolumes AccountsAssetsVolumes `json:"postCommitEffectiveVolumes,omitempty"` +} + +func (t *ExpandedTransaction) AppendPosting(p Posting) { + t.Postings = append(t.Postings, p) +} + +func ExpandTransaction(tx *Transaction, preCommitVolumes AccountsAssetsVolumes) ExpandedTransaction { + postCommitVolumes := preCommitVolumes.Copy() + for _, posting := range tx.Postings { + preCommitVolumes.AddInput(posting.Destination, posting.Asset, Zero) + preCommitVolumes.AddOutput(posting.Source, posting.Asset, Zero) + postCommitVolumes.AddOutput(posting.Source, posting.Asset, posting.Amount) + postCommitVolumes.AddInput(posting.Destination, posting.Asset, posting.Amount) + } + return ExpandedTransaction{ + Transaction: *tx, + PreCommitVolumes: preCommitVolumes, + PostCommitVolumes: postCommitVolumes, + } +} diff --git a/components/ledger/pkg/core/transaction_test.go b/components/ledger/internal/transaction_test.go similarity index 99% rename from components/ledger/pkg/core/transaction_test.go rename to components/ledger/internal/transaction_test.go index 3bd0390aa..0263c8ca2 100644 --- a/components/ledger/pkg/core/transaction_test.go +++ b/components/ledger/internal/transaction_test.go @@ -1,4 +1,4 @@ -package core +package ledger import ( "math/big" diff --git a/components/ledger/internal/volumes.go b/components/ledger/internal/volumes.go new file mode 100644 index 000000000..479422dd3 --- /dev/null +++ b/components/ledger/internal/volumes.go @@ -0,0 +1,249 @@ +package ledger + +import ( + "database/sql/driver" + "encoding/json" + "math/big" +) + +type Volumes struct { + Input *big.Int `json:"input"` + Output *big.Int `json:"output"` +} + +func (v Volumes) CopyWithZerosIfNeeded() *Volumes { + var input *big.Int + if v.Input == nil { + input = &big.Int{} + } else { + input = new(big.Int).Set(v.Input) + } + var output *big.Int + if v.Output == nil { + output = &big.Int{} + } else { + output = new(big.Int).Set(v.Output) + } + return &Volumes{ + Input: input, + Output: output, + } +} + +func (v Volumes) WithInput(input *big.Int) *Volumes { + v.Input = input + return &v +} + +func (v Volumes) WithInputInt64(value int64) *Volumes { + v.Input = big.NewInt(value) + return &v +} + +func (v Volumes) WithOutput(output *big.Int) *Volumes { + v.Output = output + return &v +} + +func (v Volumes) WithOutputInt64(value int64) *Volumes { + v.Output = big.NewInt(value) + return &v +} + +func NewEmptyVolumes() *Volumes { + return &Volumes{ + Input: new(big.Int), + Output: new(big.Int), + } +} + +func NewVolumesInt64(input, output int64) *Volumes { + return &Volumes{ + Input: big.NewInt(input), + Output: big.NewInt(output), + } +} + +type VolumesWithBalance struct { + Input *big.Int `json:"input"` + Output *big.Int `json:"output"` + Balance *big.Int `json:"balance"` +} + +func (v Volumes) MarshalJSON() ([]byte, error) { + return json.Marshal(VolumesWithBalance{ + Input: v.Input, + Output: v.Output, + Balance: v.Balance(), + }) +} + +func (v Volumes) Balance() *big.Int { + input := v.Input + if input == nil { + input = Zero + } + output := v.Output + if output == nil { + output = Zero + } + return new(big.Int).Sub(input, output) +} + +func (v Volumes) copy() *Volumes { + return &Volumes{ + Input: new(big.Int).Set(v.Input), + Output: new(big.Int).Set(v.Output), + } +} + +type BalancesByAssets map[string]*big.Int + +type VolumesByAssets map[string]*Volumes + +type BalancesByAssetsByAccounts map[string]BalancesByAssets + +func (v VolumesByAssets) Balances() BalancesByAssets { + balances := BalancesByAssets{} + for asset, vv := range v { + balances[asset] = new(big.Int).Sub(vv.Input, vv.Output) + } + return balances +} + +func (v VolumesByAssets) copy() VolumesByAssets { + ret := VolumesByAssets{} + for key, volumes := range v { + ret[key] = volumes.copy() + } + return ret +} + +type AccountsAssetsVolumes map[string]VolumesByAssets + +func (a AccountsAssetsVolumes) GetVolumes(account, asset string) *Volumes { + if a == nil { + return &Volumes{ + Input: &big.Int{}, + Output: &big.Int{}, + } + } + if assetsVolumes, ok := a[account]; !ok { + return &Volumes{ + Input: &big.Int{}, + Output: &big.Int{}, + } + } else { + return &Volumes{ + Input: assetsVolumes[asset].Input, + Output: assetsVolumes[asset].Output, + } + } +} + +func (a *AccountsAssetsVolumes) SetVolumes(account, asset string, volumes *Volumes) { + if *a == nil { + *a = AccountsAssetsVolumes{} + } + if assetsVolumes, ok := (*a)[account]; !ok { + (*a)[account] = map[string]*Volumes{ + asset: volumes.CopyWithZerosIfNeeded(), + } + } else { + assetsVolumes[asset] = volumes.CopyWithZerosIfNeeded() + } +} + +func (a *AccountsAssetsVolumes) AddInput(account, asset string, input *big.Int) { + if *a == nil { + *a = AccountsAssetsVolumes{} + } + if assetsVolumes, ok := (*a)[account]; !ok { + (*a)[account] = map[string]*Volumes{ + asset: { + Input: input, + Output: &big.Int{}, + }, + } + } else { + volumes := assetsVolumes[asset].CopyWithZerosIfNeeded() + volumes.Input.Add(volumes.Input, input) + assetsVolumes[asset] = volumes + } +} + +func (a *AccountsAssetsVolumes) AddOutput(account, asset string, output *big.Int) { + if *a == nil { + *a = AccountsAssetsVolumes{} + } + if assetsVolumes, ok := (*a)[account]; !ok { + (*a)[account] = map[string]*Volumes{ + asset: { + Output: output, + Input: &big.Int{}, + }, + } + } else { + volumes := assetsVolumes[asset].CopyWithZerosIfNeeded() + volumes.Output.Add(volumes.Output, output) + assetsVolumes[asset] = volumes + } +} + +func (a AccountsAssetsVolumes) HasAccount(account string) bool { + if a == nil { + return false + } + _, ok := a[account] + return ok +} + +func (a AccountsAssetsVolumes) HasAccountAndAsset(account, asset string) bool { + if a == nil { + return false + } + volumesByAsset, ok := a[account] + if !ok { + return false + } + _, ok = volumesByAsset[asset] + return ok +} + +// Scan - Implement the database/sql scanner interface +func (a *AccountsAssetsVolumes) Scan(value interface{}) error { + if value == nil { + return nil + } + + val, err := driver.String.ConvertValue(value) + if err != nil { + return err + } + + *a = AccountsAssetsVolumes{} + switch val := val.(type) { + case []uint8: + return json.Unmarshal(val, a) + case string: + return json.Unmarshal([]byte(val), a) + default: + panic("not handled type") + } +} + +func (a AccountsAssetsVolumes) Copy() AccountsAssetsVolumes { + ret := AccountsAssetsVolumes{} + for key, volumes := range a { + ret[key] = volumes.copy() + } + return ret +} + +func (a AccountsAssetsVolumes) Balances() BalancesByAssetsByAccounts { + ret := BalancesByAssetsByAccounts{} + for account, volumesByAssets := range a { + ret[account] = volumesByAssets.Balances() + } + return ret +} diff --git a/components/ledger/libs/bun/bundebug/debug_hook.go b/components/ledger/libs/bun/bundebug/debug_hook.go new file mode 100644 index 000000000..236177352 --- /dev/null +++ b/components/ledger/libs/bun/bundebug/debug_hook.go @@ -0,0 +1,41 @@ +package bundebug + +import ( + "context" + "fmt" + "time" + + "github.com/formancehq/stack/libs/go-libs/logging" + + "github.com/uptrace/bun" +) + +type QueryHook struct{} + +var _ bun.QueryHook = (*QueryHook)(nil) + +func NewQueryHook() *QueryHook { + return &QueryHook{} +} + +func (h *QueryHook) BeforeQuery( + ctx context.Context, event *bun.QueryEvent, +) context.Context { + return ctx +} + +func (h *QueryHook) AfterQuery(ctx context.Context, event *bun.QueryEvent) { + dur := time.Since(event.StartTime) + + fields := map[string]any{ + "component": "bun", + "operation": event.Operation(), + "duration": fmt.Sprintf("%s", dur.Round(time.Microsecond)), + } + + if event.Err != nil { + fields["err"] = event.Err.Error() + } + + logging.FromContext(ctx).WithFields(fields).Debug(event.Query) +} diff --git a/components/ledger/libs/bun/bunexplain/explain_hook.go b/components/ledger/libs/bun/bunexplain/explain_hook.go new file mode 100644 index 000000000..5767cc30a --- /dev/null +++ b/components/ledger/libs/bun/bunexplain/explain_hook.go @@ -0,0 +1,50 @@ +package bunexplain + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/uptrace/bun" +) + +//nolint:unused +type explainHook struct{} + +//nolint:unused +func (h *explainHook) AfterQuery(ctx context.Context, event *bun.QueryEvent) {} + +//nolint:unused +func (h *explainHook) BeforeQuery(ctx context.Context, event *bun.QueryEvent) context.Context { + lowerQuery := strings.ToLower(event.Query) + if strings.HasPrefix(lowerQuery, "explain") || + strings.HasPrefix(lowerQuery, "create") || + strings.HasPrefix(lowerQuery, "begin") || + strings.HasPrefix(lowerQuery, "alter") || + strings.HasPrefix(lowerQuery, "rollback") || + strings.HasPrefix(lowerQuery, "commit") { + return ctx + } + + event.DB.RunInTx(context.Background(), &sql.TxOptions{}, func(ctx context.Context, tx bun.Tx) error { + rows, err := tx.Query("explain analyze " + event.Query) + if err != nil { + return err + } + defer rows.Next() + + for rows.Next() { + var line string + if err := rows.Scan(&line); err != nil { + return err + } + fmt.Println(line) + } + + return tx.Rollback() + + }) + + return ctx +} diff --git a/components/ledger/libs/httpserver/serverport.go b/components/ledger/libs/httpserver/serverport.go index 86a16f761..d1e096d06 100644 --- a/components/ledger/libs/httpserver/serverport.go +++ b/components/ledger/libs/httpserver/serverport.go @@ -18,7 +18,7 @@ type serverInfoContextKey string var serverInfoKey serverInfoContextKey = "_serverInfo" -func getActualServerInfo(ctx context.Context) *serverInfo { +func GetActualServerInfo(ctx context.Context) *serverInfo { siAsAny := ctx.Value(serverInfoKey) if siAsAny == nil { return nil @@ -33,7 +33,7 @@ func ContextWithServerInfo(ctx context.Context) context.Context { } func Started(ctx context.Context) chan struct{} { - si := getActualServerInfo(ctx) + si := GetActualServerInfo(ctx) if si == nil { return nil } @@ -41,7 +41,7 @@ func Started(ctx context.Context) chan struct{} { } func Port(ctx context.Context) int { - si := getActualServerInfo(ctx) + si := GetActualServerInfo(ctx) if si == nil { return 0 } @@ -49,7 +49,7 @@ func Port(ctx context.Context) int { } func StartedServer(ctx context.Context, listener net.Listener) { - si := getActualServerInfo(ctx) + si := GetActualServerInfo(ctx) if si == nil { return } diff --git a/components/ledger/libs/migrations/migration.go b/components/ledger/libs/migrations/migration.go index f3aecbe0a..1405f18bd 100644 --- a/components/ledger/libs/migrations/migration.go +++ b/components/ledger/libs/migrations/migration.go @@ -1,9 +1,13 @@ package migrations import ( + "context" + "github.com/uptrace/bun" ) type Migration struct { - Up func(tx bun.Tx) error + Name string + Up func(tx bun.Tx) error + UpWithContext func(ctx context.Context, tx bun.Tx) error } diff --git a/components/ledger/libs/migrations/migrator.go b/components/ledger/libs/migrations/migrator.go index 9c5c02aba..858f12d61 100644 --- a/components/ledger/libs/migrations/migrator.go +++ b/components/ledger/libs/migrations/migrator.go @@ -15,8 +15,28 @@ const ( migrationTable = "goose_db_version" ) +type Info struct { + bun.BaseModel `bun:"goose_db_version"` + + Version string `json:"version" bun:"version_id"` + Name string `json:"name" bun:"-"` + State string `json:"state,omitempty" bun:"-"` + Date time.Time `json:"date,omitempty" bun:"tstamp"` +} + type Migrator struct { - migrations []Migration + migrations []Migration + schema string + createSchema bool +} + +type option func(m *Migrator) + +func WithSchema(schema string, create bool) option { + return func(m *Migrator) { + m.schema = schema + m.createSchema = create + } } func (m *Migrator) RegisterMigrations(migrations ...Migration) *Migrator { @@ -82,8 +102,8 @@ func (m *Migrator) GetDBVersion(ctx context.Context, db *bun.DB) (int64, error) return m.getLastVersion(ctx, db) } -func (m *Migrator) Up(ctx context.Context, db *bun.DB) error { - tx, err := db.Begin() +func (m *Migrator) Up(ctx context.Context, db bun.IDB) error { + tx, err := db.BeginTx(ctx, &sql.TxOptions{}) if err != nil { return err } @@ -91,6 +111,19 @@ func (m *Migrator) Up(ctx context.Context, db *bun.DB) error { _ = tx.Rollback() }() + if m.schema != "" { + if m.createSchema { + _, err := tx.ExecContext(ctx, fmt.Sprintf(`create schema if not exists "%s"`, m.schema)) + if err != nil { + return err + } + } + _, err := tx.ExecContext(ctx, fmt.Sprintf(`set search_path = "%s"`, m.schema)) + if err != nil { + return err + } + } + if err := m.createVersionTable(ctx, tx); err != nil { return err } @@ -102,9 +135,17 @@ func (m *Migrator) Up(ctx context.Context, db *bun.DB) error { if len(m.migrations) > int(lastMigration)-1 { for ind, migration := range m.migrations[lastMigration:] { + if migration.UpWithContext != nil { + if err := migration.UpWithContext(ctx, tx); err != nil { + return err + } + } else if migration.Up != nil { if err := migration.Up(tx); err != nil { return err } + } else { + return errors.New("no code defined for migration") + } if err := m.insertVersion(ctx, tx, int(lastMigration)+ind+1); err != nil { return err @@ -115,6 +156,42 @@ func (m *Migrator) Up(ctx context.Context, db *bun.DB) error { return tx.Commit() } -func NewMigrator() *Migrator { - return &Migrator{} +func (m *Migrator) GetMigrations(ctx context.Context, db bun.IDB) ([]Info, error) { + migrationTableName := migrationTable + if m.schema != "" { + migrationTableName = fmt.Sprintf(`"%s".%s`, m.schema, migrationTableName) + } + + ret := make([]Info, 0) + if err := db.NewSelect(). + TableExpr(migrationTableName). + Order("version_id"). + Where("version_id >= 1"). + Column("version_id", "tstamp"). + Scan(ctx, &ret); err != nil { + return nil, err + } + + for i := 0; i < len(ret); i++ { + ret[i].Name = m.migrations[i].Name + ret[i].State = "DONE" + } + + for i := len(ret); i < len(m.migrations); i++ { + ret = append(ret, Info{ + Version: fmt.Sprint(i), + Name: m.migrations[i].Name, + State: "TO DO", + }) + } + + return ret, nil +} + +func NewMigrator(opts ...option) *Migrator { + ret := &Migrator{} + for _, opt := range opts { + opt(ret) + } + return ret } diff --git a/components/ledger/libs/otlp/otlpmetrics/cli.go b/components/ledger/libs/otlp/otlpmetrics/cli.go index 894564cd1..98e8072c7 100644 --- a/components/ledger/libs/otlp/otlpmetrics/cli.go +++ b/components/ledger/libs/otlp/otlpmetrics/cli.go @@ -24,7 +24,7 @@ func InitOTLPMetricsFlags(flags *flag.FlagSet) { otlp.InitOTLPFlags(flags) flags.Bool(OtelMetricsFlag, false, "Enable OpenTelemetry traces support") - flags.Duration(OtelMetricsExporterPushIntervalFlag, 100*time.Millisecond, "OpenTelemetry metrics exporter push interval") + flags.Duration(OtelMetricsExporterPushIntervalFlag, 10*time.Second, "OpenTelemetry metrics exporter push interval") flags.Bool(OtelMetricsRuntimeFlag, false, "Enable OpenTelemetry runtime metrics") flags.Duration(OtelMetricsRuntimeMinimumReadMemStatsIntervalFlag, 15*time.Second, "OpenTelemetry runtime metrics minimum read mem stats interval") flags.String(OtelMetricsExporterFlag, "stdout", "OpenTelemetry metrics exporter") diff --git a/components/ledger/libs/otlp/otlpmetrics/module.go b/components/ledger/libs/otlp/otlpmetrics/module.go index 3628cea21..77366f863 100644 --- a/components/ledger/libs/otlp/otlpmetrics/module.go +++ b/components/ledger/libs/otlp/otlpmetrics/module.go @@ -2,6 +2,7 @@ package otlpmetrics import ( "context" + "fmt" "time" "github.com/formancehq/stack/libs/go-libs/logging" @@ -63,9 +64,11 @@ func MetricsModule(cfg ModuleConfig) fx.Option { otlp.LoadResource(cfg.ServiceName, cfg.ResourceAttributes), fx.Decorate(fx.Annotate(func(mp *sdkmetric.MeterProvider) metric.MeterProvider { return mp }, fx.As(new(metric.MeterProvider)))), fx.Provide(fx.Annotate(func(options ...sdkmetric.Option) *sdkmetric.MeterProvider { + fmt.Println("run meter provider with options", options) return sdkmetric.NewMeterProvider(options...) }, fx.ParamTags(metricsProviderOptionKey))), fx.Invoke(func(lc fx.Lifecycle, metricProvider *sdkmetric.MeterProvider, options ...runtime.Option) { + fmt.Println("start meter provider") // set global propagator to tracecontext (the default is no-op). otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator( b3.New(), propagation.TraceContext{})) // B3 format is common and used by zipkin. Always enabled right now. @@ -99,7 +102,7 @@ func MetricsModule(cfg ModuleConfig) fx.Option { ProvideMetricsProviderOption(sdkmetric.WithResource), ProvideMetricsProviderOption(sdkmetric.WithReader), fx.Provide( - fx.Annotate(sdkmetric.NewPeriodicReader, fx.As(new(sdkmetric.Reader))), + fx.Annotate(sdkmetric.NewPeriodicReader, fx.ParamTags(``, OTLPMetricsPeriodicReaderOptionsKey), fx.As(new(sdkmetric.Reader))), ), ProvideOTLPMetricsPeriodicReaderOption(func() sdkmetric.PeriodicReaderOption { return sdkmetric.WithInterval(cfg.PushInterval) diff --git a/components/ledger/libs/pgtesting/postgres.go b/components/ledger/libs/pgtesting/postgres.go index 578044a42..372001e6b 100644 --- a/components/ledger/libs/pgtesting/postgres.go +++ b/components/ledger/libs/pgtesting/postgres.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "fmt" + "os" "strconv" "sync" "time" @@ -76,12 +77,14 @@ func (s *pgServer) NewDatabase(t TestingT) *pgDatabase { _, err := s.db.ExecContext(context.Background(), fmt.Sprintf(`CREATE DATABASE "%s"`, databaseName)) require.NoError(t, err) - t.Cleanup(func() { - s.lock.Lock() - defer s.lock.Unlock() + if os.Getenv("NO_CLEANUP") != "true" { + t.Cleanup(func() { + s.lock.Lock() + defer s.lock.Unlock() - _, _ = s.db.ExecContext(context.Background(), fmt.Sprintf(`DROP DATABASE "%s"`, databaseName)) - }) + _, _ = s.db.ExecContext(context.Background(), fmt.Sprintf(`DROP DATABASE "%s"`, databaseName)) + }) + } return &pgDatabase{ url: s.GetDatabaseDSN(databaseName), @@ -92,6 +95,9 @@ func (s *pgServer) Close() error { if s.db == nil { return nil } + if os.Getenv("NO_CLEANUP") == "true" { + return nil + } if err := s.db.Close(); err != nil { return err } diff --git a/components/ledger/libs/publish/module.go b/components/ledger/libs/publish/module.go index 3b7c4b966..1f0df0bf9 100644 --- a/components/ledger/libs/publish/module.go +++ b/components/ledger/libs/publish/module.go @@ -9,12 +9,12 @@ import ( "go.uber.org/fx" ) -func newGoChannel(logger watermill.LoggerAdapter) *gochannel.GoChannel { +func newGoChannel() *gochannel.GoChannel { return gochannel.NewGoChannel( gochannel.Config{ BlockPublishUntilSubscriberAck: true, }, - logger, + watermill.NopLogger{}, ) } diff --git a/components/ledger/libs/service/app.go b/components/ledger/libs/service/app.go index 85ed6b41a..f1ce5831d 100644 --- a/components/ledger/libs/service/app.go +++ b/components/ledger/libs/service/app.go @@ -18,8 +18,9 @@ type App struct { } func (a *App) Run(ctx context.Context) error { - app := a.newFxApp(ctx) - if err := app.Start(ctx); err != nil { + logger := GetDefaultLogger(a.output, viper.GetBool(DebugFlag), viper.GetBool(JsonFormattingLoggerFlag)) + app := a.newFxApp(logger) + if err := app.Start(logging.ContextWithLogger(ctx, logger)); err != nil { return err } @@ -30,22 +31,19 @@ func (a *App) Run(ctx context.Context) error { // app.Stop in order to gracefully shutdown the app } - return app.Stop(context.Background()) + return app.Stop(logging.ContextWithLogger(context.Background(), logger)) } func (a *App) Start(ctx context.Context) error { - return a.newFxApp(ctx).Start(ctx) + logger := GetDefaultLogger(a.output, viper.GetBool(DebugFlag), viper.GetBool(JsonFormattingLoggerFlag)) + return a.newFxApp(logger).Start(ctx) } -func (a *App) newFxApp(ctx context.Context) *fx.App { - ctx = defaultLoggingContext(ctx, a.output, viper.GetBool(DebugFlag), viper.GetBool(JsonFormattingLoggerFlag)) - options := append(a.options, +func (a *App) newFxApp(logger logging.Logger) *fx.App { + return fx.New(append(a.options, fx.NopLogger, - fx.Provide(func() logging.Logger { - return logging.FromContext(ctx) - }), - ) - return fx.New(options...) + fx.Supply(fx.Annotate(logger, fx.As(new(logging.Logger)))), + )...) } func New(output io.Writer, options ...fx.Option) *App { diff --git a/components/ledger/libs/service/logging.go b/components/ledger/libs/service/logging.go index 20821588f..5b20fd01b 100644 --- a/components/ledger/libs/service/logging.go +++ b/components/ledger/libs/service/logging.go @@ -1,7 +1,6 @@ package service import ( - "context" "io" "github.com/formancehq/stack/libs/go-libs/logging" @@ -42,7 +41,3 @@ func GetDefaultLogger(w io.Writer, debug, jsonFormattingLog bool) logging.Logger } return logging.NewLogrus(l) } - -func defaultLoggingContext(parent context.Context, w io.Writer, debug, jsonFormattingLog bool) context.Context { - return logging.ContextWithLogger(parent, GetDefaultLogger(w, debug, jsonFormattingLog)) -} diff --git a/components/ledger/openapi.yaml b/components/ledger/openapi.yaml index 224b054a0..2e28c49a4 100644 --- a/components/ledger/openapi.yaml +++ b/components/ledger/openapi.yaml @@ -5,7 +5,7 @@ info: version: "LEDGER_VERSION" paths: - /_info: + /v2/_info: get: tags: - Ledger @@ -26,7 +26,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/_info: + /v2/{ledger}/_info: get: summary: Get information about a ledger operationId: getLedgerInfo @@ -54,7 +54,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/accounts: + /v2/{ledger}/accounts: head: summary: Count the accounts from a ledger operationId: countAccounts @@ -69,21 +69,18 @@ paths: schema: type: string example: ledger001 - - name: address + - name: pit in: query - description: Filter accounts by address pattern (regular expression placed between ^ and $). + required: false schema: type: string - example: users:.+ - - name: metadata - in: query - description: Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - style: deepObject - explode: true - schema: - type: object - properties: {} - example: { admin: "true" } + format: date-time + requestBody: + content: + application/json: + schema: + type: object + additionalProperties: true responses: "204": description: OK @@ -125,22 +122,6 @@ paths: format: int64 minimum: 1 maximum: 1000 - - name: address - in: query - description: Filter accounts by address pattern (regular expression placed between ^ and $). - schema: - type: string - example: users:.+ - - name: metadata - in: query - description: Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - style: deepObject - schema: - type: object - properties: {} - additionalProperties: - type: string - example: { admin: "true" } - name: cursor in: query description: | @@ -151,6 +132,24 @@ paths: schema: type: string example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== + - name: expand + in: query + schema: + type: string + items: + type: string + - name: pit + in: query + required: false + schema: + type: string + format: date-time + requestBody: + content: + application/json: + schema: + type: object + additionalProperties: true responses: "200": description: OK @@ -165,7 +164,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/accounts/{address}: + /v2/{ledger}/accounts/{address}: get: summary: Get account by its address operationId: getAccount @@ -191,6 +190,18 @@ paths: schema: type: string example: users:001 + - name: expand + in: query + schema: + type: string + items: + type: string + - name: pit + in: query + required: false + schema: + type: string + format: date-time responses: "200": description: OK @@ -205,7 +216,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/accounts/{address}/metadata: + /v2/{ledger}/accounts/{address}/metadata: post: summary: Add metadata to an account operationId: addMetadataToAccount @@ -237,12 +248,6 @@ paths: schema: type: boolean example: true - - name: async - in: query - description: Set async mode. - schema: - type: boolean - example: true - name: Idempotency-Key in: header description: Use an idempotency key @@ -266,7 +271,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/stats: + /v2/{ledger}/stats: get: tags: - Ledger @@ -297,7 +302,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/transactions: + /v2/{ledger}/transactions: head: tags: - Ledger @@ -312,57 +317,18 @@ paths: schema: type: string example: ledger001 - - name: reference - in: query - description: Filter transactions by reference field. - schema: - type: string - example: ref:001 - - name: account - in: query - description: Filter transactions with postings involving given account, either - as source or destination (regular expression placed between ^ and $). - schema: - type: string - example: users:001 - - name: source + - name: pit in: query - description: Filter transactions with postings involving given account at source (regular expression placed between ^ and $). - schema: - type: string - example: users:001 - - name: destination - in: query - description: Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). - schema: - type: string - example: users:001 - - name: startTime - in: query - description: | - Filter transactions that occurred after this timestamp. - The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - schema: - type: string - format: date-time - - name: endTime - in: query - description: | - Filter transactions that occurred before this timestamp. - The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). + required: false schema: type: string format: date-time - - name: metadata - in: query - description: Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - style: deepObject - schema: - type: object - properties: { } - additionalProperties: - type: string - example: { admin: "true" } + requestBody: + content: + application/json: + schema: + type: object + additionalProperties: true responses: "204": description: OK @@ -384,7 +350,7 @@ paths: - Ledger - Transactions summary: List transactions from a ledger - description: List transactions from a ledger, sorted by txid in descending order. + description: List transactions from a ledger, sorted by id in descending order. operationId: listTransactions parameters: - name: ledger @@ -404,47 +370,6 @@ paths: format: int64 minimum: 1 maximum: 1000 - - name: reference - in: query - description: Find transactions by reference field. - schema: - type: string - example: ref:001 - - name: account - in: query - description: Filter transactions with postings involving given account, either - as source or destination (regular expression placed between ^ and $). - schema: - type: string - example: users:001 - - name: source - in: query - description: Filter transactions with postings involving given account at source (regular expression placed between ^ and $). - schema: - type: string - example: users:001 - - name: destination - in: query - description: Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). - schema: - type: string - example: users:001 - - name: startTime - in: query - description: | - Filter transactions that occurred after this timestamp. - The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - schema: - type: string - format: date-time - - name: endTime - in: query - description: | - Filter transactions that occurred before this timestamp. - The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - schema: - type: string - format: date-time - name: cursor in: query description: | @@ -455,16 +380,24 @@ paths: schema: type: string example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== - - name: metadata + - name: expand in: query - description: Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below. - style: deepObject schema: - type: object - properties: { } - additionalProperties: + type: string + items: type: string - example: { admin: "true" } + - name: pit + in: query + required: false + schema: + type: string + format: date-time + requestBody: + content: + application/json: + schema: + type: object + additionalProperties: true responses: "200": description: OK @@ -499,12 +432,6 @@ paths: schema: type: boolean example: true - - name: async - in: query - description: Set async mode. - schema: - type: boolean - example: true - name: Idempotency-Key in: header description: Use an idempotency key @@ -534,7 +461,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/transactions/{txid}: + /v2/{ledger}/transactions/{id}: get: tags: - Ledger @@ -549,7 +476,7 @@ paths: schema: type: string example: ledger001 - - name: txid + - name: id in: path description: Transaction ID. required: true @@ -558,6 +485,18 @@ paths: format: int64 minimum: 0 example: 1234 + - name: expand + in: query + schema: + type: string + items: + type: string + - name: pit + in: query + required: false + schema: + type: string + format: date-time responses: "200": description: OK @@ -572,7 +511,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/transactions/{txid}/metadata: + /v2/{ledger}/transactions/{id}/metadata: post: tags: - Ledger @@ -587,7 +526,7 @@ paths: schema: type: string example: ledger001 - - name: txid + - name: id in: path description: Transaction ID. required: true @@ -602,12 +541,6 @@ paths: schema: type: boolean example: true - - name: async - in: query - description: Set async mode. - schema: - type: boolean - example: true - name: Idempotency-Key in: header description: Use an idempotency key @@ -630,7 +563,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/transactions/{txid}/revert: + /v2/{ledger}/transactions/{id}/revert: post: tags: - Ledger @@ -645,7 +578,7 @@ paths: schema: type: string example: ledger001 - - name: txid + - name: id in: path description: Transaction ID. required: true @@ -667,64 +600,7 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - - /{ledger}/balances: - get: - tags: - - Ledger - - Balances - summary: Get the balances from a ledger's account - operationId: getBalances - parameters: - - name: ledger - in: path - description: Name of the ledger. - required: true - schema: - type: string - example: ledger001 - - name: address - in: query - description: Filter balances involving given account, either - as source or destination. - schema: - type: string - example: users:001 - - name: pageSize - in: query - description: | - The maximum number of results to return per page. - example: 100 - schema: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - - name: cursor - in: query - description: | - Parameter used in pagination requests. Maximum page size is set to 15. - Set to the value of next for the next page of results. - Set to the value of previous for the previous page of results. - No other parameters can be set when this parameter is set. - schema: - type: string - example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/BalancesCursorResponse' - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /{ledger}/aggregate/balances: + /v2/{ledger}/aggregate/balances: get: tags: - Ledger @@ -739,13 +615,18 @@ paths: schema: type: string example: ledger001 - - name: address + - name: pit in: query - description: Filter balances involving given account, either - as source or destination. + required: false schema: type: string - example: users:001 + format: date-time + requestBody: + content: + application/json: + schema: + type: object + additionalProperties: true responses: "200": description: OK @@ -760,7 +641,7 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /{ledger}/logs: + /v2/{ledger}/logs: get: tags: - Ledger @@ -786,22 +667,6 @@ paths: format: int64 minimum: 1 maximum: 1000 - - name: startTime - in: query - description: | - Filter transactions that occurred after this timestamp. - The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - schema: - type: string - format: date-time - - name: endTime - in: query - description: | - Filter transactions that occurred before this timestamp. - The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - schema: - type: string - format: date-time - name: cursor in: query description: | @@ -812,6 +677,18 @@ paths: schema: type: string example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== + - name: pit + in: query + required: false + schema: + type: string + format: date-time + requestBody: + content: + application/json: + schema: + type: object + additionalProperties: true responses: "200": description: OK @@ -1034,8 +911,6 @@ components: required: - address - metadata - - volumes - - balances properties: address: type: string @@ -1058,13 +933,6 @@ components: format: bigint minimum: 0 example: { COIN: { input: 100, output: 0 } } - balances: - type: object - additionalProperties: - type: integer - format: bigint - example: - COIN: 100 AccountsBalances: type: object @@ -1147,15 +1015,18 @@ components: example: ref:001 metadata: $ref: '#/components/schemas/Metadata' - txid: + id: type: integer format: int64 minimum: 0 + reverted: + type: boolean required: - postings - timestamp - - txid + - id - metadata + - reverted ExpandedTransaction: allOf: @@ -1166,9 +1037,6 @@ components: $ref: '#/components/schemas/AggregatedVolumes' postCommitVolumes: $ref: '#/components/schemas/AggregatedVolumes' - required: - - preCommitVolumes - - postCommitVolumes PostTransaction: type: object diff --git a/components/ledger/pkg/analytics/backend.go b/components/ledger/pkg/analytics/backend.go deleted file mode 100644 index f682fc9a0..000000000 --- a/components/ledger/pkg/analytics/backend.go +++ /dev/null @@ -1,83 +0,0 @@ -package analytics - -import ( - "context" - - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/driver" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/google/uuid" - "github.com/pkg/errors" -) - -//go:generate mockgen -source backend.go -destination backend_test.go -package analytics . Ledger - -type Ledger interface { - CountTransactions(ctx context.Context) (uint64, error) - CountAccounts(ctx context.Context) (uint64, error) -} - -type defaultLedger struct { - store *ledgerstore.Store -} - -func (d defaultLedger) CountTransactions(ctx context.Context) (uint64, error) { - return d.store.CountTransactions(ctx, ledgerstore.NewTransactionsQuery()) -} - -func (d defaultLedger) CountAccounts(ctx context.Context) (uint64, error) { - return d.store.CountAccounts(ctx, ledgerstore.NewAccountsQuery()) -} - -var _ Ledger = (*defaultLedger)(nil) - -type Backend interface { - AppID(ctx context.Context) (string, error) - ListLedgers(ctx context.Context) ([]string, error) - GetLedgerStore(ctx context.Context, l string) (Ledger, error) -} - -type defaultBackend struct { - driver *driver.Driver - appID string -} - -func (d defaultBackend) AppID(ctx context.Context) (string, error) { - var err error - if d.appID == "" { - d.appID, err = d.driver.GetSystemStore().GetConfiguration(ctx, "appId") - if err != nil && !errors.Is(err, storageerrors.ErrNotFound) { - return "", err - } - if errors.Is(err, storageerrors.ErrNotFound) { - d.appID = uuid.NewString() - if err := d.driver.GetSystemStore().InsertConfiguration(ctx, "appId", d.appID); err != nil { - return "", err - } - } - } - return d.appID, nil -} - -func (d defaultBackend) ListLedgers(ctx context.Context) ([]string, error) { - return d.driver.GetSystemStore().ListLedgers(ctx) -} - -func (d defaultBackend) GetLedgerStore(ctx context.Context, name string) (Ledger, error) { - ledgerStore, err := d.driver.GetLedgerStore(ctx, name) - if err != nil { - return nil, err - } - return &defaultLedger{ - store: ledgerStore, - }, nil -} - -var _ Backend = (*defaultBackend)(nil) - -func newDefaultBackend(driver *driver.Driver, appID string) *defaultBackend { - return &defaultBackend{ - driver: driver, - appID: appID, - } -} diff --git a/components/ledger/pkg/analytics/module.go b/components/ledger/pkg/analytics/module.go deleted file mode 100644 index 83314e909..000000000 --- a/components/ledger/pkg/analytics/module.go +++ /dev/null @@ -1,48 +0,0 @@ -package analytics - -import ( - "context" - "time" - - "github.com/formancehq/ledger/pkg/storage/driver" - "go.uber.org/fx" - "gopkg.in/segmentio/analytics-go.v3" -) - -func NewHeartbeatModule(version, writeKey, appID string, interval time.Duration) fx.Option { - return fx.Options( - fx.Supply(analytics.Config{}), // Provide empty config to be able to replace (use fx.Replace) if necessary - fx.Provide(func(cfg analytics.Config) (analytics.Client, error) { - return analytics.NewWithConfig(writeKey, cfg) - }), - fx.Provide(func(client analytics.Client, backend Backend) *heartbeat { - return newHeartbeat(backend, client, version, interval) - }), - fx.Provide(func(driver *driver.Driver) Backend { - return newDefaultBackend(driver, appID) - }), - fx.Invoke(func(m *heartbeat, lc fx.Lifecycle) { - lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - go func() { - err := m.Run(context.Background()) - if err != nil { - panic(err) - } - }() - return nil - }, - OnStop: func(ctx context.Context) error { - return m.Stop(ctx) - }, - }) - }), - fx.Invoke(func(lc fx.Lifecycle, client analytics.Client) { - lc.Append(fx.Hook{ - OnStop: func(ctx context.Context) error { - return client.Close() - }, - }) - }), - ) -} diff --git a/components/ledger/pkg/api/api.go b/components/ledger/pkg/api/api.go deleted file mode 100644 index 19c0616ec..000000000 --- a/components/ledger/pkg/api/api.go +++ /dev/null @@ -1,42 +0,0 @@ -package api - -import ( - "context" - _ "embed" - - "github.com/formancehq/ledger/pkg/api/controllers" - "github.com/formancehq/ledger/pkg/api/routes" - "github.com/formancehq/ledger/pkg/ledger" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage/driver" - "github.com/formancehq/stack/libs/go-libs/health" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" - "go.uber.org/fx" -) - -type Config struct { - Version string -} - -func Module(cfg Config) fx.Option { - return fx.Options( - fx.Provide(routes.NewRouter), - fx.Provide(func(storageDriver *driver.Driver, resolver *ledger.Resolver) controllers.Backend { - return controllers.NewDefaultBackend(storageDriver, cfg.Version, resolver) - }), - //TODO(gfyrag): Move in pkg/ledger package - fx.Invoke(func(lc fx.Lifecycle, backend controllers.Backend) { - lc.Append(fx.Hook{ - OnStop: func(ctx context.Context) error { - return backend.CloseLedgers(ctx) - }, - }) - }), - fx.Provide(fx.Annotate(noop.NewMeterProvider, fx.As(new(metric.MeterProvider)))), - fx.Decorate(fx.Annotate(func(meterProvider metric.MeterProvider) (metrics.GlobalRegistry, error) { - return metrics.RegisterGlobalRegistry(meterProvider) - }, fx.As(new(metrics.GlobalRegistry)))), - health.Module(), - ) -} diff --git a/components/ledger/pkg/api/apierrors/errors.go b/components/ledger/pkg/api/apierrors/errors.go deleted file mode 100644 index f8b6d67b0..000000000 --- a/components/ledger/pkg/api/apierrors/errors.go +++ /dev/null @@ -1,110 +0,0 @@ -package apierrors - -import ( - "context" - "encoding/base64" - "encoding/json" - "fmt" - "net/http" - "strings" - - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/machine/vm" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/logging" - "github.com/pkg/errors" -) - -const ( - ErrInternal = "INTERNAL" - ErrConflict = "CONFLICT" - ErrInsufficientFund = "INSUFFICIENT_FUND" - ErrValidation = "VALIDATION" - ErrContextCancelled = "CONTEXT_CANCELLED" - ErrStore = "STORE" - ErrNotFound = "NOT_FOUND" - ErrScriptCompilationFailed = "COMPILATION_FAILED" - ErrScriptNoScript = "NO_SCRIPT" - ErrScriptMetadataOverride = "METADATA_OVERRIDE" - ScriptErrorInsufficientFund = "INSUFFICIENT_FUND" - ScriptErrorCompilationFailed = "COMPILATION_FAILED" - ScriptErrorNoScript = "NO_SCRIPT" - ScriptErrorMetadataOverride = "METADATA_OVERRIDE" - ResourceResolutionError = "RESOURCE_RESOLUTION_ERROR" -) - -func ResponseError(w http.ResponseWriter, r *http.Request, err error) { - status, code, details := coreErrorToErrorCode(err) - - baseError := errors.Cause(err) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(status) - if status < 500 { - err := json.NewEncoder(w).Encode(api.ErrorResponse{ - ErrorCode: code, - ErrorMessage: baseError.Error(), - Details: details, - }) - if err != nil { - panic(err) - } - } else { - logging.FromContext(r.Context()).Errorf("internal server error: %s", err) - } -} - -func coreErrorToErrorCode(err error) (int, string, string) { - switch { - case command.IsConflictError(err): - return http.StatusConflict, ErrConflict, "" - case - command.IsValidationError(err), - command.IsPastTransactionError(err), - command.IsNoPostingsError(err), - errors.Is(err, command.ErrAlreadyReverted), - errors.Is(err, command.ErrRevertOccurring): - return http.StatusBadRequest, ErrValidation, "" - case storageerrors.IsNotFoundError(err): - return http.StatusNotFound, ErrNotFound, "" - case command.IsNoScriptError(err): - baseError := errors.Cause(err) - return http.StatusBadRequest, ScriptErrorNoScript, EncodeLink(baseError.Error()) - case vm.IsInsufficientFundError(err): - baseError := errors.Cause(err) - return http.StatusBadRequest, ScriptErrorInsufficientFund, EncodeLink(baseError.Error()) - case command.IsCompilationFailedError(err): - baseError := errors.Cause(err) - return http.StatusBadRequest, ScriptErrorCompilationFailed, EncodeLink(baseError.Error()) - case vm.IsMetadataOverrideError(err): - baseError := errors.Cause(err) - return http.StatusBadRequest, ScriptErrorMetadataOverride, EncodeLink(baseError.Error()) - case vm.IsResourceResolutionInvalidTypeFromExtSourcesError(err), - vm.IsResourceResolutionMissingMetadataError(err): - baseError := errors.Cause(err) - return http.StatusBadRequest, ResourceResolutionError, EncodeLink(baseError.Error()) - case errors.Is(err, context.Canceled): - return http.StatusInternalServerError, ErrContextCancelled, "" - case storageerrors.IsStorageError(err): - return http.StatusServiceUnavailable, ErrStore, "" - default: - return http.StatusInternalServerError, ErrInternal, "" - } -} - -func EncodeLink(errStr string) string { - if errStr == "" { - return "" - } - - errStr = strings.ReplaceAll(errStr, "\n", "\r\n") - payload, err := json.Marshal(map[string]string{ - "error": errStr, - }) - if err != nil { - panic(err) - } - payloadB64 := base64.StdEncoding.EncodeToString(payload) - return fmt.Sprintf("https://play.numscript.org/?payload=%v", payloadB64) -} diff --git a/components/ledger/pkg/api/controllers/account_controller.go b/components/ledger/pkg/api/controllers/account_controller.go deleted file mode 100644 index bebb4288a..000000000 --- a/components/ledger/pkg/api/controllers/account_controller.go +++ /dev/null @@ -1,127 +0,0 @@ -package controllers - -import ( - "encoding/json" - "fmt" - "net/http" - "strconv" - - "github.com/formancehq/ledger/pkg/api/apierrors" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - sharedapi "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/errorsutil" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/go-chi/chi/v5" - "github.com/pkg/errors" -) - -func CountAccounts(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - accountsQuery := ledgerstore.NewAccountsQuery(). - WithAddressFilter(r.URL.Query().Get("address")). - WithMetadataFilter(sharedapi.GetQueryMap(r.URL.Query(), "metadata")) - - count, err := l.CountAccounts(r.Context(), accountsQuery) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - w.Header().Set("Count", fmt.Sprint(count)) - sharedapi.NoContent(w) -} - -func GetAccounts(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - accountsQuery := ledgerstore.NewAccountsQuery() - - if r.URL.Query().Get(QueryKeyCursor) != "" { - if r.URL.Query().Get("after") != "" || - r.URL.Query().Get("address") != "" || - len(sharedapi.GetQueryMap(r.URL.Query(), "metadata")) > 0 || - r.URL.Query().Get("balance") != "" || - r.URL.Query().Get(QueryKeyBalanceOperator) != "" || - r.URL.Query().Get(QueryKeyPageSize) != "" { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.Errorf("no other query params can be set with '%s'", QueryKeyCursor))) - return - } - - err := ledgerstore.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), &accountsQuery) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.Errorf("invalid '%s' query param", QueryKeyCursor))) - return - } - } else { - balance := r.URL.Query().Get("balance") - if balance != "" { - if _, err := strconv.ParseInt(balance, 10, 64); err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.New("invalid parameter 'balance', should be a number"))) - return - } - } - - pageSize, err := getPageSize(r) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - accountsQuery = accountsQuery. - WithAfterAddress(r.URL.Query().Get("after")). - WithAddressFilter(r.URL.Query().Get("address")). - WithMetadataFilter(sharedapi.GetQueryMap(r.URL.Query(), "metadata")). - WithPageSize(pageSize) - } - - cursor, err := l.GetAccounts(r.Context(), accountsQuery) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.RenderCursor(w, *cursor) -} - -func GetAccount(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - acc, err := l.GetAccount(r.Context(), chi.URLParam(r, "address")) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.Ok(w, acc) -} - -func PostAccountMetadata(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - if !core.ValidateAddress(chi.URLParam(r, "address")) { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.New("invalid account address format"))) - return - } - - var m metadata.Metadata - if err := json.NewDecoder(r.Body).Decode(&m); err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.New("invalid metadata format"))) - return - } - - err := l.SaveMeta(r.Context(), getCommandParameters(r), core.MetaTargetTypeAccount, chi.URLParam(r, "address"), m) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.NoContent(w) -} diff --git a/components/ledger/pkg/api/controllers/account_controller_test.go b/components/ledger/pkg/api/controllers/account_controller_test.go deleted file mode 100644 index d6cc51df2..000000000 --- a/components/ledger/pkg/api/controllers/account_controller_test.go +++ /dev/null @@ -1,256 +0,0 @@ -package controllers_test - -import ( - "net/http" - "net/http/httptest" - "net/url" - "testing" - - "github.com/formancehq/ledger/pkg/api/apierrors" - "github.com/formancehq/ledger/pkg/api/controllers" - "github.com/formancehq/ledger/pkg/api/routes" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - sharedapi "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" -) - -func TestGetAccounts(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - queryParams url.Values - expectQuery ledgerstore.AccountsQuery - expectStatusCode int - expectedErrorCode string - } - - testCases := []testCase{ - { - name: "nominal", - expectQuery: ledgerstore.NewAccountsQuery(), - }, - { - name: "using metadata", - queryParams: url.Values{ - "metadata[roles]": []string{"admin"}, - }, - expectQuery: ledgerstore.NewAccountsQuery(). - WithMetadataFilter(map[string]string{ - "roles": "admin", - }), - }, - { - name: "using nested metadata", - queryParams: url.Values{ - "metadata[a.nested.key]": []string{"hello"}, - }, - expectQuery: ledgerstore.NewAccountsQuery(). - WithMetadataFilter(map[string]string{ - "a.nested.key": "hello", - }), - }, - { - name: "using after", - queryParams: url.Values{ - "after": []string{"foo"}, - }, - expectQuery: ledgerstore.NewAccountsQuery(). - WithAfterAddress("foo"). - WithMetadataFilter(map[string]string{}), - }, - { - name: "using address", - queryParams: url.Values{ - "address": []string{"foo"}, - }, - expectQuery: ledgerstore.NewAccountsQuery(). - WithAddressFilter("foo"). - WithMetadataFilter(map[string]string{}), - }, - { - name: "using empty cursor", - queryParams: url.Values{ - "cursor": []string{ledgerstore.EncodeCursor(ledgerstore.NewAccountsQuery())}, - }, - expectQuery: ledgerstore.NewAccountsQuery(), - }, - { - name: "using cursor with other param", - queryParams: url.Values{ - "cursor": []string{ledgerstore.EncodeCursor(ledgerstore.NewAccountsQuery())}, - "after": []string{"foo"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using invalid cursor", - queryParams: url.Values{ - "cursor": []string{"XXX"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "invalid page size", - queryParams: url.Values{ - "pageSize": []string{"nan"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "page size over maximum", - queryParams: url.Values{ - "pageSize": []string{"1000000"}, - }, - expectQuery: ledgerstore.NewAccountsQuery(). - WithPageSize(controllers.MaxPageSize). - WithMetadataFilter(map[string]string{}), - }, - } - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - - if testCase.expectStatusCode == 0 { - testCase.expectStatusCode = http.StatusOK - } - - expectedCursor := sharedapi.Cursor[core.Account]{ - Data: []core.Account{ - { - Address: "world", - Metadata: metadata.Metadata{}, - }, - }, - } - - backend, mockLedger := newTestingBackend(t) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - mockLedger.EXPECT(). - GetAccounts(gomock.Any(), testCase.expectQuery). - Return(&expectedCursor, nil) - } - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodGet, "/xxx/accounts", nil) - rec := httptest.NewRecorder() - req.URL.RawQuery = testCase.queryParams.Encode() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectStatusCode, rec.Code) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - cursor := sharedapi.DecodeCursorResponse[core.Account](t, rec.Body) - require.Equal(t, expectedCursor, *cursor) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} - -func TestGetAccount(t *testing.T) { - t.Parallel() - - account := core.AccountWithVolumes{ - Account: core.Account{ - Address: "foo", - Metadata: metadata.Metadata{}, - }, - Volumes: core.VolumesByAssets{}, - } - - backend, mock := newTestingBackend(t) - mock.EXPECT(). - GetAccount(gomock.Any(), "foo"). - Return(&account, nil) - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodGet, "/xxx/accounts/foo", nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Code) - response, _ := sharedapi.DecodeSingleResponse[core.AccountWithVolumes](t, rec.Body) - require.Equal(t, account, response) -} - -func TestPostAccountMetadata(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - queryParams url.Values - expectStatusCode int - expectedErrorCode string - account string - body any - } - - testCases := []testCase{ - { - name: "nominal", - account: "world", - body: metadata.Metadata{ - "foo": "bar", - }, - }, - { - name: "invalid account address format", - account: "invalid-acc", - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "invalid body", - account: "world", - body: "invalid - not an object", - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - } - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - - if testCase.expectStatusCode == 0 { - testCase.expectStatusCode = http.StatusNoContent - } - - backend, mock := newTestingBackend(t) - if testCase.expectStatusCode == http.StatusNoContent { - mock.EXPECT(). - SaveMeta(gomock.Any(), command.Parameters{}, core.MetaTargetTypeAccount, testCase.account, testCase.body). - Return(nil) - } - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodPost, "/xxx/accounts/"+testCase.account+"/metadata", sharedapi.Buffer(t, testCase.body)) - rec := httptest.NewRecorder() - req.URL.RawQuery = testCase.queryParams.Encode() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectStatusCode, rec.Code) - if testCase.expectStatusCode >= 300 || testCase.expectStatusCode < 200 { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} diff --git a/components/ledger/pkg/api/controllers/api.go b/components/ledger/pkg/api/controllers/api.go deleted file mode 100644 index c96f14a07..000000000 --- a/components/ledger/pkg/api/controllers/api.go +++ /dev/null @@ -1,72 +0,0 @@ -package controllers - -import ( - "context" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/storage/driver" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/metadata" -) - -//go:generate mockgen -source api.go -destination api_test.go -package controllers_test . Ledger - -type Ledger interface { - GetAccount(ctx context.Context, param string) (*core.AccountWithVolumes, error) - GetAccounts(ctx context.Context, query ledgerstore.AccountsQuery) (*api.Cursor[core.Account], error) - CountAccounts(ctx context.Context, query ledgerstore.AccountsQuery) (uint64, error) - GetBalancesAggregated(ctx context.Context, q ledgerstore.BalancesQuery) (core.BalancesByAssets, error) - GetBalances(ctx context.Context, q ledgerstore.BalancesQuery) (*api.Cursor[core.BalancesByAssetsByAccounts], error) - GetMigrationsInfo(ctx context.Context) ([]core.MigrationInfo, error) - Stats(ctx context.Context) (ledger.Stats, error) - GetLogs(ctx context.Context, query ledgerstore.LogsQuery) (*api.Cursor[core.ChainedLog], error) - CountTransactions(ctx context.Context, query ledgerstore.TransactionsQuery) (uint64, error) - GetTransactions(ctx context.Context, query ledgerstore.TransactionsQuery) (*api.Cursor[core.ExpandedTransaction], error) - GetTransaction(ctx context.Context, id uint64) (*core.ExpandedTransaction, error) - - CreateTransaction(ctx context.Context, parameters command.Parameters, data core.RunScript) (*core.Transaction, error) - RevertTransaction(ctx context.Context, parameters command.Parameters, id uint64) (*core.Transaction, error) - SaveMeta(ctx context.Context, parameters command.Parameters, targetType string, targetID any, m metadata.Metadata) error -} - -type Backend interface { - GetLedger(ctx context.Context, name string) (Ledger, error) - ListLedgers(ctx context.Context) ([]string, error) - CloseLedgers(ctx context.Context) error - GetVersion() string -} - -type DefaultBackend struct { - storageDriver *driver.Driver - resolver *ledger.Resolver - version string -} - -func (d DefaultBackend) GetLedger(ctx context.Context, name string) (Ledger, error) { - return d.resolver.GetLedger(ctx, name) -} - -func (d DefaultBackend) ListLedgers(ctx context.Context) ([]string, error) { - return d.storageDriver.GetSystemStore().ListLedgers(ctx) -} - -func (d DefaultBackend) CloseLedgers(ctx context.Context) error { - return d.resolver.CloseLedgers(ctx) -} - -func (d DefaultBackend) GetVersion() string { - return d.version -} - -var _ Backend = (*DefaultBackend)(nil) - -func NewDefaultBackend(driver *driver.Driver, version string, resolver *ledger.Resolver) *DefaultBackend { - return &DefaultBackend{ - storageDriver: driver, - resolver: resolver, - version: version, - } -} diff --git a/components/ledger/pkg/api/controllers/api_test.go b/components/ledger/pkg/api/controllers/api_test.go deleted file mode 100644 index 50460c246..000000000 --- a/components/ledger/pkg/api/controllers/api_test.go +++ /dev/null @@ -1,332 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: api.go - -// Package controllers_test is a generated GoMock package. -package controllers_test - -import ( - context "context" - reflect "reflect" - - controllers "github.com/formancehq/ledger/pkg/api/controllers" - core "github.com/formancehq/ledger/pkg/core" - ledger "github.com/formancehq/ledger/pkg/ledger" - command "github.com/formancehq/ledger/pkg/ledger/command" - ledgerstore "github.com/formancehq/ledger/pkg/storage/ledgerstore" - api "github.com/formancehq/stack/libs/go-libs/api" - metadata "github.com/formancehq/stack/libs/go-libs/metadata" - gomock "github.com/golang/mock/gomock" -) - -// MockLedger is a mock of Ledger interface. -type MockLedger struct { - ctrl *gomock.Controller - recorder *MockLedgerMockRecorder -} - -// MockLedgerMockRecorder is the mock recorder for MockLedger. -type MockLedgerMockRecorder struct { - mock *MockLedger -} - -// NewMockLedger creates a new mock instance. -func NewMockLedger(ctrl *gomock.Controller) *MockLedger { - mock := &MockLedger{ctrl: ctrl} - mock.recorder = &MockLedgerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockLedger) EXPECT() *MockLedgerMockRecorder { - return m.recorder -} - -// CountAccounts mocks base method. -func (m *MockLedger) CountAccounts(ctx context.Context, query ledgerstore.AccountsQuery) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CountAccounts", ctx, query) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CountAccounts indicates an expected call of CountAccounts. -func (mr *MockLedgerMockRecorder) CountAccounts(ctx, query interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CountAccounts", reflect.TypeOf((*MockLedger)(nil).CountAccounts), ctx, query) -} - -// CountTransactions mocks base method. -func (m *MockLedger) CountTransactions(ctx context.Context, query ledgerstore.TransactionsQuery) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CountTransactions", ctx, query) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CountTransactions indicates an expected call of CountTransactions. -func (mr *MockLedgerMockRecorder) CountTransactions(ctx, query interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CountTransactions", reflect.TypeOf((*MockLedger)(nil).CountTransactions), ctx, query) -} - -// CreateTransaction mocks base method. -func (m *MockLedger) CreateTransaction(ctx context.Context, parameters command.Parameters, data core.RunScript) (*core.Transaction, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateTransaction", ctx, parameters, data) - ret0, _ := ret[0].(*core.Transaction) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CreateTransaction indicates an expected call of CreateTransaction. -func (mr *MockLedgerMockRecorder) CreateTransaction(ctx, parameters, data interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTransaction", reflect.TypeOf((*MockLedger)(nil).CreateTransaction), ctx, parameters, data) -} - -// GetAccount mocks base method. -func (m *MockLedger) GetAccount(ctx context.Context, param string) (*core.AccountWithVolumes, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAccount", ctx, param) - ret0, _ := ret[0].(*core.AccountWithVolumes) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAccount indicates an expected call of GetAccount. -func (mr *MockLedgerMockRecorder) GetAccount(ctx, param interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccount", reflect.TypeOf((*MockLedger)(nil).GetAccount), ctx, param) -} - -// GetAccounts mocks base method. -func (m *MockLedger) GetAccounts(ctx context.Context, query ledgerstore.AccountsQuery) (*api.Cursor[core.Account], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAccounts", ctx, query) - ret0, _ := ret[0].(*api.Cursor[core.Account]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAccounts indicates an expected call of GetAccounts. -func (mr *MockLedgerMockRecorder) GetAccounts(ctx, query interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccounts", reflect.TypeOf((*MockLedger)(nil).GetAccounts), ctx, query) -} - -// GetBalances mocks base method. -func (m *MockLedger) GetBalances(ctx context.Context, q ledgerstore.BalancesQuery) (*api.Cursor[core.BalancesByAssetsByAccounts], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBalances", ctx, q) - ret0, _ := ret[0].(*api.Cursor[core.BalancesByAssetsByAccounts]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBalances indicates an expected call of GetBalances. -func (mr *MockLedgerMockRecorder) GetBalances(ctx, q interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalances", reflect.TypeOf((*MockLedger)(nil).GetBalances), ctx, q) -} - -// GetBalancesAggregated mocks base method. -func (m *MockLedger) GetBalancesAggregated(ctx context.Context, q ledgerstore.BalancesQuery) (core.BalancesByAssets, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBalancesAggregated", ctx, q) - ret0, _ := ret[0].(core.BalancesByAssets) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBalancesAggregated indicates an expected call of GetBalancesAggregated. -func (mr *MockLedgerMockRecorder) GetBalancesAggregated(ctx, q interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalancesAggregated", reflect.TypeOf((*MockLedger)(nil).GetBalancesAggregated), ctx, q) -} - -// GetLogs mocks base method. -func (m *MockLedger) GetLogs(ctx context.Context, query ledgerstore.LogsQuery) (*api.Cursor[core.ChainedLog], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLogs", ctx, query) - ret0, _ := ret[0].(*api.Cursor[core.ChainedLog]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetLogs indicates an expected call of GetLogs. -func (mr *MockLedgerMockRecorder) GetLogs(ctx, query interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogs", reflect.TypeOf((*MockLedger)(nil).GetLogs), ctx, query) -} - -// GetMigrationsInfo mocks base method. -func (m *MockLedger) GetMigrationsInfo(ctx context.Context) ([]core.MigrationInfo, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMigrationsInfo", ctx) - ret0, _ := ret[0].([]core.MigrationInfo) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetMigrationsInfo indicates an expected call of GetMigrationsInfo. -func (mr *MockLedgerMockRecorder) GetMigrationsInfo(ctx interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMigrationsInfo", reflect.TypeOf((*MockLedger)(nil).GetMigrationsInfo), ctx) -} - -// GetTransaction mocks base method. -func (m *MockLedger) GetTransaction(ctx context.Context, id uint64) (*core.ExpandedTransaction, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTransaction", ctx, id) - ret0, _ := ret[0].(*core.ExpandedTransaction) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTransaction indicates an expected call of GetTransaction. -func (mr *MockLedgerMockRecorder) GetTransaction(ctx, id interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTransaction", reflect.TypeOf((*MockLedger)(nil).GetTransaction), ctx, id) -} - -// GetTransactions mocks base method. -func (m *MockLedger) GetTransactions(ctx context.Context, query ledgerstore.TransactionsQuery) (*api.Cursor[core.ExpandedTransaction], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTransactions", ctx, query) - ret0, _ := ret[0].(*api.Cursor[core.ExpandedTransaction]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTransactions indicates an expected call of GetTransactions. -func (mr *MockLedgerMockRecorder) GetTransactions(ctx, query interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTransactions", reflect.TypeOf((*MockLedger)(nil).GetTransactions), ctx, query) -} - -// RevertTransaction mocks base method. -func (m *MockLedger) RevertTransaction(ctx context.Context, parameters command.Parameters, id uint64) (*core.Transaction, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RevertTransaction", ctx, parameters, id) - ret0, _ := ret[0].(*core.Transaction) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RevertTransaction indicates an expected call of RevertTransaction. -func (mr *MockLedgerMockRecorder) RevertTransaction(ctx, parameters, id interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertTransaction", reflect.TypeOf((*MockLedger)(nil).RevertTransaction), ctx, parameters, id) -} - -// SaveMeta mocks base method. -func (m_2 *MockLedger) SaveMeta(ctx context.Context, parameters command.Parameters, targetType string, targetID any, m metadata.Metadata) error { - m_2.ctrl.T.Helper() - ret := m_2.ctrl.Call(m_2, "SaveMeta", ctx, parameters, targetType, targetID, m) - ret0, _ := ret[0].(error) - return ret0 -} - -// SaveMeta indicates an expected call of SaveMeta. -func (mr *MockLedgerMockRecorder) SaveMeta(ctx, parameters, targetType, targetID, m interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveMeta", reflect.TypeOf((*MockLedger)(nil).SaveMeta), ctx, parameters, targetType, targetID, m) -} - -// Stats mocks base method. -func (m *MockLedger) Stats(ctx context.Context) (ledger.Stats, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Stats", ctx) - ret0, _ := ret[0].(ledger.Stats) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Stats indicates an expected call of Stats. -func (mr *MockLedgerMockRecorder) Stats(ctx interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stats", reflect.TypeOf((*MockLedger)(nil).Stats), ctx) -} - -// MockBackend is a mock of Backend interface. -type MockBackend struct { - ctrl *gomock.Controller - recorder *MockBackendMockRecorder -} - -// MockBackendMockRecorder is the mock recorder for MockBackend. -type MockBackendMockRecorder struct { - mock *MockBackend -} - -// NewMockBackend creates a new mock instance. -func NewMockBackend(ctrl *gomock.Controller) *MockBackend { - mock := &MockBackend{ctrl: ctrl} - mock.recorder = &MockBackendMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockBackend) EXPECT() *MockBackendMockRecorder { - return m.recorder -} - -// CloseLedgers mocks base method. -func (m *MockBackend) CloseLedgers(ctx context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CloseLedgers", ctx) - ret0, _ := ret[0].(error) - return ret0 -} - -// CloseLedgers indicates an expected call of CloseLedgers. -func (mr *MockBackendMockRecorder) CloseLedgers(ctx interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseLedgers", reflect.TypeOf((*MockBackend)(nil).CloseLedgers), ctx) -} - -// GetLedger mocks base method. -func (m *MockBackend) GetLedger(ctx context.Context, name string) (controllers.Ledger, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLedger", ctx, name) - ret0, _ := ret[0].(controllers.Ledger) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetLedger indicates an expected call of GetLedger. -func (mr *MockBackendMockRecorder) GetLedger(ctx, name interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLedger", reflect.TypeOf((*MockBackend)(nil).GetLedger), ctx, name) -} - -// GetVersion mocks base method. -func (m *MockBackend) GetVersion() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetVersion") - ret0, _ := ret[0].(string) - return ret0 -} - -// GetVersion indicates an expected call of GetVersion. -func (mr *MockBackendMockRecorder) GetVersion() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVersion", reflect.TypeOf((*MockBackend)(nil).GetVersion)) -} - -// ListLedgers mocks base method. -func (m *MockBackend) ListLedgers(ctx context.Context) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListLedgers", ctx) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListLedgers indicates an expected call of ListLedgers. -func (mr *MockBackendMockRecorder) ListLedgers(ctx interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLedgers", reflect.TypeOf((*MockBackend)(nil).ListLedgers), ctx) -} diff --git a/components/ledger/pkg/api/controllers/balance_controller.go b/components/ledger/pkg/api/controllers/balance_controller.go deleted file mode 100644 index 18238c2cb..000000000 --- a/components/ledger/pkg/api/controllers/balance_controller.go +++ /dev/null @@ -1,68 +0,0 @@ -package controllers - -import ( - "net/http" - - "github.com/formancehq/ledger/pkg/api/apierrors" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - sharedapi "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/errorsutil" - "github.com/pkg/errors" -) - -func GetBalancesAggregated(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - balancesQuery := ledgerstore.NewBalancesQuery().WithAddressFilter(r.URL.Query().Get("address")) - balances, err := l.GetBalancesAggregated(r.Context(), balancesQuery) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.Ok(w, balances) -} - -func GetBalances(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - balancesQuery := ledgerstore.NewBalancesQuery() - - if r.URL.Query().Get(QueryKeyCursor) != "" { - if r.URL.Query().Get("after") != "" || - r.URL.Query().Get("address") != "" || - r.URL.Query().Get(QueryKeyPageSize) != "" { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.Errorf("no other query params can be set with '%s'", QueryKeyCursor))) - return - } - - err := ledgerstore.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), &balancesQuery) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.Errorf("invalid '%s' query param", QueryKeyCursor))) - return - } - - } else { - pageSize, err := getPageSize(r) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - balancesQuery = balancesQuery. - WithAfterAddress(r.URL.Query().Get("after")). - WithAddressFilter(r.URL.Query().Get("address")). - WithPageSize(pageSize) - } - - cursor, err := l.GetBalances(r.Context(), balancesQuery) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.RenderCursor(w, *cursor) -} diff --git a/components/ledger/pkg/api/controllers/balance_controller_test.go b/components/ledger/pkg/api/controllers/balance_controller_test.go deleted file mode 100644 index dc937d17f..000000000 --- a/components/ledger/pkg/api/controllers/balance_controller_test.go +++ /dev/null @@ -1,162 +0,0 @@ -package controllers_test - -import ( - "math/big" - "net/http" - "net/http/httptest" - "net/url" - "testing" - - "github.com/formancehq/ledger/pkg/api/apierrors" - "github.com/formancehq/ledger/pkg/api/routes" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - sharedapi "github.com/formancehq/stack/libs/go-libs/api" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" -) - -func TestGetBalancesAggregated(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - queryParams url.Values - expectQuery ledgerstore.BalancesQuery - } - - testCases := []testCase{ - { - name: "nominal", - expectQuery: ledgerstore.NewBalancesQuery(), - }, - { - name: "using address", - queryParams: url.Values{ - "address": []string{"foo"}, - }, - expectQuery: ledgerstore.NewBalancesQuery().WithAddressFilter("foo"), - }, - } - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - - expectedBalances := core.BalancesByAssets{ - "world": big.NewInt(-100), - } - backend, mock := newTestingBackend(t) - mock.EXPECT(). - GetBalancesAggregated(gomock.Any(), testCase.expectQuery). - Return(expectedBalances, nil) - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodGet, "/xxx/aggregate/balances", nil) - rec := httptest.NewRecorder() - req.URL.RawQuery = testCase.queryParams.Encode() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Code) - balances, ok := sharedapi.DecodeSingleResponse[core.BalancesByAssets](t, rec.Body) - require.True(t, ok) - require.Equal(t, expectedBalances, balances) - }) - } -} - -func TestGetBalances(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - queryParams url.Values - expectQuery ledgerstore.BalancesQuery - expectStatusCode int - expectedErrorCode string - } - - testCases := []testCase{ - { - name: "nominal", - expectQuery: ledgerstore.NewBalancesQuery(), - }, - { - name: "empty cursor with other param", - queryParams: url.Values{ - "cursor": []string{ledgerstore.EncodeCursor(ledgerstore.NewBalancesQuery())}, - "after": []string{"bob"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "invalid cursor", - queryParams: url.Values{ - "cursor": []string{"xxx"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using after", - queryParams: url.Values{ - "after": []string{"foo"}, - }, - expectQuery: ledgerstore.NewBalancesQuery().WithAfterAddress("foo"), - }, - { - name: "using address", - queryParams: url.Values{ - "address": []string{"foo"}, - }, - expectQuery: ledgerstore.NewBalancesQuery().WithAddressFilter("foo"), - }, - } - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - - if testCase.expectStatusCode == 0 { - testCase.expectStatusCode = http.StatusOK - } - - expectedCursor := sharedapi.Cursor[core.BalancesByAssetsByAccounts]{ - Data: []core.BalancesByAssetsByAccounts{ - { - "world": core.BalancesByAssets{ - "USD": big.NewInt(100), - }, - }, - }, - } - - backend, mock := newTestingBackend(t) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - mock.EXPECT(). - GetBalances(gomock.Any(), testCase.expectQuery). - Return(&expectedCursor, nil) - } - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodGet, "/xxx/balances", nil) - rec := httptest.NewRecorder() - req.URL.RawQuery = testCase.queryParams.Encode() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectStatusCode, rec.Code) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - cursor := sharedapi.DecodeCursorResponse[core.BalancesByAssetsByAccounts](t, rec.Body) - require.Equal(t, expectedCursor, *cursor) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} diff --git a/components/ledger/pkg/api/controllers/config_controller.go b/components/ledger/pkg/api/controllers/config_controller.go deleted file mode 100644 index 1ba68f7fa..000000000 --- a/components/ledger/pkg/api/controllers/config_controller.go +++ /dev/null @@ -1,43 +0,0 @@ -package controllers - -import ( - _ "embed" - "net/http" - - sharedapi "github.com/formancehq/stack/libs/go-libs/api" -) - -type ConfigInfo struct { - Server string `json:"server"` - Version string `json:"version"` - Config *Config `json:"config"` -} - -type Config struct { - LedgerStorage *LedgerStorage `json:"storage"` -} - -type LedgerStorage struct { - Driver string `json:"driver"` - Ledgers []string `json:"ledgers"` -} - -func GetInfo(backend Backend) func(w http.ResponseWriter, r *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - ledgers, err := backend.ListLedgers(r.Context()) - if err != nil { - panic(err) - } - - sharedapi.RawOk(w, ConfigInfo{ - Server: "ledger", - Version: backend.GetVersion(), - Config: &Config{ - LedgerStorage: &LedgerStorage{ - Driver: "postgres", - Ledgers: ledgers, - }, - }, - }) - } -} diff --git a/components/ledger/pkg/api/controllers/config_controller_test.go b/components/ledger/pkg/api/controllers/config_controller_test.go deleted file mode 100644 index 22bf88da9..000000000 --- a/components/ledger/pkg/api/controllers/config_controller_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package controllers_test - -import ( - "encoding/json" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/ledger/pkg/api/controllers" - "github.com/formancehq/ledger/pkg/api/routes" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" -) - -func TestGetInfo(t *testing.T) { - t.Parallel() - - backend, _ := newTestingBackend(t) - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - backend. - EXPECT(). - ListLedgers(gomock.Any()). - Return([]string{"a", "b"}, nil) - - backend. - EXPECT(). - GetVersion(). - Return("latest") - - req := httptest.NewRequest(http.MethodGet, "/_info", nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Code) - - info := controllers.ConfigInfo{} - require.NoError(t, json.NewDecoder(rec.Body).Decode(&info)) - - require.EqualValues(t, controllers.ConfigInfo{ - Server: "ledger", - Version: "latest", - Config: &controllers.Config{ - LedgerStorage: &controllers.LedgerStorage{ - Driver: "postgres", - Ledgers: []string{"a", "b"}, - }, - }, - }, info) -} diff --git a/components/ledger/pkg/api/controllers/context.go b/components/ledger/pkg/api/controllers/context.go deleted file mode 100644 index bdf8d04c0..000000000 --- a/components/ledger/pkg/api/controllers/context.go +++ /dev/null @@ -1,17 +0,0 @@ -package controllers - -import ( - "context" -) - -type ledgerKey struct{} - -var _ledgerKey = ledgerKey{} - -func ContextWithLedger(ctx context.Context, ledger Ledger) context.Context { - return context.WithValue(ctx, _ledgerKey, ledger) -} - -func LedgerFromContext(ctx context.Context) Ledger { - return ctx.Value(_ledgerKey).(Ledger) -} diff --git a/components/ledger/pkg/api/controllers/ledger_controller.go b/components/ledger/pkg/api/controllers/ledger_controller.go deleted file mode 100644 index 2e1cbfc8e..000000000 --- a/components/ledger/pkg/api/controllers/ledger_controller.go +++ /dev/null @@ -1,113 +0,0 @@ -package controllers - -import ( - "net/http" - - "github.com/formancehq/ledger/pkg/api/apierrors" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - sharedapi "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/errorsutil" - "github.com/go-chi/chi/v5" - "github.com/pkg/errors" -) - -type Info struct { - Name string `json:"name"` - Storage StorageInfo `json:"storage"` -} - -type StorageInfo struct { - Migrations []core.MigrationInfo `json:"migrations"` -} - -func GetLedgerInfo(w http.ResponseWriter, r *http.Request) { - ledger := LedgerFromContext(r.Context()) - - var err error - res := Info{ - Name: chi.URLParam(r, "ledger"), - Storage: StorageInfo{}, - } - res.Storage.Migrations, err = ledger.GetMigrationsInfo(r.Context()) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.Ok(w, res) -} - -func GetStats(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - stats, err := l.Stats(r.Context()) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.Ok(w, stats) -} - -func GetLogs(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - logsQuery := ledgerstore.NewLogsQuery() - - if r.URL.Query().Get(QueryKeyCursor) != "" { - if r.URL.Query().Get(QueryKeyStartTime) != "" || - r.URL.Query().Get(QueryKeyEndTime) != "" || - r.URL.Query().Get(QueryKeyPageSize) != "" { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.Errorf("no other query params can be set with '%s'", QueryKeyCursor))) - return - } - - err := ledgerstore.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), &logsQuery) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.Errorf("invalid '%s' query param", QueryKeyCursor))) - return - } - } else { - var err error - - var startTimeParsed, endTimeParsed core.Time - if r.URL.Query().Get(QueryKeyStartTime) != "" { - startTimeParsed, err = core.ParseTime(r.URL.Query().Get(QueryKeyStartTime)) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, ErrInvalidStartTime)) - return - } - } - - if r.URL.Query().Get(QueryKeyEndTime) != "" { - endTimeParsed, err = core.ParseTime(r.URL.Query().Get(QueryKeyEndTime)) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, ErrInvalidEndTime)) - return - } - } - - pageSize, err := getPageSize(r) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - logsQuery = logsQuery. - WithStartTimeFilter(startTimeParsed). - WithEndTimeFilter(endTimeParsed). - WithPageSize(pageSize) - } - - cursor, err := l.GetLogs(r.Context(), logsQuery) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.RenderCursor(w, *cursor) -} diff --git a/components/ledger/pkg/api/controllers/ledger_controller_test.go b/components/ledger/pkg/api/controllers/ledger_controller_test.go deleted file mode 100644 index c3ed8d540..000000000 --- a/components/ledger/pkg/api/controllers/ledger_controller_test.go +++ /dev/null @@ -1,212 +0,0 @@ -package controllers_test - -import ( - "encoding/json" - "net/http" - "net/http/httptest" - "net/url" - "testing" - "time" - - "github.com/formancehq/ledger/pkg/api/apierrors" - "github.com/formancehq/ledger/pkg/api/controllers" - "github.com/formancehq/ledger/pkg/api/routes" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - sharedapi "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" -) - -func TestGetLedgerInfo(t *testing.T) { - t.Parallel() - - backend, mock := newTestingBackend(t) - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - migrationInfo := []core.MigrationInfo{ - { - Version: "1", - Name: "init", - State: "ready", - Date: core.Now().Add(-2 * time.Minute).Round(time.Second), - }, - { - Version: "2", - Name: "fix", - State: "ready", - Date: core.Now().Add(-time.Minute).Round(time.Second), - }, - } - - mock.EXPECT(). - GetMigrationsInfo(gomock.Any()). - Return(migrationInfo, nil) - - req := httptest.NewRequest(http.MethodGet, "/xxx/_info", nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Code) - - info, ok := sharedapi.DecodeSingleResponse[controllers.Info](t, rec.Body) - require.True(t, ok) - - require.EqualValues(t, controllers.Info{ - Name: "xxx", - Storage: controllers.StorageInfo{ - Migrations: migrationInfo, - }, - }, info) -} - -func TestGetStats(t *testing.T) { - t.Parallel() - - backend, mock := newTestingBackend(t) - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - expectedStats := ledger.Stats{ - Transactions: 10, - Accounts: 5, - } - - mock.EXPECT(). - Stats(gomock.Any()). - Return(expectedStats, nil) - - req := httptest.NewRequest(http.MethodGet, "/xxx/stats", nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Code) - - stats, ok := sharedapi.DecodeSingleResponse[ledger.Stats](t, rec.Body) - require.True(t, ok) - - require.EqualValues(t, expectedStats, stats) -} - -func TestGetLogs(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - queryParams url.Values - expectQuery ledgerstore.LogsQuery - expectStatusCode int - expectedErrorCode string - } - - now := core.Now() - testCases := []testCase{ - { - name: "nominal", - expectQuery: ledgerstore.NewLogsQuery(), - }, - { - name: "using start time", - queryParams: url.Values{ - "startTime": []string{now.Format(core.DateFormat)}, - }, - expectQuery: ledgerstore.NewLogsQuery().WithStartTimeFilter(now), - }, - { - name: "using end time", - queryParams: url.Values{ - "endTime": []string{now.Format(core.DateFormat)}, - }, - expectQuery: ledgerstore.NewLogsQuery().WithEndTimeFilter(now), - }, - { - name: "using invalid start time", - queryParams: url.Values{ - "startTime": []string{"xxx"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using invalid end time", - queryParams: url.Values{ - "endTime": []string{"xxx"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using empty cursor", - queryParams: url.Values{ - "cursor": []string{ledgerstore.EncodeCursor(ledgerstore.NewLogsQuery())}, - }, - expectQuery: ledgerstore.NewLogsQuery(), - }, - { - name: "using invalid cursor", - queryParams: url.Values{ - "cursor": []string{"xxx"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - } - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - - if testCase.expectStatusCode == 0 { - testCase.expectStatusCode = http.StatusOK - } - - expectedCursor := sharedapi.Cursor[core.ChainedLog]{ - Data: []core.ChainedLog{ - *core.NewTransactionLog(core.NewTransaction(), map[string]metadata.Metadata{}). - ChainLog(nil), - }, - } - - backend, mockLedger := newTestingBackend(t) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - mockLedger.EXPECT(). - GetLogs(gomock.Any(), testCase.expectQuery). - Return(&expectedCursor, nil) - } - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodGet, "/xxx/logs", nil) - rec := httptest.NewRecorder() - req.URL.RawQuery = testCase.queryParams.Encode() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectStatusCode, rec.Code) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - cursor := sharedapi.DecodeCursorResponse[core.ChainedLog](t, rec.Body) - - cursorData, err := json.Marshal(cursor) - require.NoError(t, err) - - cursorAsMap := make(map[string]any) - require.NoError(t, json.Unmarshal(cursorData, &cursorAsMap)) - - expectedCursorData, err := json.Marshal(expectedCursor) - require.NoError(t, err) - - expectedCursorAsMap := make(map[string]any) - require.NoError(t, json.Unmarshal(expectedCursorData, &expectedCursorAsMap)) - - require.Equal(t, expectedCursorAsMap, cursorAsMap) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} diff --git a/components/ledger/pkg/api/controllers/query.go b/components/ledger/pkg/api/controllers/query.go deleted file mode 100644 index 69fe7568e..000000000 --- a/components/ledger/pkg/api/controllers/query.go +++ /dev/null @@ -1,69 +0,0 @@ -package controllers - -import ( - "net/http" - "strconv" - "strings" - - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/stack/libs/go-libs/errorsutil" - "github.com/pkg/errors" -) - -const ( - MaxPageSize = 100 - DefaultPageSize = ledgerstore.QueryDefaultPageSize - - QueryKeyCursor = "cursor" - QueryKeyPageSize = "pageSize" - QueryKeyBalanceOperator = "balanceOperator" - QueryKeyStartTime = "startTime" - QueryKeyEndTime = "endTime" -) - -var ( - ErrInvalidPageSize = errors.New("invalid 'pageSize' query param") - ErrInvalidBalanceOperator = errors.New( - "invalid parameter 'balanceOperator', should be one of 'e, ne, gt, gte, lt, lte'") - ErrInvalidStartTime = errors.New("invalid 'startTime' query param") - ErrInvalidEndTime = errors.New("invalid 'endTime' query param") -) - -func getPageSize(r *http.Request) (uint64, error) { - pageSizeParam := r.URL.Query().Get(QueryKeyPageSize) - if pageSizeParam == "" { - return DefaultPageSize, nil - } - - var pageSize uint64 - var err error - if pageSizeParam != "" { - pageSize, err = strconv.ParseUint(pageSizeParam, 10, 32) - if err != nil { - return 0, errorsutil.NewError(command.ErrValidation, ErrInvalidPageSize) - } - } - - if pageSize > MaxPageSize { - return MaxPageSize, nil - } - - return pageSize, nil -} - -func getCommandParameters(r *http.Request) command.Parameters { - dryRunAsString := r.URL.Query().Get("dryRun") - dryRun := strings.ToUpper(dryRunAsString) == "YES" || strings.ToUpper(dryRunAsString) == "TRUE" || dryRunAsString == "1" - - asyncAsString := r.URL.Query().Get("async") - async := strings.ToUpper(asyncAsString) == "YES" || strings.ToUpper(asyncAsString) == "TRUE" || asyncAsString == "1" - - idempotencyKey := r.Header.Get("Idempotency-Key") - - return command.Parameters{ - DryRun: dryRun, - Async: async, - IdempotencyKey: idempotencyKey, - } -} diff --git a/components/ledger/pkg/api/controllers/transaction_controller.go b/components/ledger/pkg/api/controllers/transaction_controller.go deleted file mode 100644 index cb02f4f3e..000000000 --- a/components/ledger/pkg/api/controllers/transaction_controller.go +++ /dev/null @@ -1,287 +0,0 @@ -package controllers - -import ( - "encoding/json" - "fmt" - "net/http" - "strconv" - - "github.com/formancehq/ledger/pkg/api/apierrors" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - sharedapi "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/errorsutil" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/go-chi/chi/v5" - "github.com/pkg/errors" -) - -func CountTransactions(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - var startTimeParsed, endTimeParsed core.Time - var err error - if r.URL.Query().Get(QueryKeyStartTime) != "" { - startTimeParsed, err = core.ParseTime(r.URL.Query().Get(QueryKeyStartTime)) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, ErrInvalidStartTime)) - return - } - } - - if r.URL.Query().Get(QueryKeyEndTime) != "" { - endTimeParsed, err = core.ParseTime(r.URL.Query().Get(QueryKeyEndTime)) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, ErrInvalidEndTime)) - return - } - } - - txQuery := ledgerstore.NewTransactionsQuery(). - WithReferenceFilter(r.URL.Query().Get("reference")). - WithAccountFilter(r.URL.Query().Get("account")). - WithSourceFilter(r.URL.Query().Get("source")). - WithDestinationFilter(r.URL.Query().Get("destination")). - WithStartTimeFilter(startTimeParsed). - WithEndTimeFilter(endTimeParsed). - WithMetadataFilter(sharedapi.GetQueryMap(r.URL.Query(), "metadata")) - - count, err := l.CountTransactions(r.Context(), txQuery) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - w.Header().Set("Count", fmt.Sprint(count)) - sharedapi.NoContent(w) -} - -func GetTransactions(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - txQuery := ledgerstore.NewTransactionsQuery() - - if r.URL.Query().Get(QueryKeyCursor) != "" { - if r.URL.Query().Get("after") != "" || - r.URL.Query().Get("reference") != "" || - r.URL.Query().Get("account") != "" || - r.URL.Query().Get("source") != "" || - r.URL.Query().Get("destination") != "" || - r.URL.Query().Get(QueryKeyStartTime) != "" || - r.URL.Query().Get(QueryKeyEndTime) != "" || - r.URL.Query().Get(QueryKeyPageSize) != "" { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.Errorf("no other query params can be set with '%s'", QueryKeyCursor))) - return - } - - err := ledgerstore.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), &txQuery) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.Errorf("invalid '%s' query param", QueryKeyCursor))) - return - } - } else { - var ( - err error - afterTxIDParsed uint64 - ) - if r.URL.Query().Get("after") != "" { - afterTxIDParsed, err = strconv.ParseUint(r.URL.Query().Get("after"), 10, 64) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.New("invalid 'after' query param"))) - return - } - } - - var startTimeParsed, endTimeParsed core.Time - if r.URL.Query().Get(QueryKeyStartTime) != "" { - startTimeParsed, err = core.ParseTime(r.URL.Query().Get(QueryKeyStartTime)) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, ErrInvalidStartTime)) - return - } - } - - if r.URL.Query().Get(QueryKeyEndTime) != "" { - endTimeParsed, err = core.ParseTime(r.URL.Query().Get(QueryKeyEndTime)) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, ErrInvalidEndTime)) - return - } - } - - pageSize, err := getPageSize(r) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - txQuery = txQuery. - WithAfterTxID(afterTxIDParsed). - WithReferenceFilter(r.URL.Query().Get("reference")). - WithAccountFilter(r.URL.Query().Get("account")). - WithSourceFilter(r.URL.Query().Get("source")). - WithDestinationFilter(r.URL.Query().Get("destination")). - WithStartTimeFilter(startTimeParsed). - WithEndTimeFilter(endTimeParsed). - WithMetadataFilter(sharedapi.GetQueryMap(r.URL.Query(), "metadata")). - WithPageSize(pageSize) - } - - cursor, err := l.GetTransactions(r.Context(), txQuery) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.RenderCursor(w, *cursor) -} - -type Script struct { - core.Script - Vars map[string]any `json:"vars"` -} - -func (s Script) ToCore() core.Script { - s.Script.Vars = map[string]string{} - for k, v := range s.Vars { - switch v := v.(type) { - case string: - s.Script.Vars[k] = v - case map[string]any: - s.Script.Vars[k] = fmt.Sprintf("%s %v", v["asset"], v["amount"]) - default: - s.Script.Vars[k] = fmt.Sprint(v) - } - } - return s.Script -} - -type PostTransactionRequest struct { - Postings core.Postings `json:"postings"` - Script Script `json:"script"` - Timestamp core.Time `json:"timestamp"` - Reference string `json:"reference"` - Metadata metadata.Metadata `json:"metadata" swaggertype:"object"` -} - -func PostTransaction(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - payload := PostTransactionRequest{} - if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { - apierrors.ResponseError(w, r, - errorsutil.NewError(command.ErrValidation, - errors.New("invalid transaction format"))) - return - } - - if len(payload.Postings) > 0 && payload.Script.Plain != "" || - len(payload.Postings) == 0 && payload.Script.Plain == "" { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.New("invalid payload: should contain either postings or script"))) - return - } else if len(payload.Postings) > 0 { - if i, err := payload.Postings.Validate(); err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, errors.Wrap(err, - fmt.Sprintf("invalid posting %d", i)))) - return - } - txData := core.TransactionData{ - Postings: payload.Postings, - Timestamp: payload.Timestamp, - Reference: payload.Reference, - Metadata: payload.Metadata, - } - - res, err := l.CreateTransaction(r.Context(), getCommandParameters(r), core.TxToScriptData(txData)) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.Ok(w, res) - return - } - - script := core.RunScript{ - Script: payload.Script.ToCore(), - Timestamp: payload.Timestamp, - Reference: payload.Reference, - Metadata: payload.Metadata, - } - - res, err := l.CreateTransaction(r.Context(), getCommandParameters(r), script) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.Ok(w, res) -} - -func GetTransaction(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - txId, err := strconv.ParseUint(chi.URLParam(r, "txid"), 10, 64) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.New("invalid transaction ID"))) - return - } - - tx, err := l.GetTransaction(r.Context(), txId) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.Ok(w, tx) -} - -func RevertTransaction(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - txId, err := strconv.ParseUint(chi.URLParam(r, "txid"), 10, 64) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.New("invalid transaction ID"))) - return - } - - tx, err := l.RevertTransaction(r.Context(), getCommandParameters(r), txId) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.Created(w, tx) -} - -func PostTransactionMetadata(w http.ResponseWriter, r *http.Request) { - l := LedgerFromContext(r.Context()) - - var m metadata.Metadata - if err := json.NewDecoder(r.Body).Decode(&m); err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.New("invalid metadata format"))) - return - } - - txId, err := strconv.ParseUint(chi.URLParam(r, "txid"), 10, 64) - if err != nil { - apierrors.ResponseError(w, r, errorsutil.NewError(command.ErrValidation, - errors.New("invalid transaction ID"))) - return - } - - if err := l.SaveMeta(r.Context(), getCommandParameters(r), core.MetaTargetTypeTransaction, txId, m); err != nil { - apierrors.ResponseError(w, r, err) - return - } - - sharedapi.NoContent(w) -} diff --git a/components/ledger/pkg/api/controllers/transaction_controller_test.go b/components/ledger/pkg/api/controllers/transaction_controller_test.go deleted file mode 100644 index 5903d9e30..000000000 --- a/components/ledger/pkg/api/controllers/transaction_controller_test.go +++ /dev/null @@ -1,708 +0,0 @@ -package controllers_test - -import ( - "math/big" - "net/http" - "net/http/httptest" - "net/url" - "testing" - - "github.com/formancehq/ledger/pkg/api/apierrors" - "github.com/formancehq/ledger/pkg/api/controllers" - "github.com/formancehq/ledger/pkg/api/routes" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - sharedapi "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" -) - -func TestPostTransactions(t *testing.T) { - type testCase struct { - name string - expectedDryRun bool - expectedRunScript core.RunScript - payload any - expectedStatusCode int - expectedErrorCode string - queryParams url.Values - } - - testCases := []testCase{ - { - name: "using plain numscript", - payload: controllers.PostTransactionRequest{ - Script: controllers.Script{ - Script: core.Script{ - Plain: `XXX`, - }, - }, - }, - expectedRunScript: core.RunScript{ - Script: core.Script{ - Plain: `XXX`, - Vars: map[string]string{}, - }, - }, - }, - { - name: "using plain numscript with variables", - payload: controllers.PostTransactionRequest{ - Script: controllers.Script{ - Script: core.Script{ - Plain: `vars { - monetary $val - } - - send $val ( - source = @world - destination = @bank - )`, - }, - Vars: map[string]any{ - "val": "USD/2 100", - }, - }, - }, - expectedRunScript: core.RunScript{ - Script: core.Script{ - Plain: `vars { - monetary $val - } - - send $val ( - source = @world - destination = @bank - )`, - Vars: map[string]string{ - "val": "USD/2 100", - }, - }, - }, - }, - { - name: "using plain numscript with variables (legacy format)", - payload: controllers.PostTransactionRequest{ - Script: controllers.Script{ - Script: core.Script{ - Plain: `vars { - monetary $val - } - - send $val ( - source = @world - destination = @bank - )`, - }, - Vars: map[string]any{ - "val": map[string]any{ - "asset": "USD/2", - "amount": 100, - }, - }, - }, - }, - expectedRunScript: core.RunScript{ - Script: core.Script{ - Plain: `vars { - monetary $val - } - - send $val ( - source = @world - destination = @bank - )`, - Vars: map[string]string{ - "val": "USD/2 100", - }, - }, - }, - }, - { - name: "using plain numscript and dry run", - payload: controllers.PostTransactionRequest{ - Script: controllers.Script{ - Script: core.Script{ - Plain: `send ( - source = @world - destination = @bank - )`, - }, - }, - }, - expectedRunScript: core.RunScript{ - Script: core.Script{ - Plain: `send ( - source = @world - destination = @bank - )`, - Vars: map[string]string{}, - }, - }, - expectedDryRun: true, - queryParams: url.Values{ - "dryRun": []string{"true"}, - }, - }, - { - name: "using JSON postings", - payload: controllers.PostTransactionRequest{ - Postings: []core.Posting{ - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - }, - }, - expectedRunScript: core.TxToScriptData(core.NewTransactionData().WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - )), - }, - { - name: "using JSON postings and dry run", - queryParams: url.Values{ - "dryRun": []string{"true"}, - }, - payload: controllers.PostTransactionRequest{ - Postings: []core.Posting{ - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - }, - }, - expectedDryRun: true, - expectedRunScript: core.TxToScriptData(core.NewTransactionData().WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - )), - }, - { - name: "no postings or script", - payload: controllers.PostTransactionRequest{}, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "postings and script", - payload: controllers.PostTransactionRequest{ - Postings: core.Postings{ - { - Source: "world", - Destination: "alice", - Amount: big.NewInt(100), - Asset: "COIN", - }, - }, - Script: controllers.Script{ - Script: core.Script{ - Plain: ` - send [COIN 100] ( - source = @world - destination = @bob - )`, - }, - }, - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using invalid body", - payload: "not a valid payload", - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - } - - for _, testCase := range testCases { - tc := testCase - t.Run(tc.name, func(t *testing.T) { - if testCase.expectedStatusCode == 0 { - testCase.expectedStatusCode = http.StatusOK - } - - expectedTx := core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - ) - - backend, mockLedger := newTestingBackend(t) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - mockLedger.EXPECT(). - CreateTransaction(gomock.Any(), command.Parameters{ - DryRun: tc.expectedDryRun, - Async: false, - }, testCase.expectedRunScript). - Return(expectedTx, nil) - } - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodPost, "/xxx/transactions", sharedapi.Buffer(t, testCase.payload)) - rec := httptest.NewRecorder() - req.URL.RawQuery = testCase.queryParams.Encode() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectedStatusCode, rec.Code) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - tx, ok := sharedapi.DecodeSingleResponse[core.Transaction](t, rec.Body) - require.True(t, ok) - require.Equal(t, *expectedTx, tx) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} - -func TestPostTransactionMetadata(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - queryParams url.Values - expectStatusCode int - expectedErrorCode string - body any - } - - testCases := []testCase{ - { - name: "nominal", - body: metadata.Metadata{ - "foo": "bar", - }, - }, - { - name: "invalid body", - body: "invalid - not an object", - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - } - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - - if testCase.expectStatusCode == 0 { - testCase.expectStatusCode = http.StatusNoContent - } - - backend, mock := newTestingBackend(t) - if testCase.expectStatusCode == http.StatusNoContent { - mock.EXPECT(). - SaveMeta(gomock.Any(), command.Parameters{}, core.MetaTargetTypeTransaction, uint64(0), testCase.body). - Return(nil) - } - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodPost, "/xxx/transactions/0/metadata", sharedapi.Buffer(t, testCase.body)) - rec := httptest.NewRecorder() - req.URL.RawQuery = testCase.queryParams.Encode() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectStatusCode, rec.Code) - if testCase.expectStatusCode >= 300 || testCase.expectStatusCode < 200 { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} - -func TestGetTransaction(t *testing.T) { - t.Parallel() - - tx := core.ExpandTransaction( - core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - ), - nil, - ) - - backend, mock := newTestingBackend(t) - mock.EXPECT(). - GetTransaction(gomock.Any(), uint64(0)). - Return(&tx, nil) - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodGet, "/xxx/transactions/0", nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Code) - response, _ := sharedapi.DecodeSingleResponse[core.ExpandedTransaction](t, rec.Body) - require.Equal(t, tx, response) -} - -func TestGetTransactions(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - queryParams url.Values - expectQuery ledgerstore.TransactionsQuery - expectStatusCode int - expectedErrorCode string - } - now := core.Now() - - testCases := []testCase{ - { - name: "nominal", - expectQuery: ledgerstore.NewTransactionsQuery(), - }, - { - name: "using metadata", - queryParams: url.Values{ - "metadata[roles]": []string{"admin"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithMetadataFilter(map[string]string{ - "roles": "admin", - }), - }, - { - name: "using nested metadata", - queryParams: url.Values{ - "metadata[a.nested.key]": []string{"hello"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithMetadataFilter(map[string]string{ - "a.nested.key": "hello", - }), - }, - { - name: "using after", - queryParams: url.Values{ - "after": []string{"10"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithAfterTxID(10), - }, - { - name: "using startTime", - queryParams: url.Values{ - "startTime": []string{now.Format(core.DateFormat)}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithStartTimeFilter(now), - }, - { - name: "using invalid startTime", - queryParams: url.Values{ - "startTime": []string{"xxx"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using endTime", - queryParams: url.Values{ - "endTime": []string{now.Format(core.DateFormat)}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithEndTimeFilter(now), - }, - { - name: "using invalid endTime", - queryParams: url.Values{ - "endTime": []string{"xxx"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using account", - queryParams: url.Values{ - "account": []string{"xxx"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithAccountFilter("xxx"), - }, - { - name: "using reference", - queryParams: url.Values{ - "reference": []string{"xxx"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithReferenceFilter("xxx"), - }, - { - name: "using destination", - queryParams: url.Values{ - "destination": []string{"xxx"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithDestinationFilter("xxx"), - }, - { - name: "using source", - queryParams: url.Values{ - "source": []string{"xxx"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithSourceFilter("xxx"), - }, - { - name: "using empty cursor", - queryParams: url.Values{ - "cursor": []string{ledgerstore.EncodeCursor(ledgerstore.NewTransactionsQuery())}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(), - }, - { - name: "using cursor with other param", - queryParams: url.Values{ - "cursor": []string{ledgerstore.EncodeCursor(ledgerstore.NewTransactionsQuery())}, - "after": []string{"foo"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using invalid cursor", - queryParams: url.Values{ - "cursor": []string{"XXX"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "invalid page size", - queryParams: url.Values{ - "pageSize": []string{"nan"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "invalid after", - queryParams: url.Values{ - "after": []string{"nan"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "page size over maximum", - queryParams: url.Values{ - "pageSize": []string{"1000000"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithPageSize(controllers.MaxPageSize). - WithMetadataFilter(map[string]string{}), - }, - } - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - - if testCase.expectStatusCode == 0 { - testCase.expectStatusCode = http.StatusOK - } - - expectedCursor := sharedapi.Cursor[core.ExpandedTransaction]{ - Data: []core.ExpandedTransaction{ - core.ExpandTransaction( - core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - ), - nil, - ), - }, - } - - backend, mockLedger := newTestingBackend(t) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - mockLedger.EXPECT(). - GetTransactions(gomock.Any(), testCase.expectQuery). - Return(&expectedCursor, nil) - } - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodGet, "/xxx/transactions", nil) - rec := httptest.NewRecorder() - req.URL.RawQuery = testCase.queryParams.Encode() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectStatusCode, rec.Code) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - cursor := sharedapi.DecodeCursorResponse[core.ExpandedTransaction](t, rec.Body) - require.Equal(t, expectedCursor, *cursor) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} - -func TestCountTransactions(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - queryParams url.Values - expectQuery ledgerstore.TransactionsQuery - expectStatusCode int - expectedErrorCode string - } - now := core.Now() - - testCases := []testCase{ - { - name: "nominal", - expectQuery: ledgerstore.NewTransactionsQuery(), - }, - { - name: "using metadata", - queryParams: url.Values{ - "metadata[roles]": []string{"admin"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithMetadataFilter(map[string]string{ - "roles": "admin", - }), - }, - { - name: "using nested metadata", - queryParams: url.Values{ - "metadata[a.nested.key]": []string{"hello"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithMetadataFilter(map[string]string{ - "a.nested.key": "hello", - }), - }, - { - name: "using startTime", - queryParams: url.Values{ - "startTime": []string{now.Format(core.DateFormat)}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithStartTimeFilter(now), - }, - { - name: "using invalid startTime", - queryParams: url.Values{ - "startTime": []string{"xxx"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using endTime", - queryParams: url.Values{ - "endTime": []string{now.Format(core.DateFormat)}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithEndTimeFilter(now), - }, - { - name: "using invalid endTime", - queryParams: url.Values{ - "endTime": []string{"xxx"}, - }, - expectStatusCode: http.StatusBadRequest, - expectedErrorCode: apierrors.ErrValidation, - }, - { - name: "using account", - queryParams: url.Values{ - "account": []string{"xxx"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithAccountFilter("xxx"), - }, - { - name: "using reference", - queryParams: url.Values{ - "reference": []string{"xxx"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithReferenceFilter("xxx"), - }, - { - name: "using destination", - queryParams: url.Values{ - "destination": []string{"xxx"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithDestinationFilter("xxx"), - }, - { - name: "using source", - queryParams: url.Values{ - "source": []string{"xxx"}, - }, - expectQuery: ledgerstore.NewTransactionsQuery(). - WithSourceFilter("xxx"), - }, - } - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - - if testCase.expectStatusCode == 0 { - testCase.expectStatusCode = http.StatusNoContent - } - - backend, mockLedger := newTestingBackend(t) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - mockLedger.EXPECT(). - CountTransactions(gomock.Any(), testCase.expectQuery). - Return(uint64(10), nil) - } - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodHead, "/xxx/transactions", nil) - rec := httptest.NewRecorder() - req.URL.RawQuery = testCase.queryParams.Encode() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectStatusCode, rec.Code) - if testCase.expectStatusCode < 300 && testCase.expectStatusCode >= 200 { - require.Equal(t, "10", rec.Header().Get("Count")) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} - -func TestRevertTransaction(t *testing.T) { - - expectedTx := core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - ) - - backend, mockLedger := newTestingBackend(t) - mockLedger. - EXPECT(). - RevertTransaction(gomock.Any(), command.Parameters{}, uint64(0)). - Return(expectedTx, nil) - - router := routes.NewRouter(backend, nil, metrics.NewNoOpRegistry()) - - req := httptest.NewRequest(http.MethodPost, "/xxx/transactions/0/revert", nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Code) - tx, ok := sharedapi.DecodeSingleResponse[core.Transaction](t, rec.Body) - require.True(t, ok) - require.Equal(t, *expectedTx, tx) -} diff --git a/components/ledger/pkg/api/controllers/utils_test.go b/components/ledger/pkg/api/controllers/utils_test.go deleted file mode 100644 index 9fec5cf83..000000000 --- a/components/ledger/pkg/api/controllers/utils_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package controllers_test - -import ( - "testing" - - "github.com/golang/mock/gomock" -) - -func newTestingBackend(t *testing.T) (*MockBackend, *MockLedger) { - ctrl := gomock.NewController(t) - mockLedger := NewMockLedger(ctrl) - backend := NewMockBackend(ctrl) - backend. - EXPECT(). - GetLedger(gomock.Any(), gomock.Any()). - MinTimes(0). - Return(mockLedger, nil) - t.Cleanup(func() { - ctrl.Finish() - }) - return backend, mockLedger -} diff --git a/components/ledger/pkg/api/middlewares/ledger_middleware.go b/components/ledger/pkg/api/middlewares/ledger_middleware.go deleted file mode 100644 index da6d75a94..000000000 --- a/components/ledger/pkg/api/middlewares/ledger_middleware.go +++ /dev/null @@ -1,72 +0,0 @@ -package middlewares - -import ( - "math/rand" - "net/http" - "time" - - "github.com/formancehq/ledger/pkg/api/apierrors" - "github.com/formancehq/ledger/pkg/api/controllers" - "github.com/formancehq/ledger/pkg/opentelemetry/tracer" - "github.com/formancehq/stack/libs/go-libs/logging" - "github.com/go-chi/chi/v5" -) - -var r *rand.Rand - -func init() { - r = rand.New(rand.NewSource(time.Now().UnixNano())) -} - -var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") - -func randomTraceID(n int) string { - b := make([]rune, n) - for i := range b { - b[i] = letterRunes[r.Intn(len(letterRunes))] - } - return string(b) -} - -func LedgerMiddleware( - resolver controllers.Backend, -) func(handler http.Handler) http.Handler { - return func(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - name := chi.URLParam(r, "ledger") - if name == "" { - w.WriteHeader(http.StatusNotFound) - return - } - - ctx, span := tracer.Start(r.Context(), name) - defer span.End() - - r = r.WithContext(ctx) - - loggerFields := map[string]any{ - "ledger": name, - } - if span.SpanContext().TraceID().IsValid() { - loggerFields["trace-id"] = span.SpanContext().TraceID().String() - } else { - loggerFields["trace-id"] = randomTraceID(10) - } - r = r.WithContext(logging.ContextWithFields(r.Context(), loggerFields)) - - l, err := resolver.GetLedger(r.Context(), name) - if err != nil { - apierrors.ResponseError(w, r, err) - return - } - // TODO(polo/gfyrag): close ledger if not used for x minutes - // defer l.Close(context.Background()) - // When close, we have to decrease the active ledgers counter: - // globalMetricsRegistry.ActiveLedgers.Add(r.Context(), -1) - - r = r.WithContext(controllers.ContextWithLedger(r.Context(), l)) - - handler.ServeHTTP(w, r) - }) - } -} diff --git a/components/ledger/pkg/api/middlewares/log_middleware.go b/components/ledger/pkg/api/middlewares/log_middleware.go deleted file mode 100644 index 28e2f421a..000000000 --- a/components/ledger/pkg/api/middlewares/log_middleware.go +++ /dev/null @@ -1,25 +0,0 @@ -package middlewares - -import ( - "net/http" - "time" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/stack/libs/go-libs/logging" -) - -func Log() func(h http.Handler) http.Handler { - return func(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - start := core.Now() - h.ServeHTTP(w, r) - latency := time.Since(start.Time) - logging.FromContext(r.Context()).WithFields(map[string]interface{}{ - "method": r.Method, - "path": r.URL.Path, - "latency": latency, - "user_agent": r.UserAgent(), - }).Info("Request") - }) - } -} diff --git a/components/ledger/pkg/api/middlewares/metrics_middleware.go b/components/ledger/pkg/api/middlewares/metrics_middleware.go deleted file mode 100644 index 86c086299..000000000 --- a/components/ledger/pkg/api/middlewares/metrics_middleware.go +++ /dev/null @@ -1,54 +0,0 @@ -package middlewares - -import ( - "net/http" - "time" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/go-chi/chi/v5" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" -) - -type statusRecorder struct { - http.ResponseWriter - Status int -} - -func newStatusRecorder(w http.ResponseWriter) *statusRecorder { - return &statusRecorder{ResponseWriter: w} -} - -func (r *statusRecorder) WriteHeader(status int) { - r.Status = status - r.ResponseWriter.WriteHeader(status) -} - -func MetricsMiddleware(globalMetricsRegistry metrics.GlobalRegistry) func(h http.Handler) http.Handler { - return func(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - attrs := []attribute.KeyValue{} - - ctx := r.Context() - name := chi.URLParam(r, "ledger") - if name != "" { - attrs = append(attrs, attribute.String("ledger", name)) - } - - recorder := newStatusRecorder(w) - - start := core.Now() - h.ServeHTTP(recorder, r) - latency := time.Since(start.Time) - - attrs = append(attrs, - attribute.String("route", chi.RouteContext(r.Context()).RoutePattern())) - - globalMetricsRegistry.APILatencies().Record(ctx, latency.Milliseconds(), metric.WithAttributes(attrs...)) - - attrs = append(attrs, attribute.Int("status", recorder.Status)) - globalMetricsRegistry.StatusCodes().Add(ctx, 1, metric.WithAttributes(attrs...)) - }) - } -} diff --git a/components/ledger/pkg/api/routes/routes.go b/components/ledger/pkg/api/routes/routes.go deleted file mode 100644 index 197a1559d..000000000 --- a/components/ledger/pkg/api/routes/routes.go +++ /dev/null @@ -1,77 +0,0 @@ -package routes - -import ( - "net/http" - - "github.com/formancehq/ledger/pkg/api/controllers" - "github.com/formancehq/ledger/pkg/api/middlewares" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/stack/libs/go-libs/health" - "github.com/go-chi/chi/v5" - "github.com/go-chi/chi/v5/middleware" - "github.com/go-chi/cors" - "github.com/riandyrn/otelchi" -) - -func NewRouter( - backend controllers.Backend, - healthController *health.HealthController, - globalMetricsRegistry metrics.GlobalRegistry, -) chi.Router { - router := chi.NewMux() - - router.Use( - cors.New(cors.Options{ - AllowOriginFunc: func(r *http.Request, origin string) bool { - return true - }, - AllowCredentials: true, - }).Handler, - middlewares.MetricsMiddleware(globalMetricsRegistry), - middleware.Recoverer, - ) - - router.Get("/_healthcheck", healthController.Check) - - router.Group(func(router chi.Router) { - router.Use(otelchi.Middleware("ledger")) - router.Get("/_info", controllers.GetInfo(backend)) - - router.Route("/{ledger}", func(router chi.Router) { - router.Use(func(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - handler.ServeHTTP(w, r) - }) - }) - router.Use(middlewares.LedgerMiddleware(backend)) - - // LedgerController - router.Get("/_info", controllers.GetLedgerInfo) - router.Get("/stats", controllers.GetStats) - router.Get("/logs", controllers.GetLogs) - - // AccountController - router.Get("/accounts", controllers.GetAccounts) - router.Head("/accounts", controllers.CountAccounts) - router.Get("/accounts/{address}", controllers.GetAccount) - router.Post("/accounts/{address}/metadata", controllers.PostAccountMetadata) - - // TransactionController - router.Get("/transactions", controllers.GetTransactions) - router.Head("/transactions", controllers.CountTransactions) - - router.Post("/transactions", controllers.PostTransaction) - - router.Get("/transactions/{txid}", controllers.GetTransaction) - router.Post("/transactions/{txid}/revert", controllers.RevertTransaction) - router.Post("/transactions/{txid}/metadata", controllers.PostTransactionMetadata) - - // BalanceController - router.Get("/balances", controllers.GetBalances) - // TODO: Rename to /aggregatedBalances - router.Get("/aggregate/balances", controllers.GetBalancesAggregated) - }) - }) - - return router -} diff --git a/components/ledger/pkg/bus/message.go b/components/ledger/pkg/bus/message.go deleted file mode 100644 index 469f6d913..000000000 --- a/components/ledger/pkg/bus/message.go +++ /dev/null @@ -1,71 +0,0 @@ -package bus - -import ( - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/stack/libs/go-libs/metadata" -) - -const ( - EventVersion = "v1" - EventApp = "ledger" - - EventTypeCommittedTransactions = "COMMITTED_TRANSACTIONS" - EventTypeSavedMetadata = "SAVED_METADATA" - EventTypeRevertedTransaction = "REVERTED_TRANSACTION" -) - -type EventMessage struct { - Date core.Time `json:"date"` - App string `json:"app"` - Version string `json:"version"` - Type string `json:"type"` - Payload any `json:"payload"` -} - -type CommittedTransactions struct { - Ledger string `json:"ledger"` - Transactions []core.Transaction `json:"transactions"` -} - -func newEventCommittedTransactions(txs CommittedTransactions) EventMessage { - return EventMessage{ - Date: core.Now(), - App: EventApp, - Version: EventVersion, - Type: EventTypeCommittedTransactions, - Payload: txs, - } -} - -type SavedMetadata struct { - Ledger string `json:"ledger"` - TargetType string `json:"targetType"` - TargetID string `json:"targetId"` - Metadata metadata.Metadata `json:"metadata"` -} - -func newEventSavedMetadata(metadata SavedMetadata) EventMessage { - return EventMessage{ - Date: core.Now(), - App: EventApp, - Version: EventVersion, - Type: EventTypeSavedMetadata, - Payload: metadata, - } -} - -type RevertedTransaction struct { - Ledger string `json:"ledger"` - RevertedTransaction core.Transaction `json:"revertedTransaction"` - RevertTransaction core.Transaction `json:"revertTransaction"` -} - -func newEventRevertedTransaction(tx RevertedTransaction) EventMessage { - return EventMessage{ - Date: core.Now(), - App: EventApp, - Version: EventVersion, - Type: EventTypeRevertedTransaction, - Payload: tx, - } -} diff --git a/components/ledger/pkg/bus/monitor.go b/components/ledger/pkg/bus/monitor.go deleted file mode 100644 index b04c1b2bd..000000000 --- a/components/ledger/pkg/bus/monitor.go +++ /dev/null @@ -1,61 +0,0 @@ -package bus - -import ( - "context" - - "github.com/ThreeDotsLabs/watermill/message" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/query" - "github.com/formancehq/stack/libs/go-libs/logging" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/formancehq/stack/libs/go-libs/publish" -) - -type ledgerMonitor struct { - publisher message.Publisher - ledgerName string -} - -var _ query.Monitor = &ledgerMonitor{} - -func NewLedgerMonitor(publisher message.Publisher, ledgerName string) *ledgerMonitor { - m := &ledgerMonitor{ - publisher: publisher, - ledgerName: ledgerName, - } - return m -} - -func (l *ledgerMonitor) CommittedTransactions(ctx context.Context, txs ...core.Transaction) { - l.publish(ctx, EventTypeCommittedTransactions, - newEventCommittedTransactions(CommittedTransactions{ - Ledger: l.ledgerName, - Transactions: txs, - })) -} - -func (l *ledgerMonitor) SavedMetadata(ctx context.Context, targetType, targetID string, metadata metadata.Metadata) { - l.publish(ctx, EventTypeSavedMetadata, - newEventSavedMetadata(SavedMetadata{ - Ledger: l.ledgerName, - TargetType: targetType, - TargetID: targetID, - Metadata: metadata, - })) -} - -func (l *ledgerMonitor) RevertedTransaction(ctx context.Context, reverted, revert *core.Transaction) { - l.publish(ctx, EventTypeRevertedTransaction, - newEventRevertedTransaction(RevertedTransaction{ - Ledger: l.ledgerName, - RevertedTransaction: *reverted, - RevertTransaction: *revert, - })) -} - -func (l *ledgerMonitor) publish(ctx context.Context, topic string, ev EventMessage) { - if err := l.publisher.Publish(topic, publish.NewMessage(ctx, ev)); err != nil { - logging.FromContext(ctx).Errorf("publishing message: %s", err) - return - } -} diff --git a/components/ledger/pkg/core/account.go b/components/ledger/pkg/core/account.go deleted file mode 100644 index c5abb30f6..000000000 --- a/components/ledger/pkg/core/account.go +++ /dev/null @@ -1,65 +0,0 @@ -package core - -import ( - "encoding/json" - "regexp" - - "github.com/formancehq/stack/libs/go-libs/metadata" -) - -const ( - WORLD = "world" -) - -type Account struct { - Address string `json:"address"` - Metadata metadata.Metadata `json:"metadata"` -} - -func (a Account) copy() Account { - a.Metadata = a.Metadata.Copy() - return a -} - -func NewAccount(address string) Account { - return Account{ - Address: address, - Metadata: metadata.Metadata{}, - } -} - -type AccountWithVolumes struct { - Account - Volumes VolumesByAssets `json:"volumes"` -} - -func NewAccountWithVolumes(address string) *AccountWithVolumes { - return &AccountWithVolumes{ - Account: Account{ - Address: address, - Metadata: metadata.Metadata{}, - }, - Volumes: map[string]*Volumes{}, - } -} - -func (v AccountWithVolumes) MarshalJSON() ([]byte, error) { - type aux AccountWithVolumes - return json.Marshal(struct { - aux - Balances BalancesByAssets `json:"balances"` - }{ - aux: aux(v), - Balances: v.Volumes.Balances(), - }) -} - -func (v AccountWithVolumes) Copy() AccountWithVolumes { - v.Account = v.Account.copy() - v.Volumes = v.Volumes.copy() - return v -} - -const AccountPattern = "^[a-zA-Z_]+[a-zA-Z0-9_:]*$" - -var AccountRegexp = regexp.MustCompile(AccountPattern) diff --git a/components/ledger/pkg/core/asset.go b/components/ledger/pkg/core/asset.go deleted file mode 100644 index 4a334039e..000000000 --- a/components/ledger/pkg/core/asset.go +++ /dev/null @@ -1,13 +0,0 @@ -package core - -import ( - "regexp" -) - -const AssetPattern = `^[A-Z][A-Z0-9]{0,16}(\/\d{1,6})?$` - -var AssetRegexp = regexp.MustCompile(AssetPattern) - -func AssetIsValid(v string) bool { - return AssetRegexp.Match([]byte(v)) -} diff --git a/components/ledger/pkg/core/bigint.go b/components/ledger/pkg/core/bigint.go deleted file mode 100644 index 02b549d11..000000000 --- a/components/ledger/pkg/core/bigint.go +++ /dev/null @@ -1,7 +0,0 @@ -package core - -import ( - "math/big" -) - -var Zero = big.NewInt(0) diff --git a/components/ledger/pkg/core/log.go b/components/ledger/pkg/core/log.go deleted file mode 100644 index 9c830f696..000000000 --- a/components/ledger/pkg/core/log.go +++ /dev/null @@ -1,391 +0,0 @@ -package core - -import ( - "bytes" - "crypto/sha256" - "encoding/json" - "reflect" - "sort" - "strconv" - "strings" - "sync" - - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/pkg/errors" -) - -type LogType int16 - -const ( - // TODO(gfyrag): Create dedicated log type for account and metadata - SetMetadataLogType LogType = iota // "SET_METADATA" - NewTransactionLogType // "NEW_TRANSACTION" - RevertedTransactionLogType // "REVERTED_TRANSACTION" -) - -func (l LogType) String() string { - switch l { - case SetMetadataLogType: - return "SET_METADATA" - case NewTransactionLogType: - return "NEW_TRANSACTION" - case RevertedTransactionLogType: - return "REVERTED_TRANSACTION" - } - - return "" -} - -func LogTypeFromString(logType string) (LogType, error) { - switch logType { - case "SET_METADATA": - return SetMetadataLogType, nil - case "NEW_TRANSACTION": - return NewTransactionLogType, nil - case "REVERTED_TRANSACTION": - return RevertedTransactionLogType, nil - } - - return 0, errors.New("invalid log type") -} - -// Needed in order to keep the compatibility with the openapi response for -// ListLogs. -func (lt LogType) MarshalJSON() ([]byte, error) { - return json.Marshal(lt.String()) -} - -func (lt *LogType) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - - switch s { - case "SET_METADATA": - *lt = SetMetadataLogType - case "NEW_TRANSACTION": - *lt = NewTransactionLogType - case "REVERTED_TRANSACTION": - *lt = RevertedTransactionLogType - default: - return errors.New("invalid log type") - } - - return nil -} - -type hashable interface { - hashString(buf *buffer) -} - -type ChainedLog struct { - Log - ID uint64 `json:"id"` - Projected bool `json:"-"` - Hash []byte `json:"hash"` -} - -func (l *ChainedLog) WithID(id uint64) *ChainedLog { - l.ID = id - return l -} - -func (l *ChainedLog) UnmarshalJSON(data []byte) error { - type auxLog ChainedLog - type log struct { - auxLog - Data json.RawMessage `json:"data"` - } - rawLog := log{} - if err := json.Unmarshal(data, &rawLog); err != nil { - return err - } - - var err error - rawLog.auxLog.Data, err = HydrateLog(rawLog.Type, rawLog.Data) - if err != nil { - return err - } - *l = ChainedLog(rawLog.auxLog) - return err -} - -func (l *ChainedLog) ComputeHash(previous *ChainedLog) { - - buf := bufferPool.Get().(*buffer) - defer func() { - buf.reset() - bufferPool.Put(buf) - }() - hashLog := func(l *ChainedLog) { - buf.writeUInt64(l.ID) - buf.writeUInt16(uint16(l.Type)) - buf.writeUInt64(uint64(l.Date.UnixNano())) - buf.writeString(l.IdempotencyKey) - l.Data.hashString(buf) - } - - if previous != nil { - hashLog(previous) - } - hashLog(l) - - h := sha256.New() - _, err := h.Write(buf.bytes()) - if err != nil { - panic(err) - } - - l.Hash = h.Sum(nil) -} - -type Log struct { - Type LogType `json:"type"` - Data hashable `json:"data"` - Date Time `json:"date"` - IdempotencyKey string `json:"idempotencyKey"` -} - -func (l *Log) WithDate(date Time) *Log { - l.Date = date - return l -} - -func (l *Log) WithIdempotencyKey(key string) *Log { - l.IdempotencyKey = key - return l -} - -func (l *Log) ChainLog(previous *ChainedLog) *ChainedLog { - ret := &ChainedLog{} - ret.Log = *l - ret.ComputeHash(previous) - if previous != nil { - ret.ID = previous.ID + 1 - } - return ret -} - -type AccountMetadata map[string]metadata.Metadata - -func (m AccountMetadata) hashString(buf *buffer) { - if len(m) == 0 { - return - } - accounts := collectionutils.Keys(m) - if len(accounts) > 1 { - sort.Strings(accounts) - } - - for _, account := range accounts { - buf.writeString(account) - hashStringMetadata(buf, m[account]) - } -} - -type NewTransactionLogPayload struct { - Transaction *Transaction `json:"transaction"` - AccountMetadata AccountMetadata `json:"accountMetadata"` -} - -func (n NewTransactionLogPayload) hashString(buf *buffer) { - n.AccountMetadata.hashString(buf) - n.Transaction.hashString(buf) -} - -func NewTransactionLogWithDate(tx *Transaction, accountMetadata map[string]metadata.Metadata, time Time) *Log { - // Since the id is unique and the hash is a hash of the previous log, they - // will be filled at insertion time during the batch process. - return &Log{ - Type: NewTransactionLogType, - Date: time, - Data: NewTransactionLogPayload{ - Transaction: tx, - AccountMetadata: accountMetadata, - }, - } -} - -func NewTransactionLog(tx *Transaction, accountMetadata map[string]metadata.Metadata) *Log { - return NewTransactionLogWithDate(tx, accountMetadata, tx.Timestamp) -} - -type SetMetadataLogPayload struct { - TargetType string `json:"targetType"` - TargetID any `json:"targetId"` - Metadata metadata.Metadata `json:"metadata"` -} - -func (s SetMetadataLogPayload) hashString(buf *buffer) { - buf.writeString(s.TargetType) - switch targetID := s.TargetID.(type) { - case string: - buf.writeString(targetID) - case uint64: - buf.writeUInt64(targetID) - } - hashStringMetadata(buf, s.Metadata) -} - -func (s *SetMetadataLogPayload) UnmarshalJSON(data []byte) error { - type X struct { - TargetType string `json:"targetType"` - TargetID json.RawMessage `json:"targetId"` - Metadata metadata.Metadata `json:"metadata"` - } - x := X{} - err := json.Unmarshal(data, &x) - if err != nil { - return err - } - var id interface{} - switch strings.ToUpper(x.TargetType) { - case strings.ToUpper(MetaTargetTypeAccount): - id = "" - err = json.Unmarshal(x.TargetID, &id) - case strings.ToUpper(MetaTargetTypeTransaction): - id, err = strconv.ParseUint(string(x.TargetID), 10, 64) - default: - panic("unknown type") - } - if err != nil { - return err - } - - *s = SetMetadataLogPayload{ - TargetType: x.TargetType, - TargetID: id, - Metadata: x.Metadata, - } - return nil -} - -func NewSetMetadataLog(at Time, metadata SetMetadataLogPayload) *Log { - // Since the id is unique and the hash is a hash of the previous log, they - // will be filled at insertion time during the batch process. - return &Log{ - Type: SetMetadataLogType, - Date: at, - Data: metadata, - } -} - -type RevertedTransactionLogPayload struct { - RevertedTransactionID uint64 `json:"revertedTransactionID"` - RevertTransaction *Transaction `json:"transaction"` -} - -func (r RevertedTransactionLogPayload) hashString(buf *buffer) { - buf.writeUInt64(r.RevertedTransactionID) - r.RevertTransaction.hashString(buf) -} - -func NewRevertedTransactionLog(at Time, revertedTxID uint64, tx *Transaction) *Log { - return &Log{ - Type: RevertedTransactionLogType, - Date: at, - Data: RevertedTransactionLogPayload{ - RevertedTransactionID: revertedTxID, - RevertTransaction: tx, - }, - } -} - -func HydrateLog(_type LogType, data []byte) (hashable, error) { - var payload any - switch _type { - case NewTransactionLogType: - payload = &NewTransactionLogPayload{} - case SetMetadataLogType: - payload = &SetMetadataLogPayload{} - case RevertedTransactionLogType: - payload = &RevertedTransactionLogPayload{} - default: - panic("unknown type " + _type.String()) - } - err := json.Unmarshal(data, &payload) - if err != nil { - return nil, err - } - - return reflect.ValueOf(payload).Elem().Interface().(hashable), nil -} - -type Accounts map[string]Account - -type ActiveLog struct { - *ChainedLog - Projected chan struct{} `json:"-"` -} - -func (h *ActiveLog) SetProjected() { - h.ChainedLog.Projected = true - close(h.Projected) -} - -func NewActiveLog(log *ChainedLog) *ActiveLog { - return &ActiveLog{ - ChainedLog: log, - Projected: make(chan struct{}), - } -} - -type buffer struct { - buf *bytes.Buffer -} - -func (b *buffer) must(err error) { - if err != nil { - panic(err) - } -} - -func (b *buffer) mustWithValue(v any, err error) { - if err != nil { - panic(err) - } -} - -func (b *buffer) writeUInt64(v uint64) { - b.must(b.buf.WriteByte(byte((v >> 56) & 0xFF))) - b.must(b.buf.WriteByte(byte((v >> 48) & 0xFF))) - b.must(b.buf.WriteByte(byte((v >> 40) & 0xFF))) - b.must(b.buf.WriteByte(byte((v >> 32) & 0xFF))) - b.must(b.buf.WriteByte(byte(v >> 24))) - b.must(b.buf.WriteByte(byte((v >> 16) & 0xFF))) - b.must(b.buf.WriteByte(byte((v >> 8) & 0xFF))) - b.must(b.buf.WriteByte(byte(v & 0xFF))) -} - -func (b *buffer) writeUInt16(v uint16) { - b.must(b.buf.WriteByte(byte((v >> 8) & 0xFF))) - b.must(b.buf.WriteByte(byte(v & 0xFF))) -} - -func (b *buffer) writeString(v string) { - b.mustWithValue(b.buf.WriteString(v)) -} - -func (b *buffer) reset() { - b.buf.Reset() -} - -func (b *buffer) bytes() []byte { - return b.buf.Bytes() -} - -func (b *buffer) write(bytes []byte) { - b.mustWithValue(b.buf.Write(bytes)) -} - -var ( - bufferPool = sync.Pool{ - New: func() any { - return &buffer{ - buf: bytes.NewBuffer(make([]byte, 4096)), - } - }, - } -) diff --git a/components/ledger/pkg/core/metadata.go b/components/ledger/pkg/core/metadata.go deleted file mode 100644 index b8e765a4d..000000000 --- a/components/ledger/pkg/core/metadata.go +++ /dev/null @@ -1,68 +0,0 @@ -package core - -import ( - "fmt" - "sort" - - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "github.com/formancehq/stack/libs/go-libs/metadata" -) - -const ( - formanceNamespace = "com.formance.spec/" - revertKey = "state/reverts" - revertedKey = "state/reverted" - MetaTargetTypeAccount = "ACCOUNT" - MetaTargetTypeTransaction = "TRANSACTION" -) - -func SpecMetadata(name string) string { - return formanceNamespace + name -} - -func MarkReverts(m metadata.Metadata, txID uint64) metadata.Metadata { - return m.Merge(RevertMetadata(txID)) -} - -func RevertedMetadataSpecKey() string { - return SpecMetadata(revertedKey) -} - -func RevertMetadataSpecKey() string { - return SpecMetadata(revertKey) -} - -func ComputeMetadata(key, value string) metadata.Metadata { - return metadata.Metadata{ - key: value, - } -} - -func RevertedMetadata(by uint64) metadata.Metadata { - return ComputeMetadata(RevertedMetadataSpecKey(), fmt.Sprint(by)) -} - -func RevertMetadata(tx uint64) metadata.Metadata { - return ComputeMetadata(RevertMetadataSpecKey(), fmt.Sprint(tx)) -} - -func IsReverted(m metadata.Metadata) bool { - if _, ok := m[RevertedMetadataSpecKey()]; ok { - return true - } - return false -} - -func hashStringMetadata(buf *buffer, m metadata.Metadata) { - if len(m) == 0 { - return - } - keysOfAccount := collectionutils.Keys(m) - if len(m) > 1 { - sort.Strings(keysOfAccount) - } - for _, key := range keysOfAccount { - buf.writeString(key) - buf.writeString(m[key]) - } -} diff --git a/components/ledger/pkg/core/migrations.go b/components/ledger/pkg/core/migrations.go deleted file mode 100644 index 6bb30146f..000000000 --- a/components/ledger/pkg/core/migrations.go +++ /dev/null @@ -1,8 +0,0 @@ -package core - -type MigrationInfo struct { - Version string `json:"version"` - Name string `json:"name"` - State string `json:"state,omitempty"` - Date Time `json:"date,omitempty"` -} diff --git a/components/ledger/pkg/core/move.go b/components/ledger/pkg/core/move.go deleted file mode 100644 index a30fc8eb8..000000000 --- a/components/ledger/pkg/core/move.go +++ /dev/null @@ -1,15 +0,0 @@ -package core - -import ( - "math/big" -) - -type Move struct { - TransactionID uint64 - Amount *big.Int - Asset string - Account string - PostingIndex uint8 - IsSource bool - Timestamp Time -} diff --git a/components/ledger/pkg/core/transaction.go b/components/ledger/pkg/core/transaction.go deleted file mode 100644 index d6f8d1713..000000000 --- a/components/ledger/pkg/core/transaction.go +++ /dev/null @@ -1,148 +0,0 @@ -package core - -import ( - "github.com/formancehq/stack/libs/go-libs/metadata" -) - -type Transactions struct { - Transactions []TransactionData `json:"transactions"` -} - -type TransactionData struct { - Postings Postings `json:"postings"` - Metadata metadata.Metadata `json:"metadata"` - Timestamp Time `json:"timestamp"` - Reference string `json:"reference"` -} - -func (d TransactionData) WithPostings(postings ...Posting) TransactionData { - d.Postings = append(d.Postings, postings...) - return d -} - -func NewTransactionData() TransactionData { - return TransactionData{ - Metadata: metadata.Metadata{}, - } -} - -func (t *TransactionData) Reverse() TransactionData { - postings := make(Postings, len(t.Postings)) - copy(postings, t.Postings) - postings.Reverse() - - return TransactionData{ - Postings: postings, - } -} - -func (d TransactionData) hashString(buf *buffer) { - buf.writeString(d.Reference) - buf.writeUInt64(uint64(d.Timestamp.UnixNano())) - hashStringMetadata(buf, d.Metadata) - for _, posting := range d.Postings { - posting.hashString(buf) - } -} - -type Transaction struct { - TransactionData - ID uint64 `json:"txid"` -} - -type TransactionWithMetadata struct { - ID uint64 - Metadata metadata.Metadata -} - -func (t *Transaction) WithPostings(postings ...Posting) *Transaction { - t.TransactionData = t.TransactionData.WithPostings(postings...) - return t -} - -func (t *Transaction) WithReference(ref string) *Transaction { - t.Reference = ref - return t -} - -func (t *Transaction) WithTimestamp(ts Time) *Transaction { - t.Timestamp = ts - return t -} - -func (t *Transaction) WithID(id uint64) *Transaction { - t.ID = id - return t -} - -func (t *Transaction) WithMetadata(m metadata.Metadata) *Transaction { - t.Metadata = m - return t -} - -func (t Transaction) GetMoves() []*Move { - ret := make([]*Move, 0) - for ind, posting := range t.Postings { - ret = append(ret, &Move{ - TransactionID: t.ID, - Amount: posting.Amount, - Asset: posting.Asset, - Account: posting.Source, - PostingIndex: uint8(ind), - IsSource: true, - Timestamp: t.Timestamp, - }, &Move{ - TransactionID: t.ID, - Amount: posting.Amount, - Asset: posting.Asset, - Account: posting.Destination, - PostingIndex: uint8(ind), - Timestamp: t.Timestamp, - }) - } - return ret -} - -func (t *Transaction) hashString(buf *buffer) { - buf.writeUInt64(t.ID) - t.TransactionData.hashString(buf) -} - -func NewTransaction() *Transaction { - return &Transaction{ - TransactionData: NewTransactionData(), - } -} - -type ExpandedTransaction struct { - Transaction - PreCommitVolumes AccountsAssetsVolumes `json:"preCommitVolumes,omitempty"` - PostCommitVolumes AccountsAssetsVolumes `json:"postCommitVolumes,omitempty"` -} - -func (t *ExpandedTransaction) AppendPosting(p Posting) { - t.Postings = append(t.Postings, p) -} - -func (t *ExpandedTransaction) IsReverted() bool { - return IsReverted(t.Metadata) -} - -func ExpandTransaction(tx *Transaction, preCommitVolumes AccountsAssetsVolumes) ExpandedTransaction { - postCommitVolumes := preCommitVolumes.copy() - for _, posting := range tx.Postings { - preCommitVolumes.AddInput(posting.Destination, posting.Asset, Zero) - preCommitVolumes.AddOutput(posting.Source, posting.Asset, Zero) - postCommitVolumes.AddOutput(posting.Source, posting.Asset, posting.Amount) - postCommitVolumes.AddInput(posting.Destination, posting.Asset, posting.Amount) - } - return ExpandedTransaction{ - Transaction: *tx, - PreCommitVolumes: preCommitVolumes, - PostCommitVolumes: postCommitVolumes, - } -} - -func ExpandTransactionFromEmptyPreCommitVolumes(tx *Transaction) ExpandedTransaction { - return ExpandTransaction(tx, AccountsAssetsVolumes{}) -} diff --git a/components/ledger/pkg/core/volumes.go b/components/ledger/pkg/core/volumes.go deleted file mode 100644 index 277294a7c..000000000 --- a/components/ledger/pkg/core/volumes.go +++ /dev/null @@ -1,259 +0,0 @@ -package core - -import ( - "database/sql/driver" - "encoding/json" - "math/big" -) - -type Volumes struct { - Input *big.Int `json:"input"` - Output *big.Int `json:"output"` -} - -func (v Volumes) CopyWithZerosIfNeeded() *Volumes { - var input *big.Int - if v.Input == nil { - input = &big.Int{} - } else { - input = new(big.Int).Set(v.Input) - } - var output *big.Int - if v.Output == nil { - output = &big.Int{} - } else { - output = new(big.Int).Set(v.Output) - } - return &Volumes{ - Input: input, - Output: output, - } -} - -func (v Volumes) WithInput(input *big.Int) *Volumes { - v.Input = input - return &v -} - -func (v Volumes) WithInputInt64(value int64) *Volumes { - v.Input = big.NewInt(value) - return &v -} - -func (v Volumes) WithOutput(output *big.Int) *Volumes { - v.Output = output - return &v -} - -func (v Volumes) WithOutputInt64(value int64) *Volumes { - v.Output = big.NewInt(value) - return &v -} - -func NewEmptyVolumes() *Volumes { - return &Volumes{ - Input: new(big.Int), - Output: new(big.Int), - } -} - -func NewVolumesInt64(input, output int64) *Volumes { - return &Volumes{ - Input: big.NewInt(input), - Output: big.NewInt(output), - } -} - -type VolumesWithBalance struct { - Input *big.Int `json:"input"` - Output *big.Int `json:"output"` - Balance *big.Int `json:"balance"` -} - -func (v Volumes) MarshalJSON() ([]byte, error) { - return json.Marshal(VolumesWithBalance{ - Input: v.Input, - Output: v.Output, - Balance: v.Balance(), - }) -} - -func (v Volumes) Balance() *big.Int { - input := v.Input - if input == nil { - input = Zero - } - output := v.Output - if output == nil { - output = Zero - } - return new(big.Int).Sub(input, output) -} - -func (v Volumes) copy() *Volumes { - return &Volumes{ - Input: new(big.Int).Set(v.Input), - Output: new(big.Int).Set(v.Output), - } -} - -type BalancesByAssets map[string]*big.Int - -type VolumesByAssets map[string]*Volumes - -type BalancesByAssetsByAccounts map[string]BalancesByAssets - -func (v VolumesByAssets) Balances() BalancesByAssets { - balances := BalancesByAssets{} - for asset, vv := range v { - balances[asset] = new(big.Int).Sub(vv.Input, vv.Output) - } - return balances -} - -func (v VolumesByAssets) copy() VolumesByAssets { - ret := VolumesByAssets{} - for key, volumes := range v { - ret[key] = volumes.copy() - } - return ret -} - -type AccountsAssetsVolumes map[string]VolumesByAssets - -func (a AccountsAssetsVolumes) GetVolumes(account, asset string) *Volumes { - if a == nil { - return &Volumes{ - Input: &big.Int{}, - Output: &big.Int{}, - } - } - if assetsVolumes, ok := a[account]; !ok { - return &Volumes{ - Input: &big.Int{}, - Output: &big.Int{}, - } - } else { - return &Volumes{ - Input: assetsVolumes[asset].Input, - Output: assetsVolumes[asset].Output, - } - } -} - -func (a *AccountsAssetsVolumes) SetVolumes(account, asset string, volumes *Volumes) { - if *a == nil { - *a = AccountsAssetsVolumes{} - } - if assetsVolumes, ok := (*a)[account]; !ok { - (*a)[account] = map[string]*Volumes{ - asset: volumes.CopyWithZerosIfNeeded(), - } - } else { - assetsVolumes[asset] = volumes.CopyWithZerosIfNeeded() - } -} - -func (a *AccountsAssetsVolumes) AddInput(account, asset string, input *big.Int) { - if *a == nil { - *a = AccountsAssetsVolumes{} - } - if assetsVolumes, ok := (*a)[account]; !ok { - (*a)[account] = map[string]*Volumes{ - asset: { - Input: input, - Output: &big.Int{}, - }, - } - } else { - volumes := assetsVolumes[asset].CopyWithZerosIfNeeded() - volumes.Input.Add(volumes.Input, input) - assetsVolumes[asset] = volumes - } -} - -func (a *AccountsAssetsVolumes) AddOutput(account, asset string, output *big.Int) { - if *a == nil { - *a = AccountsAssetsVolumes{} - } - if assetsVolumes, ok := (*a)[account]; !ok { - (*a)[account] = map[string]*Volumes{ - asset: { - Output: output, - Input: &big.Int{}, - }, - } - } else { - volumes := assetsVolumes[asset].CopyWithZerosIfNeeded() - volumes.Output.Add(volumes.Output, output) - assetsVolumes[asset] = volumes - } -} - -func (a AccountsAssetsVolumes) HasAccount(account string) bool { - if a == nil { - return false - } - _, ok := a[account] - return ok -} - -func (a AccountsAssetsVolumes) HasAccountAndAsset(account, asset string) bool { - if a == nil { - return false - } - volumesByAsset, ok := a[account] - if !ok { - return false - } - _, ok = volumesByAsset[asset] - return ok -} - -// Scan - Implement the database/sql scanner interface -func (a *AccountsAssetsVolumes) Scan(value interface{}) error { - if value == nil { - return nil - } - - val, err := driver.String.ConvertValue(value) - if err != nil { - return err - } - - *a = AccountsAssetsVolumes{} - switch val := val.(type) { - case []uint8: - return json.Unmarshal(val, a) - case string: - return json.Unmarshal([]byte(val), a) - default: - panic("not handled type") - } -} - -func (a AccountsAssetsVolumes) copy() AccountsAssetsVolumes { - ret := AccountsAssetsVolumes{} - for key, volumes := range a { - ret[key] = volumes.copy() - } - return ret -} - -func AggregatePreCommitVolumes(txs ...ExpandedTransaction) AccountsAssetsVolumes { - ret := AccountsAssetsVolumes{} - for i := 0; i < len(txs); i++ { - tx := txs[i] - for _, posting := range tx.Postings { - if !ret.HasAccountAndAsset(posting.Source, posting.Asset) { - ret.SetVolumes(posting.Source, posting.Asset, - tx.PreCommitVolumes.GetVolumes(posting.Source, posting.Asset)) - } - if !ret.HasAccountAndAsset(posting.Destination, posting.Asset) { - ret.SetVolumes(posting.Destination, posting.Asset, - tx.PreCommitVolumes.GetVolumes(posting.Destination, posting.Asset)) - } - } - } - return ret -} diff --git a/components/ledger/pkg/events/events.go b/components/ledger/pkg/events/events.go new file mode 100644 index 000000000..f6d6f55c6 --- /dev/null +++ b/components/ledger/pkg/events/events.go @@ -0,0 +1,11 @@ +package events + +const ( + EventVersion = "v2" + EventApp = "ledger" + + EventTypeCommittedTransactions = "COMMITTED_TRANSACTIONS" + EventTypeSavedMetadata = "SAVED_METADATA" + EventTypeRevertedTransaction = "REVERTED_TRANSACTION" + EventTypeDeletedMetadata = "DELETED_METADATA" +) diff --git a/components/ledger/pkg/ledger/command/commander.go b/components/ledger/pkg/ledger/command/commander.go deleted file mode 100644 index 5433b5c62..000000000 --- a/components/ledger/pkg/ledger/command/commander.go +++ /dev/null @@ -1,288 +0,0 @@ -package command - -import ( - "context" - "fmt" - "sync" - "sync/atomic" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/utils/batching" - "github.com/formancehq/ledger/pkg/machine" - "github.com/formancehq/ledger/pkg/machine/vm" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "github.com/formancehq/stack/libs/go-libs/errorsutil" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/pkg/errors" -) - -type Parameters struct { - DryRun bool - Async bool - IdempotencyKey string -} - -type Commander struct { - *batching.Batcher[*core.ActiveLog] - store Store - locker Locker - metricsRegistry metrics.PerLedgerRegistry - compiler *Compiler - running sync.WaitGroup - lastTXID *atomic.Int64 - referencer *Referencer - mu sync.Mutex - - lastLog *core.ChainedLog -} - -func New( - store Store, - locker Locker, - compiler *Compiler, - referencer *Referencer, - metricsRegistry metrics.PerLedgerRegistry, - onBatchProcessed batching.OnBatchProcessed[*core.ActiveLog], -) *Commander { - log, err := store.ReadLastLogWithType(context.Background(), core.NewTransactionLogType, core.RevertedTransactionLogType) - if err != nil && !storageerrors.IsNotFoundError(err) { - panic(err) - } - - var lastTxID *uint64 - if err == nil { - switch payload := log.Data.(type) { - case core.NewTransactionLogPayload: - lastTxID = &payload.Transaction.ID - case core.RevertedTransactionLogPayload: - lastTxID = &payload.RevertTransaction.ID - default: - panic(fmt.Sprintf("unhandled payload type: %T", payload)) - } - } - lastTXID := &atomic.Int64{} - if lastTxID != nil { - lastTXID.Add(int64(*lastTxID)) - } else { - lastTXID.Add(-1) - } - - lastLog, err := store.GetLastLog(context.Background()) - if err != nil && !storageerrors.IsNotFoundError(err) { - panic(err) - } - - return &Commander{ - store: store, - locker: locker, - metricsRegistry: metricsRegistry, - compiler: compiler, - referencer: referencer, - lastTXID: lastTXID, - lastLog: lastLog, - Batcher: batching.NewBatcher(store.InsertLogs, onBatchProcessed, 1, 4096), - } -} - -func (commander *Commander) GetLedgerStore() Store { - return commander.store -} - -func (commander *Commander) exec(ctx context.Context, parameters Parameters, script core.RunScript, - logComputer func(tx *core.Transaction, accountMetadata map[string]metadata.Metadata) *core.Log) (*core.ChainedLog, error) { - - if script.Script.Plain == "" { - return nil, ErrNoScript - } - - if script.Timestamp.IsZero() { - script.Timestamp = core.Now() - } - - execContext := newExecutionContext(commander, parameters) - return execContext.run(ctx, func(executionContext *executionContext) (*core.ActiveLog, chan struct{}, error) { - if script.Reference != "" { - if err := commander.referencer.take(referenceTxReference, script.Reference); err != nil { - return nil, nil, ErrConflictError - } - defer commander.referencer.release(referenceTxReference, script.Reference) - - _, err := commander.store.ReadLogForCreatedTransactionWithReference(ctx, script.Reference) - if err == nil { - return nil, nil, ErrConflictError - } - if err != storageerrors.ErrNotFound && err != nil { - return nil, nil, err - } - } - - program, err := commander.compiler.Compile(ctx, script.Plain) - if err != nil { - return nil, nil, errorsutil.NewError(ErrCompilationFailed, errors.Wrap(err, "compiling numscript")) - } - - m := vm.NewMachine(*program) - - if err := m.SetVarsFromJSON(script.Vars); err != nil { - return nil, nil, errorsutil.NewError(ErrCompilationFailed, - errors.Wrap(err, "could not set variables")) - } - - involvedAccounts, involvedSources, err := m.ResolveResources(ctx, commander.store) - if err != nil { - return nil, nil, errorsutil.NewError(ErrCompilationFailed, - errors.Wrap(err, "could not resolve program resources")) - } - - worldFilter := collectionutils.FilterNot(collectionutils.FilterEq("world")) - lockAccounts := Accounts{ - Read: collectionutils.Filter(involvedAccounts, worldFilter), - Write: collectionutils.Filter(involvedSources, worldFilter), - } - - unlock, err := commander.locker.Lock(ctx, lockAccounts) - if err != nil { - return nil, nil, errors.Wrap(err, "locking accounts for tx processing") - } - unlock(ctx) - - err = m.ResolveBalances(ctx, commander.store) - if err != nil { - return nil, nil, errorsutil.NewError(ErrCompilationFailed, - errors.Wrap(err, "could not resolve balances")) - } - - result, err := machine.Run(m, script) - if err != nil { - return nil, nil, errors.Wrap(err, "running numscript") - } - - if len(result.Postings) == 0 { - return nil, nil, ErrNoPostings - } - - tx := core.NewTransaction(). - WithPostings(result.Postings...). - WithMetadata(result.Metadata). - WithTimestamp(script.Timestamp). - WithID(uint64(commander.lastTXID.Add(1))). - WithReference(script.Reference) - - log := logComputer(tx, result.AccountMetadata) - if parameters.IdempotencyKey != "" { - log = log.WithIdempotencyKey(parameters.IdempotencyKey) - } - - return executionContext.AppendLog(ctx, log) - }) -} - -func (commander *Commander) CreateTransaction(ctx context.Context, parameters Parameters, script core.RunScript) (*core.Transaction, error) { - log, err := commander.exec(ctx, parameters, script, core.NewTransactionLog) - if err != nil { - return nil, err - } - return log.Data.(core.NewTransactionLogPayload).Transaction, nil -} - -func (commander *Commander) SaveMeta(ctx context.Context, parameters Parameters, targetType string, targetID interface{}, m metadata.Metadata) error { - if m == nil { - return nil - } - - if targetType == "" { - return errorsutil.NewError(ErrValidation, errors.New("empty target type")) - } - if targetID == "" { - return errorsutil.NewError(ErrValidation, errors.New("empty target id")) - } - - execContext := newExecutionContext(commander, parameters) - _, err := execContext.run(ctx, func(executionContext *executionContext) (*core.ActiveLog, chan struct{}, error) { - var ( - log *core.Log - at = core.Now() - ) - switch targetType { - case core.MetaTargetTypeTransaction: - _, err := commander.store.ReadLogForCreatedTransaction(ctx, targetID.(uint64)) - if err != nil { - return nil, nil, err - } - log = core.NewSetMetadataLog(at, core.SetMetadataLogPayload{ - TargetType: core.MetaTargetTypeTransaction, - TargetID: targetID.(uint64), - Metadata: m, - }) - case core.MetaTargetTypeAccount: - log = core.NewSetMetadataLog(at, core.SetMetadataLogPayload{ - TargetType: core.MetaTargetTypeAccount, - TargetID: targetID.(string), - Metadata: m, - }) - default: - return nil, nil, errorsutil.NewError(ErrValidation, errors.Errorf("unknown target type '%s'", targetType)) - } - - return executionContext.AppendLog(ctx, log) - }) - return err -} - -func (commander *Commander) RevertTransaction(ctx context.Context, parameters Parameters, id uint64) (*core.Transaction, error) { - - if err := commander.referencer.take(referenceReverts, id); err != nil { - return nil, ErrRevertOccurring - } - defer commander.referencer.release(referenceReverts, id) - - _, err := commander.store.ReadLogForRevertedTransaction(ctx, id) - if err == nil { - return nil, ErrAlreadyReverted - } - if err != nil && !errors.Is(err, storageerrors.ErrNotFound) { - return nil, err - } - - transactionToRevertLog, err := commander.store.ReadLogForCreatedTransaction(ctx, id) - if storageerrors.IsNotFoundError(err) { - return nil, errorsutil.NewError(err, errors.Errorf("transaction %d not found", id)) - } - if err != nil { - return nil, err - } - - transactionToRevert := transactionToRevertLog.Data.(core.NewTransactionLogPayload).Transaction - - rt := transactionToRevert.Reverse() - rt.Metadata = core.MarkReverts(metadata.Metadata{}, transactionToRevert.ID) - - log, err := commander.exec(ctx, parameters, - core.TxToScriptData(core.TransactionData{ - Postings: rt.Postings, - Metadata: rt.Metadata, - }), - func(tx *core.Transaction, accountMetadata map[string]metadata.Metadata) *core.Log { - return core.NewRevertedTransactionLog(tx.Timestamp, transactionToRevert.ID, tx) - }) - if err != nil { - return nil, err - } - - return log.Data.(core.RevertedTransactionLogPayload).RevertTransaction, nil -} - -func (commander *Commander) Close() { - commander.Batcher.Close() - commander.running.Wait() -} - -func (commander *Commander) chainLog(log *core.Log) *core.ChainedLog { - commander.mu.Lock() - defer commander.mu.Unlock() - - commander.lastLog = log.ChainLog(commander.lastLog) - return commander.lastLog -} diff --git a/components/ledger/pkg/ledger/command/commander_test.go b/components/ledger/pkg/ledger/command/commander_test.go deleted file mode 100644 index 547ce545e..000000000 --- a/components/ledger/pkg/ledger/command/commander_test.go +++ /dev/null @@ -1,408 +0,0 @@ -package command - -import ( - "context" - "math/big" - "testing" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "github.com/formancehq/stack/libs/go-libs/logging" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/pkg/errors" - "github.com/stretchr/testify/require" -) - -type mockStore struct { - logs []*core.ChainedLog -} - -func (m *mockStore) GetLastLog(ctx context.Context) (*core.ChainedLog, error) { - if len(m.logs) == 0 { - return nil, nil - } - return m.logs[len(m.logs)-1], nil -} - -func (m *mockStore) GetBalanceFromLogs(ctx context.Context, address, asset string) (*big.Int, error) { - balance := new(big.Int) - for _, log := range m.logs { - switch payload := log.Data.(type) { - case core.NewTransactionLogPayload: - postings := payload.Transaction.Postings - for _, posting := range postings { - if posting.Asset != asset { - continue - } - if posting.Source == address { - balance = balance.Sub(balance, posting.Amount) - } - if posting.Destination == address { - balance = balance.Add(balance, posting.Amount) - } - } - } - } - return balance, nil -} - -func (m *mockStore) GetMetadataFromLogs(ctx context.Context, address, key string) (string, error) { - for i := len(m.logs) - 1; i >= 0; i-- { - switch payload := m.logs[i].Data.(type) { - case core.NewTransactionLogPayload: - forAccount, ok := payload.AccountMetadata[address] - if ok { - value, ok := forAccount[key] - if ok { - return value, nil - } - } - case core.SetMetadataLogPayload: - if payload.TargetID != address { - continue - } - value, ok := payload.Metadata[key] - if ok { - return value, nil - } - } - } - return "", errors.New("not found") -} - -func (m *mockStore) ReadLogWithIdempotencyKey(ctx context.Context, key string) (*core.ChainedLog, error) { - first := collectionutils.First(m.logs, func(log *core.ChainedLog) bool { - return log.IdempotencyKey == key - }) - if first == nil { - return nil, storageerrors.ErrNotFound - } - return first, nil -} - -func (m *mockStore) ReadLogForCreatedTransactionWithReference(ctx context.Context, reference string) (*core.ChainedLog, error) { - first := collectionutils.First(m.logs, func(log *core.ChainedLog) bool { - if log.Type != core.NewTransactionLogType { - return false - } - return log.Data.(core.NewTransactionLogPayload).Transaction.Reference == reference - }) - if first == nil { - return nil, storageerrors.ErrNotFound - } - return first, nil -} - -func (m *mockStore) ReadLogForCreatedTransaction(ctx context.Context, txID uint64) (*core.ChainedLog, error) { - first := collectionutils.First(m.logs, func(log *core.ChainedLog) bool { - if log.Type != core.NewTransactionLogType { - return false - } - return log.Data.(core.NewTransactionLogPayload).Transaction.ID == txID - }) - if first == nil { - return nil, storageerrors.ErrNotFound - } - return first, nil -} - -func (m *mockStore) ReadLogForRevertedTransaction(ctx context.Context, txID uint64) (*core.ChainedLog, error) { - first := collectionutils.First(m.logs, func(log *core.ChainedLog) bool { - if log.Type != core.RevertedTransactionLogType { - return false - } - return log.Data.(core.RevertedTransactionLogPayload).RevertedTransactionID == txID - }) - if first == nil { - return nil, storageerrors.ErrNotFound - } - return first, nil -} - -func (m *mockStore) ReadLastLogWithType(background context.Context, logType ...core.LogType) (*core.ChainedLog, error) { - first := collectionutils.First(m.logs, func(log *core.ChainedLog) bool { - return collectionutils.Contains(logType, log.Type) - }) - if first == nil { - return nil, storageerrors.ErrNotFound - } - return first, nil -} - -func (m *mockStore) InsertLogs(ctx context.Context, logs ...*core.ActiveLog) error { - - for _, log := range logs { - var previousLog *core.ChainedLog - if len(m.logs) > 0 { - previousLog = m.logs[len(m.logs)-1] - } - chainedLog := log.ChainLog(previousLog) - m.logs = append(m.logs, chainedLog) - } - - return nil -} - -var ( - _ Store = (*mockStore)(nil) - now = core.Now() -) - -func newMockStore() *mockStore { - return &mockStore{ - logs: []*core.ChainedLog{}, - } -} - -type testCase struct { - name string - setup func(t *testing.T, r Store) - script string - reference string - expectedError error - expectedTx *core.Transaction - expectedLogs []*core.Log - parameters Parameters -} - -var testCases = []testCase{ - { - name: "nominal", - script: ` - send [GEM 100] ( - source = @world - destination = @mint - )`, - expectedTx: core.NewTransaction().WithPostings( - core.NewPosting("world", "mint", "GEM", big.NewInt(100)), - ), - expectedLogs: []*core.Log{ - core.NewTransactionLog( - core.NewTransaction().WithPostings( - core.NewPosting("world", "mint", "GEM", big.NewInt(100))), - map[string]metadata.Metadata{}, - ), - }, - }, - { - name: "no script", - script: ``, - expectedError: ErrNoScript, - }, - { - name: "invalid script", - script: `XXX`, - expectedError: ErrCompilationFailed, - }, - { - name: "set reference conflict", - setup: func(t *testing.T, store Store) { - tx := core.NewTransaction(). - WithPostings(core.NewPosting("world", "mint", "GEM", big.NewInt(100))). - WithReference("tx_ref") - log := core.NewTransactionLog(tx, nil) - err := store.InsertLogs(context.Background(), core.NewActiveLog(log.ChainLog(nil))) - require.NoError(t, err) - }, - script: ` - send [GEM 100] ( - source = @world - destination = @mint - )`, - reference: "tx_ref", - expectedError: ErrConflictError, - }, - { - name: "set reference", - script: ` - send [GEM 100] ( - source = @world - destination = @mint - )`, - reference: "tx_ref", - expectedTx: core.NewTransaction(). - WithPostings( - core.NewPosting("world", "mint", "GEM", big.NewInt(100)), - ). - WithReference("tx_ref"), - expectedLogs: []*core.Log{ - core.NewTransactionLog( - core.NewTransaction(). - WithPostings( - core.NewPosting("world", "mint", "GEM", big.NewInt(100)), - ). - WithReference("tx_ref"), - map[string]metadata.Metadata{}, - ), - }, - }, - { - name: "using idempotency", - script: ` - send [GEM 100] ( - source = @world - destination = @mint - )`, - reference: "tx_ref", - expectedTx: core.NewTransaction(). - WithPostings( - core.NewPosting("world", "mint", "GEM", big.NewInt(100)), - ), - expectedLogs: []*core.Log{ - core.NewTransactionLog( - core.NewTransaction(). - WithPostings( - core.NewPosting("world", "mint", "GEM", big.NewInt(100)), - ), - map[string]metadata.Metadata{}, - ).WithIdempotencyKey("testing"), - }, - setup: func(t *testing.T, r Store) { - log := core.NewTransactionLog( - core.NewTransaction(). - WithPostings( - core.NewPosting("world", "mint", "GEM", big.NewInt(100)), - ). - WithTimestamp(now), - map[string]metadata.Metadata{}, - ).WithIdempotencyKey("testing") - err := r.InsertLogs(context.Background(), core.NewActiveLog(log.ChainLog(nil))) - require.NoError(t, err) - }, - parameters: Parameters{ - IdempotencyKey: "testing", - }, - }, -} - -func TestCreateTransaction(t *testing.T) { - t.Parallel() - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - - store := newMockStore() - ctx := logging.TestingContext() - - commander := New(store, NoOpLocker, NewCompiler(1024), - NewReferencer(), nil, func(activeLogs ...*core.ActiveLog) { - for _, activeLog := range activeLogs { - activeLog.SetProjected() - } - }) - go commander.Run(ctx) - defer commander.Close() - - if tc.setup != nil { - tc.setup(t, store) - } - ret, err := commander.CreateTransaction(ctx, tc.parameters, core.RunScript{ - Script: core.Script{ - Plain: tc.script, - }, - Timestamp: now, - Reference: tc.reference, - }) - - if tc.expectedError != nil { - require.True(t, errors.Is(err, tc.expectedError)) - } else { - require.NoError(t, err) - require.NotNil(t, ret) - tc.expectedTx.Timestamp = now - require.Equal(t, tc.expectedTx, ret) - - require.Len(t, store.logs, len(tc.expectedLogs)) - for ind := range tc.expectedLogs { - expectedLog := tc.expectedLogs[ind] - switch v := expectedLog.Data.(type) { - case core.NewTransactionLogPayload: - v.Transaction.Timestamp = now - expectedLog.Data = v - } - expectedLog.Date = now - } - } - }) - } -} - -func TestRevert(t *testing.T) { - txID := uint64(0) - store := newMockStore() - ctx := logging.TestingContext() - - log := core.NewTransactionLog( - core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - ), - map[string]metadata.Metadata{}, - ) - err := store.InsertLogs(context.Background(), core.NewActiveLog(log.ChainLog(nil))) - require.NoError(t, err) - - commander := New(store, NoOpLocker, NewCompiler(1024), NewReferencer(), nil, func(activeLogs ...*core.ActiveLog) { - for _, activeLog := range activeLogs { - activeLog.SetProjected() - } - }) - go commander.Run(ctx) - defer commander.Close() - - _, err = commander.RevertTransaction(ctx, Parameters{}, txID) - require.NoError(t, err) -} - -func TestRevertWithAlreadyReverted(t *testing.T) { - - store := newMockStore() - ctx := logging.TestingContext() - - log := core. - NewRevertedTransactionLog(core.Now(), 0, core.NewTransaction()) - err := store.InsertLogs(context.Background(), core.NewActiveLog(log.ChainLog(nil))) - require.NoError(t, err) - - commander := New(store, NoOpLocker, NewCompiler(1024), NewReferencer(), nil, func(activeLogs ...*core.ActiveLog) { - for _, activeLog := range activeLogs { - activeLog.SetProjected() - } - }) - go commander.Run(ctx) - defer commander.Close() - - _, err = commander.RevertTransaction(context.Background(), Parameters{}, 0) - require.True(t, errors.Is(err, ErrAlreadyReverted)) -} - -func TestRevertWithRevertOccurring(t *testing.T) { - - store := newMockStore() - ctx := logging.TestingContext() - - log := core.NewTransactionLog( - core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - ), - map[string]metadata.Metadata{}, - ) - err := store.InsertLogs(ctx, core.NewActiveLog(log.ChainLog(nil))) - require.NoError(t, err) - - referencer := NewReferencer() - commander := New(store, NoOpLocker, NewCompiler(1024), - referencer, nil, func(activeLogs ...*core.ActiveLog) { - for _, activeLog := range activeLogs { - activeLog.SetProjected() - } - }) - go commander.Run(ctx) - defer commander.Close() - - referencer.take(referenceReverts, uint64(0)) - - _, err = commander.RevertTransaction(ctx, Parameters{}, 0) - require.True(t, errors.Is(err, ErrRevertOccurring)) -} diff --git a/components/ledger/pkg/ledger/command/compiler.go b/components/ledger/pkg/ledger/command/compiler.go deleted file mode 100644 index c9b56550c..000000000 --- a/components/ledger/pkg/ledger/command/compiler.go +++ /dev/null @@ -1,48 +0,0 @@ -package command - -import ( - "context" - "crypto/sha256" - "encoding/base64" - - "github.com/bluele/gcache" - "github.com/formancehq/ledger/pkg/machine/script/compiler" - "github.com/formancehq/ledger/pkg/machine/vm" - "github.com/formancehq/ledger/pkg/machine/vm/program" - "github.com/formancehq/stack/libs/go-libs/errorsutil" -) - -type Compiler struct { - cache gcache.Cache -} - -func (c *Compiler) Compile(ctx context.Context, script string) (*program.Program, error) { - - digest := sha256.New() - _, err := digest.Write([]byte(script)) - if err != nil { - return nil, errorsutil.NewError(vm.ErrCompilationFailed, err) - } - - cacheKey := base64.StdEncoding.EncodeToString(digest.Sum(nil)) - v, err := c.cache.Get(cacheKey) - if err == nil { - return v.(*program.Program), nil - } - - program, err := compiler.Compile(script) - if err != nil { - return nil, errorsutil.NewError(vm.ErrCompilationFailed, err) - } - _ = c.cache.Set(cacheKey, program) - - return program, nil -} - -func NewCompiler(maxCacheCount int) *Compiler { - return &Compiler{ - cache: gcache.New(maxCacheCount). - LFU(). - Build(), - } -} diff --git a/components/ledger/pkg/ledger/command/context.go b/components/ledger/pkg/ledger/command/context.go deleted file mode 100644 index 98363ca2b..000000000 --- a/components/ledger/pkg/ledger/command/context.go +++ /dev/null @@ -1,70 +0,0 @@ -package command - -import ( - "context" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/logging" -) - -type executionContext struct { - commander *Commander - parameters Parameters -} - -func (e *executionContext) AppendLog(ctx context.Context, log *core.Log) (*core.ActiveLog, chan struct{}, error) { - if e.parameters.DryRun { - ret := make(chan struct{}) - close(ret) - return core.NewActiveLog(log.ChainLog(nil)), ret, nil - } - - activeLog := core.NewActiveLog(e.commander.chainLog(log)) - logging.FromContext(ctx).WithFields(map[string]any{ - "id": activeLog.ChainedLog.ID, - }).Debugf("Appending log") - done := make(chan struct{}) - e.commander.Append(activeLog, func() { - close(done) - }) - return activeLog, done, nil -} - -func (e *executionContext) run(ctx context.Context, executor func(e *executionContext) (*core.ActiveLog, chan struct{}, error)) (*core.ChainedLog, error) { - if ik := e.parameters.IdempotencyKey; ik != "" { - if err := e.commander.referencer.take(referenceIks, ik); err != nil { - return nil, err - } - defer e.commander.referencer.release(referenceIks, ik) - - chainedLog, err := e.commander.store.ReadLogWithIdempotencyKey(ctx, ik) - if err == nil { - return chainedLog, nil - } - if err != storageerrors.ErrNotFound && err != nil { - return nil, err - } - } - activeLog, done, err := executor(e) - if err != nil { - return nil, err - } - <-done - logger := logging.FromContext(ctx).WithFields(map[string]any{ - "id": activeLog.ID, - }) - logger.Debugf("Log inserted in database") - if !e.parameters.Async { - <-activeLog.Projected - logger.Debugf("Log fully ingested") - } - return activeLog.ChainedLog, nil -} - -func newExecutionContext(commander *Commander, parameters Parameters) *executionContext { - return &executionContext{ - commander: commander, - parameters: parameters, - } -} diff --git a/components/ledger/pkg/ledger/command/store.go b/components/ledger/pkg/ledger/command/store.go deleted file mode 100644 index 3a020048b..000000000 --- a/components/ledger/pkg/ledger/command/store.go +++ /dev/null @@ -1,20 +0,0 @@ -package command - -import ( - "context" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/machine/vm" -) - -type Store interface { - vm.Store - //AppendLog(ctx context.Context, log *core.ActiveLog) (*core.LogPersistenceTracker, error) - InsertLogs(ctx context.Context, logs ...*core.ActiveLog) error - ReadLastLogWithType(ctx context.Context, logType ...core.LogType) (*core.ChainedLog, error) - ReadLogForCreatedTransactionWithReference(ctx context.Context, reference string) (*core.ChainedLog, error) - ReadLogForCreatedTransaction(ctx context.Context, txID uint64) (*core.ChainedLog, error) - ReadLogForRevertedTransaction(ctx context.Context, txID uint64) (*core.ChainedLog, error) - ReadLogWithIdempotencyKey(ctx context.Context, key string) (*core.ChainedLog, error) - GetLastLog(ctx context.Context) (*core.ChainedLog, error) -} diff --git a/components/ledger/pkg/ledger/ledger.go b/components/ledger/pkg/ledger/ledger.go deleted file mode 100644 index 4fdd1ec27..000000000 --- a/components/ledger/pkg/ledger/ledger.go +++ /dev/null @@ -1,122 +0,0 @@ -package ledger - -import ( - "context" - - "github.com/ThreeDotsLabs/watermill/message" - "github.com/formancehq/ledger/pkg/bus" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/ledger/query" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/logging" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/pkg/errors" -) - -type Ledger struct { - commander *command.Commander - store *ledgerstore.Store - projector *query.Projector -} - -func (l *Ledger) CreateTransaction(ctx context.Context, parameters command.Parameters, data core.RunScript) (*core.Transaction, error) { - return l.commander.CreateTransaction(ctx, parameters, data) -} - -func (l *Ledger) RevertTransaction(ctx context.Context, parameters command.Parameters, id uint64) (*core.Transaction, error) { - return l.commander.RevertTransaction(ctx, parameters, id) -} - -func (l *Ledger) SaveMeta(ctx context.Context, parameters command.Parameters, targetType string, targetID any, m metadata.Metadata) error { - return l.commander.SaveMeta(ctx, parameters, targetType, targetID, m) -} - -func New( - name string, - store *ledgerstore.Store, - publisher message.Publisher, - compiler *command.Compiler, -) *Ledger { - var monitor query.Monitor = query.NewNoOpMonitor() - if publisher != nil { - monitor = bus.NewLedgerMonitor(publisher, name) - } - metricsRegistry, err := metrics.RegisterPerLedgerMetricsRegistry(name) - if err != nil { - panic(err) - } - projector := query.NewProjector(store, monitor, metricsRegistry) - return &Ledger{ - commander: command.New( - store, - command.NewDefaultLocker(), - compiler, - command.NewReferencer(), - metricsRegistry, - projector.QueueLog, - ), - store: store, - projector: projector, - } -} - -func (l *Ledger) Start(ctx context.Context) { - go l.commander.Run(logging.ContextWithField(ctx, "component", "commander")) - l.projector.Start(logging.ContextWithField(ctx, "component", "projector")) -} - -func (l *Ledger) Close(ctx context.Context) { - logging.FromContext(ctx).Debugf("Close commander") - l.commander.Close() - - logging.FromContext(ctx).Debugf("Close projector") - l.projector.Stop(logging.ContextWithField(ctx, "component", "projector")) -} - -func (l *Ledger) GetTransactions(ctx context.Context, q ledgerstore.TransactionsQuery) (*api.Cursor[core.ExpandedTransaction], error) { - txs, err := l.store.GetTransactions(ctx, q) - return txs, errors.Wrap(err, "getting transactions") -} - -func (l *Ledger) CountTransactions(ctx context.Context, q ledgerstore.TransactionsQuery) (uint64, error) { - count, err := l.store.CountTransactions(ctx, q) - return count, errors.Wrap(err, "counting transactions") -} - -func (l *Ledger) GetTransaction(ctx context.Context, id uint64) (*core.ExpandedTransaction, error) { - tx, err := l.store.GetTransaction(ctx, id) - return tx, errors.Wrap(err, "getting transaction") -} - -func (l *Ledger) CountAccounts(ctx context.Context, a ledgerstore.AccountsQuery) (uint64, error) { - count, err := l.store.CountAccounts(ctx, a) - return count, errors.Wrap(err, "counting accounts") -} - -func (l *Ledger) GetAccounts(ctx context.Context, a ledgerstore.AccountsQuery) (*api.Cursor[core.Account], error) { - accounts, err := l.store.GetAccounts(ctx, a) - return accounts, errors.Wrap(err, "getting accounts") -} - -func (l *Ledger) GetAccount(ctx context.Context, address string) (*core.AccountWithVolumes, error) { - accounts, err := l.store.GetAccountWithVolumes(ctx, address) - return accounts, errors.Wrap(err, "getting account") -} - -func (l *Ledger) GetBalances(ctx context.Context, q ledgerstore.BalancesQuery) (*api.Cursor[core.BalancesByAssetsByAccounts], error) { - balances, err := l.store.GetBalances(ctx, q) - return balances, errors.Wrap(err, "getting balances") -} - -func (l *Ledger) GetBalancesAggregated(ctx context.Context, q ledgerstore.BalancesQuery) (core.BalancesByAssets, error) { - balances, err := l.store.GetBalancesAggregated(ctx, q) - return balances, errors.Wrap(err, "getting balances aggregated") -} - -func (l *Ledger) GetLogs(ctx context.Context, q ledgerstore.LogsQuery) (*api.Cursor[core.ChainedLog], error) { - logs, err := l.store.GetLogs(ctx, q) - return logs, errors.Wrap(err, "getting logs") -} diff --git a/components/ledger/pkg/ledger/migrations.go b/components/ledger/pkg/ledger/migrations.go deleted file mode 100644 index 875ce8782..000000000 --- a/components/ledger/pkg/ledger/migrations.go +++ /dev/null @@ -1,49 +0,0 @@ -package ledger - -import ( - "context" - - "github.com/formancehq/ledger/pkg/core" - "github.com/pkg/errors" -) - -func (l *Ledger) GetMigrationsInfo(ctx context.Context) ([]core.MigrationInfo, error) { - migrationsAvailable, err := l.store.GetMigrationsAvailable() - if err != nil { - return []core.MigrationInfo{}, errors.Wrap(err, "getting migrations available") - } - - migrationsDone, err := l.store.GetMigrationsDone(ctx) - if err != nil { - return []core.MigrationInfo{}, errors.Wrap(err, "getting migrations done") - } - - res := make([]core.MigrationInfo, 0) - for _, mAvailable := range migrationsAvailable { - timestamp := core.Time{} - done := false - for _, mDone := range migrationsDone { - if mDone.Version == mAvailable.Version { - done = true - timestamp = mDone.Date - break - } - } - if done { - res = append(res, core.MigrationInfo{ - Version: mAvailable.Version, - Name: mAvailable.Name, - Date: timestamp, - State: "DONE", - }) - } else { - res = append(res, core.MigrationInfo{ - Version: mAvailable.Version, - Name: mAvailable.Name, - State: "TO DO", - }) - } - } - - return res, nil -} diff --git a/components/ledger/pkg/ledger/module.go b/components/ledger/pkg/ledger/module.go deleted file mode 100644 index 9f6ef1e90..000000000 --- a/components/ledger/pkg/ledger/module.go +++ /dev/null @@ -1,42 +0,0 @@ -package ledger - -import ( - "github.com/ThreeDotsLabs/watermill/message" - "github.com/formancehq/ledger/pkg/ledger/command" - "github.com/formancehq/ledger/pkg/ledger/query" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage/driver" - "github.com/formancehq/stack/libs/go-libs/logging" - "go.uber.org/fx" -) - -type NumscriptCacheConfiguration struct { - MaxCount int -} - -type Configuration struct { - NumscriptCache NumscriptCacheConfiguration -} - -func Module(configuration Configuration) fx.Option { - return fx.Options( - fx.Provide(func( - storageDriver *driver.Driver, - publisher message.Publisher, - metricsRegistry metrics.GlobalRegistry, - logger logging.Logger, - ) *Resolver { - options := []option{ - WithMessagePublisher(publisher), - WithMetricsRegistry(metricsRegistry), - WithLogger(logger), - } - if configuration.NumscriptCache.MaxCount != 0 { - options = append(options, WithCompiler(command.NewCompiler(configuration.NumscriptCache.MaxCount))) - } - return NewResolver(storageDriver, options...) - }), - fx.Provide(fx.Annotate(query.NewNoOpMonitor, fx.As(new(query.Monitor)))), - fx.Provide(fx.Annotate(metrics.NewNoOpRegistry, fx.As(new(metrics.GlobalRegistry)))), - ) -} diff --git a/components/ledger/pkg/ledger/query/metadata_updater.go b/components/ledger/pkg/ledger/query/metadata_updater.go deleted file mode 100644 index 9c2c8c5a6..000000000 --- a/components/ledger/pkg/ledger/query/metadata_updater.go +++ /dev/null @@ -1,139 +0,0 @@ -package query - -import ( - "context" - "fmt" - "sync" - - "github.com/formancehq/ledger/pkg/ledger/utils/job" - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "github.com/formancehq/stack/libs/go-libs/metadata" -) - -type metadataUpdaterInput struct { - id any - metadata.Metadata - callback func() -} - -type inputs []*metadataUpdaterInput - -func (inputs inputs) aggregated() metadata.Metadata { - m := metadata.Metadata{} - for _, object := range inputs { - m = m.Merge(object.Metadata) - } - return m -} - -type metadataUpdaterBuffer struct { - id any - inputs inputs -} - -type metadataUpdaterJob struct { - updater *metadataUpdater - buffers []*metadataUpdaterBuffer - inputs []*metadataUpdaterInput - aggregated []*MetadataUpdate -} - -func (j metadataUpdaterJob) String() string { - return fmt.Sprintf("inserting %d objects", len(j.inputs)) -} - -func (j metadataUpdaterJob) Terminated() { - for _, input := range j.inputs { - input.callback() - } - - j.updater.mu.Lock() - defer j.updater.mu.Unlock() - - for _, buffer := range j.buffers { - if len(buffer.inputs) == 0 { - delete(j.updater.objects, buffer.id) - } else { - j.updater.queue.Append(buffer) - } - } -} - -type metadataUpdater struct { - *job.Runner[metadataUpdaterJob] - queue *collectionutils.LinkedList[*metadataUpdaterBuffer] - objects map[any]*metadataUpdaterBuffer - input chan *moveBufferInput - mu sync.Mutex - maxBufferSize int -} - -func (r *metadataUpdater) Append(id any, metadata metadata.Metadata, callback func()) { - r.mu.Lock() - - mba, ok := r.objects[id] - if !ok { - mba = &metadataUpdaterBuffer{ - id: id, - } - r.objects[id] = mba - r.queue.Append(mba) - } - mba.inputs = append(mba.inputs, &metadataUpdaterInput{ - id: id, - Metadata: metadata, - callback: callback, - }) - r.mu.Unlock() - - r.Runner.Next() -} - -func (r *metadataUpdater) nextJob() *metadataUpdaterJob { - r.mu.Lock() - defer r.mu.Unlock() - - batch := make([]*metadataUpdaterInput, 0) - aggregated := make([]*MetadataUpdate, 0) - for len(batch) < r.maxBufferSize { - mba := r.queue.TakeFirst() - if mba == nil { - break - } - - batch = append(batch, mba.inputs...) - aggregated = append(aggregated, &MetadataUpdate{ - ID: mba.id, - Metadata: mba.inputs.aggregated(), - }) - mba.inputs = inputs{} - } - - if len(batch) == 0 { - return nil - } - - return &metadataUpdaterJob{ - inputs: batch, - updater: r, - aggregated: aggregated, - } -} - -type MetadataUpdate struct { - ID any - Metadata metadata.Metadata -} - -func newMetadataUpdater(runner func(context.Context, ...*MetadataUpdate) error, nbWorkers, maxBufferSize int) *metadataUpdater { - ret := &metadataUpdater{ - queue: collectionutils.NewLinkedList[*metadataUpdaterBuffer](), - objects: map[any]*metadataUpdaterBuffer{}, - input: make(chan *moveBufferInput), - maxBufferSize: maxBufferSize, - } - ret.Runner = job.NewJobRunner[metadataUpdaterJob](func(ctx context.Context, job *metadataUpdaterJob) error { - return runner(ctx, job.aggregated...) - }, ret.nextJob, nbWorkers) - return ret -} diff --git a/components/ledger/pkg/ledger/query/monitor.go b/components/ledger/pkg/ledger/query/monitor.go deleted file mode 100644 index 121ecdf01..000000000 --- a/components/ledger/pkg/ledger/query/monitor.go +++ /dev/null @@ -1,29 +0,0 @@ -package query - -import ( - "context" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/stack/libs/go-libs/metadata" -) - -type Monitor interface { - CommittedTransactions(ctx context.Context, res ...core.Transaction) - SavedMetadata(ctx context.Context, targetType, id string, metadata metadata.Metadata) - RevertedTransaction(ctx context.Context, reverted, revert *core.Transaction) -} - -type noOpMonitor struct{} - -func (n noOpMonitor) CommittedTransactions(ctx context.Context, res ...core.Transaction) { -} -func (n noOpMonitor) SavedMetadata(ctx context.Context, targetType string, id string, metadata metadata.Metadata) { -} -func (n noOpMonitor) RevertedTransaction(ctx context.Context, reverted, revert *core.Transaction) { -} - -var _ Monitor = &noOpMonitor{} - -func NewNoOpMonitor() *noOpMonitor { - return &noOpMonitor{} -} diff --git a/components/ledger/pkg/ledger/query/move_updater.go b/components/ledger/pkg/ledger/query/move_updater.go deleted file mode 100644 index d6ee7c699..000000000 --- a/components/ledger/pkg/ledger/query/move_updater.go +++ /dev/null @@ -1,125 +0,0 @@ -package query - -import ( - "context" - "fmt" - "sync" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/utils/job" - "github.com/formancehq/stack/libs/go-libs/collectionutils" -) - -type moveBufferInput struct { - move *core.Move - callback func() -} - -type moveBufferAccount struct { - account string - moves []*moveBufferInput -} - -type insertMovesJob struct { - buf *moveBuffer - moves []*moveBufferInput - accounts []*moveBufferAccount -} - -func (j insertMovesJob) String() string { - return fmt.Sprintf("inserting %d moves", len(j.moves)) -} - -func (j insertMovesJob) Terminated() { - for _, input := range j.moves { - input.callback() - } - - j.buf.mu.Lock() - defer j.buf.mu.Unlock() - for _, account := range j.accounts { - if len(account.moves) == 0 { - delete(j.buf.accounts, account.account) - } else { - j.buf.accountsQueue.Append(account) - } - } -} - -type moveBuffer struct { - *job.Runner[insertMovesJob] - accountsQueue *collectionutils.LinkedList[*moveBufferAccount] - accounts map[string]*moveBufferAccount - inputMoves chan *moveBufferInput - mu sync.Mutex - maxBufferSize int -} - -func (r *moveBuffer) AppendMove(move *core.Move, callback func()) { - r.mu.Lock() - mba, ok := r.accounts[move.Account] - if !ok { - mba = &moveBufferAccount{ - account: move.Account, - } - r.accounts[move.Account] = mba - r.accountsQueue.Append(mba) - } - mba.moves = append(mba.moves, &moveBufferInput{ - move: move, - callback: callback, - }) - r.mu.Unlock() - - r.Runner.Next() -} - -func (r *moveBuffer) nextJob() *insertMovesJob { - r.mu.Lock() - defer r.mu.Unlock() - - batch := make([]*moveBufferInput, 0) - accounts := make([]*moveBufferAccount, 0) - for { - mba := r.accountsQueue.TakeFirst() - if mba == nil { - break - } - accounts = append(accounts, mba) - - if len(batch)+len(mba.moves) >= r.maxBufferSize { - nbItems := r.maxBufferSize - len(batch) - batch = append(batch, mba.moves[:nbItems]...) - mba.moves = mba.moves[nbItems:] - break - } else { - batch = append(batch, mba.moves...) - mba.moves = make([]*moveBufferInput, 0) - } - } - - if len(batch) == 0 { - return nil - } - - return &insertMovesJob{ - accounts: accounts, - moves: batch, - buf: r, - } -} - -func newMoveUpdater(runner func(context.Context, ...*core.Move) error, nbWorkers, maxBufferSize int) *moveBuffer { - ret := &moveBuffer{ - accountsQueue: collectionutils.NewLinkedList[*moveBufferAccount](), - accounts: map[string]*moveBufferAccount{}, - inputMoves: make(chan *moveBufferInput), - maxBufferSize: maxBufferSize, - } - ret.Runner = job.NewJobRunner[insertMovesJob](func(ctx context.Context, job *insertMovesJob) error { - return runner(ctx, collectionutils.Map(job.moves, func(from *moveBufferInput) *core.Move { - return from.move - })...) - }, ret.nextJob, nbWorkers) - return ret -} diff --git a/components/ledger/pkg/ledger/query/move_updater_test.go b/components/ledger/pkg/ledger/query/move_updater_test.go deleted file mode 100644 index 9c920e066..000000000 --- a/components/ledger/pkg/ledger/query/move_updater_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package query - -import ( - "context" - "fmt" - "sync" - "testing" - "time" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/stack/libs/go-libs/logging" -) - -func TestMoveBuffer(t *testing.T) { - t.Parallel() - - locked := sync.Map{} - buf := newMoveUpdater(func(ctx context.Context, moves ...*core.Move) error { - accounts := make(map[string]struct{}) - for _, move := range moves { - accounts[move.Account] = struct{}{} - } - for account := range accounts { - _, loaded := locked.LoadOrStore(account, struct{}{}) - if loaded { - panic(fmt.Sprintf("account '%s' already used", account)) - } - } - <-time.After(10 * time.Millisecond) - for account := range accounts { - locked.Delete(account) - } - - return nil - }, 5, 100) - go buf.Run(logging.ContextWithLogger(context.Background(), logging.Testing())) - defer buf.Close() - - wg := sync.WaitGroup{} - for i := 0; i < 100; i++ { - for j := 0; j < 100; j++ { - wg.Add(1) - j := j - go func() { - buf.AppendMove(&core.Move{ - Account: fmt.Sprintf("accounts:%d", j%10), - }, func() { - wg.Done() - }) - }() - } - } - wg.Wait() - <-time.After(time.Second) -} diff --git a/components/ledger/pkg/ledger/query/projector.go b/components/ledger/pkg/ledger/query/projector.go deleted file mode 100644 index cea359981..000000000 --- a/components/ledger/pkg/ledger/query/projector.go +++ /dev/null @@ -1,265 +0,0 @@ -package query - -import ( - "context" - "fmt" - "sync" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/ledger/utils/batching" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "github.com/formancehq/stack/libs/go-libs/logging" -) - -type logPersistenceParts struct { - mu sync.Mutex - parts map[string]struct{} - onTerminated func() -} - -func (p *logPersistenceParts) Store(id string) { - p.mu.Lock() - defer p.mu.Unlock() - - p.parts[id] = struct{}{} -} - -func (p *logPersistenceParts) Delete(id string) { - p.mu.Lock() - defer p.mu.Unlock() - delete(p.parts, id) - - if len(p.parts) == 0 { - p.onTerminated() - } -} - -func newLogPersistenceParts(onTerminated func()) *logPersistenceParts { - return &logPersistenceParts{ - mu: sync.Mutex{}, - parts: map[string]struct{}{}, - onTerminated: onTerminated, - } -} - -type Projector struct { - store Store - monitor Monitor - metricsRegistry metrics.PerLedgerRegistry - - queue chan []*core.ActiveLog - stopChan chan chan struct{} - activeLogs *collectionutils.LinkedList[*core.ActiveLog] - - txUpdater *batching.Batcher[core.Transaction] - txMetadataUpdater *metadataUpdater - accountMetadataUpdater *metadataUpdater - - moveUpdater *moveBuffer - limitReadLogs int -} - -func (p *Projector) QueueLog(logs ...*core.ActiveLog) { - p.queue <- logs -} - -func (p *Projector) Stop(ctx context.Context) { - logger := logging.FromContext(ctx).WithField("component", "projector") - logger.Infof("Stop") - ch := make(chan struct{}) - p.stopChan <- ch - <-ch -} - -func (p *Projector) Start(ctx context.Context) { - logger := logging.FromContext(ctx).WithField("component", "projector") - logger.Infof("Start") - - ctx = logging.ContextWithLogger(ctx, logger) - - go p.moveUpdater.Run(logging.ContextWithField(ctx, "component", "moves buffer")) - go p.txUpdater.Run(logging.ContextWithField(ctx, "component", "transactions buffer")) - go p.accountMetadataUpdater.Run(logging.ContextWithField(ctx, "component", "accounts metadata buffer")) - go p.txMetadataUpdater.Run(logging.ContextWithField(ctx, "component", "transactions metadata buffer")) - - p.syncLogs(ctx) - - go func() { - - for { - select { - case ch := <-p.stopChan: - logger.Debugf("Close move buffer") - p.moveUpdater.Close() - - logger.Debugf("Stop transaction worker") - p.txUpdater.Close() - - logger.Debugf("Stop account metadata worker") - p.accountMetadataUpdater.Close() - - logger.Debugf("Stop transaction metadata worker") - p.txMetadataUpdater.Close() - - close(ch) - return - case logs := <-p.queue: - logger.Debugf("Got %d new logs to project", len(logs)) - p.processLogs(ctx, logs) - } - } - }() -} - -func (p *Projector) syncLogs(ctx context.Context) error { - lastReadLogID, err := p.store.GetNextLogID(ctx) - if err != nil && !storageerrors.IsNotFoundError(err) { - panic(err) - } - - logging.FromContext(ctx).Infof("Project logs since id: %d", lastReadLogID) - - for { - logs, err := p.store.ReadLogsRange(ctx, lastReadLogID, lastReadLogID+uint64(p.limitReadLogs)) - if err != nil { - panic(err) - } - - if len(logs) == 0 { - // No logs, nothing to do - return nil - } - - p.processLogs(ctx, collectionutils.Map(logs, func(from core.ChainedLog) *core.ActiveLog { - return core.NewActiveLog(&from) - })) - - lastReadLogID = logs[len(logs)-1].ID + 1 - - if len(logs) < p.limitReadLogs { - // Nothing to do anymore, no need to read more logs - return nil - } - } -} - -func (p *Projector) processLogs(ctx context.Context, logs []*core.ActiveLog) { - p.metricsRegistry.QueryInboundLogs().Add(ctx, int64(len(logs))) - p.activeLogs.Append(logs...) - - for _, log := range logs { - log := log - markLogAsProjected := func() { - log.SetProjected() - if err := p.store.MarkedLogsAsProjected(ctx, log.ID); err != nil { - panic(err) - } - p.metricsRegistry.QueryProcessedLogs().Add(ctx, 1) - } - dispatchTransaction := func(l *logPersistenceParts, log *core.ActiveLog, tx core.Transaction) { - logger := logging.FromContext(ctx).WithFields(map[string]any{ - "log-id": log.ID, - }) - moves := tx.GetMoves() - moveKey := func(move *core.Move) string { - return fmt.Sprintf("move/%d/%v/%s", move.PostingIndex, move.IsSource, move.Account) - } - l.Store("tx") - for _, move := range moves { - l.Store(moveKey(move)) - } - - p.txUpdater.Append(tx, func() { - logger.Debugf("Transaction projected") - l.Delete("tx") - }) - - for _, move := range moves { - move := move - p.moveUpdater.AppendMove(move, func() { - logger.WithFields(map[string]any{ - "asset": move.Asset, - "is_source": move.IsSource, - "account": move.Account, - }).Debugf("Move projected") - l.Delete(moveKey(move)) - }) - } - } - switch payload := log.Log.Data.(type) { - case core.NewTransactionLogPayload: - l := newLogPersistenceParts(func() { - markLogAsProjected() - p.monitor.CommittedTransactions(ctx, *payload.Transaction) - }) - - dispatchTransaction(l, log, *payload.Transaction) - case core.SetMetadataLogPayload: - switch payload.TargetType { - case core.MetaTargetTypeAccount: - p.accountMetadataUpdater.Append(payload.TargetID, payload.Metadata, func() { - markLogAsProjected() - p.monitor.SavedMetadata(ctx, payload.TargetType, fmt.Sprint(payload.TargetID), payload.Metadata) - }) - case core.MetaTargetTypeTransaction: - p.txMetadataUpdater.Append(payload.TargetID, payload.Metadata, func() { - markLogAsProjected() - p.monitor.SavedMetadata(ctx, payload.TargetType, fmt.Sprint(payload.TargetID), payload.Metadata) - }) - } - case core.RevertedTransactionLogPayload: - l := newLogPersistenceParts(func() { - markLogAsProjected() - p.activeLogs.RemoveValue(log) - - revertedTx, err := p.store.GetTransaction(ctx, payload.RevertedTransactionID) - if err != nil { - panic(err) - } - p.monitor.RevertedTransaction(ctx, payload.RevertTransaction, &revertedTx.Transaction) - }) - l.Store("metadata") - dispatchTransaction(l, log, *payload.RevertTransaction) - p.txMetadataUpdater.Append(payload.RevertedTransactionID, core.RevertedMetadata(payload.RevertTransaction.ID), func() { - l.Delete("metadata") - }) - } - } -} - -func NewProjector(store Store, monitor Monitor, metricsRegistry metrics.PerLedgerRegistry) *Projector { - return &Projector{ - store: store, - monitor: monitor, - metricsRegistry: metricsRegistry, - txUpdater: batching.NewBatcher( - store.InsertTransactions, - batching.NoOpOnBatchProcessed[core.Transaction](), - 2, - 512, - ), - accountMetadataUpdater: newMetadataUpdater(func(ctx context.Context, update ...*MetadataUpdate) error { - return store.UpdateAccountsMetadata(ctx, collectionutils.Map(update, func(from *MetadataUpdate) core.Account { - return core.Account{ - Address: from.ID.(string), - Metadata: from.Metadata, - } - })...) - }, 1, 512), - txMetadataUpdater: newMetadataUpdater(func(ctx context.Context, update ...*MetadataUpdate) error { - return store.UpdateTransactionsMetadata(ctx, collectionutils.Map(update, func(from *MetadataUpdate) core.TransactionWithMetadata { - return core.TransactionWithMetadata{ - ID: from.ID.(uint64), - Metadata: from.Metadata, - } - })...) - }, 1, 512), - moveUpdater: newMoveUpdater(store.InsertMoves, 5, 100), - activeLogs: collectionutils.NewLinkedList[*core.ActiveLog](), - queue: make(chan []*core.ActiveLog, 1024), - stopChan: make(chan chan struct{}), - limitReadLogs: 10000, - } -} diff --git a/components/ledger/pkg/ledger/query/projector_test.go b/components/ledger/pkg/ledger/query/projector_test.go deleted file mode 100644 index d12bb5a77..000000000 --- a/components/ledger/pkg/ledger/query/projector_test.go +++ /dev/null @@ -1,183 +0,0 @@ -package query - -import ( - "context" - "fmt" - "math/big" - "testing" - "time" - - "github.com/alitto/pond" - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/opentelemetry/metrics" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/logging" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/stretchr/testify/require" -) - -func TestProjector(t *testing.T) { - t.Parallel() - - ledgerStore := storage.NewInMemoryStore() - - ctx := logging.TestingContext() - - projector := NewProjector(ledgerStore, NewNoOpMonitor(), metrics.NewNoOpRegistry()) - projector.Start(ctx) - defer projector.Stop(ctx) - - now := core.Now() - - tx0 := core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD/2", big.NewInt(100)), - ) - tx1 := core.NewTransaction().WithPostings( - core.NewPosting("bank", "user:1", "USD/2", big.NewInt(10)), - ).WithID(1) - - appliedMetadataOnTX1 := metadata.Metadata{ - "paymentID": "1234", - } - appliedMetadataOnAccount := metadata.Metadata{ - "category": "gold", - } - - logs := []*core.ChainedLog{ - core.NewTransactionLog(tx0, nil).ChainLog(nil), - core.NewTransactionLog(tx1, nil).ChainLog(nil), - core.NewSetMetadataLog(now, core.SetMetadataLogPayload{ - TargetType: core.MetaTargetTypeTransaction, - TargetID: tx1.ID, - Metadata: appliedMetadataOnTX1, - }).ChainLog(nil), - core.NewSetMetadataLog(now, core.SetMetadataLogPayload{ - TargetType: core.MetaTargetTypeAccount, - TargetID: "bank", - Metadata: appliedMetadataOnAccount, - }).ChainLog(nil), - core.NewSetMetadataLog(now, core.SetMetadataLogPayload{ - TargetType: core.MetaTargetTypeAccount, - TargetID: "another:account", - Metadata: appliedMetadataOnAccount, - }).ChainLog(nil), - } - for i, chainedLog := range logs { - chainedLog.ID = uint64(i) - activeLog := core.NewActiveLog(chainedLog) - projector.QueueLog(activeLog) - <-activeLog.Projected - } - - ledgerStore.Logs = logs - require.Eventually(t, func() bool { - nextLogID, err := ledgerStore.GetNextLogID(context.Background()) - require.NoError(t, err) - return nextLogID == uint64(len(logs)) - }, time.Second, 100*time.Millisecond) - - require.EqualValues(t, 2, len(ledgerStore.Transactions)) - require.EqualValues(t, 4, len(ledgerStore.Accounts)) - - account := ledgerStore.Accounts["bank"] - require.NotNil(t, account) - require.NotEmpty(t, account.Volumes) - require.EqualValues(t, 100, account.Volumes["USD/2"].Input.Uint64()) - require.EqualValues(t, 10, account.Volumes["USD/2"].Output.Uint64()) - - tx1FromDatabase := ledgerStore.Transactions[1] - tx1.Metadata = appliedMetadataOnTX1 - require.Equal(t, core.ExpandedTransaction{ - Transaction: *tx1, - PreCommitVolumes: map[string]core.VolumesByAssets{ - "bank": { - "USD/2": { - Input: big.NewInt(100), - Output: big.NewInt(0), - }, - }, - "user:1": { - "USD/2": { - Output: big.NewInt(0), - Input: big.NewInt(0), - }, - }, - }, - PostCommitVolumes: map[string]core.VolumesByAssets{ - "bank": { - "USD/2": { - Input: big.NewInt(100), - Output: big.NewInt(10), - }, - }, - "user:1": { - "USD/2": { - Input: big.NewInt(10), - Output: big.NewInt(0), - }, - }, - }, - }, *tx1FromDatabase) - - accountWithVolumes := ledgerStore.Accounts["bank"] - require.Equal(t, &core.AccountWithVolumes{ - Account: core.Account{ - Address: "bank", - Metadata: appliedMetadataOnAccount, - }, - Volumes: core.VolumesByAssets{ - "USD/2": { - Input: big.NewInt(100), - Output: big.NewInt(10), - }, - }, - }, accountWithVolumes) - - accountWithVolumes = ledgerStore.Accounts["another:account"] - require.Equal(t, &core.AccountWithVolumes{ - Account: core.Account{ - Address: "another:account", - Metadata: appliedMetadataOnAccount, - }, - Volumes: core.VolumesByAssets{}, - }, accountWithVolumes) -} - -func TestProjectorUnderHeavyParallelLoad(t *testing.T) { - t.Parallel() - - const nbWorkers = 5 - pool := pond.New(nbWorkers, nbWorkers) - ledgerStore := storage.NewInMemoryStore() - - ctx := logging.ContextWithLogger(context.TODO(), logging.Testing()) - - projector := NewProjector(ledgerStore, NewNoOpMonitor(), metrics.NewNoOpRegistry()) - projector.Start(ctx) - defer projector.Stop(ctx) - - var ( - previousLog *core.ChainedLog - allLogs = make([]*core.ActiveLog, 0) - ) - for i := 0; i < nbWorkers*500; i++ { - log := core.NewTransactionLog(core.NewTransaction().WithID(uint64(i)).WithPostings( - core.NewPosting("world", fmt.Sprintf("accounts:%d", i%100), "USD/2", big.NewInt(100)), - ), nil).ChainLog(previousLog) - activeLog := core.NewActiveLog(log) - pool.Submit(func() { - projector.QueueLog(activeLog) - }) - previousLog = log - allLogs = append(allLogs, activeLog) - } - - pool.StopAndWait() - for _, log := range allLogs { - select { - case <-log.Projected: - case <-time.After(time.Second): - require.Fail(t, fmt.Sprintf("log %d must have been ingested", log.ID)) - } - } -} diff --git a/components/ledger/pkg/ledger/query/store.go b/components/ledger/pkg/ledger/query/store.go deleted file mode 100644 index 680804578..000000000 --- a/components/ledger/pkg/ledger/query/store.go +++ /dev/null @@ -1,20 +0,0 @@ -package query - -import ( - "context" - - "github.com/formancehq/ledger/pkg/core" -) - -type Store interface { - IsInitialized() bool - GetNextLogID(ctx context.Context) (uint64, error) - ReadLogsRange(ctx context.Context, idMin, idMax uint64) ([]core.ChainedLog, error) - GetAccountWithVolumes(ctx context.Context, address string) (*core.AccountWithVolumes, error) - GetTransaction(ctx context.Context, id uint64) (*core.ExpandedTransaction, error) - UpdateAccountsMetadata(ctx context.Context, update ...core.Account) error - InsertTransactions(ctx context.Context, insert ...core.Transaction) error - InsertMoves(ctx context.Context, insert ...*core.Move) error - UpdateTransactionsMetadata(ctx context.Context, update ...core.TransactionWithMetadata) error - MarkedLogsAsProjected(ctx context.Context, id uint64) error -} diff --git a/components/ledger/pkg/ledger/stats.go b/components/ledger/pkg/ledger/stats.go deleted file mode 100644 index a0381c893..000000000 --- a/components/ledger/pkg/ledger/stats.go +++ /dev/null @@ -1,32 +0,0 @@ -package ledger - -import ( - "context" - - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/pkg/errors" -) - -type Stats struct { - Transactions uint64 `json:"transactions"` - Accounts uint64 `json:"accounts"` -} - -func (l *Ledger) Stats(ctx context.Context) (Stats, error) { - var stats Stats - - transactions, err := l.store.CountTransactions(ctx, ledgerstore.TransactionsQuery{}) - if err != nil { - return stats, errors.Wrap(err, "counting transactions") - } - - accounts, err := l.store.CountAccounts(ctx, ledgerstore.AccountsQuery{}) - if err != nil { - return stats, errors.Wrap(err, "counting accounts") - } - - return Stats{ - Transactions: transactions, - Accounts: accounts, - }, nil -} diff --git a/components/ledger/pkg/ledger/utils/batching/batcher.go b/components/ledger/pkg/ledger/utils/batching/batcher.go deleted file mode 100644 index ec435d7b0..000000000 --- a/components/ledger/pkg/ledger/utils/batching/batcher.go +++ /dev/null @@ -1,95 +0,0 @@ -package batching - -import ( - "context" - "fmt" - "sync" - - "github.com/formancehq/ledger/pkg/ledger/utils/job" - "github.com/formancehq/stack/libs/go-libs/collectionutils" -) - -type OnBatchProcessed[T any] func(...T) - -func NoOpOnBatchProcessed[T any]() func(...T) { - return func(t ...T) {} -} - -type pending[T any] struct { - object T - callback func() -} - -type batcherJob[T any] struct { - items []*pending[T] - onBatchProcessed OnBatchProcessed[T] -} - -func (b batcherJob[T]) String() string { - return fmt.Sprintf("processing %d items", len(b.items)) -} - -func (b batcherJob[T]) Terminated() { - for _, v := range b.items { - v.callback() - } - if b.onBatchProcessed != nil { - b.onBatchProcessed(collectionutils.Map(b.items, func(from *pending[T]) T { - return from.object - })...) - } -} - -type Batcher[T any] struct { - *job.Runner[batcherJob[T]] - pending []*pending[T] - mu sync.Mutex - maxBatchSize int - onBatchProcessed OnBatchProcessed[T] -} - -func (s *Batcher[T]) Append(object T, callback func()) { - s.mu.Lock() - s.pending = append(s.pending, &pending[T]{ - callback: callback, - object: object, - }) - s.mu.Unlock() - s.Runner.Next() -} - -func (s *Batcher[T]) nextBatch() *batcherJob[T] { - s.mu.Lock() - defer s.mu.Unlock() - - if len(s.pending) == 0 { - return nil - } - if len(s.pending) > s.maxBatchSize { - batch := s.pending[:s.maxBatchSize] - s.pending = s.pending[s.maxBatchSize:] - return &batcherJob[T]{ - onBatchProcessed: s.onBatchProcessed, - items: batch, - } - } - batch := s.pending - s.pending = make([]*pending[T], 0) - return &batcherJob[T]{ - items: batch, - onBatchProcessed: s.onBatchProcessed, - } -} - -func NewBatcher[T any](runner func(context.Context, ...T) error, onBatchProcessed OnBatchProcessed[T], nbWorkers, maxBatchSize int) *Batcher[T] { - ret := &Batcher[T]{ - maxBatchSize: maxBatchSize, - onBatchProcessed: onBatchProcessed, - } - ret.Runner = job.NewJobRunner[batcherJob[T]](func(ctx context.Context, job *batcherJob[T]) error { - return runner(ctx, collectionutils.Map(job.items, func(from *pending[T]) T { - return from.object - })...) - }, ret.nextBatch, nbWorkers) - return ret -} diff --git a/components/ledger/pkg/machine/examples/basic.go b/components/ledger/pkg/machine/examples/basic.go deleted file mode 100644 index 50ef667b7..000000000 --- a/components/ledger/pkg/machine/examples/basic.go +++ /dev/null @@ -1,81 +0,0 @@ -package main - -import ( - "context" - "fmt" - "math/big" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/machine/script/compiler" - "github.com/formancehq/ledger/pkg/machine/vm" - "github.com/formancehq/stack/libs/go-libs/metadata" -) - -func main() { - program, err := compiler.Compile(` - // This is a comment - vars { - account $dest - } - send [COIN 99] ( - source = { - 15% from { - @alice - @bob - } - remaining from @bob - } - destination = $dest - )`) - if err != nil { - panic(err) - } - fmt.Print(program) - - m := vm.NewMachine(*program) - m.Debug = true - - if err = m.SetVarsFromJSON(map[string]string{ - "dest": "charlie", - }); err != nil { - panic(err) - } - - initialVolumes := map[string]map[string]*big.Int{ - "alice": { - "COIN": big.NewInt(10), - }, - "bob": { - "COIN": big.NewInt(100), - }, - } - - store := vm.StaticStore{} - for account, balances := range initialVolumes { - store[account] = &vm.AccountWithBalances{ - Account: core.Account{ - Address: account, - Metadata: metadata.Metadata{}, - }, - Balances: balances, - } - } - - _, _, err = m.ResolveResources(context.Background(), vm.EmptyStore) - if err != nil { - panic(err) - } - - err = m.ResolveBalances(context.Background(), store) - if err != nil { - panic(err) - } - - err = m.Execute() - if err != nil { - panic(err) - } - - fmt.Println(m.Postings) - fmt.Println(m.TxMeta) -} diff --git a/components/ledger/pkg/machine/internal/account.go b/components/ledger/pkg/machine/internal/account.go deleted file mode 100644 index 24e58a387..000000000 --- a/components/ledger/pkg/machine/internal/account.go +++ /dev/null @@ -1,21 +0,0 @@ -package internal - -import ( - "fmt" - - "github.com/formancehq/ledger/pkg/core" -) - -type AccountAddress string - -func (AccountAddress) GetType() Type { return TypeAccount } -func (a AccountAddress) String() string { - return fmt.Sprintf("@%v", string(a)) -} - -func ValidateAccountAddress(acc AccountAddress) error { - if !core.AccountRegexp.MatchString(string(acc)) { - return fmt.Errorf("accounts should respect pattern %s", core.AccountPattern) - } - return nil -} diff --git a/components/ledger/pkg/machine/internal/asset.go b/components/ledger/pkg/machine/internal/asset.go deleted file mode 100644 index 7db578267..000000000 --- a/components/ledger/pkg/machine/internal/asset.go +++ /dev/null @@ -1,27 +0,0 @@ -package internal - -import ( - "fmt" - - "github.com/formancehq/ledger/pkg/core" -) - -type Asset string - -func (Asset) GetType() Type { return TypeAsset } -func (a Asset) String() string { - return fmt.Sprintf("%v", string(a)) -} - -type HasAsset interface { - GetAsset() Asset -} - -func (a Asset) GetAsset() Asset { return a } - -func ValidateAsset(ass Asset) error { - if !core.AssetRegexp.MatchString(string(ass)) { - return fmt.Errorf("asset should respect pattern '%s'", core.AssetPattern) - } - return nil -} diff --git a/components/ledger/pkg/machine/machine.go b/components/ledger/pkg/machine/machine.go deleted file mode 100644 index b21040e55..000000000 --- a/components/ledger/pkg/machine/machine.go +++ /dev/null @@ -1,50 +0,0 @@ -package machine - -import ( - "math/big" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/machine/vm" - "github.com/formancehq/stack/libs/go-libs/errorsutil" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/pkg/errors" -) - -type Result struct { - Postings core.Postings - Metadata metadata.Metadata - AccountMetadata map[string]metadata.Metadata -} - -func Run(m *vm.Machine, script core.RunScript) (*Result, error) { - err := m.Execute() - if err != nil { - return nil, errors.Wrap(err, "script execution failed") - } - - result := Result{ - Postings: make([]core.Posting, len(m.Postings)), - Metadata: m.GetTxMetaJSON(), - AccountMetadata: m.GetAccountsMetaJSON(), - } - - for j, posting := range m.Postings { - result.Postings[j] = core.Posting{ - Source: posting.Source, - Destination: posting.Destination, - Amount: (*big.Int)(posting.Amount), - Asset: posting.Asset, - } - } - - for k, v := range script.Metadata { - _, ok := result.Metadata[k] - if ok { - return nil, errorsutil.NewError(vm.ErrMetadataOverride, - errors.New("cannot override metadata from script")) - } - result.Metadata[k] = v - } - - return &result, nil -} diff --git a/components/ledger/pkg/machine/machine_test.go b/components/ledger/pkg/machine/machine_test.go deleted file mode 100644 index 9cd1c52b8..000000000 --- a/components/ledger/pkg/machine/machine_test.go +++ /dev/null @@ -1,407 +0,0 @@ -package machine - -import ( - "context" - "errors" - "math/big" - "testing" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/machine/script/compiler" - "github.com/formancehq/ledger/pkg/machine/vm" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/stretchr/testify/require" -) - -type testCase struct { - name string - script string - vars map[string]string - expectErrorCode error - expectResult Result - store vm.Store - metadata metadata.Metadata -} - -var testCases = []testCase{ - { - name: "nominal", - script: ` - send [USD/2 99] ( - source = @world - destination = @user:001 - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("world", "user:001", "USD/2", big.NewInt(99)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "not enough funds", - script: ` - send [USD/2 99] ( - source = @bank - destination = @user:001 - )`, - expectErrorCode: vm.ErrInsufficientFund, - }, - { - name: "send $0", - script: ` - send [USD/2 0] ( - source = @alice - destination = @user:001 - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("alice", "user:001", "USD/2", big.NewInt(0)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "send $0 world", - script: ` - send [USD/2 0] ( - source = @world - destination = @user:001 - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("world", "user:001", "USD/2", big.NewInt(0)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "send all available", - script: ` - send [USD/2 *] ( - source = @alice - destination = @user:001 - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("alice", "user:001", "USD/2", big.NewInt(0)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "with variable", - script: ` - vars { - account $dest - } - - send [CAD/2 42] ( - source = @world - destination = $dest - )`, - vars: map[string]string{ - "dest": "user:001", - }, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("world", "user:001", "CAD/2", big.NewInt(42)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "using metadata", - store: vm.StaticStore{ - "sales:001": &vm.AccountWithBalances{ - Account: core.Account{ - Address: "sales:001", - Metadata: metadata.Metadata{ - "seller": "users:001", - }, - }, - Balances: map[string]*big.Int{ - "COIN": big.NewInt(100), - }, - }, - "users:001": &vm.AccountWithBalances{ - Account: core.Account{ - Address: "sales:001", - Metadata: metadata.Metadata{ - "commission": "15.5%", - }, - }, - Balances: map[string]*big.Int{}, - }, - }, - script: ` - vars { - account $sale - account $seller = meta($sale, "seller") - portion $commission = meta($seller, "commission") - } - - send [COIN *] ( - source = $sale - destination = { - remaining to $seller - $commission to @platform - } - ) - `, - vars: map[string]string{ - "sale": "sales:001", - }, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("sales:001", "users:001", "COIN", big.NewInt(85)), - core.NewPosting("sales:001", "platform", "COIN", big.NewInt(15)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "defining metadata from input", - script: ` - send [USD/2 99] ( - source = @world - destination = @users:001 - )`, - metadata: metadata.Metadata{ - "priority": "low", - }, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("world", "users:001", "USD/2", big.NewInt(99)), - }, - Metadata: metadata.Metadata{ - "priority": "low", - }, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "defining metadata from script", - script: ` - set_tx_meta("priority", "low") - send [USD/2 99] ( - source = @world - destination = @users:001 - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("world", "users:001", "USD/2", big.NewInt(99)), - }, - Metadata: metadata.Metadata{ - "priority": "low", - }, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "override metadata from script", - script: ` - set_tx_meta("priority", "low") - send [USD/2 99] ( - source = @world - destination = @users:001 - )`, - metadata: metadata.Metadata{ - "priority": "low", - }, - expectErrorCode: vm.ErrMetadataOverride, - }, - { - name: "set account meta", - script: ` - send [USD/2 99] ( - source = @world - destination = @users:001 - ) - set_account_meta(@alice, "aaa", "string meta") - set_account_meta(@alice, "bbb", 42) - set_account_meta(@alice, "ccc", COIN) - set_account_meta(@alice, "ddd", [COIN 30]) - set_account_meta(@alice, "eee", @bob) - `, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("world", "users:001", "USD/2", big.NewInt(99)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{ - "alice": { - "aaa": "string meta", - "bbb": "42", - "ccc": "COIN", - "ddd": "COIN 30", - "eee": "bob", - }, - }, - }, - }, - { - name: "balance function", - store: vm.StaticStore{ - "users:001": { - Account: core.Account{ - Address: "users:001", - Metadata: metadata.Metadata{}, - }, - Balances: map[string]*big.Int{ - "COIN": big.NewInt(100), - }, - }, - }, - script: ` - vars { - monetary $bal = balance(@users:001, COIN) - } - send $bal ( - source = @users:001 - destination = @world - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("users:001", "world", "COIN", big.NewInt(100)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "overdraft", - script: ` - send [USD/2 100] ( - source = @users:001 allowing unbounded overdraft - destination = @users:002 - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("users:001", "users:002", "USD/2", big.NewInt(100)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "send amount 0", - store: vm.StaticStore{ - "alice": { - Account: core.Account{ - Address: "alice", - Metadata: metadata.Metadata{}, - }, - Balances: map[string]*big.Int{}, - }, - }, - script: ` - send [USD 0] ( - source = @alice - destination = @bob - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("alice", "bob", "USD", big.NewInt(0)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "send all with balance 0", - store: vm.StaticStore{ - "alice": { - Account: core.Account{ - Address: "alice", - Metadata: metadata.Metadata{}, - }, - Balances: map[string]*big.Int{}, - }, - }, - script: ` - send [USD *] ( - source = @alice - destination = @bob - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("alice", "bob", "USD", big.NewInt(0)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, - { - name: "send account balance of 0", - store: vm.StaticStore{ - "alice": { - Account: core.Account{ - Address: "alice", - Metadata: metadata.Metadata{}, - }, - Balances: map[string]*big.Int{}, - }, - }, - script: ` - vars { - monetary $bal = balance(@alice, USD) - } - send $bal ( - source = @alice - destination = @bob - )`, - expectResult: Result{ - Postings: []core.Posting{ - core.NewPosting("alice", "bob", "USD", big.NewInt(0)), - }, - Metadata: metadata.Metadata{}, - AccountMetadata: map[string]metadata.Metadata{}, - }, - }, -} - -func TestMachine(t *testing.T) { - t.Parallel() - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - - if tc.store == nil { - tc.store = vm.StaticStore{} - } - - program, err := compiler.Compile(tc.script) - require.NoError(t, err) - - m := vm.NewMachine(*program) - require.NoError(t, m.SetVarsFromJSON(tc.vars)) - - _, _, err = m.ResolveResources(context.Background(), tc.store) - require.NoError(t, err) - require.NoError(t, m.ResolveBalances(context.Background(), tc.store)) - - result, err := Run(m, core.RunScript{ - Script: core.Script{ - Plain: tc.script, - Vars: tc.vars, - }, - Metadata: tc.metadata, - }) - if tc.expectErrorCode != nil { - require.True(t, errors.Is(err, tc.expectErrorCode)) - } else { - require.NoError(t, err) - require.NotNil(t, result) - require.Equal(t, tc.expectResult, *result) - } - }) - } -} diff --git a/components/ledger/pkg/machine/script/compiler/compiler.go b/components/ledger/pkg/machine/script/compiler/compiler.go deleted file mode 100644 index 18c840743..000000000 --- a/components/ledger/pkg/machine/script/compiler/compiler.go +++ /dev/null @@ -1,697 +0,0 @@ -package compiler - -import ( - "fmt" - "sort" - "strings" - - "github.com/antlr/antlr4/runtime/Go/antlr" - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/formancehq/ledger/pkg/machine/script/parser" - "github.com/formancehq/ledger/pkg/machine/vm/program" - "github.com/pkg/errors" -) - -type parseVisitor struct { - errListener *ErrorListener - instructions []byte - // resources must not exceed 65536 elements - resources []program.Resource - // sources store all source accounts - // a source can be also a destination of another posting - sources map[internal.Address]struct{} - // varIdx maps name to resource index - varIdx map[string]internal.Address - // needBalances store for each account, the set of assets needed - neededBalances map[internal.Address]map[internal.Address]struct{} -} - -// Allocates constants if it hasn't already been, -// and returns its resource address. -func (p *parseVisitor) findConstant(constant program.Constant) (*internal.Address, bool) { - for i := 0; i < len(p.resources); i++ { - if c, ok := p.resources[i].(program.Constant); ok { - if internal.ValueEquals(c.Inner, constant.Inner) { - addr := internal.Address(i) - return &addr, true - } - } - } - return nil, false -} - -func (p *parseVisitor) AllocateResource(res program.Resource) (*internal.Address, error) { - if c, ok := res.(program.Constant); ok { - idx, ok := p.findConstant(c) - if ok { - return idx, nil - } - } - if len(p.resources) >= 65536 { - return nil, errors.New("number of unique constants exceeded 65536") - } - p.resources = append(p.resources, res) - addr := internal.NewAddress(uint16(len(p.resources) - 1)) - return &addr, nil -} - -func (p *parseVisitor) isWorld(addr internal.Address) bool { - idx := int(addr) - if idx < len(p.resources) { - if c, ok := p.resources[idx].(program.Constant); ok { - if acc, ok := c.Inner.(internal.AccountAddress); ok { - if string(acc) == "world" { - return true - } - } - } - } - return false -} - -func (p *parseVisitor) VisitVariable(c parser.IVariableContext, push bool) (internal.Type, *internal.Address, *CompileError) { - name := c.GetText()[1:] // strip '$' prefix - if idx, ok := p.varIdx[name]; ok { - res := p.resources[idx] - if push { - p.PushAddress(idx) - } - return res.GetType(), &idx, nil - } else { - return 0, nil, LogicError(c, errors.New("variable not declared")) - } -} - -func (p *parseVisitor) VisitExpr(c parser.IExpressionContext, push bool) (internal.Type, *internal.Address, *CompileError) { - switch c := c.(type) { - case *parser.ExprAddSubContext: - lhsType, lhsAddr, err := p.VisitExpr(c.GetLhs(), push) - if err != nil { - return 0, nil, err - } - switch lhsType { - case internal.TypeNumber: - rhsType, _, err := p.VisitExpr(c.GetRhs(), push) - if err != nil { - return 0, nil, err - } - if rhsType != internal.TypeNumber { - return 0, nil, LogicError(c, fmt.Errorf( - "tried to do an arithmetic operation with incompatible left and right-hand side operand types: %s and %s", - lhsType, rhsType)) - } - if push { - switch c.GetOp().GetTokenType() { - case parser.NumScriptLexerOP_ADD: - p.AppendInstruction(program.OP_IADD) - case parser.NumScriptLexerOP_SUB: - p.AppendInstruction(program.OP_ISUB) - } - } - return internal.TypeNumber, nil, nil - case internal.TypeMonetary: - rhsType, _, err := p.VisitExpr(c.GetRhs(), push) - if err != nil { - return 0, nil, err - } - if rhsType != internal.TypeMonetary { - return 0, nil, LogicError(c, fmt.Errorf( - "tried to do an arithmetic operation with incompatible left and right-hand side operand types: %s and %s", - lhsType, rhsType)) - } - if push { - switch c.GetOp().GetTokenType() { - case parser.NumScriptLexerOP_ADD: - p.AppendInstruction(program.OP_MONETARY_ADD) - case parser.NumScriptLexerOP_SUB: - p.AppendInstruction(program.OP_MONETARY_SUB) - } - } - return internal.TypeMonetary, lhsAddr, nil - default: - return 0, nil, LogicError(c, fmt.Errorf( - "tried to do an arithmetic operation with unsupported left-hand side operand type: %s", - lhsType)) - } - case *parser.ExprLiteralContext: - return p.VisitLit(c.GetLit(), push) - case *parser.ExprVariableContext: - return p.VisitVariable(c.GetVar_(), push) - default: - return 0, nil, InternalError(c) - } -} - -func (p *parseVisitor) VisitLit(c parser.ILiteralContext, push bool) (internal.Type, *internal.Address, *CompileError) { - switch c := c.(type) { - case *parser.LitAccountContext: - account := internal.AccountAddress(c.GetText()[1:]) - addr, err := p.AllocateResource(program.Constant{Inner: account}) - if err != nil { - return 0, nil, LogicError(c, err) - } - if push { - p.PushAddress(*addr) - } - return internal.TypeAccount, addr, nil - case *parser.LitAssetContext: - asset := internal.Asset(c.GetText()) - addr, err := p.AllocateResource(program.Constant{Inner: asset}) - if err != nil { - return 0, nil, LogicError(c, err) - } - if push { - p.PushAddress(*addr) - } - return internal.TypeAsset, addr, nil - case *parser.LitNumberContext: - number, err := internal.ParseNumber(c.GetText()) - if err != nil { - return 0, nil, LogicError(c, err) - } - addr, err := p.AllocateResource(program.Constant{Inner: number}) - if err != nil { - return 0, nil, LogicError(c, err) - } - if push { - p.PushAddress(*addr) - } - return internal.TypeNumber, addr, nil - case *parser.LitStringContext: - addr, err := p.AllocateResource(program.Constant{ - Inner: internal.String(strings.Trim(c.GetText(), `"`)), - }) - if err != nil { - return 0, nil, LogicError(c, err) - } - if push { - p.PushAddress(*addr) - } - return internal.TypeString, addr, nil - case *parser.LitPortionContext: - portion, err := internal.ParsePortionSpecific(c.GetText()) - if err != nil { - return 0, nil, LogicError(c, err) - } - addr, err := p.AllocateResource(program.Constant{Inner: *portion}) - if err != nil { - return 0, nil, LogicError(c, err) - } - if push { - p.PushAddress(*addr) - } - return internal.TypePortion, addr, nil - case *parser.LitMonetaryContext: - typ, assetAddr, compErr := p.VisitExpr(c.Monetary().GetAsset(), false) - if compErr != nil { - return 0, nil, compErr - } - if typ != internal.TypeAsset { - return 0, nil, LogicError(c, fmt.Errorf( - "the expression in monetary literal should be of type '%s' instead of '%s'", - internal.TypeAsset, typ)) - } - - amt, err := internal.ParseMonetaryInt(c.Monetary().GetAmt().GetText()) - if err != nil { - return 0, nil, LogicError(c, err) - } - - var ( - monAddr *internal.Address - alreadyAllocated bool - ) - for i, r := range p.resources { - switch v := r.(type) { - case program.Monetary: - if v.Asset == *assetAddr && v.Amount.Equal(amt) { - alreadyAllocated = true - tmp := internal.Address(uint16(i)) - monAddr = &tmp - break - } - } - } - if !alreadyAllocated { - monAddr, err = p.AllocateResource(program.Monetary{ - Asset: *assetAddr, - Amount: amt, - }) - if err != nil { - return 0, nil, LogicError(c, err) - } - } - if push { - p.PushAddress(*monAddr) - } - return internal.TypeMonetary, monAddr, nil - default: - return 0, nil, InternalError(c) - } -} - -func (p *parseVisitor) VisitMonetaryAll(c *parser.SendContext, monAll parser.IMonetaryAllContext) *CompileError { - assetType, assetAddr, compErr := p.VisitExpr(monAll.GetAsset(), false) - if compErr != nil { - return compErr - } - if assetType != internal.TypeAsset { - return LogicError(c, fmt.Errorf( - "send monetary all: the expression should be of type 'asset' instead of '%s'", assetType)) - } - - switch c := c.GetSrc().(type) { - case *parser.SrcContext: - accounts, _, _, compErr := p.VisitSource(c.Source(), func() { - p.PushAddress(*assetAddr) - }, true) - if compErr != nil { - return compErr - } - p.setNeededBalances(accounts, assetAddr) - - case *parser.SrcAllotmentContext: - return LogicError(c, errors.New("cannot take all balance of an allotment source")) - } - return nil -} - -func (p *parseVisitor) VisitMonetary(c *parser.SendContext, mon parser.IExpressionContext) *CompileError { - monType, monAddr, compErr := p.VisitExpr(mon, false) - if compErr != nil { - return compErr - } - if monType != internal.TypeMonetary { - return LogicError(c, fmt.Errorf( - "send monetary: the expression should be of type 'monetary' instead of '%s'", monType)) - } - - switch c := c.GetSrc().(type) { - case *parser.SrcContext: - accounts, _, fallback, compErr := p.VisitSource(c.Source(), func() { - p.PushAddress(*monAddr) - p.AppendInstruction(program.OP_ASSET) - }, false) - if compErr != nil { - return compErr - } - p.setNeededBalances(accounts, monAddr) - - if _, _, err := p.VisitExpr(mon, true); err != nil { - return err - } - - if err := p.TakeFromSource(fallback); err != nil { - return LogicError(c, err) - } - case *parser.SrcAllotmentContext: - if _, _, err := p.VisitExpr(mon, true); err != nil { - return err - } - p.VisitAllotment(c.SourceAllotment(), c.SourceAllotment().GetPortions()) - p.AppendInstruction(program.OP_ALLOC) - - sources := c.SourceAllotment().GetSources() - n := len(sources) - for i := 0; i < n; i++ { - accounts, _, fallback, compErr := p.VisitSource(sources[i], func() { - p.PushAddress(*monAddr) - p.AppendInstruction(program.OP_ASSET) - }, false) - if compErr != nil { - return compErr - } - p.setNeededBalances(accounts, monAddr) - - if err := p.Bump(int64(i + 1)); err != nil { - return LogicError(c, err) - } - - if err := p.TakeFromSource(fallback); err != nil { - return LogicError(c, err) - } - } - - if err := p.PushInteger(internal.NewNumber(int64(n))); err != nil { - return LogicError(c, err) - } - - p.AppendInstruction(program.OP_FUNDING_ASSEMBLE) - } - return nil -} - -func (p *parseVisitor) setNeededBalances(accounts map[internal.Address]struct{}, addr *internal.Address) { - for acc := range accounts { - if b, ok := p.neededBalances[acc]; ok { - b[*addr] = struct{}{} - } else { - p.neededBalances[acc] = map[internal.Address]struct{}{ - *addr: {}, - } - } - } -} - -func (p *parseVisitor) VisitSend(c *parser.SendContext) *CompileError { - if monAll := c.GetMonAll(); monAll != nil { - if err := p.VisitMonetaryAll(c, monAll); err != nil { - return err - } - } else if mon := c.GetMon(); mon != nil { - if err := p.VisitMonetary(c, mon); err != nil { - return err - } - } - - if err := p.VisitDestination(c.GetDest()); err != nil { - return err - } - - return nil -} - -func (p *parseVisitor) VisitSetTxMeta(ctx *parser.SetTxMetaContext) *CompileError { - _, _, compErr := p.VisitExpr(ctx.GetValue(), true) - if compErr != nil { - return compErr - } - - keyAddr, err := p.AllocateResource(program.Constant{ - Inner: internal.String(strings.Trim(ctx.GetKey().GetText(), `"`)), - }) - if err != nil { - return LogicError(ctx, err) - } - p.PushAddress(*keyAddr) - - p.AppendInstruction(program.OP_TX_META) - - return nil -} - -func (p *parseVisitor) VisitSetAccountMeta(ctx *parser.SetAccountMetaContext) *CompileError { - _, _, compErr := p.VisitExpr(ctx.GetValue(), true) - if compErr != nil { - return compErr - } - - keyAddr, err := p.AllocateResource(program.Constant{ - Inner: internal.String(strings.Trim(ctx.GetKey().GetText(), `"`)), - }) - if err != nil { - return LogicError(ctx, err) - } - p.PushAddress(*keyAddr) - - ty, accAddr, compErr := p.VisitExpr(ctx.GetAcc(), false) - if compErr != nil { - return compErr - } - if ty != internal.TypeAccount { - return LogicError(ctx, fmt.Errorf( - "set_account_meta: expression is of type %s, and should be of type account", ty)) - } - p.PushAddress(*accAddr) - - p.AppendInstruction(program.OP_ACCOUNT_META) - - return nil -} - -func (p *parseVisitor) VisitSaveFromAccount(c *parser.SaveFromAccountContext) *CompileError { - var ( - typ internal.Type - addr *internal.Address - compErr *CompileError - ) - if monAll := c.GetMonAll(); monAll != nil { - typ, addr, compErr = p.VisitExpr(monAll.GetAsset(), false) - if compErr != nil { - return compErr - } - if typ != internal.TypeAsset { - return LogicError(c, fmt.Errorf( - "save monetary all from account: the first expression should be of type 'asset' instead of '%s'", typ)) - } - } else if mon := c.GetMon(); mon != nil { - typ, addr, compErr = p.VisitExpr(mon, false) - if compErr != nil { - return compErr - } - if typ != internal.TypeMonetary { - return LogicError(c, fmt.Errorf( - "save monetary from account: the first expression should be of type 'monetary' instead of '%s'", typ)) - } - } - p.PushAddress(*addr) - - typ, addr, compErr = p.VisitExpr(c.GetAcc(), false) - if compErr != nil { - return compErr - } - if typ != internal.TypeAccount { - return LogicError(c, fmt.Errorf( - "save monetary from account: the second expression should be of type 'account' instead of '%s'", typ)) - } - p.PushAddress(*addr) - - p.AppendInstruction(program.OP_SAVE) - - return nil -} - -func (p *parseVisitor) VisitPrint(ctx *parser.PrintContext) *CompileError { - _, _, err := p.VisitExpr(ctx.GetExpr(), true) - if err != nil { - return err - } - - p.AppendInstruction(program.OP_PRINT) - - return nil -} - -func (p *parseVisitor) VisitVars(c *parser.VarListDeclContext) *CompileError { - if len(c.GetV()) > 32768 { - return LogicError(c, fmt.Errorf("number of variables exceeded %v", 32768)) - } - - for _, v := range c.GetV() { - name := v.GetName().GetText()[1:] - if _, ok := p.varIdx[name]; ok { - return LogicError(c, fmt.Errorf("duplicate variable $%s", name)) - } - var ty internal.Type - switch v.GetTy().GetText() { - case "account": - ty = internal.TypeAccount - case "asset": - ty = internal.TypeAsset - case "number": - ty = internal.TypeNumber - case "string": - ty = internal.TypeString - case "monetary": - ty = internal.TypeMonetary - case "portion": - ty = internal.TypePortion - default: - return InternalError(c) - } - - var addr *internal.Address - var err error - if v.GetOrig() == nil { - addr, err = p.AllocateResource(program.Variable{Typ: ty, Name: name}) - if err != nil { - return &CompileError{ - Msg: errors.Wrap(err, - "allocating variable resource").Error(), - } - } - p.varIdx[name] = *addr - continue - } - - switch c := v.GetOrig().(type) { - case *parser.OriginAccountMetaContext: - srcTy, src, compErr := p.VisitExpr(c.GetAccount(), false) - if compErr != nil { - return compErr - } - if srcTy != internal.TypeAccount { - return LogicError(c, fmt.Errorf( - "variable $%s: type should be 'account' to pull account metadata", name)) - } - key := strings.Trim(c.GetKey().GetText(), `"`) - addr, err = p.AllocateResource(program.VariableAccountMetadata{ - Typ: ty, - Name: name, - Account: *src, - Key: key, - }) - case *parser.OriginAccountBalanceContext: - if ty != internal.TypeMonetary { - return LogicError(c, fmt.Errorf( - "variable $%s: type should be 'monetary' to pull account balance", name)) - } - accTy, accAddr, compErr := p.VisitExpr(c.GetAccount(), false) - if compErr != nil { - return compErr - } - if accTy != internal.TypeAccount { - return LogicError(c, fmt.Errorf( - "variable $%s: the first argument to pull account balance should be of type 'account'", name)) - } - - assTy, assAddr, compErr := p.VisitExpr(c.GetAsset(), false) - if compErr != nil { - return compErr - } - if assTy != internal.TypeAsset { - return LogicError(c, fmt.Errorf( - "variable $%s: the second argument to pull account balance should be of type 'asset'", name)) - } - - addr, err = p.AllocateResource(program.VariableAccountBalance{ - Name: name, - Account: *accAddr, - Asset: *assAddr, - }) - if err != nil { - return LogicError(c, err) - } - } - if err != nil { - return LogicError(c, err) - } - - p.varIdx[name] = *addr - } - - return nil -} - -func (p *parseVisitor) VisitScript(c parser.IScriptContext) *CompileError { - switch c := c.(type) { - case *parser.ScriptContext: - vars := c.GetVars() - if vars != nil { - switch c := vars.(type) { - case *parser.VarListDeclContext: - if err := p.VisitVars(c); err != nil { - return err - } - default: - return InternalError(c) - } - } - - for _, stmt := range c.GetStmts() { - var err *CompileError - switch c := stmt.(type) { - case *parser.PrintContext: - err = p.VisitPrint(c) - case *parser.FailContext: - p.AppendInstruction(program.OP_FAIL) - case *parser.SendContext: - err = p.VisitSend(c) - case *parser.SetTxMetaContext: - err = p.VisitSetTxMeta(c) - case *parser.SetAccountMetaContext: - err = p.VisitSetAccountMeta(c) - case *parser.SaveFromAccountContext: - err = p.VisitSaveFromAccount(c) - default: - return InternalError(c) - } - if err != nil { - return err - } - } - default: - return InternalError(c) - } - - return nil -} - -type CompileArtifacts struct { - Source string - Tokens []antlr.Token - Errors []CompileError - Program *program.Program -} - -func CompileFull(input string) CompileArtifacts { - artifacts := CompileArtifacts{ - Source: input, - } - - errListener := &ErrorListener{} - - is := antlr.NewInputStream(input) - lexer := parser.NewNumScriptLexer(is) - lexer.RemoveErrorListeners() - lexer.AddErrorListener(errListener) - - stream := antlr.NewCommonTokenStream(lexer, antlr.LexerDefaultTokenChannel) - p := parser.NewNumScriptParser(stream) - p.RemoveErrorListeners() - p.AddErrorListener(errListener) - - p.BuildParseTrees = true - - tree := p.Script() - - artifacts.Tokens = stream.GetAllTokens() - artifacts.Errors = append(artifacts.Errors, errListener.Errors...) - - if len(errListener.Errors) != 0 { - return artifacts - } - - visitor := parseVisitor{ - errListener: errListener, - instructions: make([]byte, 0), - resources: make([]program.Resource, 0), - varIdx: make(map[string]internal.Address), - neededBalances: make(map[internal.Address]map[internal.Address]struct{}), - sources: map[internal.Address]struct{}{}, - } - - err := visitor.VisitScript(tree) - if err != nil { - artifacts.Errors = append(artifacts.Errors, *err) - return artifacts - } - - sources := make(internal.Addresses, 0) - for address := range visitor.sources { - sources = append(sources, address) - } - sort.Stable(sources) - - artifacts.Program = &program.Program{ - Instructions: visitor.instructions, - Resources: visitor.resources, - NeededBalances: visitor.neededBalances, - Sources: sources, - } - - return artifacts -} - -func Compile(input string) (*program.Program, error) { - artifacts := CompileFull(input) - if len(artifacts.Errors) > 0 { - err := CompileErrorList{ - Errors: artifacts.Errors, - Source: artifacts.Source, - } - return nil, &err - } - - return artifacts.Program, nil -} diff --git a/components/ledger/pkg/machine/script/compiler/compiler_test.go b/components/ledger/pkg/machine/script/compiler/compiler_test.go deleted file mode 100644 index 57a7224d7..000000000 --- a/components/ledger/pkg/machine/script/compiler/compiler_test.go +++ /dev/null @@ -1,1711 +0,0 @@ -package compiler - -import ( - "bytes" - "fmt" - "math/big" - "reflect" - "testing" - - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/formancehq/ledger/pkg/machine/vm/program" - "github.com/stretchr/testify/require" -) - -type TestCase struct { - Case string - Expected CaseResult -} - -type CaseResult struct { - Instructions []byte - Resources []program.Resource - Variables []string - Error string -} - -func test(t *testing.T, c TestCase) { - p, err := Compile(c.Case) - if c.Expected.Error != "" { - require.Error(t, err) - require.NotEmpty(t, err.Error()) - require.ErrorContains(t, err, c.Expected.Error) - return - } - require.NoError(t, err) - require.NotNil(t, p) - - if len(c.Expected.Instructions) > 0 && !bytes.Equal(p.Instructions, c.Expected.Instructions) { - t.Error(fmt.Errorf( - "unexpected instructions:\n%v\nhas: %+v\nwant:%+v", - *p, p.Instructions, c.Expected.Instructions)) - return - } else if len(p.Resources) != len(c.Expected.Resources) { - t.Error(fmt.Errorf( - "unexpected resources\n%v\nhas: \n%+v\nwant:\n%+v", - *p, p.Resources, c.Expected.Resources)) - return - } - - for i, expected := range c.Expected.Resources { - if !checkResourcesEqual(p.Resources[i], c.Expected.Resources[i]) { - t.Error(fmt.Errorf("%v: %v is not %v: %v", - p.Resources[i], reflect.TypeOf(p.Resources[i]).Name(), - expected, reflect.TypeOf(expected).Name(), - )) - t.Error(fmt.Errorf( - "unexpected resources\n%v\nhas: \n%+v\nwant:\n%+v", - *p, p.Resources, c.Expected.Resources)) - return - } - } -} - -func checkResourcesEqual(actual, expected program.Resource) bool { - if reflect.TypeOf(actual) != reflect.TypeOf(expected) { - return false - } - switch res := actual.(type) { - case program.Constant: - return internal.ValueEquals(res.Inner, expected.(program.Constant).Inner) - case program.Variable: - e := expected.(program.Variable) - return res.Typ == e.Typ && res.Name == e.Name - case program.VariableAccountMetadata: - e := expected.(program.VariableAccountMetadata) - return res.Account == e.Account && - res.Key == e.Key && - res.Typ == e.Typ - case program.VariableAccountBalance: - e := expected.(program.VariableAccountBalance) - return res.Account == e.Account && - res.Asset == e.Asset - case program.Monetary: - e := expected.(program.Monetary) - return res.Amount.Equal(e.Amount) && res.Asset == e.Asset - default: - panic(fmt.Errorf("invalid resource of type '%T'", res)) - } -} - -func TestSimplePrint(t *testing.T) { - test(t, TestCase{ - Case: "print 1", - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_PRINT, - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.NewMonetaryInt(1)}, - }, - }, - }) -} - -func TestCompositeExpr(t *testing.T) { - test(t, TestCase{ - Case: "print 29 + 15 - 2", - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_APUSH, 01, 00, - program.OP_IADD, - program.OP_APUSH, 02, 00, - program.OP_ISUB, - program.OP_PRINT, - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.NewMonetaryInt(29)}, - program.Constant{Inner: internal.NewMonetaryInt(15)}, - program.Constant{Inner: internal.NewMonetaryInt(2)}, - }, - }, - }) -} - -func TestFail(t *testing.T) { - test(t, TestCase{ - Case: "fail", - Expected: CaseResult{ - Instructions: []byte{program.OP_FAIL}, - Resources: []program.Resource{}, - }, - }) -} - -func TestCRLF(t *testing.T) { - test(t, TestCase{ - Case: "print @a\r\nprint @b", - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_PRINT, - program.OP_APUSH, 01, 00, - program.OP_PRINT, - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.AccountAddress("a")}, - program.Constant{Inner: internal.AccountAddress("b")}, - }, - }, - }) -} - -func TestConstant(t *testing.T) { - user := internal.AccountAddress("user:U001") - test(t, TestCase{ - Case: "print @user:U001", - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_PRINT, - }, - Resources: []program.Resource{program.Constant{Inner: user}}, - }, - }) -} - -func TestSetTxMeta(t *testing.T) { - test(t, TestCase{ - Case: ` - set_tx_meta("aaa", @platform) - set_tx_meta("bbb", GEM) - set_tx_meta("ccc", 42) - set_tx_meta("ddd", "test") - set_tx_meta("eee", [COIN 30]) - set_tx_meta("fff", 15%) - `, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_APUSH, 01, 00, - program.OP_TX_META, - program.OP_APUSH, 02, 00, - program.OP_APUSH, 03, 00, - program.OP_TX_META, - program.OP_APUSH, 04, 00, - program.OP_APUSH, 05, 00, - program.OP_TX_META, - program.OP_APUSH, 06, 00, - program.OP_APUSH, 07, 00, - program.OP_TX_META, - program.OP_APUSH, 9, 00, - program.OP_APUSH, 10, 00, - program.OP_TX_META, - program.OP_APUSH, 11, 00, - program.OP_APUSH, 12, 00, - program.OP_TX_META, - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.AccountAddress("platform")}, - program.Constant{Inner: internal.String("aaa")}, - program.Constant{Inner: internal.Asset("GEM")}, - program.Constant{Inner: internal.String("bbb")}, - program.Constant{Inner: internal.NewNumber(42)}, - program.Constant{Inner: internal.String("ccc")}, - program.Constant{Inner: internal.String("test")}, - program.Constant{Inner: internal.String("ddd")}, - program.Constant{Inner: internal.Asset("COIN")}, - program.Monetary{Asset: 8, Amount: internal.NewMonetaryInt(30)}, - program.Constant{Inner: internal.String("eee")}, - program.Constant{Inner: internal.Portion{ - Remaining: false, - Specific: big.NewRat(15, 100), - }}, - program.Constant{Inner: internal.String("fff")}, - }, - }, - }) -} - -func TestSetTxMetaVars(t *testing.T) { - test(t, TestCase{ - Case: ` - vars { - portion $commission - } - set_tx_meta("fee", $commission) - `, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_APUSH, 01, 00, - program.OP_TX_META, - }, - Resources: []program.Resource{ - program.Variable{Typ: internal.TypePortion, Name: "commission"}, - program.Constant{Inner: internal.String("fee")}, - }, - }, - }) -} - -func TestComments(t *testing.T) { - test(t, TestCase{ - Case: ` - /* This is a multi-line comment, it spans multiple lines - and /* doesn't choke on nested comments */ ! */ - vars { - account $a - } - // this is a single-line comment - print $a - `, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_PRINT, - }, - Resources: []program.Resource{ - program.Variable{Typ: internal.TypeAccount, Name: "a"}, - }, - }, - }) -} - -func TestUndeclaredVariable(t *testing.T) { - test(t, TestCase{ - Case: "print $nope", - Expected: CaseResult{ - Error: "declared", - }, - }) -} - -func TestInvalidTypeInSendValue(t *testing.T) { - test(t, TestCase{ - Case: ` - send @a ( - source = { - @a - [GEM 2] - } - destination = @b - )`, - Expected: CaseResult{ - Error: "send monetary: the expression should be of type 'monetary' instead of 'account'", - }, - }) -} - -func TestInvalidTypeInSource(t *testing.T) { - test(t, TestCase{ - Case: ` - send [USD/2 99] ( - source = { - @a - [GEM 2] - } - destination = @b - )`, - Expected: CaseResult{ - Error: "wrong type", - }, - }) -} - -func TestDestinationAllotment(t *testing.T) { - test(t, TestCase{ - Case: `send [EUR/2 43] ( - source = @foo - destination = { - 1/8 to @bar - 7/8 to @baz - } - )`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 02, 00, // @foo - program.OP_APUSH, 01, 00, // @foo, [EUR/2 43] - program.OP_ASSET, // @foo, EUR/2 - program.OP_APUSH, 03, 00, // @foo, EUR/2, 0 - program.OP_MONETARY_NEW, // @foo, [EUR/2 0] - program.OP_TAKE_ALL, // [EUR/2 @foo ] - program.OP_APUSH, 01, 00, // [EUR/2 @foo ], [EUR/2 43] - program.OP_TAKE, // [EUR/2 @foo ], [EUR/2 @foo 43] - program.OP_APUSH, 04, 00, // [EUR/2 @foo ], [EUR/2 @foo 43] 1 - program.OP_BUMP, // [EUR/2 @foo 43], [EUR/2 @foo ] - program.OP_REPAY, // [EUR/2 @foo 43] - program.OP_FUNDING_SUM, // [EUR/2 @foo 43], [EUR/2 43] - program.OP_APUSH, 05, 00, // [EUR/2 @foo 43], [EUR/2 43], 7/8 - program.OP_APUSH, 06, 00, // [EUR/2 @foo 43], [EUR/2 43], 7/8, 1/8 - program.OP_APUSH, 07, 00, // [EUR/2 @foo 43], [EUR/2 43], 7/8, 1/8, 2 - program.OP_MAKE_ALLOTMENT, // [EUR/2 @foo 43], [EUR/2 43], {1/8 : 7/8} - program.OP_ALLOC, // [EUR/2 @foo 43], [EUR/2 37], [EUR/2 6] - program.OP_APUSH, 07, 00, // [EUR/2 @foo 43], [EUR/2 37] [EUR/2 6], 2 - program.OP_BUMP, // [EUR/2 37], [EUR/2 6], [EUR/2 @foo 43] - program.OP_APUSH, 04, 00, // [EUR/2 37], [EUR/2 6], [EUR/2 @foo 43] 1 - program.OP_BUMP, // [EUR/2 37], [EUR/2 @foo 43], [EUR/2 6] - program.OP_TAKE, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2 @foo 6] - program.OP_FUNDING_SUM, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2 @foo 6] [EUR/2 6] - program.OP_TAKE, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2] [EUR/2 @foo 6] - program.OP_APUSH, 8, 00, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2] [EUR/2 @foo 6], @bar - program.OP_SEND, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2] - program.OP_APUSH, 04, 00, // [EUR/2 37], [EUR/2 @foo 37], [EUR/2] 1 - program.OP_BUMP, // [EUR/2 37], [EUR/2], [EUR/2 @foo 37] - program.OP_APUSH, 07, 00, // [EUR/2 37], [EUR/2], [EUR/2 @foo 37] 2 - program.OP_FUNDING_ASSEMBLE, // [EUR/2 37], [EUR/2 @foo 37] - program.OP_APUSH, 04, 00, // [EUR/2 37], [EUR/2 @foo 37], 1 - program.OP_BUMP, // [EUR/2 @foo 37], [EUR/2 37] - program.OP_TAKE, // [EUR/2], [EUR/2 @foo 37] - program.OP_FUNDING_SUM, // [EUR/2], [EUR/2 @foo 37], [EUR/2 37] - program.OP_TAKE, // [EUR/2], [EUR/2], [EUR/2 @foo 37] - program.OP_APUSH, 9, 00, // [EUR/2], [EUR/2], [EUR/2 @foo 37], @baz - program.OP_SEND, // [EUR/2], [EUR/2] - program.OP_APUSH, 04, 00, // [EUR/2], [EUR/2], 1 - program.OP_BUMP, // [EUR/2], [EUR/2] - program.OP_APUSH, 07, 00, // [EUR/2], [EUR/2], 2 - program.OP_FUNDING_ASSEMBLE, // [EUR/2] - program.OP_REPAY, // - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.Asset("EUR/2")}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(43), - }, - program.Constant{Inner: internal.AccountAddress("foo")}, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.Portion{Specific: big.NewRat(7, 8)}}, - program.Constant{Inner: internal.Portion{Specific: big.NewRat(1, 8)}}, - program.Constant{Inner: internal.NewMonetaryInt(2)}, - program.Constant{Inner: internal.AccountAddress("bar")}, - program.Constant{Inner: internal.AccountAddress("baz")}, - }, - }, - }) -} - -func TestDestinationInOrder(t *testing.T) { - test(t, TestCase{ - Case: `send [COIN 50] ( - source = @a - destination = { - max [COIN 10] to @b - remaining to @c - } - )`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 02, 00, // @a - program.OP_APUSH, 01, 00, // @a, [COIN 50] - program.OP_ASSET, // @a, COIN - program.OP_APUSH, 03, 00, // @a, COIN, 0 - program.OP_MONETARY_NEW, // @a, [COIN 0] - program.OP_TAKE_ALL, // [COIN @a ] - program.OP_APUSH, 01, 00, // [COIN @a ], [COIN 50] - program.OP_TAKE, // [COIN @a ], [COIN @a 50] - program.OP_APUSH, 04, 00, // [COIN @a ], [COIN @a 50], 1 - program.OP_BUMP, // [COIN @a 50], [COIN @a ] - program.OP_REPAY, // [COIN @a 50] - program.OP_FUNDING_SUM, // [COIN @a 50], [COIN 50] <- start of DestinationInOrder - program.OP_ASSET, // [COIN @a 50], COIN - program.OP_APUSH, 03, 00, // [COIN @a 50], COIN, 0 - program.OP_MONETARY_NEW, // [COIN @a 50], [COIN 0] - program.OP_APUSH, 04, 00, // [COIN @a 50], [COIN 0], 1 - program.OP_BUMP, // [COIN 0], [COIN @a 50] - program.OP_APUSH, 05, 00, // [COIN 0], [COIN @a 50], [COIN 10] <- start processing max subdestinations - program.OP_TAKE_MAX, // [COIN 0], [COIN 0], [COIN @a 40], [COIN @a 10] - program.OP_APUSH, 06, 00, // [COIN 0], [COIN 0], [COIN @a 40], [COIN @a 10], 2 - program.OP_BUMP, // [COIN 0], [COIN @a 40], [COIN @a 10], [COIN 0] - program.OP_DELETE, // [COIN 0], [COIN @a 40], [COIN @a 10] - program.OP_FUNDING_SUM, // [COIN 0], [COIN @a 40], [COIN @a 10], [COIN 10] - program.OP_TAKE, // [COIN 0], [COIN @a 40], [COIN], [COIN @a 10] - program.OP_APUSH, 07, 00, // [COIN 0], [COIN @a 40], [COIN], [COIN @a 10], @b - program.OP_SEND, // [COIN 0], [COIN @a 40], [COIN] - program.OP_FUNDING_SUM, // [COIN 0], [COIN @a 40], [COIN], [COIN 0] - program.OP_APUSH, 8, 00, // [COIN 0], [COIN @a 40], [COIN], [COIN 0], 3 - program.OP_BUMP, // [COIN @a 40], [COIN], [COIN 0], [COIN 0] - program.OP_MONETARY_ADD, // [COIN @a 40], [COIN], [COIN 0] - program.OP_APUSH, 04, 00, // [COIN @a 40], [COIN], [COIN 0], 1 - program.OP_BUMP, // [COIN @a 40], [COIN 0], [COIN] - program.OP_APUSH, 06, 00, // [COIN @a 40], [COIN 0], [COIN] 2 - program.OP_BUMP, // [COIN 0], [COIN], [COIN @a 40] - program.OP_APUSH, 06, 00, // [COIN 0], [COIN], [COIN @a 40], 2 - program.OP_FUNDING_ASSEMBLE, // [COIN 0], [COIN @a 40] - program.OP_FUNDING_REVERSE, // [COIN 0], [COIN @a 40] <- start processing remaining subdestination - program.OP_APUSH, 04, 00, // [COIN 0], [COIN @a 40], 1 - program.OP_BUMP, // [COIN @a 40], [COIN 0] - program.OP_TAKE, // [COIN @a 40], [COIN] - program.OP_FUNDING_REVERSE, // [COIN @a 40], [COIN] - program.OP_APUSH, 04, 00, // [COIN @a 40], [COIN], 1 - program.OP_BUMP, // [COIN], [COIN @a 40] - program.OP_FUNDING_REVERSE, // [COIN], [COIN @a 40] - program.OP_FUNDING_SUM, // [COIN], [COIN @a 40], [COIN 40] - program.OP_TAKE, // [COIN], [COIN], [COIN @a 40] - program.OP_APUSH, 9, 00, // [COIN], [COIN], [COIN @a 40], @c - program.OP_SEND, // [COIN], [COIN] - program.OP_APUSH, 04, 00, // [COIN], [COIN], 1 - program.OP_BUMP, // [COIN], [COIN] - program.OP_APUSH, 06, 00, // [COIN], [COIN], 2 - program.OP_FUNDING_ASSEMBLE, // [COIN] - program.OP_REPAY, // - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.Asset("COIN")}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(50), - }, - program.Constant{Inner: internal.AccountAddress("a")}, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(10), - }, - program.Constant{Inner: internal.NewMonetaryInt(2)}, - program.Constant{Inner: internal.AccountAddress("b")}, - program.Constant{Inner: internal.NewMonetaryInt(3)}, - program.Constant{Inner: internal.AccountAddress("c")}, - }, - }, - }) -} - -func TestAllocationPercentages(t *testing.T) { - test(t, TestCase{ - Case: `send [EUR/2 43] ( - source = @foo - destination = { - 12.5% to @bar - 37.5% to @baz - 50% to @qux - } - )`, - Expected: CaseResult{ - Resources: []program.Resource{ - program.Constant{Inner: internal.Asset("EUR/2")}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(43), - }, - program.Constant{Inner: internal.AccountAddress("foo")}, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.Portion{Specific: big.NewRat(1, 2)}}, - program.Constant{Inner: internal.Portion{Specific: big.NewRat(3, 8)}}, - program.Constant{Inner: internal.Portion{Specific: big.NewRat(1, 8)}}, - program.Constant{Inner: internal.NewMonetaryInt(3)}, - program.Constant{Inner: internal.AccountAddress("bar")}, - program.Constant{Inner: internal.NewMonetaryInt(2)}, - program.Constant{Inner: internal.AccountAddress("baz")}, - program.Constant{Inner: internal.AccountAddress("qux")}, - }, - }, - }) -} - -func TestSend(t *testing.T) { - script := ` - send [EUR/2 99] ( - source = @alice - destination = @bob - )` - alice := internal.AccountAddress("alice") - bob := internal.AccountAddress("bob") - test(t, TestCase{ - Case: script, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 02, 00, // @alice - program.OP_APUSH, 01, 00, // @alice, [EUR/2 99] - program.OP_ASSET, // @alice, EUR/2 - program.OP_APUSH, 03, 00, // @alice, EUR/2, 0 - program.OP_MONETARY_NEW, // @alice, [EUR/2 0] - program.OP_TAKE_ALL, // [EUR/2 @alice ] - program.OP_APUSH, 01, 00, // [EUR/2 @alice ], [EUR/2 99] - program.OP_TAKE, // [EUR/2 @alice ], [EUR/2 @alice 99] - program.OP_APUSH, 04, 00, // [EUR/2 @alice ], [EUR/2 @alice 99], 1 - program.OP_BUMP, // [EUR/2 @alice 99], [EUR/2 @alice ] - program.OP_REPAY, // [EUR/2 @alice 99] - program.OP_FUNDING_SUM, // [EUR/2 @alice 99], [EUR/2 99] - program.OP_TAKE, // [EUR/2], [EUR/2 @alice 99] - program.OP_APUSH, 05, 00, // [EUR/2], [EUR/2 @alice 99], @bob - program.OP_SEND, // [EUR/2] - program.OP_REPAY, // - }, Resources: []program.Resource{ - program.Constant{Inner: internal.Asset("EUR/2")}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(99), - }, - program.Constant{Inner: alice}, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: bob}}, - }, - }) -} - -func TestSendAll(t *testing.T) { - test(t, TestCase{ - Case: `send [EUR/2 *] ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 01, 00, // @alice - program.OP_APUSH, 00, 00, // @alice, EUR/2 - program.OP_APUSH, 02, 00, // @alice, EUR/2, 0 - program.OP_MONETARY_NEW, // @alice, [EUR/2 0] - program.OP_TAKE_ALL, // [EUR/2 @alice ] - program.OP_FUNDING_SUM, // [EUR/2 @alice ], [EUR/2 ] - program.OP_TAKE, // [EUR/2], [EUR/2 @alice ] - program.OP_APUSH, 03, 00, // [EUR/2], [EUR/2 @alice ], @b - program.OP_SEND, // [EUR/2] - program.OP_REPAY, // - }, Resources: []program.Resource{ - program.Constant{Inner: internal.Asset("EUR/2")}, - program.Constant{Inner: internal.AccountAddress("alice")}, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.AccountAddress("bob")}}, - }, - }) -} - -func TestMetadata(t *testing.T) { - test(t, TestCase{ - Case: ` - vars { - account $sale - account $seller = meta($sale, "seller") - portion $commission = meta($seller, "commission") - } - send [EUR/2 53] ( - source = $sale - destination = { - $commission to @platform - remaining to $seller - } - )`, - Expected: CaseResult{ - Resources: []program.Resource{ - program.Variable{Typ: internal.TypeAccount, Name: "sale"}, - program.VariableAccountMetadata{ - Typ: internal.TypeAccount, - Account: internal.NewAddress(0), - Key: "seller", - }, - program.VariableAccountMetadata{ - Typ: internal.TypePortion, - Account: internal.NewAddress(1), - Key: "commission", - }, - program.Constant{Inner: internal.Asset("EUR/2")}, - program.Monetary{ - Asset: 3, - Amount: internal.NewMonetaryInt(53), - }, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.NewPortionRemaining()}, - program.Constant{Inner: internal.NewMonetaryInt(2)}, - program.Constant{Inner: internal.AccountAddress("platform")}, - }, - }, - }) -} - -func TestSyntaxError(t *testing.T) { - test(t, TestCase{ - Case: "print fail", - Expected: CaseResult{ - Error: "mismatched input", - }, - }) -} - -func TestLogicError(t *testing.T) { - test(t, TestCase{ - Case: `send [EUR/2 200] ( - source = 200 - destination = @bob - )`, - Expected: CaseResult{ - Error: "expected", - }, - }) -} - -func TestPreventTakeAllFromWorld(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM *] ( - source = @world - destination = @foo - )`, - Expected: CaseResult{ - Error: "cannot", - }, - }) -} - -func TestPreventAddToBottomlessSource(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 1000] ( - source = { - @a - @world - @c - } - destination = @out - )`, - Expected: CaseResult{ - Error: "world", - }, - }) -} - -func TestPreventAddToBottomlessSource2(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 1000] ( - source = { - { - @a - @world - } - { - @b - @world - } - } - destination = @out - )`, - Expected: CaseResult{ - Error: "world", - }, - }) -} - -func TestPreventSourceAlreadyEmptied(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 1000] ( - source = { - { - @a - @b - } - @a - } - destination = @out - )`, - Expected: CaseResult{ - Error: "empt", - }, - }) -} - -func TestPreventTakeAllFromAllocation(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM *] ( - source = { - 50% from @a - 50% from @b - } - destination = @out - )`, - Expected: CaseResult{ - Error: "all", - }, - }) -} - -func TestWrongTypeSourceMax(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 15] ( - source = { - max @foo from @bar - @world - } - destination = @baz - )`, - Expected: CaseResult{ - Error: "type", - }, - }) -} - -func TestOverflowingAllocation(t *testing.T) { - t.Run(">100%", func(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 15] ( - source = @world - destination = { - 2/3 to @a - 2/3 to @b - } - )`, - Expected: CaseResult{ - Error: "100%", - }, - }) - }) - - t.Run("=100% + remaining", func(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 15] ( - source = @world - destination = { - 1/2 to @a - 1/2 to @b - remaining to @c - } - )`, - Expected: CaseResult{ - Error: "100%", - }, - }) - }) - - t.Run(">100% + remaining", func(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 15] ( - source = @world - destination = { - 2/3 to @a - 1/2 to @b - remaining to @c - } - )`, - Expected: CaseResult{ - Error: "100%", - }, - }) - }) - - t.Run("const remaining + remaining", func(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 15] ( - source = @world - destination = { - 2/3 to @a - remaining to @b - remaining to @c - } - )`, - Expected: CaseResult{ - Error: "`remaining` in the same", - }, - }) - }) - - t.Run("dyn remaining + remaining", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - portion $p - } - send [GEM 15] ( - source = @world - destination = { - $p to @a - remaining to @b - remaining to @c - } - )`, - Expected: CaseResult{ - Error: "`remaining` in the same", - }, - }) - }) - - t.Run(">100% + remaining + variable", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - portion $prop - } - send [GEM 15] ( - source = @world - destination = { - 1/2 to @a - 2/3 to @b - remaining to @c - $prop to @d - } - )`, - Expected: CaseResult{ - Error: "100%", - }, - }) - }) - - t.Run("variable - remaining", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - portion $prop - } - send [GEM 15] ( - source = @world - destination = { - 2/3 to @a - $prop to @b - } - )`, - Expected: CaseResult{ - Error: "100%", - }, - }) - }) -} - -func TestAllocationWrongDestination(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 15] ( - source = @world - destination = [GEM 10] - )`, - Expected: CaseResult{ - Error: "account", - }, - }) - test(t, TestCase{ - Case: `send [GEM 15] ( - source = @world - destination = { - 2/3 to @a - 1/3 to [GEM 10] - } - )`, - Expected: CaseResult{ - Error: "account", - }, - }) -} - -func TestAllocationInvalidPortion(t *testing.T) { - test(t, TestCase{ - Case: `vars { - account $p - } - send [GEM 15] ( - source = @world - destination = { - 10% to @a - $p to @b - } - )`, - Expected: CaseResult{ - Error: "type", - }, - }) -} - -func TestOverdraftOnWorld(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 15] ( - source = @world allowing overdraft up to [GEM 10] - destination = @foo - )`, - Expected: CaseResult{ - Error: "overdraft", - }, - }) -} - -func TestOverdraftWrongType(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 15] ( - source = @foo allowing overdraft up to @baz - destination = @bar - )`, - Expected: CaseResult{ - Error: "type", - }, - }) -} - -func TestDestinationInOrderWrongType(t *testing.T) { - test(t, TestCase{ - Case: `send [GEM 15] ( - source = @foo - destination = { - max @bar to @baz - remaining to @qux - } - )`, - Expected: CaseResult{ - Error: "type", - }, - }) -} - -func TestSetAccountMeta(t *testing.T) { - t.Run("all types", func(t *testing.T) { - test(t, TestCase{ - Case: ` - set_account_meta(@alice, "aaa", @platform) - set_account_meta(@alice, "bbb", GEM) - set_account_meta(@alice, "ccc", 42) - set_account_meta(@alice, "ddd", "test") - set_account_meta(@alice, "eee", [COIN 30]) - set_account_meta(@alice, "fff", 15%) - `, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_APUSH, 01, 00, - program.OP_APUSH, 02, 00, - program.OP_ACCOUNT_META, - program.OP_APUSH, 03, 00, - program.OP_APUSH, 04, 00, - program.OP_APUSH, 02, 00, - program.OP_ACCOUNT_META, - program.OP_APUSH, 05, 00, - program.OP_APUSH, 06, 00, - program.OP_APUSH, 02, 00, - program.OP_ACCOUNT_META, - program.OP_APUSH, 7, 00, - program.OP_APUSH, 8, 00, - program.OP_APUSH, 02, 00, - program.OP_ACCOUNT_META, - program.OP_APUSH, 10, 00, - program.OP_APUSH, 11, 00, - program.OP_APUSH, 02, 00, - program.OP_ACCOUNT_META, - program.OP_APUSH, 12, 00, - program.OP_APUSH, 13, 00, - program.OP_APUSH, 02, 00, - program.OP_ACCOUNT_META, - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.AccountAddress("platform")}, - program.Constant{Inner: internal.String("aaa")}, - program.Constant{Inner: internal.AccountAddress("alice")}, - program.Constant{Inner: internal.Asset("GEM")}, - program.Constant{Inner: internal.String("bbb")}, - program.Constant{Inner: internal.NewNumber(42)}, - program.Constant{Inner: internal.String("ccc")}, - program.Constant{Inner: internal.String("test")}, - program.Constant{Inner: internal.String("ddd")}, - program.Constant{Inner: internal.Asset("COIN")}, - program.Monetary{ - Asset: 9, - Amount: internal.NewMonetaryInt(30), - }, - program.Constant{Inner: internal.String("eee")}, - program.Constant{Inner: internal.Portion{ - Remaining: false, - Specific: big.NewRat(15, 100), - }}, - program.Constant{Inner: internal.String("fff")}, - }, - }, - }) - }) - - t.Run("with vars", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - account $acc - } - send [EUR/2 100] ( - source = @world - destination = $acc - ) - set_account_meta($acc, "fees", 1%)`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 03, 00, - program.OP_APUSH, 02, 00, - program.OP_ASSET, - program.OP_APUSH, 04, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 02, 00, - program.OP_TAKE_MAX, - program.OP_APUSH, 05, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_APUSH, 03, 00, - program.OP_APUSH, 06, 00, - program.OP_BUMP, - program.OP_TAKE_ALWAYS, - program.OP_APUSH, 06, 00, - program.OP_FUNDING_ASSEMBLE, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 00, 00, - program.OP_SEND, - program.OP_REPAY, - program.OP_APUSH, 07, 00, - program.OP_APUSH, 8, 00, - program.OP_APUSH, 00, 00, - program.OP_ACCOUNT_META, - }, - Resources: []program.Resource{ - program.Variable{Typ: internal.TypeAccount, Name: "acc"}, - program.Constant{Inner: internal.Asset("EUR/2")}, - program.Monetary{ - Asset: 1, - Amount: internal.NewMonetaryInt(100), - }, - program.Constant{Inner: internal.AccountAddress("world")}, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.NewMonetaryInt(2)}, - program.Constant{Inner: internal.Portion{ - Remaining: false, - Specific: big.NewRat(1, 100), - }}, - program.Constant{Inner: internal.String("fees")}, - }, - }, - }) - }) - - t.Run("errors", func(t *testing.T) { - test(t, TestCase{ - Case: `set_account_meta(@alice, "fees")`, - Expected: CaseResult{ - Error: "mismatched input", - }, - }) - test(t, TestCase{ - Case: `set_account_meta("test")`, - Expected: CaseResult{ - Error: "mismatched input", - }, - }) - test(t, TestCase{ - Case: `set_account_meta(@alice, "t1", "t2", "t3")`, - Expected: CaseResult{ - Error: "mismatched input", - }, - }) - test(t, TestCase{ - Case: `vars { - portion $p - } - set_account_meta($p, "fees", 1%)`, - Expected: CaseResult{ - Error: "should be of type account", - }, - }) - }) -} - -func TestVariableBalance(t *testing.T) { - t.Run("simplest", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - monetary $bal = balance(@alice, COIN) - } - send $bal ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_APUSH, 02, 00, - program.OP_ASSET, - program.OP_APUSH, 03, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 02, 00, - program.OP_TAKE, - program.OP_APUSH, 04, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 05, 00, - program.OP_SEND, - program.OP_REPAY, - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.AccountAddress("alice")}, - program.Constant{Inner: internal.Asset("COIN")}, - program.VariableAccountBalance{Account: 0, Asset: 1}, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.AccountAddress("bob")}, - }, - }, - }) - }) - - t.Run("with account variable", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - account $acc - monetary $bal = balance($acc, COIN) - } - send $bal ( - source = @world - destination = @alice - )`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 03, 00, - program.OP_APUSH, 02, 00, - program.OP_ASSET, - program.OP_APUSH, 04, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 02, 00, - program.OP_TAKE_MAX, - program.OP_APUSH, 05, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_APUSH, 03, 00, - program.OP_APUSH, 06, 00, - program.OP_BUMP, - program.OP_TAKE_ALWAYS, - program.OP_APUSH, 06, 00, - program.OP_FUNDING_ASSEMBLE, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 07, 00, - program.OP_SEND, - program.OP_REPAY, - }, - Resources: []program.Resource{ - program.Variable{Typ: internal.TypeAccount, Name: "acc"}, - program.Constant{Inner: internal.Asset("COIN")}, - program.VariableAccountBalance{Account: 0, Asset: 1}, - program.Constant{Inner: internal.AccountAddress("world")}, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.NewMonetaryInt(2)}, - program.Constant{Inner: internal.AccountAddress("alice")}, - }, - }, - }) - }) - - t.Run("error variable type", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - account $bal = balance(@alice, COIN) - } - send $bal ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Error: "variable $bal: type should be 'monetary' to pull account balance", - }, - }) - }) - - t.Run("error no asset", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - monetary $bal = balance(@alice) - } - send $bal ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Error: "mismatched input", - }, - }) - }) - - t.Run("error too many arguments", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - monetary $bal = balance(@alice, USD, COIN) - } - send $bal ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Error: "mismatched input ',' expecting ')'", - }, - }) - }) - - t.Run("error wrong type for account", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - monetary $bal = balance(USD, COIN) - } - send $bal ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Error: "variable $bal: the first argument to pull account balance should be of type 'account'", - }, - }) - }) - - t.Run("error wrong type for asset", func(t *testing.T) { - test(t, TestCase{ - Case: `vars { - monetary $bal = balance(@alice, @bob) - } - send $bal ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Error: "variable $bal: the second argument to pull account balance should be of type 'asset'", - }, - }) - }) - - t.Run("error not in variables", func(t *testing.T) { - test(t, TestCase{ - Case: `send balance(@alice, COIN) ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Error: "mismatched input 'balance'", - }, - }) - }) -} - -func TestVariableAsset(t *testing.T) { - script := `vars { - asset $ass - monetary $bal = balance(@alice, $ass) - } - - send [$ass *] ( - source = @alice - destination = @bob - ) - - send [$ass 1] ( - source = @bob - destination = @alice - ) - - send $bal ( - source = @alice - destination = @bob - )` - - test(t, TestCase{ - Case: script, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 01, 00, - program.OP_APUSH, 00, 00, - program.OP_APUSH, 03, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 04, 00, - program.OP_SEND, - program.OP_REPAY, - program.OP_APUSH, 04, 00, - program.OP_APUSH, 05, 00, - program.OP_ASSET, - program.OP_APUSH, 03, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 05, 00, - program.OP_TAKE, - program.OP_APUSH, 06, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 01, 00, - program.OP_SEND, - program.OP_REPAY, - program.OP_APUSH, 01, 00, - program.OP_APUSH, 02, 00, - program.OP_ASSET, - program.OP_APUSH, 03, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 02, 00, - program.OP_TAKE, - program.OP_APUSH, 06, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 04, 00, - program.OP_SEND, - program.OP_REPAY, - }, - Resources: []program.Resource{ - program.Variable{Typ: internal.TypeAsset, Name: "ass"}, - program.Constant{Inner: internal.AccountAddress("alice")}, - program.VariableAccountBalance{ - Name: "bal", - Account: 1, - Asset: 0, - }, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.AccountAddress("bob")}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(1), - }, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - }, - }, - }) -} - -func TestPrint(t *testing.T) { - script := `print 1 + 2 + 3` - test(t, TestCase{ - Case: script, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_APUSH, 01, 00, - program.OP_IADD, - program.OP_APUSH, 02, 00, - program.OP_IADD, - program.OP_PRINT, - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.NewMonetaryInt(2)}, - program.Constant{Inner: internal.NewMonetaryInt(3)}, - }, - }, - }) -} - -func TestSendWithArithmetic(t *testing.T) { - t.Run("nominal", func(t *testing.T) { - script := ` - vars { - asset $ass - monetary $mon - } - send [EUR 1] + $mon + [$ass 3] - [EUR 4] ( - source = @a - destination = @b - )` - - test(t, TestCase{ - Case: script, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 06, 00, - program.OP_APUSH, 03, 00, - program.OP_ASSET, - program.OP_APUSH, 07, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 03, 00, - program.OP_APUSH, 01, 00, - program.OP_MONETARY_ADD, - program.OP_APUSH, 04, 00, - program.OP_MONETARY_ADD, - program.OP_APUSH, 05, 00, - program.OP_MONETARY_SUB, - program.OP_TAKE, - program.OP_APUSH, 8, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 9, 00, - program.OP_SEND, - program.OP_REPAY, - }, - Resources: []program.Resource{ - program.Variable{ - Typ: internal.TypeAsset, - Name: "ass", - }, - program.Variable{ - Typ: internal.TypeMonetary, - Name: "mon", - }, - program.Constant{Inner: internal.Asset("EUR")}, - program.Monetary{ - Asset: 2, - Amount: internal.NewMonetaryInt(1), - }, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(3), - }, - program.Monetary{ - Asset: 2, - Amount: internal.NewMonetaryInt(4), - }, - program.Constant{Inner: internal.AccountAddress("a")}, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.AccountAddress("b")}, - }, - }, - }) - }) - - t.Run("error incompatible types", func(t *testing.T) { - script := `send [EUR 1] + 2 ( - source = @world - destination = @bob - )` - - test(t, TestCase{ - Case: script, - Expected: CaseResult{ - Instructions: []byte{}, - Resources: []program.Resource{}, - Error: "tried to do an arithmetic operation with incompatible left and right-hand side operand types: monetary and number", - }, - }) - }) - - t.Run("error incompatible types var", func(t *testing.T) { - script := ` - vars { - number $nb - } - send [EUR 1] - $nb ( - source = @world - destination = @bob - )` - - test(t, TestCase{ - Case: script, - Expected: CaseResult{ - Instructions: []byte{}, - Resources: []program.Resource{}, - Error: "tried to do an arithmetic operation with incompatible left and right-hand side operand types: monetary and number", - }, - }) - }) -} - -func TestSaveFromAccount(t *testing.T) { - t.Run("simple", func(t *testing.T) { - test(t, TestCase{ - Case: ` - save [EUR 10] from @alice - - send [EUR 20] ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 01, 00, - program.OP_APUSH, 02, 00, - program.OP_SAVE, - program.OP_APUSH, 02, 00, - program.OP_APUSH, 03, 00, - program.OP_ASSET, - program.OP_APUSH, 04, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 03, 00, - program.OP_TAKE, - program.OP_APUSH, 05, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 06, 00, - program.OP_SEND, - program.OP_REPAY, - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.Asset("EUR")}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(10), - }, - program.Constant{Inner: internal.AccountAddress("alice")}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(20), - }, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.AccountAddress("bob")}, - }, - }, - }) - }) - - t.Run("save all", func(t *testing.T) { - test(t, TestCase{ - Case: ` - save [EUR *] from @alice - - send [EUR 20] ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_APUSH, 01, 00, - program.OP_SAVE, - program.OP_APUSH, 01, 00, - program.OP_APUSH, 02, 00, - program.OP_ASSET, - program.OP_APUSH, 03, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 02, 00, - program.OP_TAKE, - program.OP_APUSH, 04, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 05, 00, - program.OP_SEND, - program.OP_REPAY, - }, - Resources: []program.Resource{ - program.Constant{Inner: internal.Asset("EUR")}, - program.Constant{Inner: internal.AccountAddress("alice")}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(20), - }, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.AccountAddress("bob")}, - }, - }, - }) - }) - - t.Run("with asset var", func(t *testing.T) { - test(t, TestCase{ - Case: ` - vars { - asset $ass - } - - save [$ass 10] from @alice - - send [$ass 20] ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 01, 00, - program.OP_APUSH, 02, 00, - program.OP_SAVE, - program.OP_APUSH, 02, 00, - program.OP_APUSH, 03, 00, - program.OP_ASSET, - program.OP_APUSH, 04, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 03, 00, - program.OP_TAKE, - program.OP_APUSH, 05, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 06, 00, - program.OP_SEND, - program.OP_REPAY, - }, - Resources: []program.Resource{ - program.Variable{Typ: internal.TypeAsset, Name: "ass"}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(10), - }, - program.Constant{Inner: internal.AccountAddress("alice")}, - program.Monetary{ - Asset: 0, - Amount: internal.NewMonetaryInt(20), - }, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.AccountAddress("bob")}, - }, - }, - }) - }) - - t.Run("with monetary var", func(t *testing.T) { - test(t, TestCase{ - Case: ` - vars { - monetary $mon - } - - save $mon from @alice - - send [EUR 20] ( - source = @alice - destination = @bob - )`, - Expected: CaseResult{ - Instructions: []byte{ - program.OP_APUSH, 00, 00, - program.OP_APUSH, 01, 00, - program.OP_SAVE, - program.OP_APUSH, 01, 00, - program.OP_APUSH, 03, 00, - program.OP_ASSET, - program.OP_APUSH, 04, 00, - program.OP_MONETARY_NEW, - program.OP_TAKE_ALL, - program.OP_APUSH, 03, 00, - program.OP_TAKE, - program.OP_APUSH, 05, 00, - program.OP_BUMP, - program.OP_REPAY, - program.OP_FUNDING_SUM, - program.OP_TAKE, - program.OP_APUSH, 06, 00, - program.OP_SEND, - program.OP_REPAY, - }, - Resources: []program.Resource{ - program.Variable{Typ: internal.TypeMonetary, Name: "mon"}, - program.Constant{Inner: internal.AccountAddress("alice")}, - program.Constant{Inner: internal.Asset("EUR")}, - program.Monetary{ - Asset: 2, - Amount: internal.NewMonetaryInt(20), - }, - program.Constant{Inner: internal.NewMonetaryInt(0)}, - program.Constant{Inner: internal.NewMonetaryInt(1)}, - program.Constant{Inner: internal.AccountAddress("bob")}, - }, - }, - }) - }) - - t.Run("error wrong type monetary", func(t *testing.T) { - test(t, TestCase{ - Case: ` - save 30 from @alice - `, - Expected: CaseResult{ - Instructions: []byte{}, - Resources: []program.Resource{}, - Error: "save monetary from account: the first expression should be of type 'monetary' instead of 'number'", - }, - }) - }) - - t.Run("error wrong type account", func(t *testing.T) { - test(t, TestCase{ - Case: ` - save [EUR 30] from ALICE - `, - Expected: CaseResult{ - Instructions: []byte{}, - Resources: []program.Resource{}, - Error: "save monetary from account: the second expression should be of type 'account' instead of 'asset'", - }, - }) - }) -} diff --git a/components/ledger/pkg/machine/script/compiler/program.go b/components/ledger/pkg/machine/script/compiler/program.go deleted file mode 100644 index 1094f8961..000000000 --- a/components/ledger/pkg/machine/script/compiler/program.go +++ /dev/null @@ -1,36 +0,0 @@ -package compiler - -import ( - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/formancehq/ledger/pkg/machine/vm/program" -) - -func (p *parseVisitor) AppendInstruction(instruction byte) { - p.instructions = append(p.instructions, instruction) -} - -func (p *parseVisitor) PushAddress(addr internal.Address) { - p.instructions = append(p.instructions, program.OP_APUSH) - bytes := addr.ToBytes() - p.instructions = append(p.instructions, bytes...) -} - -func (p *parseVisitor) PushInteger(val internal.Number) error { - addr, err := p.AllocateResource(program.Constant{Inner: val}) - if err != nil { - return err - } - p.instructions = append(p.instructions, program.OP_APUSH) - bytes := addr.ToBytes() - p.instructions = append(p.instructions, bytes...) - return nil -} - -func (p *parseVisitor) Bump(n int64) error { - err := p.PushInteger(internal.NewNumber(n)) - if err != nil { - return err - } - p.instructions = append(p.instructions, program.OP_BUMP) - return nil -} diff --git a/components/ledger/pkg/machine/vm/machine.go b/components/ledger/pkg/machine/vm/machine.go deleted file mode 100644 index cc27d85f6..000000000 --- a/components/ledger/pkg/machine/vm/machine.go +++ /dev/null @@ -1,639 +0,0 @@ -/* -Provides `Machine`, which executes programs and outputs postings. -1: Create New Machine -2: Set Variables (with `internal.Value`s or JSON) -3: Resolve Resources (answer requests on channel) -4: Resolve Balances (answer requests on channel) -6: Execute -*/ -package vm - -import ( - "context" - "encoding/binary" - "fmt" - "math/big" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/formancehq/ledger/pkg/machine/vm/program" - "github.com/formancehq/stack/libs/go-libs/errorsutil" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/logrusorgru/aurora" - "github.com/pkg/errors" -) - -type Machine struct { - P uint - Program program.Program - Vars map[string]internal.Value - UnresolvedResources []program.Resource - Resources []internal.Value // Constants and Variables - UnresolvedResourceBalances map[string]int - resolveCalled bool - Balances map[internal.AccountAddress]map[internal.Asset]*internal.MonetaryInt // keeps track of balances throughout execution - setBalanceCalled bool - Stack []internal.Value - Postings []Posting // accumulates postings throughout execution - TxMeta map[string]internal.Value // accumulates transaction meta throughout execution - AccountsMeta map[internal.AccountAddress]map[string]internal.Value // accumulates accounts meta throughout execution - Printer func(chan internal.Value) - printChan chan internal.Value - Debug bool -} - -type Posting struct { - Source string `json:"source"` - Destination string `json:"destination"` - Amount *internal.MonetaryInt `json:"amount"` - Asset string `json:"asset"` -} - -type Metadata map[string]any - -func NewMachine(p program.Program) *Machine { - printChan := make(chan internal.Value) - - m := Machine{ - Program: p, - UnresolvedResources: p.Resources, - Resources: make([]internal.Value, 0), - printChan: printChan, - Printer: StdOutPrinter, - Postings: make([]Posting, 0), - TxMeta: map[string]internal.Value{}, - AccountsMeta: map[internal.AccountAddress]map[string]internal.Value{}, - UnresolvedResourceBalances: map[string]int{}, - } - - return &m -} - -func StdOutPrinter(c chan internal.Value) { - for v := range c { - fmt.Println("OUT:", v) - } -} - -func (m *Machine) GetTxMetaJSON() metadata.Metadata { - meta := metadata.Metadata{} - for k, v := range m.TxMeta { - var err error - meta[k], err = internal.NewStringFromValue(v) - if err != nil { - panic(err) - } - } - return meta -} - -func (m *Machine) GetAccountsMetaJSON() map[string]metadata.Metadata { - res := make(map[string]metadata.Metadata) - for account, meta := range m.AccountsMeta { - for k, v := range meta { - if _, ok := res[string(account)]; !ok { - res[string(account)] = metadata.Metadata{} - } - - var err error - res[string(account)][k], err = internal.NewStringFromValue(v) - if err != nil { - panic(err) - } - } - } - - return res -} - -func (m *Machine) getResource(addr internal.Address) (*internal.Value, bool) { - a := int(addr) - if a >= len(m.Resources) { - return nil, false - } - return &m.Resources[a], true -} - -func (m *Machine) withdrawAll(account internal.AccountAddress, asset internal.Asset, overdraft *internal.MonetaryInt) (*internal.Funding, error) { - if accBalances, ok := m.Balances[account]; ok { - if balance, ok := accBalances[asset]; ok { - amountTaken := internal.Zero - balanceWithOverdraft := balance.Add(overdraft) - if balanceWithOverdraft.Gt(internal.Zero) { - amountTaken = balanceWithOverdraft - accBalances[asset] = overdraft.Neg() - } - - return &internal.Funding{ - Asset: asset, - Parts: []internal.FundingPart{{ - Account: account, - Amount: amountTaken, - }}, - }, nil - } - } - return nil, fmt.Errorf("missing %v balance from %v", asset, account) -} - -func (m *Machine) withdrawAlways(account internal.AccountAddress, mon internal.Monetary) (*internal.Funding, error) { - if accBalance, ok := m.Balances[account]; ok { - if balance, ok := accBalance[mon.Asset]; ok { - accBalance[mon.Asset] = balance.Sub(mon.Amount) - return &internal.Funding{ - Asset: mon.Asset, - Parts: []internal.FundingPart{{ - Account: account, - Amount: mon.Amount, - }}, - }, nil - } - } - return nil, fmt.Errorf("missing %v balance from %v", mon.Asset, account) -} - -func (m *Machine) credit(account internal.AccountAddress, funding internal.Funding) { - if account == "world" { - return - } - if accBalance, ok := m.Balances[account]; ok { - if _, ok := accBalance[funding.Asset]; ok { - for _, part := range funding.Parts { - balance := accBalance[funding.Asset] - accBalance[funding.Asset] = balance.Add(part.Amount) - } - } - } -} - -func (m *Machine) repay(funding internal.Funding) { - for _, part := range funding.Parts { - if part.Account == "world" { - continue - } - balance := m.Balances[part.Account][funding.Asset] - m.Balances[part.Account][funding.Asset] = balance.Add(part.Amount) - } -} - -func (m *Machine) tick() (bool, error) { - op := m.Program.Instructions[m.P] - - if m.Debug { - fmt.Println("STATE ---------------------------------------------------------------------") - fmt.Printf(" %v\n", aurora.Blue(m.Stack)) - fmt.Printf(" %v\n", aurora.Cyan(m.Balances)) - fmt.Printf(" %v\n", program.OpcodeName(op)) - } - - switch op { - case program.OP_APUSH: - bytes := m.Program.Instructions[m.P+1 : m.P+3] - v, ok := m.getResource(internal.Address(binary.LittleEndian.Uint16(bytes))) - if !ok { - return true, ErrResourceNotFound - } - m.Stack = append(m.Stack, *v) - m.P += 2 - - case program.OP_BUMP: - n := big.Int(*pop[internal.Number](m)) - idx := len(m.Stack) - int(n.Uint64()) - 1 - v := m.Stack[idx] - m.Stack = append(m.Stack[:idx], m.Stack[idx+1:]...) - m.Stack = append(m.Stack, v) - - case program.OP_DELETE: - n := m.popValue() - if n.GetType() == internal.TypeFunding { - return true, errorsutil.NewError(ErrInvalidScript, - errors.Errorf("wrong type: want: %v, got: %v", n.GetType(), internal.TypeFunding)) - } - - case program.OP_IADD: - b := pop[internal.Number](m) - a := pop[internal.Number](m) - m.pushValue(a.Add(b)) - - case program.OP_ISUB: - b := pop[internal.Number](m) - a := pop[internal.Number](m) - m.pushValue(a.Sub(b)) - - case program.OP_PRINT: - a := m.popValue() - m.printChan <- a - - case program.OP_FAIL: - return true, ErrScriptFailed - - case program.OP_ASSET: - v := m.popValue() - switch v := v.(type) { - case internal.Asset: - m.pushValue(v) - case internal.Monetary: - m.pushValue(v.Asset) - case internal.Funding: - m.pushValue(v.Asset) - default: - return true, errorsutil.NewError(ErrInvalidScript, - errors.Errorf("wrong type for op asset: %v", v.GetType())) - } - - case program.OP_MONETARY_NEW: - amount := pop[internal.Number](m) - asset := pop[internal.Asset](m) - m.pushValue(internal.Monetary{ - Asset: asset, - Amount: amount, - }) - - case program.OP_MONETARY_ADD: - b := pop[internal.Monetary](m) - a := pop[internal.Monetary](m) - if a.Asset != b.Asset { - return true, errorsutil.NewError(ErrInvalidScript, - errors.Errorf("cannot add different assets: %v and %v", a.Asset, b.Asset)) - } - m.pushValue(internal.Monetary{ - Asset: a.Asset, - Amount: a.Amount.Add(b.Amount), - }) - - case program.OP_MONETARY_SUB: - b := pop[internal.Monetary](m) - a := pop[internal.Monetary](m) - if a.Asset != b.Asset { - return true, fmt.Errorf("%s", program.OpcodeName(op)) - } - m.pushValue(internal.Monetary{ - Asset: a.Asset, - Amount: a.Amount.Sub(b.Amount), - }) - - case program.OP_MAKE_ALLOTMENT: - n := pop[internal.Number](m) - portions := make([]internal.Portion, n.Uint64()) - for i := uint64(0); i < n.Uint64(); i++ { - p := pop[internal.Portion](m) - portions[i] = p - } - allotment, err := internal.NewAllotment(portions) - if err != nil { - return true, errorsutil.NewError(ErrInvalidScript, err) - } - m.pushValue(*allotment) - - case program.OP_TAKE_ALL: - overdraft := pop[internal.Monetary](m) - account := pop[internal.AccountAddress](m) - funding, err := m.withdrawAll(account, overdraft.Asset, overdraft.Amount) - if err != nil { - return true, errorsutil.NewError(ErrInvalidScript, err) - } - m.pushValue(*funding) - - case program.OP_TAKE_ALWAYS: - mon := pop[internal.Monetary](m) - account := pop[internal.AccountAddress](m) - funding, err := m.withdrawAlways(account, mon) - if err != nil { - return true, errorsutil.NewError(ErrInvalidScript, err) - } - m.pushValue(*funding) - - case program.OP_TAKE: - mon := pop[internal.Monetary](m) - funding := pop[internal.Funding](m) - if funding.Asset != mon.Asset { - return true, errorsutil.NewError(ErrInvalidScript, - errors.Errorf("cannot take from different assets: %v and %v", funding.Asset, mon.Asset)) - } - result, remainder, err := funding.Take(mon.Amount) - if err != nil { - return true, errorsutil.NewError(ErrInsufficientFund, err) - } - m.pushValue(remainder) - m.pushValue(result) - - case program.OP_TAKE_MAX: - mon := pop[internal.Monetary](m) - if mon.Amount.Ltz() { - return true, fmt.Errorf( - "cannot send a monetary with a negative amount: [%s %s]", - string(mon.Asset), mon.Amount) - } - funding := pop[internal.Funding](m) - if funding.Asset != mon.Asset { - return true, errorsutil.NewError(ErrInvalidScript, - errors.Errorf("cannot take from different assets: %v and %v", funding.Asset, mon.Asset)) - } - missing := internal.Zero - total := funding.Total() - if mon.Amount.Gt(total) { - missing = mon.Amount.Sub(total) - } - m.pushValue(internal.Monetary{ - Asset: mon.Asset, - Amount: missing, - }) - result, remainder := funding.TakeMax(mon.Amount) - m.pushValue(remainder) - m.pushValue(result) - - case program.OP_FUNDING_ASSEMBLE: - num := pop[internal.Number](m) - n := int(num.Uint64()) - if n == 0 { - return true, errorsutil.NewError(ErrInvalidScript, - errors.New("cannot assemble zero fundings")) - } - first := pop[internal.Funding](m) - result := internal.Funding{ - Asset: first.Asset, - } - fundings_rev := make([]internal.Funding, n) - fundings_rev[0] = first - for i := 1; i < n; i++ { - f := pop[internal.Funding](m) - if f.Asset != result.Asset { - return true, errorsutil.NewError(ErrInvalidScript, - errors.Errorf("cannot assemble different assets: %v and %v", f.Asset, result.Asset)) - } - fundings_rev[i] = f - } - for i := 0; i < n; i++ { - res, err := result.Concat(fundings_rev[n-1-i]) - if err != nil { - return true, errorsutil.NewError(ErrInvalidScript, err) - } - result = res - } - m.pushValue(result) - - case program.OP_FUNDING_SUM: - funding := pop[internal.Funding](m) - sum := funding.Total() - m.pushValue(funding) - m.pushValue(internal.Monetary{ - Asset: funding.Asset, - Amount: sum, - }) - - case program.OP_FUNDING_REVERSE: - funding := pop[internal.Funding](m) - result := funding.Reverse() - m.pushValue(result) - - case program.OP_ALLOC: - allotment := pop[internal.Allotment](m) - monetary := pop[internal.Monetary](m) - total := monetary.Amount - parts := allotment.Allocate(total) - for i := len(parts) - 1; i >= 0; i-- { - m.pushValue(internal.Monetary{ - Asset: monetary.Asset, - Amount: parts[i], - }) - } - - case program.OP_REPAY: - m.repay(pop[internal.Funding](m)) - - case program.OP_SEND: - dest := pop[internal.AccountAddress](m) - funding := pop[internal.Funding](m) - m.credit(dest, funding) - for _, part := range funding.Parts { - src := part.Account - amt := part.Amount - m.Postings = append(m.Postings, Posting{ - Source: string(src), - Destination: string(dest), - Asset: string(funding.Asset), - Amount: amt, - }) - } - - case program.OP_TX_META: - k := pop[internal.String](m) - v := m.popValue() - m.TxMeta[string(k)] = v - - case program.OP_ACCOUNT_META: - a := pop[internal.AccountAddress](m) - k := pop[internal.String](m) - v := m.popValue() - if m.AccountsMeta[a] == nil { - m.AccountsMeta[a] = map[string]internal.Value{} - } - m.AccountsMeta[a][string(k)] = v - - case program.OP_SAVE: - a := pop[internal.AccountAddress](m) - v := m.popValue() - switch v := v.(type) { - case internal.Asset: - m.Balances[a][v] = internal.Zero - case internal.Monetary: - m.Balances[a][v.Asset] = m.Balances[a][v.Asset].Sub(v.Amount) - default: - panic(fmt.Errorf("invalid value type: %T", v)) - } - - default: - return true, errorsutil.NewError(ErrInvalidScript, - errors.Errorf("invalid opcode: %v", op)) - } - - m.P += 1 - - if int(m.P) >= len(m.Program.Instructions) { - return true, nil - } - - return false, nil -} - -func (m *Machine) Execute() error { - go m.Printer(m.printChan) - defer close(m.printChan) - - if len(m.Resources) != len(m.UnresolvedResources) { - return ErrResourcesNotInitialized - } else if m.Balances == nil { - return ErrBalancesNotInitialized - } - - for { - finished, err := m.tick() - if finished { - if err == nil && len(m.Stack) != 0 { - return errorsutil.NewError(ErrInvalidScript, - errors.New("stack not empty after execution")) - } else { - return err - } - } - } -} - -type BalanceRequest struct { - Account string - Asset string - Response chan *internal.MonetaryInt - Error error -} - -func (m *Machine) ResolveBalances(ctx context.Context, store Store) error { - if len(m.Resources) != len(m.UnresolvedResources) { - return errors.New("tried to resolve balances before resources") - } - if m.setBalanceCalled { - return errors.New("tried to call ResolveBalances twice") - } - m.setBalanceCalled = true - m.Balances = make(map[internal.AccountAddress]map[internal.Asset]*internal.MonetaryInt) - - for address, resourceIndex := range m.UnresolvedResourceBalances { - monetary := m.Resources[resourceIndex].(internal.Monetary) - balance, err := store.GetBalanceFromLogs(ctx, address, string(monetary.Asset)) - if err != nil { - return err - } - if balance.Cmp(core.Zero) < 0 { - return errorsutil.NewError(ErrNegativeMonetaryAmount, fmt.Errorf( - "tried to request the balance of account %s for asset %s: received %s: monetary amounts must be non-negative", - address, monetary.Asset, balance)) - } - monetary.Amount = internal.NewMonetaryIntFromBigInt(balance) - m.Resources[resourceIndex] = monetary - } - - // for every account that we need balances of, check if it's there - for addr, neededAssets := range m.Program.NeededBalances { - account, ok := m.getResource(addr) - if !ok { - return errors.New("invalid program (resolve balances: invalid address of account)") - } - accountAddress := (*account).(internal.AccountAddress) - m.Balances[accountAddress] = make(map[internal.Asset]*internal.MonetaryInt) - // for every asset, send request - for addr := range neededAssets { - mon, ok := m.getResource(addr) - if !ok { - return errors.New("invalid program (resolve balances: invalid address of monetary)") - } - - asset := (*mon).(internal.HasAsset).GetAsset() - if string(accountAddress) == "world" { - m.Balances[accountAddress][asset] = internal.Zero - continue - } - - balance, err := store.GetBalanceFromLogs(ctx, string(accountAddress), string(asset)) - if err != nil { - return errors.Wrap(err, fmt.Sprintf("could not get balance for account %q", addr)) - } - - m.Balances[accountAddress][asset] = internal.NewMonetaryIntFromBigInt(balance) - } - } - return nil -} - -func (m *Machine) ResolveResources(ctx context.Context, store Store) ([]string, []string, error) { - //TODO(gfyrag): Is that really required? Feel like defensive programming. - if m.resolveCalled { - return nil, nil, errors.New("tried to call ResolveResources twice") - } - - m.resolveCalled = true - involvedAccountsMap := make(map[internal.Address]string) - for len(m.Resources) != len(m.UnresolvedResources) { - idx := len(m.Resources) - res := m.UnresolvedResources[idx] - var val internal.Value - switch res := res.(type) { - case program.Constant: - val = res.Inner - if val.GetType() == internal.TypeAccount { - involvedAccountsMap[internal.Address(idx)] = string(val.(internal.AccountAddress)) - } - case program.Variable: - var ok bool - val, ok = m.Vars[res.Name] - if !ok { - return nil, nil, fmt.Errorf("missing variable '%s'", res.Name) - } - if val.GetType() == internal.TypeAccount { - involvedAccountsMap[internal.Address(idx)] = string(val.(internal.AccountAddress)) - } - case program.VariableAccountMetadata: - acc, _ := m.getResource(res.Account) - addr := string((*acc).(internal.AccountAddress)) - - metadata, err := store.GetMetadataFromLogs(ctx, addr, res.Key) - if err != nil { - return nil, nil, errorsutil.NewError(ErrResourceResolutionMissingMetadata, errors.New( - fmt.Sprintf("missing key %v in metadata for account %s", res.Key, addr))) - } - - val, err = internal.NewValueFromString(res.Typ, metadata) - if err != nil { - return nil, nil, err - } - case program.VariableAccountBalance: - acc, _ := m.getResource(res.Account) - address := string((*acc).(internal.AccountAddress)) - involvedAccountsMap[internal.Address(idx)] = address - m.UnresolvedResourceBalances[address] = idx - - ass, ok := m.getResource(res.Asset) - if !ok { - return nil, nil, fmt.Errorf( - "variable '%s': tried to request account balance of an asset which has not yet been solved", - res.Name) - } - if (*ass).GetType() != internal.TypeAsset { - return nil, nil, fmt.Errorf( - "variable '%s': tried to request account balance for an asset on wrong entity: %v instead of asset", - res.Name, (*ass).GetType()) - } - - val = internal.Monetary{ - Asset: (*ass).(internal.Asset), - } - case program.Monetary: - ass, _ := m.getResource(res.Asset) - val = internal.Monetary{ - Asset: (*ass).(internal.Asset), - Amount: res.Amount, - } - default: - panic(fmt.Errorf("type %T not implemented", res)) - } - m.Resources = append(m.Resources, val) - } - - involvedAccounts := make([]string, 0) - involvedSources := make([]string, 0) - for _, accountAddress := range involvedAccountsMap { - involvedAccounts = append(involvedAccounts, accountAddress) - } - for _, machineAddress := range m.Program.Sources { - involvedSources = append(involvedSources, involvedAccountsMap[machineAddress]) - } - - return involvedAccounts, involvedSources, nil -} - -func (m *Machine) SetVarsFromJSON(vars map[string]string) error { - v, err := m.Program.ParseVariablesJSON(vars) - if err != nil { - return errorsutil.NewError(ErrInvalidVars, err) - } - m.Vars = v - return nil -} diff --git a/components/ledger/pkg/machine/vm/machine_kept_test.go b/components/ledger/pkg/machine/vm/machine_kept_test.go deleted file mode 100644 index f93b5f529..000000000 --- a/components/ledger/pkg/machine/vm/machine_kept_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package vm - -import ( - "testing" - - "github.com/formancehq/ledger/pkg/machine/internal" -) - -func TestKeptDestinationAllotment(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [GEM 100] ( - source = { - @a - @world - } - destination = { - 50% kept - 25% to @x - 25% to @y - } - )`) - tc.setBalance("a", "GEM", 1) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(1), - Source: "a", - Destination: "x", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(24), - Source: "world", - Destination: "x", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(25), - Source: "world", - Destination: "y", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestKeptComplex(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [GEM 100] ( - source = { - @foo - @bar - @baz - } - destination = { - 50% to { - max [GEM 8] to { - 50% kept - 25% to @arst - 25% kept - } - remaining to @thing - } - 20% to @qux - 5% kept - remaining to @quz - } - )`) - tc.setBalance("foo", "GEM", 20) - tc.setBalance("bar", "GEM", 40) - tc.setBalance("baz", "GEM", 40) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(2), - Source: "foo", - Destination: "arst", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(18), - Source: "foo", - Destination: "thing", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(24), - Source: "bar", - Destination: "thing", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(16), - Source: "bar", - Destination: "qux", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(4), - Source: "baz", - Destination: "qux", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(25), - Source: "baz", - Destination: "quz", - }, - }, - Error: nil, - } - test(t, tc) -} diff --git a/components/ledger/pkg/machine/vm/machine_test.go b/components/ledger/pkg/machine/vm/machine_test.go deleted file mode 100644 index 0a6a67543..000000000 --- a/components/ledger/pkg/machine/vm/machine_test.go +++ /dev/null @@ -1,2132 +0,0 @@ -package vm - -import ( - "context" - "encoding/json" - "fmt" - "math/big" - "sync" - "testing" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/formancehq/ledger/pkg/machine/script/compiler" - "github.com/formancehq/ledger/pkg/machine/vm/program" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/pkg/errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -const ( - DEBUG bool = false -) - -type CaseResult struct { - Printed []internal.Value - Postings []Posting - Metadata map[string]internal.Value - Error error - ErrorContains string -} - -type TestCase struct { - program *program.Program - vars map[string]string - meta map[string]metadata.Metadata - balances map[string]map[string]*internal.MonetaryInt - expected CaseResult -} - -func NewTestCase() TestCase { - return TestCase{ - vars: make(map[string]string), - meta: make(map[string]metadata.Metadata), - balances: make(map[string]map[string]*internal.MonetaryInt), - expected: CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{}, - Metadata: make(map[string]internal.Value), - Error: nil, - }, - } -} - -func (c *TestCase) compile(t *testing.T, code string) { - p, err := compiler.Compile(code) - if err != nil { - t.Fatalf("compile error: %v", err) - return - } - c.program = p -} - -func (c *TestCase) setVarsFromJSON(t *testing.T, str string) { - var jsonVars map[string]string - err := json.Unmarshal([]byte(str), &jsonVars) - require.NoError(t, err) - c.vars = jsonVars -} - -func (c *TestCase) setBalance(account, asset string, amount int64) { - if _, ok := c.balances[account]; !ok { - c.balances[account] = make(map[string]*internal.MonetaryInt) - } - c.balances[account][asset] = internal.NewMonetaryInt(amount) -} - -func test(t *testing.T, testCase TestCase) { - testImpl(t, testCase.program, testCase.expected, func(m *Machine) error { - if err := m.SetVarsFromJSON(testCase.vars); err != nil { - return err - } - - store := StaticStore{} - for account, balances := range testCase.balances { - store[account] = &AccountWithBalances{ - Account: core.Account{ - Address: account, - Metadata: testCase.meta[account], - }, - Balances: func() map[string]*big.Int { - ret := make(map[string]*big.Int) - for asset, balance := range balances { - ret[asset] = (*big.Int)(balance) - } - return ret - }(), - } - } - - _, _, err := m.ResolveResources(context.Background(), store) - if err != nil { - return err - } - - err = m.ResolveBalances(context.Background(), store) - if err != nil { - return err - } - - return m.Execute() - }) -} - -func testImpl(t *testing.T, prog *program.Program, expected CaseResult, exec func(*Machine) error) { - printed := []internal.Value{} - - var wg sync.WaitGroup - wg.Add(1) - - require.NotNil(t, prog) - - m := NewMachine(*prog) - m.Debug = DEBUG - m.Printer = func(c chan internal.Value) { - for v := range c { - printed = append(printed, v) - } - wg.Done() - } - - err := exec(m) - if expected.Error != nil { - require.True(t, errors.Is(err, expected.Error), "got wrong error, want: %v, got: %v", expected.Error, err) - if expected.ErrorContains != "" { - require.ErrorContains(t, err, expected.ErrorContains) - } - } else { - require.NoError(t, err) - } - if err != nil { - return - } - - if expected.Postings == nil { - expected.Postings = make([]Posting, 0) - } - if expected.Metadata == nil { - expected.Metadata = make(map[string]internal.Value) - } - - assert.Equalf(t, expected.Postings, m.Postings, "unexpected postings output: %v", m.Postings) - assert.Equalf(t, expected.Metadata, m.TxMeta, "unexpected metadata output: %v", m.TxMeta) - - wg.Wait() - - assert.Equalf(t, expected.Printed, printed, "unexpected metadata output: %v", printed) -} - -func TestFail(t *testing.T) { - tc := NewTestCase() - tc.compile(t, "fail") - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{}, - Error: ErrScriptFailed, - } - test(t, tc) -} - -func TestPrint(t *testing.T) { - tc := NewTestCase() - tc.compile(t, "print 29 + 15 - 2") - mi := internal.MonetaryInt(*big.NewInt(42)) - tc.expected = CaseResult{ - Printed: []internal.Value{&mi}, - Postings: []Posting{}, - Error: nil, - } - test(t, tc) -} - -func TestSend(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [EUR/2 100] ( - source=@alice - destination=@bob - )`) - tc.setBalance("alice", "EUR/2", 100) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "EUR/2", - Amount: internal.NewMonetaryInt(100), - Source: "alice", - Destination: "bob", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestVariables(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `vars { - account $rider - account $driver - string $description - number $nb - asset $ass - } - send [$ass 999] ( - source=$rider - destination=$driver - ) - set_tx_meta("description", $description) - set_tx_meta("ride", $nb)`) - tc.vars = map[string]string{ - "rider": "users:001", - "driver": "users:002", - "description": "midnight ride", - "nb": "1", - "ass": "EUR/2", - } - tc.setBalance("users:001", "EUR/2", 1000) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "EUR/2", - Amount: internal.NewMonetaryInt(999), - Source: "users:001", - Destination: "users:002", - }, - }, - Metadata: map[string]internal.Value{ - "description": internal.String("midnight ride"), - "ride": internal.NewMonetaryInt(1), - }, - Error: nil, - } -} - -func TestVariablesJSON(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `vars { - account $rider - account $driver - string $description - number $nb - asset $ass - } - send [$ass 999] ( - source=$rider - destination=$driver - ) - set_tx_meta("description", $description) - set_tx_meta("ride", $nb)`) - tc.setVarsFromJSON(t, `{ - "rider": "users:001", - "driver": "users:002", - "description": "midnight ride", - "nb": "1", - "ass": "EUR/2" - }`) - tc.setBalance("users:001", "EUR/2", 1000) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "EUR/2", - Amount: internal.NewMonetaryInt(999), - Source: "users:001", - Destination: "users:002", - }, - }, - Metadata: map[string]internal.Value{ - "description": internal.String("midnight ride"), - "ride": internal.NewMonetaryInt(1), - }, - Error: nil, - } - test(t, tc) -} - -func TestSource(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `vars { - account $balance - account $payment - account $seller - } - send [GEM 15] ( - source = { - $balance - $payment - } - destination = $seller - )`) - tc.setVarsFromJSON(t, `{ - "balance": "users:001", - "payment": "payments:001", - "seller": "users:002" - }`) - tc.setBalance("users:001", "GEM", 3) - tc.setBalance("payments:001", "GEM", 12) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(3), - Source: "users:001", - Destination: "users:002", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(12), - Source: "payments:001", - Destination: "users:002", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestAllocation(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `vars { - account $rider - account $driver - } - send [GEM 15] ( - source = $rider - destination = { - 80% to $driver - 8% to @a - 12% to @b - } - )`) - tc.setVarsFromJSON(t, `{ - "rider": "users:001", - "driver": "users:002" - }`) - tc.setBalance("users:001", "GEM", 15) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(13), - Source: "users:001", - Destination: "users:002", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(1), - Source: "users:001", - Destination: "a", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(1), - Source: "users:001", - Destination: "b", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestDynamicAllocation(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `vars { - portion $p - } - send [GEM 15] ( - source = @a - destination = { - 80% to @b - $p to @c - remaining to @d - } - )`) - tc.setVarsFromJSON(t, `{ - "p": "15%" - }`) - tc.setBalance("a", "GEM", 15) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(13), - Source: "a", - Destination: "b", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(2), - Source: "a", - Destination: "c", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestSendAll(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [USD/2 *] ( - source = @users:001 - destination = @platform - )`) - tc.setBalance("users:001", "USD/2", 17) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD/2", - Amount: internal.NewMonetaryInt(17), - Source: "users:001", - Destination: "platform", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestSendAllMulti(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [USD/2 *] ( - source = { - @users:001:wallet - @users:001:credit - } - destination = @platform - ) - `) - tc.setBalance("users:001:wallet", "USD/2", 19) - tc.setBalance("users:001:credit", "USD/2", 22) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD/2", - Amount: internal.NewMonetaryInt(19), - Source: "users:001:wallet", - Destination: "platform", - }, - { - Asset: "USD/2", - Amount: internal.NewMonetaryInt(22), - Source: "users:001:credit", - Destination: "platform", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestInsufficientFunds(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `vars { - account $balance - account $payment - account $seller - } - send [GEM 16] ( - source = { - $balance - $payment - } - destination = $seller - )`) - tc.setVarsFromJSON(t, `{ - "balance": "users:001", - "payment": "payments:001", - "seller": "users:002" - }`) - tc.setBalance("users:001", "GEM", 3) - tc.setBalance("payments:001", "GEM", 12) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{}, - Error: ErrInsufficientFund, - } - test(t, tc) -} - -func TestWorldSource(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [GEM 15] ( - source = { - @a - @world - } - destination = @b - )`) - tc.setBalance("a", "GEM", 1) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(1), - Source: "a", - Destination: "b", - }, - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(14), - Source: "world", - Destination: "b", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestNoEmptyPostings(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [GEM 2] ( - source = @world - destination = { - 90% to @a - 10% to @b - } - )`) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "GEM", - Amount: internal.NewMonetaryInt(2), - Source: "world", - Destination: "a", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestEmptyPostings(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [GEM *] ( - source = @foo - destination = @bar - )`) - tc.setBalance("foo", "GEM", 0) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Source: "foo", - Destination: "bar", - Amount: internal.NewMonetaryInt(0), - Asset: "GEM", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestAllocateDontTakeTooMuch(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [CREDIT 200] ( - source = { - @users:001 - @users:002 - } - destination = { - 1/2 to @foo - 1/2 to @bar - } - )`) - tc.setBalance("users:001", "CREDIT", 100) - tc.setBalance("users:002", "CREDIT", 110) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "CREDIT", - Amount: internal.NewMonetaryInt(100), - Source: "users:001", - Destination: "foo", - }, - { - Asset: "CREDIT", - Amount: internal.NewMonetaryInt(100), - Source: "users:002", - Destination: "bar", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestMetadata(t *testing.T) { - //commission, _ := internal.NewPortionSpecific(*big.NewRat(125, 1000)) - tc := NewTestCase() - tc.compile(t, `vars { - account $sale - account $seller = meta($sale, "seller") - portion $commission = meta($seller, "commission") - } - send [EUR/2 100] ( - source = $sale - destination = { - remaining to $seller - $commission to @platform - } - )`) - tc.setVarsFromJSON(t, `{ - "sale": "sales:042" - }`) - tc.meta = map[string]metadata.Metadata{ - "sales:042": { - "seller": "users:053", - }, - "users:053": { - "commission": "12.5%", - }, - } - tc.setBalance("sales:042", "EUR/2", 2500) - tc.setBalance("users:053", "EUR/2", 500) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "EUR/2", - Amount: internal.NewMonetaryInt(88), - Source: "sales:042", - Destination: "users:053", - }, - { - Asset: "EUR/2", - Amount: internal.NewMonetaryInt(12), - Source: "sales:042", - Destination: "platform", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestTrackBalances(t *testing.T) { - tc := NewTestCase() - tc.compile(t, ` - send [COIN 50] ( - source = @world - destination = @a - ) - send [COIN 100] ( - source = @a - destination = @b - )`) - tc.setBalance("a", "COIN", 50) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(50), - Source: "world", - Destination: "a", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(100), - Source: "a", - Destination: "b", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestTrackBalances2(t *testing.T) { - tc := NewTestCase() - tc.compile(t, ` - send [COIN 50] ( - source = @a - destination = @z - ) - send [COIN 50] ( - source = @a - destination = @z - )`) - tc.setBalance("a", "COIN", 60) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{}, - Error: ErrInsufficientFund, - } - test(t, tc) -} - -func TestTrackBalances3(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [COIN *] ( - source = @foo - destination = { - max [COIN 1000] to @bar - remaining kept - } - ) - send [COIN *] ( - source = @foo - destination = @bar - )`) - tc.setBalance("foo", "COIN", 2000) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(1000), - Source: "foo", - Destination: "bar", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(1000), - Source: "foo", - Destination: "bar", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestSourceAllotment(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [COIN 100] ( - source = { - 60% from @a - 35.5% from @b - 4.5% from @c - } - destination = @d - )`) - tc.setBalance("a", "COIN", 100) - tc.setBalance("b", "COIN", 100) - tc.setBalance("c", "COIN", 100) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(61), - Source: "a", - Destination: "d", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(35), - Source: "b", - Destination: "d", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(4), - Source: "c", - Destination: "d", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestSourceOverlapping(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [COIN 99] ( - source = { - 15% from { - @b - @a - } - 30% from @a - remaining from @a - } - destination = @world - )`) - tc.setBalance("a", "COIN", 99) - tc.setBalance("b", "COIN", 3) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(3), - Source: "b", - Destination: "world", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(96), - Source: "a", - Destination: "world", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestSourceComplex(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `vars { - monetary $max - } - send [COIN 200] ( - source = { - 50% from { - max [COIN 4] from @a - @b - @c - } - remaining from max $max from @d - } - destination = @platform - )`) - tc.setVarsFromJSON(t, `{ - "max": "COIN 120" - }`) - tc.setBalance("a", "COIN", 1000) - tc.setBalance("b", "COIN", 40) - tc.setBalance("c", "COIN", 1000) - tc.setBalance("d", "COIN", 1000) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(4), - Source: "a", - Destination: "platform", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(40), - Source: "b", - Destination: "platform", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(56), - Source: "c", - Destination: "platform", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(100), - Source: "d", - Destination: "platform", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestDestinationComplex(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `send [COIN 100] ( - source = @world - destination = { - 20% to @a - 20% kept - 60% to { - max [COIN 10] to @b - remaining to @c - } - } - )`) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(20), - Source: "world", - Destination: "a", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(10), - Source: "world", - Destination: "b", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(50), - Source: "world", - Destination: "c", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestNeededBalances(t *testing.T) { - p, err := compiler.Compile(`vars { - account $a - } - send [GEM 15] ( - source = { - $a - @b - @world - } - destination = @c - )`) - - if err != nil { - t.Fatalf("did not expect error on Compile, got: %v", err) - } - - m := NewMachine(*p) - - err = m.SetVarsFromJSON(map[string]string{ - "a": "a", - }) - if err != nil { - t.Fatalf("did not expect error on SetVars, got: %v", err) - } - _, _, err = m.ResolveResources(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.ResolveBalances(context.Background(), EmptyStore) - require.NoError(t, err) -} - -func TestSetTxMeta(t *testing.T) { - p, err := compiler.Compile(` - set_tx_meta("aaa", @platform) - set_tx_meta("bbb", GEM) - set_tx_meta("ccc", 45) - set_tx_meta("ddd", "hello") - set_tx_meta("eee", [COIN 30]) - set_tx_meta("fff", 15%) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - _, _, err = m.ResolveResources(context.Background(), EmptyStore) - require.NoError(t, err) - err = m.ResolveBalances(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.Execute() - require.NoError(t, err) - - expectedMeta := map[string]string{ - "aaa": "platform", - "bbb": "GEM", - "ccc": "45", - "ddd": "hello", - "eee": "COIN 30", - "fff": "3/20", - } - - resMeta := m.GetTxMetaJSON() - assert.Equal(t, 6, len(resMeta)) - - for key, val := range resMeta { - assert.Equal(t, string(expectedMeta[key]), val) - } -} - -func TestSetAccountMeta(t *testing.T) { - t.Run("all types", func(t *testing.T) { - p, err := compiler.Compile(` - set_account_meta(@platform, "aaa", @platform) - set_account_meta(@platform, "bbb", GEM) - set_account_meta(@platform, "ccc", 45) - set_account_meta(@platform, "ddd", "hello") - set_account_meta(@platform, "eee", [COIN 30]) - set_account_meta(@platform, "fff", 15%)`) - require.NoError(t, err) - - m := NewMachine(*p) - - _, _, err = m.ResolveResources(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.ResolveBalances(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.Execute() - require.NoError(t, err) - - expectedMeta := metadata.Metadata{ - "aaa": "platform", - "bbb": "GEM", - "ccc": "45", - "ddd": "hello", - "eee": "COIN 30", - "fff": "3/20", - } - - resMeta := m.GetAccountsMetaJSON() - assert.Equal(t, 1, len(resMeta)) - - for acc, meta := range resMeta { - assert.Equal(t, "platform", acc) - assert.Equal(t, 6, len(meta)) - for key, val := range meta { - assert.Equal(t, expectedMeta[key], val) - } - } - }) - - t.Run("with vars", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - account $acc - } - send [EUR/2 100] ( - source = @world - destination = $acc - ) - set_account_meta($acc, "fees", 1%) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "acc": "test", - })) - - _, _, err = m.ResolveResources(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.ResolveBalances(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.Execute() - require.NoError(t, err) - - expectedMeta := map[string]json.RawMessage{ - "fees": json.RawMessage("1/100"), - } - - resMeta := m.GetAccountsMetaJSON() - assert.Equal(t, 1, len(resMeta)) - - for acc, meta := range resMeta { - assert.Equal(t, "test", acc) - assert.Equal(t, 1, len(meta)) - for key, val := range meta { - assert.Equal(t, string(expectedMeta[key]), val) - } - } - }) -} - -func TestVariableBalance(t *testing.T) { - script := ` - vars { - monetary $initial = balance(@A, USD/2) - } - send [USD/2 100] ( - source = { - @A - @C - } - destination = { - max $initial to @B - remaining to @D - } - )` - - t.Run("1", func(t *testing.T) { - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("A", "USD/2", 40) - tc.setBalance("C", "USD/2", 90) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD/2", - Amount: internal.NewMonetaryInt(40), - Source: "A", - Destination: "B", - }, - { - Asset: "USD/2", - Amount: internal.NewMonetaryInt(60), - Source: "C", - Destination: "D", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("2", func(t *testing.T) { - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("A", "USD/2", 400) - tc.setBalance("C", "USD/2", 90) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD/2", - Amount: internal.NewMonetaryInt(100), - Source: "A", - Destination: "B", - }, - }, - Error: nil, - } - test(t, tc) - }) - - script = ` - vars { - account $acc - monetary $initial = balance($acc, USD/2) - } - send [USD/2 100] ( - source = { - $acc - @C - } - destination = { - max $initial to @B - remaining to @D - } - )` - - t.Run("3", func(t *testing.T) { - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("A", "USD/2", 40) - tc.setBalance("C", "USD/2", 90) - tc.setVarsFromJSON(t, `{"acc": "A"}`) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD/2", - Amount: internal.NewMonetaryInt(40), - Source: "A", - Destination: "B", - }, - { - Asset: "USD/2", - Amount: internal.NewMonetaryInt(60), - Source: "C", - Destination: "D", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("4", func(t *testing.T) { - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("A", "USD/2", 400) - tc.setBalance("C", "USD/2", 90) - tc.setVarsFromJSON(t, `{"acc": "A"}`) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD/2", - Amount: internal.NewMonetaryInt(100), - Source: "A", - Destination: "B", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("5", func(t *testing.T) { - tc := NewTestCase() - tc.compile(t, ` - vars { - monetary $max = balance(@maxAcc, COIN) - } - send [COIN 200] ( - source = { - 50% from { - max [COIN 4] from @a - @b - @c - } - remaining from max $max from @d - } - destination = @platform - )`) - tc.setBalance("maxAcc", "COIN", 120) - tc.setBalance("a", "COIN", 1000) - tc.setBalance("b", "COIN", 40) - tc.setBalance("c", "COIN", 1000) - tc.setBalance("d", "COIN", 1000) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(4), - Source: "a", - Destination: "platform", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(40), - Source: "b", - Destination: "platform", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(56), - Source: "c", - Destination: "platform", - }, - { - Asset: "COIN", - Amount: internal.NewMonetaryInt(100), - Source: "d", - Destination: "platform", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("send negative monetary", func(t *testing.T) { - tc := NewTestCase() - script = ` - vars { - monetary $amount = balance(@world, USD/2) - } - send $amount ( - source = @A - destination = @B - )` - tc.compile(t, script) - tc.setBalance("world", "USD/2", -40) - tc.expected = CaseResult{ - Error: ErrNegativeMonetaryAmount, - ErrorContains: "must be non-negative", - } - test(t, tc) - }) -} - -func TestVariablesParsing(t *testing.T) { - t.Run("account", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - account $acc - } - set_tx_meta("account", $acc) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "acc": "valid:acc", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "acc": "invalid-acc", - })) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "acc": "valid:acc", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "acc": "invalid-acc", - })) - }) - - t.Run("asset", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - asset $ass - } - set_tx_meta("asset", $ass) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "ass": "USD/2", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "ass": "USD-2", - })) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "ass": "USD/2", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "ass": "USD-2", - })) - }) - - t.Run("monetary", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - monetary $mon - } - set_tx_meta("monetary", $mon) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "mon": "EUR/2 100", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "mon": "invalid-asset 100", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "mon": "EUR/2", - })) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "mon": "EUR/2 100", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "mon": "invalid-asset 100", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "mon": "EUR/2 null", - })) - }) - - t.Run("portion", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - portion $por - } - set_tx_meta("portion", $por) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "por": "1/2", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "por": "", - })) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "por": "1/2", - })) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "por": "50%", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "por": "3/2", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "por": "200%", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "por": "", - })) - }) - - t.Run("string", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - string $str - } - set_tx_meta("string", $str) - `) - require.NoError(t, err) - - m := NewMachine(*p) - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "str": "valid string", - })) - }) - - t.Run("number", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - number $nbr - } - set_tx_meta("number", $nbr) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - require.NoError(t, m.SetVarsFromJSON(map[string]string{ - "nbr": "100", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "nbr": "string", - })) - - require.Error(t, m.SetVarsFromJSON(map[string]string{ - "nbr": `nil`, - })) - }) - - t.Run("missing variable", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - number $nbr - string $str - } - set_tx_meta("number", $nbr) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - require.ErrorContains(t, m.SetVarsFromJSON(map[string]string{ - "nbr": "100", - }), "missing variable $str") - }) - - t.Run("extraneous variable SetVars", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - number $nbr - } - set_tx_meta("number", $nbr) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - require.ErrorContains(t, m.SetVarsFromJSON(map[string]string{ - "nbr": "100", - "nbr2": "100", - }), "extraneous variable $nbr2") - }) - - t.Run("extraneous variable SetVarsFromJSON", func(t *testing.T) { - p, err := compiler.Compile(` - vars { - number $nbr - } - set_tx_meta("number", $nbr) - `) - require.NoError(t, err) - - m := NewMachine(*p) - - require.ErrorContains(t, m.SetVarsFromJSON(map[string]string{ - "nbr": `100`, - "nbr2": `100`, - }), "extraneous variable $nbr2") - }) -} - -func TestVariablesErrors(t *testing.T) { - tc := NewTestCase() - tc.compile(t, `vars { - monetary $mon - } - send $mon ( - source = @alice - destination = @bob - )`) - tc.setBalance("alice", "COIN", 10) - tc.vars = map[string]string{ - "mon": "COIN -1", - } - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{}, - Error: ErrInvalidVars, - ErrorContains: "negative amount", - } - test(t, tc) -} - -func TestSetVarsFromJSON(t *testing.T) { - - type testCase struct { - name string - script string - expectedError error - vars map[string]string - } - for _, tc := range []testCase{ - { - name: "missing var", - script: `vars { - account $dest - } - send [COIN 99] ( - source = @world - destination = $dest - )`, - expectedError: fmt.Errorf("missing variable $dest"), - }, - { - name: "invalid format for account", - script: `vars { - account $dest - } - send [COIN 99] ( - source = @world - destination = $dest - )`, - vars: map[string]string{ - "dest": "invalid-acc", - }, - expectedError: fmt.Errorf("invalid JSON value for variable $dest of type account: value invalid-acc: accounts should respect pattern ^[a-zA-Z_]+[a-zA-Z0-9_:]*$"), - }, - } { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - p, err := compiler.Compile(tc.script) - require.NoError(t, err) - - m := NewMachine(*p) - err = m.SetVarsFromJSON(tc.vars) - if tc.expectedError != nil { - require.Error(t, err) - //TODO(gfyrag): refine error handling of SetVars/ResolveResources/ResolveBalances - require.Equal(t, tc.expectedError.Error(), err.Error()) - } else { - require.Nil(t, err) - } - }) - } -} - -func TestResolveResources(t *testing.T) { - - type testCase struct { - name string - script string - expectedError error - vars map[string]string - } - for _, tc := range []testCase{ - { - name: "missing metadata", - script: `vars { - account $sale - account $seller = meta($sale, "seller") - } - send [COIN *] ( - source = $sale - destination = $seller - )`, - vars: map[string]string{ - "sale": "sales:042", - }, - expectedError: ErrResourceResolutionMissingMetadata, - }, - } { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - p, err := compiler.Compile(tc.script) - require.NoError(t, err) - - m := NewMachine(*p) - require.NoError(t, m.SetVarsFromJSON(tc.vars)) - _, _, err = m.ResolveResources(context.Background(), EmptyStore) - if tc.expectedError != nil { - require.Error(t, err) - require.True(t, errors.Is(err, tc.expectedError)) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestResolveBalances(t *testing.T) { - - type testCase struct { - name string - script string - expectedError error - vars map[string]string - store Store - } - for _, tc := range []testCase{ - { - name: "balance function with negative balance", - store: StaticStore{ - "users:001": &AccountWithBalances{ - Account: core.Account{ - Address: "users:001", - Metadata: metadata.Metadata{}, - }, - Balances: map[string]*big.Int{ - "COIN": big.NewInt(-100), - }, - }, - }, - script: ` - vars { - monetary $bal = balance(@users:001, COIN) - } - send $bal ( - source = @users:001 - destination = @world - )`, - expectedError: ErrNegativeMonetaryAmount, - }, - } { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - p, err := compiler.Compile(tc.script) - require.NoError(t, err) - - m := NewMachine(*p) - require.NoError(t, m.SetVarsFromJSON(tc.vars)) - _, _, err = m.ResolveResources(context.Background(), EmptyStore) - require.NoError(t, err) - - store := tc.store - if store == nil { - store = EmptyStore - } - - err = m.ResolveBalances(context.Background(), store) - if tc.expectedError != nil { - require.Error(t, err) - require.True(t, errors.Is(err, tc.expectedError)) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestMachine(t *testing.T) { - p, err := compiler.Compile(` - vars { - account $dest - } - send [COIN 99] ( - source = @world - destination = $dest - )`) - require.NoError(t, err) - - t.Run("with debug", func(t *testing.T) { - m := NewMachine(*p) - m.Debug = true - - err = m.SetVarsFromJSON(map[string]string{ - "dest": "charlie", - }) - require.NoError(t, err) - - _, _, err := m.ResolveResources(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.ResolveBalances(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.Execute() - require.NoError(t, err) - }) - - t.Run("err resources", func(t *testing.T) { - m := NewMachine(*p) - err := m.Execute() - require.True(t, errors.Is(err, ErrResourcesNotInitialized)) - }) - - t.Run("err balances not initialized", func(t *testing.T) { - m := NewMachine(*p) - - err = m.SetVarsFromJSON(map[string]string{ - "dest": "charlie", - }) - require.NoError(t, err) - - _, _, err := m.ResolveResources(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.Execute() - require.True(t, errors.Is(err, ErrBalancesNotInitialized)) - }) - - t.Run("err resolve resources twice", func(t *testing.T) { - m := NewMachine(*p) - - err = m.SetVarsFromJSON(map[string]string{ - "dest": "charlie", - }) - require.NoError(t, err) - - _, _, err := m.ResolveResources(context.Background(), EmptyStore) - require.NoError(t, err) - - _, _, err = m.ResolveResources(context.Background(), EmptyStore) - require.ErrorContains(t, err, "tried to call ResolveResources twice") - }) - - t.Run("err balances before resources", func(t *testing.T) { - m := NewMachine(*p) - - err := m.ResolveBalances(context.Background(), EmptyStore) - require.ErrorContains(t, err, "tried to resolve balances before resources") - }) - - t.Run("err resolve balances twice", func(t *testing.T) { - m := NewMachine(*p) - - err = m.SetVarsFromJSON(map[string]string{ - "dest": "charlie", - }) - require.NoError(t, err) - - _, _, err := m.ResolveResources(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.ResolveBalances(context.Background(), EmptyStore) - require.NoError(t, err) - - err = m.ResolveBalances(context.Background(), EmptyStore) - require.ErrorContains(t, err, "tried to call ResolveBalances twice") - }) - - t.Run("err missing var", func(t *testing.T) { - m := NewMachine(*p) - - _, _, err := m.ResolveResources(context.Background(), EmptyStore) - require.Error(t, err) - }) -} - -func TestVariableAsset(t *testing.T) { - script := ` - vars { - asset $ass - monetary $bal = balance(@alice, $ass) - } - - send [$ass 15] ( - source = { - @alice - @bob - } - destination = @swap - ) - - send [$ass *] ( - source = @swap - destination = { - max $bal to @alice_2 - remaining to @bob_2 - } - )` - - tc := NewTestCase() - tc.compile(t, script) - tc.vars = map[string]string{ - "ass": "USD", - } - tc.setBalance("alice", "USD", 10) - tc.setBalance("bob", "USD", 10) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD", - Amount: internal.NewMonetaryInt(10), - Source: "alice", - Destination: "swap", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(5), - Source: "bob", - Destination: "swap", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(10), - Source: "swap", - Destination: "alice_2", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(5), - Source: "swap", - Destination: "bob_2", - }, - }, - Error: nil, - } - test(t, tc) -} - -func TestSaveFromAccount(t *testing.T) { - t.Run("simple", func(t *testing.T) { - script := ` - save [USD 10] from @alice - - send [USD 30] ( - source = { - @alice - @world - } - destination = @bob - )` - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("alice", "USD", 20) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD", - Amount: internal.NewMonetaryInt(10), - Source: "alice", - Destination: "bob", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(20), - Source: "world", - Destination: "bob", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("save all", func(t *testing.T) { - script := ` - save [USD *] from @alice - - send [USD 30] ( - source = { - @alice - @world - } - destination = @bob - )` - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("alice", "USD", 20) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD", - Amount: internal.NewMonetaryInt(0), - Source: "alice", - Destination: "bob", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(30), - Source: "world", - Destination: "bob", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("save more than balance", func(t *testing.T) { - script := ` - save [USD 30] from @alice - - send [USD 30] ( - source = { - @alice - @world - } - destination = @bob - )` - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("alice", "USD", 20) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD", - Amount: internal.NewMonetaryInt(0), - Source: "alice", - Destination: "bob", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(30), - Source: "world", - Destination: "bob", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("with asset var", func(t *testing.T) { - script := ` - vars { - asset $ass - } - save [$ass 10] from @alice - - send [$ass 30] ( - source = { - @alice - @world - } - destination = @bob - )` - tc := NewTestCase() - tc.compile(t, script) - tc.vars = map[string]string{ - "ass": "USD", - } - tc.setBalance("alice", "USD", 20) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD", - Amount: internal.NewMonetaryInt(10), - Source: "alice", - Destination: "bob", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(20), - Source: "world", - Destination: "bob", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("with monetary var", func(t *testing.T) { - script := ` - vars { - monetary $mon - } - - save $mon from @alice - - send [USD 30] ( - source = { - @alice - @world - } - destination = @bob - )` - tc := NewTestCase() - tc.compile(t, script) - tc.vars = map[string]string{ - "mon": "USD 10", - } - tc.setBalance("alice", "USD", 20) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD", - Amount: internal.NewMonetaryInt(10), - Source: "alice", - Destination: "bob", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(20), - Source: "world", - Destination: "bob", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("multi postings", func(t *testing.T) { - script := ` - send [USD 10] ( - source = @alice - destination = @bob - ) - - save [USD 5] from @alice - - send [USD 30] ( - source = { - @alice - @world - } - destination = @bob - )` - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("alice", "USD", 20) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD", - Amount: internal.NewMonetaryInt(10), - Source: "alice", - Destination: "bob", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(5), - Source: "alice", - Destination: "bob", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(25), - Source: "world", - Destination: "bob", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("save a different asset", func(t *testing.T) { - script := ` - save [COIN 100] from @alice - - send [USD 30] ( - source = { - @alice - @world - } - destination = @bob - )` - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("alice", "COIN", 100) - tc.setBalance("alice", "USD", 20) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{ - { - Asset: "USD", - Amount: internal.NewMonetaryInt(20), - Source: "alice", - Destination: "bob", - }, - { - Asset: "USD", - Amount: internal.NewMonetaryInt(10), - Source: "world", - Destination: "bob", - }, - }, - Error: nil, - } - test(t, tc) - }) - - t.Run("negative amount", func(t *testing.T) { - script := ` - vars { - monetary $amt = balance(@A, USD) - } - save $amt from @A` - tc := NewTestCase() - tc.compile(t, script) - tc.setBalance("A", "USD", -100) - tc.expected = CaseResult{ - Printed: []internal.Value{}, - Postings: []Posting{}, - Error: ErrNegativeMonetaryAmount, - } - test(t, tc) - }) -} diff --git a/components/ledger/pkg/machine/vm/program/program.go b/components/ledger/pkg/machine/vm/program/program.go deleted file mode 100644 index 6083e361a..000000000 --- a/components/ledger/pkg/machine/vm/program/program.go +++ /dev/null @@ -1,112 +0,0 @@ -package program - -import ( - "encoding/binary" - "fmt" - - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/pkg/errors" -) - -type Program struct { - Instructions []byte - Resources []Resource - Sources []internal.Address - NeededBalances map[internal.Address]map[internal.Address]struct{} -} - -func (p Program) String() string { - out := "Program:\nINSTRUCTIONS\n" - for i := 0; i < len(p.Instructions); i++ { - out += fmt.Sprintf("%02d----- ", i) - switch p.Instructions[i] { - case OP_APUSH: - out += "OP_APUSH " - address := binary.LittleEndian.Uint16(p.Instructions[i+1 : i+3]) - out += fmt.Sprintf("#%d\n", address) - i += 2 - default: - out += OpcodeName(p.Instructions[i]) + "\n" - } - } - - out += fmt.Sprintln("RESOURCES") - i := 0 - for i = 0; i < len(p.Resources); i++ { - out += fmt.Sprintf("%02d ", i) - out += fmt.Sprintf("%v\n", p.Resources[i]) - } - return out -} - -func (p *Program) ParseVariables(vars map[string]internal.Value) (map[string]internal.Value, error) { - variables := make(map[string]internal.Value) - for _, res := range p.Resources { - if variable, ok := res.(Variable); ok { - if val, ok := vars[variable.Name]; ok && val.GetType() == variable.Typ { - variables[variable.Name] = val - switch val.GetType() { - case internal.TypeAccount: - if err := internal.ValidateAccountAddress(val.(internal.AccountAddress)); err != nil { - return nil, errors.Wrapf(err, "invalid variable $%s value '%s'", - variable.Name, string(val.(internal.AccountAddress))) - } - case internal.TypeAsset: - if err := internal.ValidateAsset(val.(internal.Asset)); err != nil { - return nil, errors.Wrapf(err, "invalid variable $%s value '%s'", - variable.Name, string(val.(internal.Asset))) - } - case internal.TypeMonetary: - if err := internal.ParseMonetary(val.(internal.Monetary)); err != nil { - return nil, errors.Wrapf(err, "invalid variable $%s value '%s'", - variable.Name, val.(internal.Monetary).String()) - } - case internal.TypePortion: - if err := internal.ValidatePortionSpecific(val.(internal.Portion)); err != nil { - return nil, errors.Wrapf(err, "invalid variable $%s value '%s'", - variable.Name, val.(internal.Portion).String()) - } - case internal.TypeString: - case internal.TypeNumber: - default: - return nil, fmt.Errorf("unsupported type for variable $%s: %s", - variable.Name, val.GetType()) - } - delete(vars, variable.Name) - } else if val, ok := vars[variable.Name]; ok && val.GetType() != variable.Typ { - return nil, fmt.Errorf("wrong type for variable $%s: %s instead of %s", - variable.Name, variable.Typ, val.GetType()) - } else { - return nil, fmt.Errorf("missing variable $%s", variable.Name) - } - } - } - for name := range vars { - return nil, fmt.Errorf("extraneous variable $%s", name) - } - return variables, nil -} - -func (p *Program) ParseVariablesJSON(vars map[string]string) (map[string]internal.Value, error) { - variables := make(map[string]internal.Value) - for _, res := range p.Resources { - if param, ok := res.(Variable); ok { - data, ok := vars[param.Name] - if !ok { - return nil, fmt.Errorf("missing variable $%s", param.Name) - } - val, err := internal.NewValueFromString(param.Typ, data) - if err != nil { - return nil, fmt.Errorf( - "invalid JSON value for variable $%s of type %v: %w", - param.Name, param.Typ, err) - } - variables[param.Name] = val - delete(vars, param.Name) - } - } - for name := range vars { - return nil, fmt.Errorf("extraneous variable $%s", name) - } - return variables, nil -} diff --git a/components/ledger/pkg/machine/vm/program/resource.go b/components/ledger/pkg/machine/vm/program/resource.go deleted file mode 100644 index 250fdf3ee..000000000 --- a/components/ledger/pkg/machine/vm/program/resource.go +++ /dev/null @@ -1,59 +0,0 @@ -package program - -import ( - "fmt" - - "github.com/formancehq/ledger/pkg/machine/internal" -) - -type Resource interface { - GetType() internal.Type -} - -type Constant struct { - Inner internal.Value -} - -func (c Constant) GetType() internal.Type { return c.Inner.GetType() } -func (c Constant) String() string { return fmt.Sprintf("%v", c.Inner) } - -type Variable struct { - Typ internal.Type - Name string -} - -func (p Variable) GetType() internal.Type { return p.Typ } -func (p Variable) String() string { return fmt.Sprintf("<%v %v>", p.Typ, p.Name) } - -type VariableAccountMetadata struct { - Typ internal.Type - Name string - Account internal.Address - Key string -} - -func (m VariableAccountMetadata) GetType() internal.Type { return m.Typ } -func (m VariableAccountMetadata) String() string { - return fmt.Sprintf("<%v %v meta(%v, %v)>", m.Typ, m.Name, m.Account, m.Key) -} - -type VariableAccountBalance struct { - Name string - Account internal.Address - Asset internal.Address -} - -func (a VariableAccountBalance) GetType() internal.Type { return internal.TypeMonetary } -func (a VariableAccountBalance) String() string { - return fmt.Sprintf("<%v %v balance(%v, %v)>", internal.TypeMonetary, a.Name, a.Account, a.Asset) -} - -type Monetary struct { - Asset internal.Address - Amount *internal.MonetaryInt -} - -func (a Monetary) GetType() internal.Type { return internal.TypeMonetary } -func (a Monetary) String() string { - return fmt.Sprintf("<%v [%v %v]>", internal.TypeMonetary, a.Asset, a.Amount) -} diff --git a/components/ledger/pkg/machine/vm/program/resource_test.go b/components/ledger/pkg/machine/vm/program/resource_test.go deleted file mode 100644 index 83756c0c5..000000000 --- a/components/ledger/pkg/machine/vm/program/resource_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package program - -import ( - "testing" - - "github.com/formancehq/ledger/pkg/machine/internal" - "github.com/stretchr/testify/require" -) - -func TestResource(t *testing.T) { - c := Constant{ - Inner: internal.NewMonetaryInt(0), - } - c.GetType() - require.Equal(t, "0", c.String()) - - v := Variable{ - Typ: internal.TypeAccount, - Name: "acc", - } - require.Equal(t, "", v.String()) - - vab := VariableAccountBalance{ - Name: "name", - Account: internal.Address(0), - Asset: internal.Address(1), - } - require.Equal(t, "", vab.String()) - - vam := VariableAccountMetadata{ - Typ: internal.TypeMonetary, - Name: "name", - Account: internal.Address(0), - Key: "key", - } - require.Equal(t, "", vam.String()) -} diff --git a/components/ledger/pkg/machine/vm/store.go b/components/ledger/pkg/machine/vm/store.go deleted file mode 100644 index a78b01914..000000000 --- a/components/ledger/pkg/machine/vm/store.go +++ /dev/null @@ -1,63 +0,0 @@ -package vm - -import ( - "context" - "math/big" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" -) - -type Store interface { - GetBalanceFromLogs(ctx context.Context, address, asset string) (*big.Int, error) - GetMetadataFromLogs(ctx context.Context, address, key string) (string, error) -} - -type emptyStore struct{} - -func (e *emptyStore) GetBalanceFromLogs(ctx context.Context, address, asset string) (*big.Int, error) { - return new(big.Int), nil -} - -func (e *emptyStore) GetMetadataFromLogs(ctx context.Context, address, key string) (string, error) { - return "", storageerrors.ErrNotFound -} - -var _ Store = (*emptyStore)(nil) - -var EmptyStore = &emptyStore{} - -type AccountWithBalances struct { - core.Account - Balances map[string]*big.Int -} - -type StaticStore map[string]*AccountWithBalances - -func (s StaticStore) GetBalanceFromLogs(ctx context.Context, address, asset string) (*big.Int, error) { - account, ok := s[address] - if !ok { - return new(big.Int), nil - } - balance, ok := account.Balances[asset] - if !ok { - return new(big.Int), nil - } - - return balance, nil -} - -func (s StaticStore) GetMetadataFromLogs(ctx context.Context, address, key string) (string, error) { - account, ok := s[address] - if !ok { - return "", nil - } - metadata, ok := account.Metadata[key] - if !ok { - return "", storageerrors.ErrNotFound - } - - return metadata, nil -} - -var _ Store = StaticStore{} diff --git a/components/ledger/pkg/opentelemetry/metrics/metrics.go b/components/ledger/pkg/opentelemetry/metrics/metrics.go deleted file mode 100644 index 593b8ac4c..000000000 --- a/components/ledger/pkg/opentelemetry/metrics/metrics.go +++ /dev/null @@ -1,233 +0,0 @@ -package metrics - -import ( - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" -) - -type GlobalRegistry interface { - APILatencies() metric.Int64Histogram - StatusCodes() metric.Int64Counter - ActiveLedgers() metric.Int64UpDownCounter -} - -type globalRegistry struct { - // API Latencies - apiLatencies metric.Int64Histogram - statusCodes metric.Int64Counter - activeLedgers metric.Int64UpDownCounter -} - -func RegisterGlobalRegistry(meterProvider metric.MeterProvider) (GlobalRegistry, error) { - meter := meterProvider.Meter("global") - - apiLatencies, err := meter.Int64Histogram( - "ledger.api.time", - metric.WithUnit("ms"), - metric.WithDescription("Latency of API calls"), - ) - if err != nil { - return nil, err - } - - statusCodes, err := meter.Int64Counter( - "ledger.api.status", - metric.WithUnit("1"), - metric.WithDescription("Status codes of API calls"), - ) - if err != nil { - return nil, err - } - - activeLedgers, err := meter.Int64UpDownCounter( - "ledger.api.ledgers", - metric.WithUnit("1"), - metric.WithDescription("Number of active ledgers"), - ) - if err != nil { - return nil, err - } - - return &globalRegistry{ - apiLatencies: apiLatencies, - statusCodes: statusCodes, - activeLedgers: activeLedgers, - }, nil -} - -func (gm *globalRegistry) APILatencies() metric.Int64Histogram { - return gm.apiLatencies -} - -func (gm *globalRegistry) StatusCodes() metric.Int64Counter { - return gm.statusCodes -} - -func (gm *globalRegistry) ActiveLedgers() metric.Int64UpDownCounter { - return gm.activeLedgers -} - -type PerLedgerRegistry interface { - CacheMisses() metric.Int64Counter - CacheNumberEntries() metric.Int64UpDownCounter - - QueryLatencies() metric.Int64Histogram - QueryInboundLogs() metric.Int64Counter - QueryPendingMessages() metric.Int64Counter - QueryProcessedLogs() metric.Int64Counter -} - -type perLedgerRegistry struct { - cacheMisses metric.Int64Counter - cacheNumberEntries metric.Int64UpDownCounter - - queryLatencies metric.Int64Histogram - queryInboundLogs metric.Int64Counter - queryPendingMessages metric.Int64Counter - queryProcessedLogs metric.Int64Counter -} - -func RegisterPerLedgerMetricsRegistry(ledger string) (PerLedgerRegistry, error) { - // we can now use the global meter provider to create a meter - // since it was created by the fx - meter := otel.GetMeterProvider().Meter(ledger) - - cacheMisses, err := meter.Int64Counter( - "ledger.cache.misses", - metric.WithUnit("1"), - metric.WithDescription("Cache misses"), - ) - if err != nil { - return nil, err - } - - cacheNumberEntries, err := meter.Int64UpDownCounter( - "ledger.cache.pending_entries", - metric.WithUnit("1"), - metric.WithDescription("Number of entries in the cache"), - ) - if err != nil { - return nil, err - } - - queryLatencies, err := meter.Int64Histogram( - "ledger.query.time", - metric.WithUnit("ms"), - metric.WithDescription("Latency of queries processing logs"), - ) - if err != nil { - return nil, err - } - - queryInboundLogs, err := meter.Int64Counter( - "ledger.query.inbound_logs", - metric.WithUnit("1"), - metric.WithDescription("Number of inbound logs in CQRS worker"), - ) - if err != nil { - return nil, err - } - - queryPendingMessages, err := meter.Int64Counter( - "ledger.query.pending_messages", - metric.WithUnit("1"), - metric.WithDescription("Number of pending messages in CQRS worker"), - ) - if err != nil { - return nil, err - } - - queryProcessedLogs, err := meter.Int64Counter( - "ledger.query.processed_logs", - metric.WithUnit("1"), - metric.WithDescription("Number of processed logs in CQRS worker"), - ) - if err != nil { - return nil, err - } - - return &perLedgerRegistry{ - cacheMisses: cacheMisses, - cacheNumberEntries: cacheNumberEntries, - queryLatencies: queryLatencies, - queryInboundLogs: queryInboundLogs, - queryPendingMessages: queryPendingMessages, - queryProcessedLogs: queryProcessedLogs, - }, nil -} - -func (pm *perLedgerRegistry) CacheMisses() metric.Int64Counter { - return pm.cacheMisses -} - -func (pm *perLedgerRegistry) CacheNumberEntries() metric.Int64UpDownCounter { - return pm.cacheNumberEntries -} - -func (pm *perLedgerRegistry) QueryLatencies() metric.Int64Histogram { - return pm.queryLatencies -} - -func (pm *perLedgerRegistry) QueryInboundLogs() metric.Int64Counter { - return pm.queryInboundLogs -} - -func (pm *perLedgerRegistry) QueryPendingMessages() metric.Int64Counter { - return pm.queryPendingMessages -} - -func (pm *perLedgerRegistry) QueryProcessedLogs() metric.Int64Counter { - return pm.queryProcessedLogs -} - -type noOpRegistry struct{} - -func NewNoOpRegistry() *noOpRegistry { - return &noOpRegistry{} -} - -func (nm *noOpRegistry) CacheMisses() metric.Int64Counter { - counter, _ := noop.NewMeterProvider().Meter("ledger").Int64Counter("cache_misses") - return counter -} - -func (nm *noOpRegistry) CacheNumberEntries() metric.Int64UpDownCounter { - counter, _ := noop.NewMeterProvider().Meter("ledger").Int64UpDownCounter("cache_number_entries") - return counter -} - -func (nm *noOpRegistry) QueryLatencies() metric.Int64Histogram { - histogram, _ := noop.NewMeterProvider().Meter("ledger").Int64Histogram("query_latencies") - return histogram -} - -func (nm *noOpRegistry) QueryInboundLogs() metric.Int64Counter { - counter, _ := noop.NewMeterProvider().Meter("ledger").Int64Counter("query_inbound_logs") - return counter -} - -func (nm *noOpRegistry) QueryPendingMessages() metric.Int64Counter { - counter, _ := noop.NewMeterProvider().Meter("ledger").Int64Counter("query_pending_messages") - return counter -} - -func (nm *noOpRegistry) QueryProcessedLogs() metric.Int64Counter { - counter, _ := noop.NewMeterProvider().Meter("ledger").Int64Counter("query_processed_logs") - return counter -} - -func (nm *noOpRegistry) APILatencies() metric.Int64Histogram { - histogram, _ := noop.NewMeterProvider().Meter("ledger").Int64Histogram("api_latencies") - return histogram -} - -func (nm *noOpRegistry) StatusCodes() metric.Int64Counter { - counter, _ := noop.NewMeterProvider().Meter("ledger").Int64Counter("status_codes") - return counter -} - -func (nm *noOpRegistry) ActiveLedgers() metric.Int64UpDownCounter { - counter, _ := noop.NewMeterProvider().Meter("ledger").Int64UpDownCounter("active_ledgers") - return counter -} diff --git a/components/ledger/pkg/storage/database.go b/components/ledger/pkg/storage/database.go deleted file mode 100644 index cee4ce71a..000000000 --- a/components/ledger/pkg/storage/database.go +++ /dev/null @@ -1,36 +0,0 @@ -package storage - -import ( - "context" - - "github.com/uptrace/bun" -) - -type Database struct { - db *bun.DB -} - -func (p *Database) Initialize(ctx context.Context) error { - _, err := p.db.ExecContext(ctx, "CREATE EXTENSION IF NOT EXISTS pgcrypto") - if err != nil { - return PostgresError(err) - } - _, err = p.db.ExecContext(ctx, "CREATE EXTENSION IF NOT EXISTS pg_trgm") - if err != nil { - return PostgresError(err) - } - return nil -} - -func (p *Database) Schema(name string) (Schema, error) { - return Schema{ - IDB: p.db, - name: name, - }, nil -} - -func NewDatabase(db *bun.DB) *Database { - return &Database{ - db: db, - } -} diff --git a/components/ledger/pkg/storage/driver/cli.go b/components/ledger/pkg/storage/driver/cli.go deleted file mode 100644 index ca7f38990..000000000 --- a/components/ledger/pkg/storage/driver/cli.go +++ /dev/null @@ -1,65 +0,0 @@ -package driver - -import ( - "context" - "io" - "time" - - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/health" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/uptrace/bun" - "go.uber.org/fx" -) - -// TODO(gfyrag): maybe move flag handling inside cmd/internal (as telemetry flags) -// Or make the inverse (move analytics flags to pkg/analytics) -// IMO, flags are more easily discoverable if located inside cmd/ -func InitCLIFlags(cmd *cobra.Command) { - cmd.PersistentFlags().Int(storage.StoreWorkerMaxPendingSize, 0, "Max pending size for store worker") - cmd.PersistentFlags().Int(storage.StoreWorkerMaxWriteChanSize, 1024, "Max write channel size for store worker") - cmd.PersistentFlags().String(storage.StoragePostgresConnectionStringFlag, "postgresql://localhost/postgres", "Postgres connection string") - cmd.PersistentFlags().Int(storage.StoragePostgresMaxIdleConnsFlag, 20, "Max idle connections to database") - cmd.PersistentFlags().Duration(storage.StoragePostgresConnMaxIdleTimeFlag, time.Minute, "Max idle time of idle connections") - cmd.PersistentFlags().Int(storage.StoragePostgresMaxOpenConns, 20, "Max open connections") -} - -type PostgresConfig struct { - ConnString string -} - -type ModuleConfig struct { - PostgresConnectionOptions storage.ConnectionOptions - Debug bool -} - -func CLIModule(v *viper.Viper, output io.Writer, debug bool) fx.Option { - - options := make([]fx.Option, 0) - options = append(options, fx.Provide(func() (*bun.DB, error) { - return storage.OpenSQLDB(storage.ConnectionOptionsFromFlags(v, output, debug)) - })) - options = append(options, fx.Provide(func(db *bun.DB) *storage.Database { - return storage.NewDatabase(db) - })) - options = append(options, fx.Provide(func(db *storage.Database) (*Driver, error) { - return New(db), nil - })) - options = append(options, health.ProvideHealthCheck(func(db *bun.DB) health.NamedCheck { - return health.NewNamedCheck("postgres", health.CheckFn(db.PingContext)) - })) - - options = append(options, fx.Invoke(func(db *bun.DB, driver *Driver, lifecycle fx.Lifecycle) error { - lifecycle.Append(fx.Hook{ - OnStart: driver.Initialize, - }) - lifecycle.Append(fx.Hook{ - OnStop: func(ctx context.Context) error { - return db.Close() - }, - }) - return nil - })) - return fx.Options(options...) -} diff --git a/components/ledger/pkg/storage/inmemory.go b/components/ledger/pkg/storage/inmemory.go deleted file mode 100644 index 0cedd69ee..000000000 --- a/components/ledger/pkg/storage/inmemory.go +++ /dev/null @@ -1,216 +0,0 @@ -package storage - -import ( - "context" - "sync" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "github.com/formancehq/stack/libs/go-libs/metadata" -) - -type InMemoryStore struct { - mu sync.Mutex - - Logs []*core.ChainedLog - Accounts map[string]*core.AccountWithVolumes - Transactions []*core.ExpandedTransaction -} - -func (m *InMemoryStore) MarkedLogsAsProjected(ctx context.Context, id uint64) error { - m.mu.Lock() - defer m.mu.Unlock() - - for _, log := range m.Logs { - if log.ID == id { - log.Projected = true - return nil - } - } - return nil -} - -func (m *InMemoryStore) InsertMoves(ctx context.Context, insert ...*core.Move) error { - m.mu.Lock() - defer m.mu.Unlock() - // TODO(gfyrag): to reflect the behavior of the real storage, we should compute accounts volumes there - return nil -} - -func (m *InMemoryStore) UpdateAccountsMetadata(ctx context.Context, update ...core.Account) error { - m.mu.Lock() - defer m.mu.Unlock() - for _, account := range update { - persistedAccount, ok := m.Accounts[account.Address] - if !ok { - m.Accounts[account.Address] = &core.AccountWithVolumes{ - Account: account, - Volumes: core.VolumesByAssets{}, - } - return nil - } - persistedAccount.Metadata = persistedAccount.Metadata.Merge(account.Metadata) - } - return nil -} - -func (m *InMemoryStore) InsertTransactions(ctx context.Context, insert ...core.Transaction) error { - m.mu.Lock() - defer m.mu.Unlock() - for _, transaction := range insert { - expandedTransaction := &core.ExpandedTransaction{ - Transaction: transaction, - PreCommitVolumes: core.AccountsAssetsVolumes{}, - PostCommitVolumes: core.AccountsAssetsVolumes{}, - } - for _, posting := range transaction.Postings { - account, ok := m.Accounts[posting.Source] - if !ok { - account = core.NewAccountWithVolumes(posting.Source) - m.Accounts[posting.Source] = account - } - - asset, ok := account.Volumes[posting.Asset] - if !ok { - asset = core.NewEmptyVolumes() - account.Volumes[posting.Asset] = asset - } - - account, ok = m.Accounts[posting.Destination] - if !ok { - account = core.NewAccountWithVolumes(posting.Destination) - m.Accounts[posting.Destination] = account - } - - asset, ok = account.Volumes[posting.Asset] - if !ok { - asset = core.NewEmptyVolumes() - account.Volumes[posting.Asset] = asset - } - } - for _, posting := range transaction.Postings { - expandedTransaction.PreCommitVolumes.AddOutput(posting.Source, posting.Asset, - m.Accounts[posting.Source].Volumes[posting.Asset].Output) - expandedTransaction.PreCommitVolumes.AddInput(posting.Source, posting.Asset, - m.Accounts[posting.Source].Volumes[posting.Asset].Input) - - expandedTransaction.PreCommitVolumes.AddOutput(posting.Destination, posting.Asset, - m.Accounts[posting.Destination].Volumes[posting.Asset].Output) - expandedTransaction.PreCommitVolumes.AddInput(posting.Destination, posting.Asset, - m.Accounts[posting.Destination].Volumes[posting.Asset].Input) - } - for _, posting := range transaction.Postings { - account := m.Accounts[posting.Source] - asset := account.Volumes[posting.Asset] - asset.Output = asset.Output.Add(asset.Output, posting.Amount) - - account = m.Accounts[posting.Destination] - asset = account.Volumes[posting.Asset] - asset.Input = asset.Input.Add(asset.Input, posting.Amount) - } - for _, posting := range transaction.Postings { - expandedTransaction.PostCommitVolumes.AddOutput(posting.Source, posting.Asset, - m.Accounts[posting.Source].Volumes[posting.Asset].Output) - expandedTransaction.PostCommitVolumes.AddInput(posting.Source, posting.Asset, - m.Accounts[posting.Source].Volumes[posting.Asset].Input) - - expandedTransaction.PostCommitVolumes.AddOutput(posting.Destination, posting.Asset, - m.Accounts[posting.Destination].Volumes[posting.Asset].Output) - expandedTransaction.PostCommitVolumes.AddInput(posting.Destination, posting.Asset, - m.Accounts[posting.Destination].Volumes[posting.Asset].Input) - } - - m.Transactions = append(m.Transactions, expandedTransaction) - } - return nil -} - -func (m *InMemoryStore) UpdateTransactionsMetadata(ctx context.Context, update ...core.TransactionWithMetadata) error { - m.mu.Lock() - defer m.mu.Unlock() - for _, tx := range update { - m.Transactions[tx.ID].Metadata = m.Transactions[tx.ID].Metadata.Merge(tx.Metadata) - } - return nil -} - -func (m *InMemoryStore) EnsureAccountsExist(ctx context.Context, accounts []string) error { - m.mu.Lock() - defer m.mu.Unlock() - for _, address := range accounts { - _, ok := m.Accounts[address] - if ok { - continue - } - m.Accounts[address] = &core.AccountWithVolumes{ - Account: core.Account{ - Address: address, - Metadata: metadata.Metadata{}, - }, - Volumes: core.VolumesByAssets{}, - } - } - return nil -} - -func (m *InMemoryStore) IsInitialized() bool { - return true -} - -func (m *InMemoryStore) GetNextLogID(ctx context.Context) (uint64, error) { - m.mu.Lock() - defer m.mu.Unlock() - for _, log := range m.Logs { - if !log.Projected { - return log.ID, nil - } - } - return uint64(len(m.Logs)), nil -} - -func (m *InMemoryStore) ReadLogsRange(ctx context.Context, idMin, idMax uint64) ([]core.ChainedLog, error) { - m.mu.Lock() - defer m.mu.Unlock() - - if idMax > uint64(len(m.Logs)) { - idMax = uint64(len(m.Logs)) - } - - if idMin < uint64(len(m.Logs)) { - return collectionutils.Map(m.Logs[idMin:idMax], func(from *core.ChainedLog) core.ChainedLog { - return *from - }), nil - } - - return []core.ChainedLog{}, nil -} - -func (m *InMemoryStore) GetAccountWithVolumes(ctx context.Context, address string) (*core.AccountWithVolumes, error) { - m.mu.Lock() - defer m.mu.Unlock() - - account, ok := m.Accounts[address] - if !ok { - return &core.AccountWithVolumes{ - Account: core.Account{ - Address: address, - Metadata: metadata.Metadata{}, - }, - Volumes: core.VolumesByAssets{}, - }, nil - } - return account, nil -} - -func (m *InMemoryStore) GetTransaction(ctx context.Context, id uint64) (*core.ExpandedTransaction, error) { - m.mu.Lock() - defer m.mu.Unlock() - - return m.Transactions[id], nil -} - -func NewInMemoryStore() *InMemoryStore { - return &InMemoryStore{ - Accounts: make(map[string]*core.AccountWithVolumes), - } -} diff --git a/components/ledger/pkg/storage/ledgerstore/accounts.go b/components/ledger/pkg/storage/ledgerstore/accounts.go deleted file mode 100644 index 7ce1e5500..000000000 --- a/components/ledger/pkg/storage/ledgerstore/accounts.go +++ /dev/null @@ -1,195 +0,0 @@ -package ledgerstore - -import ( - "context" - "database/sql" - "fmt" - "regexp" - "strings" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/uptrace/bun" -) - -const ( - accountsTableName = "accounts" -) - -type AccountsQuery OffsetPaginatedQuery[AccountsQueryFilters] - -type AccountsQueryFilters struct { - AfterAddress string `json:"after"` - Address string `json:"address"` - Metadata metadata.Metadata `json:"metadata"` -} - -func NewAccountsQuery() AccountsQuery { - return AccountsQuery{ - PageSize: QueryDefaultPageSize, - Order: OrderAsc, - Filters: AccountsQueryFilters{ - Metadata: metadata.Metadata{}, - }, - } -} - -func (a AccountsQuery) WithPageSize(pageSize uint64) AccountsQuery { - if pageSize != 0 { - a.PageSize = pageSize - } - - return a -} - -func (a AccountsQuery) WithAfterAddress(after string) AccountsQuery { - a.Filters.AfterAddress = after - - return a -} - -func (a AccountsQuery) WithAddressFilter(address string) AccountsQuery { - a.Filters.Address = address - - return a -} - -func (a AccountsQuery) WithMetadataFilter(metadata metadata.Metadata) AccountsQuery { - a.Filters.Metadata = metadata - - return a -} - -// This regexp is used to validate the account name -// If the account name is not valid, it means that the user putted a regex in -// the address filter, and we have to change the postgres operator used. -var accountNameRegex = regexp.MustCompile(`^[a-zA-Z_0-9]+$`) - -type Account struct { - bun.BaseModel `bun:"accounts,alias:accounts"` - - Address string `bun:"address,type:varchar,unique,notnull"` - Metadata map[string]string `bun:"metadata,type:jsonb,default:'{}'"` - AddressJson []string `bun:"address_json,type:jsonb"` -} - -func (s *Store) buildAccountsQuery(p AccountsQuery) *bun.SelectQuery { - query := s.schema.NewSelect(accountsTableName). - Model((*Account)(nil)). - ColumnExpr("coalesce(accounts.address, moves.account) as address"). - ColumnExpr("coalesce(accounts.metadata, '{}'::jsonb) as metadata"). - Join(fmt.Sprintf(`full join "%s".moves moves on moves.account = accounts.address`, s.schema.Name())) - - if p.Filters.Address != "" { - src := strings.Split(p.Filters.Address, ":") - query.Where(fmt.Sprintf("jsonb_array_length(address_json) = %d", len(src))) - - for i, segment := range src { - if len(segment) == 0 { - continue - } - query.Where(fmt.Sprintf("address_json @@ ('$[%d] == \"' || ?::text || '\"')::jsonpath", i), segment) - } - } - - for key, value := range p.Filters.Metadata { - query.Where( - fmt.Sprintf(`"%s".%s(metadata, ?, '%s')`, s.schema.Name(), - SQLCustomFuncMetaCompare, strings.ReplaceAll(key, ".", "', '"), - ), value) - } - - return s.schema.IDB.NewSelect(). - With("cte1", query). - DistinctOn("cte1.address"). - ColumnExpr("cte1.address"). - ColumnExpr("cte1.metadata"). - Table("cte1") -} - -func (s *Store) GetAccounts(ctx context.Context, q AccountsQuery) (*api.Cursor[core.Account], error) { - return UsingOffset[AccountsQueryFilters, core.Account](ctx, - s.buildAccountsQuery(q), OffsetPaginatedQuery[AccountsQueryFilters](q)) -} - -func (s *Store) GetAccount(ctx context.Context, addr string) (*core.Account, error) { - account := &core.Account{} - if err := s.schema.NewSelect(accountsTableName). - ColumnExpr("address"). - ColumnExpr("metadata"). - Where("address = ?", addr). - Model(account). - Scan(ctx, account); err != nil { - if err == sql.ErrNoRows { - return &core.Account{ - Address: addr, - Metadata: metadata.Metadata{}, - }, nil - } - return nil, err - } - - return account, nil -} - -func (s *Store) GetAccountWithVolumes(ctx context.Context, account string) (*core.AccountWithVolumes, error) { - cte2 := s.schema.NewSelect(accountsTableName). - Join(fmt.Sprintf(`full join "%s".moves moves on moves.account = accounts.address`, s.schema.Name())). - Where("account = ?", account). - Group("moves.asset"). - Column("moves.asset"). - ColumnExpr(fmt.Sprintf(`"%s".first(moves.post_commit_input_value order by moves.timestamp desc) as post_commit_input_value`, s.schema.Name())). - ColumnExpr(fmt.Sprintf(`"%s".first(moves.post_commit_output_value order by moves.timestamp desc) as post_commit_output_value`, s.schema.Name())) - - cte3 := s.schema.IDB.NewSelect(). - ColumnExpr(`('{"' || data.asset || '": {"input": ' || data.post_commit_input_value || ', "output": ' || data.post_commit_output_value || '}}')::jsonb as asset`). - TableExpr("cte2 data") - - cte4 := s.schema.IDB.NewSelect(). - ColumnExpr(fmt.Sprintf(`'%s' as account`, account)). - ColumnExpr(fmt.Sprintf(`"%s".aggregate_objects(data.asset) as volumes`, s.schema.Name())). - TableExpr("cte3 data") - - accountWithVolumes := &core.AccountWithVolumes{} - err := s.schema.NewSelect(accountsTableName). - With("cte2", cte2). - With("cte3", cte3). - With("cte4", cte4). - ColumnExpr(fmt.Sprintf("'%s' as address", account)). - ColumnExpr("coalesce(accounts.metadata, '{}'::jsonb) as metadata"). - ColumnExpr("cte4.volumes"). - Join(`right join cte4 on cte4.account = accounts.address`). - Scan(ctx, accountWithVolumes) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - - return accountWithVolumes, nil -} - -func (s *Store) CountAccounts(ctx context.Context, q AccountsQuery) (uint64, error) { - sb := s.buildAccountsQuery(q) - count, err := sb.Count(ctx) - return uint64(count), storageerrors.PostgresError(err) -} - -func (s *Store) UpdateAccountsMetadata(ctx context.Context, accounts ...core.Account) error { - accs := make([]*Account, len(accounts)) - for i, a := range accounts { - accs[i] = &Account{ - Address: a.Address, - Metadata: a.Metadata, - AddressJson: strings.Split(a.Address, ":"), - } - } - - _, err := s.schema.NewInsert(accountsTableName). - Model(&accs). - On("CONFLICT (address) DO UPDATE"). - Set("metadata = accounts.metadata || EXCLUDED.metadata"). - Exec(ctx) - - return storageerrors.PostgresError(err) -} diff --git a/components/ledger/pkg/storage/ledgerstore/accounts_test.go b/components/ledger/pkg/storage/ledgerstore/accounts_test.go deleted file mode 100644 index 53ead9c4a..000000000 --- a/components/ledger/pkg/storage/ledgerstore/accounts_test.go +++ /dev/null @@ -1,145 +0,0 @@ -package ledgerstore_test - -import ( - "context" - "math/big" - "testing" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/stretchr/testify/require" -) - -func TestUpdateAccountsMetadata(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - t.Run("update metadata", func(t *testing.T) { - metadata := metadata.Metadata{ - "foo": "bar", - } - - err := store.UpdateAccountsMetadata(context.Background(), core.Account{ - Address: "bank", - Metadata: metadata, - }) - require.NoError(t, err, "account insertion should not fail") - - account, err := store.GetAccount(context.Background(), "bank") - require.NoError(t, err, "account retrieval should not fail") - - require.Equal(t, "bank", account.Address, "account address should match") - require.Equal(t, metadata, account.Metadata, "account metadata should match") - }) - - t.Run("success updating multiple account metadata", func(t *testing.T) { - accounts := []core.Account{ - { - Address: "test:account1", - Metadata: metadata.Metadata{"foo1": "bar1"}, - }, - { - Address: "test:account2", - Metadata: metadata.Metadata{"foo2": "bar2"}, - }, - { - Address: "test:account3", - Metadata: metadata.Metadata{"foo3": "bar3"}, - }, - } - - err := store.UpdateAccountsMetadata(context.Background(), accounts...) - require.NoError(t, err, "account insertion should not fail") - - for _, account := range accounts { - acc, err := store.GetAccount(context.Background(), account.Address) - require.NoError(t, err, "account retrieval should not fail") - - require.Equal(t, account.Address, acc.Address, "account address should match") - require.Equal(t, account.Metadata, acc.Metadata, "account metadata should match") - } - }) -} - -func TestGetAccount(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - require.NoError(t, insertTransactions(context.Background(), store, - *core.NewTransaction().WithPostings( - core.NewPosting("world", "multi", "USD/2", big.NewInt(100)), - ), - )) - - account, err := store.GetAccount(context.Background(), "multi") - require.NoError(t, err) - require.Equal(t, core.Account{ - Address: "multi", - Metadata: metadata.Metadata{}, - }, *account) -} - -func TestGetAccountWithVolumes(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - require.NoError(t, insertTransactions(context.Background(), store, - *core.NewTransaction().WithPostings( - core.NewPosting("world", "multi", "USD/2", big.NewInt(100)), - ), - )) - - accountWithVolumes, err := store.GetAccountWithVolumes(context.Background(), "multi") - require.NoError(t, err) - require.Equal(t, &core.AccountWithVolumes{ - Account: core.Account{ - Address: "multi", - Metadata: metadata.Metadata{}, - }, - Volumes: map[string]*core.Volumes{ - "USD/2": core.NewEmptyVolumes().WithInputInt64(100), - }, - }, accountWithVolumes) -} - -func TestUpdateAccountMetadata(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - err := store.UpdateAccountsMetadata(context.Background(), core.Account{ - Address: "central_bank", - Metadata: metadata.Metadata{ - "foo": "bar", - }, - }) - require.NoError(t, err) - - account, err := store.GetAccount(context.Background(), "central_bank") - require.NoError(t, err) - require.EqualValues(t, "bar", account.Metadata["foo"]) -} - -func TestGetAccountWithAccountNotExisting(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - account, err := store.GetAccount(context.Background(), "account_not_existing") - require.NoError(t, err) - require.NotNil(t, account) -} - -func TestCountAccounts(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - require.NoError(t, insertTransactions(context.Background(), store, - *core.NewTransaction().WithPostings( - core.NewPosting("world", "central_bank", "USD/2", big.NewInt(100)), - ), - )) - - countAccounts, err := store.CountAccounts(context.Background(), ledgerstore.AccountsQuery{}) - require.NoError(t, err) - require.EqualValues(t, 2, countAccounts) // world + central_bank -} diff --git a/components/ledger/pkg/storage/ledgerstore/balances.go b/components/ledger/pkg/storage/ledgerstore/balances.go deleted file mode 100644 index 722b06219..000000000 --- a/components/ledger/pkg/storage/ledgerstore/balances.go +++ /dev/null @@ -1,164 +0,0 @@ -package ledgerstore - -import ( - "context" - "database/sql" - "encoding/json" - "fmt" - "math/big" - "strings" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/api" -) - -type BalancesQueryFilters struct { - AfterAddress string `json:"afterAddress"` - AddressRegexp string `json:"addressRegexp"` -} - -type BalancesQuery OffsetPaginatedQuery[BalancesQueryFilters] - -func NewBalancesQuery() BalancesQuery { - return BalancesQuery{ - PageSize: QueryDefaultPageSize, - Order: OrderAsc, - Filters: BalancesQueryFilters{}, - } -} - -func (q BalancesQuery) GetPageSize() uint64 { - return q.PageSize -} - -func (b BalancesQuery) WithAfterAddress(after string) BalancesQuery { - b.Filters.AfterAddress = after - - return b -} - -func (b BalancesQuery) WithAddressFilter(address string) BalancesQuery { - b.Filters.AddressRegexp = address - - return b -} - -func (b BalancesQuery) WithPageSize(pageSize uint64) BalancesQuery { - b.PageSize = pageSize - return b -} - -type balancesByAssets core.BalancesByAssets - -func (b *balancesByAssets) Scan(value interface{}) error { - var i sql.NullString - if err := i.Scan(value); err != nil { - return err - } - - *b = balancesByAssets{} - if err := json.Unmarshal([]byte(i.String), b); err != nil { - return err - } - - return nil -} - -func (s *Store) GetBalancesAggregated(ctx context.Context, q BalancesQuery) (core.BalancesByAssets, error) { - selectLastMoveForEachAccountAsset := s.schema.NewSelect(MovesTableName). - ColumnExpr("account"). - ColumnExpr("asset"). - ColumnExpr(fmt.Sprintf(`"%s".first(post_commit_input_value order by timestamp desc) as post_commit_input_value`, s.schema.Name())). - ColumnExpr(fmt.Sprintf(`"%s".first(post_commit_output_value order by timestamp desc) as post_commit_output_value`, s.schema.Name())). - GroupExpr("account, asset") - - if q.Filters.AddressRegexp != "" { - src := strings.Split(q.Filters.AddressRegexp, ":") - selectLastMoveForEachAccountAsset.Where(fmt.Sprintf("jsonb_array_length(account_array) = %d", len(src))) - - for i, segment := range src { - if segment == "" { - continue - } - selectLastMoveForEachAccountAsset.Where(fmt.Sprintf("account_array @@ ('$[%d] == \"' || ?::text || '\"')::jsonpath", i), segment) - } - } - - type row struct { - Asset string `bun:"asset"` - Aggregated *Int `bun:"aggregated"` - } - - rows := make([]row, 0) - if err := s.schema.IDB.NewSelect(). - With("cte1", selectLastMoveForEachAccountAsset). - Column("asset"). - ColumnExpr("sum(cte1.post_commit_input_value) - sum(cte1.post_commit_output_value) as aggregated"). - Table("cte1"). - Group("cte1.asset"). - Scan(ctx, &rows); err != nil { - return nil, storageerrors.PostgresError(err) - } - - aggregatedBalances := core.BalancesByAssets{} - for _, row := range rows { - aggregatedBalances[row.Asset] = (*big.Int)(row.Aggregated) - } - - return aggregatedBalances, nil -} - -func (s *Store) GetBalances(ctx context.Context, q BalancesQuery) (*api.Cursor[core.BalancesByAssetsByAccounts], error) { - selectLastMoveForEachAccountAsset := s.schema.NewSelect(MovesTableName). - ColumnExpr("account"). - ColumnExpr("asset"). - ColumnExpr(fmt.Sprintf(`"%s".first(post_commit_input_value order by timestamp desc) as post_commit_input_value`, s.schema.Name())). - ColumnExpr(fmt.Sprintf(`"%s".first(post_commit_output_value order by timestamp desc) as post_commit_output_value`, s.schema.Name())). - GroupExpr("account, asset") - - if q.Filters.AddressRegexp != "" { - src := strings.Split(q.Filters.AddressRegexp, ":") - selectLastMoveForEachAccountAsset.Where(fmt.Sprintf("jsonb_array_length(account_array) = %d", len(src))) - - for i, segment := range src { - if len(segment) == 0 { - continue - } - selectLastMoveForEachAccountAsset.Where(fmt.Sprintf("account_array @@ ('$[%d] == \"' || ?::text || '\"')::jsonpath", i), segment) - } - } - - if q.Filters.AfterAddress != "" { - selectLastMoveForEachAccountAsset.Where("account > ?", q.Filters.AfterAddress) - } - - query := s.schema.IDB.NewSelect(). - With("cte1", selectLastMoveForEachAccountAsset). - Column("data.account"). - ColumnExpr(fmt.Sprintf(`"%s".aggregate_objects(data.asset) as balances_by_assets`, s.schema.Name())). - TableExpr(`( - select data.account, ('{"' || data.asset || '": ' || sum(data.post_commit_input_value) - sum(data.post_commit_output_value) || '}')::jsonb as asset - from cte1 data - group by data.account, data.asset - ) data`). - Order("data.account"). - Group("data.account") - - type result struct { - Account string `bun:"account"` - Assets balancesByAssets `bun:"balances_by_assets"` - } - - cursor, err := UsingOffset[BalancesQueryFilters, result](ctx, - query, OffsetPaginatedQuery[BalancesQueryFilters](q)) - if err != nil { - return nil, err - } - - return api.MapCursor(cursor, func(from result) core.BalancesByAssetsByAccounts { - return core.BalancesByAssetsByAccounts{ - from.Account: core.BalancesByAssets(from.Assets), - } - }), nil -} diff --git a/components/ledger/pkg/storage/ledgerstore/balances_test.go b/components/ledger/pkg/storage/ledgerstore/balances_test.go deleted file mode 100644 index a3e1254cd..000000000 --- a/components/ledger/pkg/storage/ledgerstore/balances_test.go +++ /dev/null @@ -1,130 +0,0 @@ -package ledgerstore_test - -import ( - "context" - "math/big" - "testing" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/stretchr/testify/require" -) - -func TestGetBalances(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - tx := core.NewTransaction().WithPostings( - core.NewPosting("world", "users:1", "USD", big.NewInt(1)), - core.NewPosting("world", "central_bank", "USD", big.NewInt(199)), - ) - require.NoError(t, insertTransactions(context.Background(), store, *tx)) - - t.Run("all accounts", func(t *testing.T) { - cursor, err := store.GetBalances(context.Background(), - ledgerstore.NewBalancesQuery().WithPageSize(10)) - require.NoError(t, err) - require.Equal(t, 10, cursor.PageSize) - require.Equal(t, false, cursor.HasMore) - require.Equal(t, "", cursor.Previous) - require.Equal(t, "", cursor.Next) - require.Equal(t, []core.BalancesByAssetsByAccounts{ - { - "central_bank": core.BalancesByAssets{ - "USD": big.NewInt(199), - }, - }, - { - "users:1": core.BalancesByAssets{ - "USD": big.NewInt(1), - }, - }, - { - "world": core.BalancesByAssets{ - "USD": big.NewInt(-200), - }, - }, - }, cursor.Data) - }) - - t.Run("limit", func(t *testing.T) { - cursor, err := store.GetBalances(context.Background(), - ledgerstore.NewBalancesQuery().WithPageSize(1), - ) - require.NoError(t, err) - require.Equal(t, 1, cursor.PageSize) - require.Equal(t, true, cursor.HasMore) - require.Equal(t, "", cursor.Previous) - require.NotEqual(t, "", cursor.Next) - require.Equal(t, []core.BalancesByAssetsByAccounts{ - { - "central_bank": core.BalancesByAssets{ - "USD": big.NewInt(199), - }, - }, - }, cursor.Data) - }) - - t.Run("after", func(t *testing.T) { - cursor, err := store.GetBalances(context.Background(), - ledgerstore.NewBalancesQuery().WithPageSize(10).WithAfterAddress("users:1"), - ) - require.NoError(t, err) - require.Equal(t, 10, cursor.PageSize) - require.Equal(t, false, cursor.HasMore) - require.Equal(t, "", cursor.Previous) - require.Equal(t, "", cursor.Next) - require.Equal(t, []core.BalancesByAssetsByAccounts{ - { - "world": core.BalancesByAssets{ - "USD": big.NewInt(-200), - }, - }, - }, cursor.Data) - }) - - t.Run("after and filter on address", func(t *testing.T) { - cursor, err := store.GetBalances(context.Background(), - ledgerstore.NewBalancesQuery(). - WithPageSize(10). - WithAfterAddress("central_bank"). - WithAddressFilter("users:1"), - ) - require.NoError(t, err) - require.Equal(t, 10, cursor.PageSize) - require.Equal(t, false, cursor.HasMore) - require.Equal(t, "", cursor.Previous) - require.Equal(t, "", cursor.Next) - require.Equal(t, []core.BalancesByAssetsByAccounts{ - { - "users:1": core.BalancesByAssets{ - "USD": big.NewInt(1), - }, - }, - }, cursor.Data) - }) -} - -func TestGetBalancesAggregated(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - tx := core.NewTransaction().WithPostings( - core.NewPosting("world", "users:1", "USD", big.NewInt(1)), - core.NewPosting("world", "users:2", "USD", big.NewInt(199)), - ) - require.NoError(t, insertTransactions(context.Background(), store, *tx)) - - q := ledgerstore.NewBalancesQuery().WithPageSize(10) - cursor, err := store.GetBalancesAggregated(context.Background(), q) - require.NoError(t, err) - require.Equal(t, core.BalancesByAssets{ - "USD": big.NewInt(0), - }, cursor) - - ret, err := store.GetBalancesAggregated(context.Background(), ledgerstore.NewBalancesQuery().WithPageSize(10).WithAddressFilter("users:")) - require.NoError(t, err) - require.Equal(t, core.BalancesByAssets{ - "USD": big.NewInt(200), - }, ret) -} diff --git a/components/ledger/pkg/storage/ledgerstore/bigint.go b/components/ledger/pkg/storage/ledgerstore/bigint.go deleted file mode 100644 index 5b3cdcf84..000000000 --- a/components/ledger/pkg/storage/ledgerstore/bigint.go +++ /dev/null @@ -1,88 +0,0 @@ -package ledgerstore - -import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "fmt" - "math/big" -) - -type Int big.Int - -func (i *Int) MarshalJSON() ([]byte, error) { - return json.Marshal(i.ToMathBig()) -} - -func (i *Int) UnmarshalJSON(bytes []byte) error { - v, err := i.FromString(string(bytes)) - if err != nil { - return err - } - *i = *v - return nil -} - -func NewInt() *Int { - return new(Int) -} -func newBigint(x *big.Int) *Int { - return (*Int)(x) -} - -// same as NewBigint() -func FromMathBig(x *big.Int) *Int { - return (*Int)(x) -} - -func FromInt64(x int64) *Int { - return FromMathBig(big.NewInt(x)) -} - -func (i *Int) FromString(x string) (*Int, error) { - if x == "" { - return FromInt64(0), nil - } - a := big.NewInt(0) - b, ok := a.SetString(x, 10) - - if !ok { - return nil, fmt.Errorf("cannot create Int from string") - } - - return newBigint(b), nil -} - -func (b *Int) Value() (driver.Value, error) { - return (*big.Int)(b).String(), nil -} - -func (b *Int) Set(v *Int) *Int { - return (*Int)((*big.Int)(b).Set((*big.Int)(v))) -} - -func (b *Int) Sub(x *Int, y *Int) *Int { - return (*Int)((*big.Int)(b).Sub((*big.Int)(x), (*big.Int)(y))) -} - -func (b *Int) Scan(value interface{}) error { - - var i sql.NullString - - if err := i.Scan(value); err != nil { - return err - } - - if _, ok := (*big.Int)(b).SetString(i.String, 10); ok { - return nil - } - - return fmt.Errorf("Error converting type %T into Bigint", value) -} - -func (b *Int) ToMathBig() *big.Int { - return (*big.Int)(b) -} - -var _ json.Unmarshaler = (*Int)(nil) -var _ json.Marshaler = (*Int)(nil) diff --git a/components/ledger/pkg/storage/ledgerstore/logs.go b/components/ledger/pkg/storage/ledgerstore/logs.go deleted file mode 100644 index 75744efde..000000000 --- a/components/ledger/pkg/storage/ledgerstore/logs.go +++ /dev/null @@ -1,388 +0,0 @@ -package ledgerstore - -import ( - "context" - "database/sql" - "database/sql/driver" - "encoding/json" - "fmt" - "math/big" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/lib/pq" - "github.com/pkg/errors" - "github.com/uptrace/bun" - "github.com/uptrace/bun/extra/bunbig" -) - -const ( - LogTableName = "logs" -) - -type LogsQueryFilters struct { - EndTime core.Time `json:"endTime"` - StartTime core.Time `json:"startTime"` -} - -type LogsQuery ColumnPaginatedQuery[LogsQueryFilters] - -func NewLogsQuery() LogsQuery { - return LogsQuery{ - PageSize: QueryDefaultPageSize, - Column: "id", - Order: OrderDesc, - Filters: LogsQueryFilters{}, - } -} - -func (a LogsQuery) WithPaginationID(id uint64) LogsQuery { - a.PaginationID = &id - return a -} - -func (l LogsQuery) WithPageSize(pageSize uint64) LogsQuery { - if pageSize != 0 { - l.PageSize = pageSize - } - - return l -} - -func (l LogsQuery) WithStartTimeFilter(start core.Time) LogsQuery { - if !start.IsZero() { - l.Filters.StartTime = start - } - - return l -} - -func (l LogsQuery) WithEndTimeFilter(end core.Time) LogsQuery { - if !end.IsZero() { - l.Filters.EndTime = end - } - - return l -} - -type AccountWithBalances struct { - bun.BaseModel `bun:"accounts,alias:accounts"` - - Address string `bun:"address,type:varchar,unique,notnull"` - Metadata metadata.Metadata `bun:"metadata,type:bytea,default:'{}'"` - Balances map[string]*big.Int `bun:"balances,type:bytea,default:'{}'"` -} - -type LogsV2 struct { - bun.BaseModel `bun:"logs,alias:logs"` - - ID uint64 `bun:"id,unique,type:bigint"` - Type int16 `bun:"type,type:smallint"` - Hash []byte `bun:"hash,type:bytea"` - Date core.Time `bun:"date,type:timestamptz"` - Data []byte `bun:"data,type:jsonb"` - IdempotencyKey string `bun:"idempotency_key,type:varchar(256),unique"` - Projected bool `bun:"projected,type:boolean"` -} - -func (log LogsV2) ToCore() core.ChainedLog { - payload, err := core.HydrateLog(core.LogType(log.Type), log.Data) - if err != nil { - panic(errors.Wrap(err, "hydrating log data")) - } - - return core.ChainedLog{ - Log: core.Log{ - Type: core.LogType(log.Type), - Data: payload, - Date: log.Date.UTC(), - IdempotencyKey: log.IdempotencyKey, - }, - ID: log.ID, - Hash: log.Hash, - Projected: log.Projected, - } -} - -type RawMessage json.RawMessage - -func (j RawMessage) Value() (driver.Value, error) { - if j == nil { - return nil, nil - } - return string(j), nil -} - -func (s *Store) InsertLogs(ctx context.Context, activeLogs ...*core.ActiveLog) error { - - txn, err := s.schema.BeginTx(ctx, &sql.TxOptions{}) - if err != nil { - return storageerrors.PostgresError(err) - } - - // Beware: COPY query is not supported by bun if the pgx driver is used. - stmt, err := txn.Prepare(pq.CopyInSchema( - s.schema.Name(), - LogTableName, - "id", "type", "hash", "date", "data", "idempotency_key", - )) - if err != nil { - return storageerrors.PostgresError(err) - } - - ls := make([]LogsV2, len(activeLogs)) - for i, activeLog := range activeLogs { - data, err := json.Marshal(activeLog.Data) - if err != nil { - return errors.Wrap(err, "marshaling log data") - } - - ls[i] = LogsV2{ - ID: activeLog.ChainedLog.ID, - Type: int16(activeLog.ChainedLog.Type), - Hash: activeLog.ChainedLog.Hash, - Date: activeLog.ChainedLog.Date, - Data: data, - IdempotencyKey: activeLog.ChainedLog.IdempotencyKey, - } - - _, err = stmt.Exec(ls[i].ID, ls[i].Type, ls[i].Hash, ls[i].Date, RawMessage(ls[i].Data), activeLog.ChainedLog.IdempotencyKey) - if err != nil { - return storageerrors.PostgresError(err) - } - } - - _, err = stmt.Exec() - if err != nil { - return storageerrors.PostgresError(err) - } - - err = stmt.Close() - if err != nil { - return storageerrors.PostgresError(err) - } - - return storageerrors.PostgresError(txn.Commit()) -} - -func (s *Store) GetLastLog(ctx context.Context) (*core.ChainedLog, error) { - raw := &LogsV2{} - err := s.schema.NewSelect(LogTableName). - Model(raw). - OrderExpr("id desc"). - Limit(1). - Scan(ctx) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - - l := raw.ToCore() - return &l, nil -} - -func (s *Store) GetLogs(ctx context.Context, q LogsQuery) (*api.Cursor[core.ChainedLog], error) { - cursor, err := UsingColumn[LogsQueryFilters, LogsV2](ctx, - s.buildLogsQuery, - ColumnPaginatedQuery[LogsQueryFilters](q), - ) - if err != nil { - return nil, err - } - - return api.MapCursor(cursor, LogsV2.ToCore), nil -} - -func (s *Store) buildLogsQuery(q LogsQueryFilters, models *[]LogsV2) *bun.SelectQuery { - sb := s.schema.NewSelect(LogTableName). - Model(models). - Column("id", "type", "hash", "date", "data", "idempotency_key") - - if !q.StartTime.IsZero() { - sb.Where("date >= ?", q.StartTime.UTC()) - } - if !q.EndTime.IsZero() { - sb.Where("date < ?", q.EndTime.UTC()) - } - - return sb -} - -func (s *Store) GetNextLogID(ctx context.Context) (uint64, error) { - var logID uint64 - err := s.schema. - NewSelect(LogTableName). - ColumnExpr("min(id)"). - Where("projected = FALSE"). - Limit(1). - Scan(ctx, &logID) - if err != nil { - return 0, storageerrors.PostgresError(err) - } - return logID, nil -} - -func (s *Store) ReadLogsRange(ctx context.Context, idMin, idMax uint64) ([]core.ChainedLog, error) { - rawLogs := make([]LogsV2, 0) - err := s.schema. - NewSelect(LogTableName). - Where("id >= ?", idMin). - Where("id < ?", idMax). - Model(&rawLogs). - Scan(ctx) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - - return collectionutils.Map(rawLogs, LogsV2.ToCore), nil -} - -func (s *Store) ReadLastLogWithType(ctx context.Context, logTypes ...core.LogType) (*core.ChainedLog, error) { - raw := &LogsV2{} - err := s.schema. - NewSelect(LogTableName). - Where("type IN (?)", bun.In(logTypes)). - OrderExpr("date DESC"). - Model(raw). - Limit(1). - Scan(ctx) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - ret := raw.ToCore() - - return &ret, nil -} - -func (s *Store) ReadLogForCreatedTransactionWithReference(ctx context.Context, reference string) (*core.ChainedLog, error) { - raw := &LogsV2{} - err := s.schema.NewSelect(LogTableName). - Model(raw). - OrderExpr("id desc"). - Limit(1). - Where("data->'transaction'->>'reference' = ?", reference). - Scan(ctx) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - - l := raw.ToCore() - return &l, nil -} - -func (s *Store) ReadLogForCreatedTransaction(ctx context.Context, txID uint64) (*core.ChainedLog, error) { - raw := &LogsV2{} - err := s.schema.NewSelect(LogTableName). - Model(raw). - OrderExpr("id desc"). - Limit(1). - Where("data->'transaction'->>'txid' = ?", fmt.Sprint(txID)). - Scan(ctx) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - - l := raw.ToCore() - return &l, nil -} - -func (s *Store) ReadLogForRevertedTransaction(ctx context.Context, txID uint64) (*core.ChainedLog, error) { - raw := &LogsV2{} - err := s.schema.NewSelect(LogTableName). - Model(raw). - OrderExpr("id desc"). - Limit(1). - Where("data->>'revertedTransactionID' = ?", fmt.Sprint(txID)). - Scan(ctx) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - - l := raw.ToCore() - return &l, nil -} - -func (s *Store) ReadLogWithIdempotencyKey(ctx context.Context, key string) (*core.ChainedLog, error) { - raw := &LogsV2{} - err := s.schema.NewSelect(LogTableName). - Model(raw). - OrderExpr("id desc"). - Limit(1). - Where("idempotency_key = ?", key). - Scan(ctx) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - - l := raw.ToCore() - return &l, nil -} - -func (s *Store) MarkedLogsAsProjected(ctx context.Context, id uint64) error { - _, err := s.schema.NewUpdate(LogTableName). - Where("id = ?", id). - Set("projected = TRUE"). - Exec(ctx) - return storageerrors.PostgresError(err) -} - -func (s *Store) GetBalanceFromLogs(ctx context.Context, address, asset string) (*big.Int, error) { - selectLogsForExistingAccount := s.schema. - NewSelect(LogTableName). - Model(&LogsV2{}). - Where(fmt.Sprintf(`data->'transaction'->'postings' @> '[{"destination": "%s", "asset": "%s"}]' OR data->'transaction'->'postings' @> '[{"source": "%s", "asset": "%s"}]'`, address, asset, address, asset)) - - selectPostings := s.schema.IDB.NewSelect(). - TableExpr(`(` + selectLogsForExistingAccount.String() + `) as logs`). - ColumnExpr("jsonb_array_elements(logs.data->'transaction'->'postings') as postings") - - selectBalances := s.schema.IDB.NewSelect(). - TableExpr(`(` + selectPostings.String() + `) as postings`). - ColumnExpr(fmt.Sprintf("SUM(CASE WHEN (postings.postings::jsonb)->>'source' = '%s' THEN -((((postings.postings::jsonb)->'amount')::numeric)) ELSE ((postings.postings::jsonb)->'amount')::numeric END)", address)) - - row := s.schema.IDB.QueryRowContext(ctx, selectBalances.String()) - if row.Err() != nil { - return nil, row.Err() - } - - var balance *bunbig.Int - if err := row.Scan(&balance); err != nil { - return nil, err - } - return (*big.Int)(balance), nil -} - -func (s *Store) GetMetadataFromLogs(ctx context.Context, address, key string) (string, error) { - l := LogsV2{} - if err := s.schema.NewSelect(LogTableName). - Model(&l). - Order("id DESC"). - WhereOr( - "type = ? AND data->>'targetId' = ? AND data->>'targetType' = ? AND "+fmt.Sprintf("data->'metadata' ? '%s'", key), - core.SetMetadataLogType, address, core.MetaTargetTypeAccount, - ). - WhereOr( - "type = ? AND "+fmt.Sprintf("data->'accountMetadata'->'%s' ? '%s'", address, key), - core.NewTransactionLogType, - ). - Limit(1). - Scan(ctx); err != nil { - return "", storageerrors.PostgresError(err) - } - - payload, err := core.HydrateLog(core.LogType(l.Type), l.Data) - if err != nil { - panic(errors.Wrap(err, "hydrating log data")) - } - - switch payload := payload.(type) { - case core.NewTransactionLogPayload: - return payload.AccountMetadata[address][key], nil - case core.SetMetadataLogPayload: - return payload.Metadata[key], nil - default: - panic("should not happen") - } -} diff --git a/components/ledger/pkg/storage/ledgerstore/logs_test.go b/components/ledger/pkg/storage/ledgerstore/logs_test.go deleted file mode 100644 index 55d550ab7..000000000 --- a/components/ledger/pkg/storage/ledgerstore/logs_test.go +++ /dev/null @@ -1,417 +0,0 @@ -package ledgerstore_test - -import ( - "context" - "fmt" - "math/big" - "testing" - "time" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/stretchr/testify/require" -) - -func TestGetLastLog(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - lastLog, err := store.GetLastLog(context.Background()) - require.True(t, storage.IsNotFoundError(err)) - require.Nil(t, lastLog) - tx1 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - TransactionData: core.TransactionData{ - Postings: []core.Posting{ - { - Source: "world", - Destination: "central_bank", - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - Reference: "tx1", - Timestamp: now.Add(-3 * time.Hour), - }, - }, - PostCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(100), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(100), - Output: big.NewInt(0), - }, - }, - }, - PreCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(0), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(0), - }, - }, - }, - } - - logTx := core.NewTransactionLog(&tx1.Transaction, nil).ChainLog(nil) - appendLog(t, store, logTx) - - lastLog, err = store.GetLastLog(context.Background()) - require.NoError(t, err) - require.NotNil(t, lastLog) - - require.Equal(t, tx1.Postings, lastLog.Data.(core.NewTransactionLogPayload).Transaction.Postings) - require.Equal(t, tx1.Reference, lastLog.Data.(core.NewTransactionLogPayload).Transaction.Reference) - require.Equal(t, tx1.Timestamp, lastLog.Data.(core.NewTransactionLogPayload).Transaction.Timestamp) -} - -func TestReadLogForCreatedTransactionWithReference(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - logTx := core.NewTransactionLog( - core.NewTransaction(). - WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - ). - WithReference("ref"), - map[string]metadata.Metadata{}, - ) - persistedLog := appendLog(t, store, logTx.ChainLog(nil)) - - lastLog, err := store.ReadLogForCreatedTransactionWithReference(context.Background(), "ref") - require.NoError(t, err) - require.NotNil(t, lastLog) - require.Equal(t, *persistedLog, *lastLog) -} - -func TestReadLogForRevertedTransaction(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - persistedLog := appendLog(t, store, core.NewRevertedTransactionLog( - core.Now(), - 0, - core.NewTransaction(), - ).ChainLog(nil)) - - lastLog, err := store.ReadLogForRevertedTransaction(context.Background(), 0) - require.NoError(t, err) - require.NotNil(t, lastLog) - require.Equal(t, *persistedLog, *lastLog) -} - -func TestReadLogForCreatedTransaction(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - logTx := core.NewTransactionLog( - core.NewTransaction(). - WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - ). - WithReference("ref"), - map[string]metadata.Metadata{}, - ) - chainedLog := appendLog(t, store, logTx.ChainLog(nil)) - - logFromDB, err := store.ReadLogForCreatedTransaction(context.Background(), 0) - require.NoError(t, err) - require.NotNil(t, logFromDB) - require.Equal(t, *chainedLog, *logFromDB) -} - -func TestReadLogWithIdempotencyKey(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - logTx := core.NewTransactionLog( - core.NewTransaction(). - WithPostings( - core.NewPosting("world", "bank", "USD", big.NewInt(100)), - ), - map[string]metadata.Metadata{}, - ) - log := logTx.WithIdempotencyKey("test") - - ret := appendLog(t, store, log.ChainLog(nil)) - - lastLog, err := store.ReadLogWithIdempotencyKey(context.Background(), "test") - require.NoError(t, err) - require.NotNil(t, lastLog) - require.Equal(t, *ret, *lastLog) -} - -func TestGetLogs(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - TransactionData: core.TransactionData{ - Postings: []core.Posting{ - { - Source: "world", - Destination: "central_bank", - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - Reference: "tx1", - Timestamp: now.Add(-3 * time.Hour), - }, - }, - PostCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(100), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(100), - Output: big.NewInt(0), - }, - }, - }, - PreCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(0), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(0), - }, - }, - }, - } - tx2 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 1, - TransactionData: core.TransactionData{ - Postings: []core.Posting{ - { - Source: "world", - Destination: "central_bank", - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - Reference: "tx2", - Timestamp: now.Add(-2 * time.Hour), - }, - }, - PostCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(200), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(200), - Output: big.NewInt(0), - }, - }, - }, - PreCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(100), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(100), - Output: big.NewInt(0), - }, - }, - }, - } - tx3 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 2, - TransactionData: core.TransactionData{ - Postings: []core.Posting{ - { - Source: "central_bank", - Destination: "users:1", - Amount: big.NewInt(1), - Asset: "USD", - }, - }, - Reference: "tx3", - Metadata: metadata.Metadata{ - "priority": "high", - }, - Timestamp: now.Add(-1 * time.Hour), - }, - }, - PreCommitVolumes: core.AccountsAssetsVolumes{ - "central_bank": { - "USD": { - Input: big.NewInt(200), - Output: big.NewInt(0), - }, - }, - "users:1": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(0), - }, - }, - }, - PostCommitVolumes: core.AccountsAssetsVolumes{ - "central_bank": { - "USD": { - Input: big.NewInt(200), - Output: big.NewInt(1), - }, - }, - "users:1": { - "USD": { - Input: big.NewInt(1), - Output: big.NewInt(0), - }, - }, - }, - } - - var previousLog *core.ChainedLog - for _, tx := range []core.ExpandedTransaction{tx1, tx2, tx3} { - newLog := core.NewTransactionLog(&tx.Transaction, nil).ChainLog(previousLog) - appendLog(t, store, newLog) - previousLog = newLog - } - - cursor, err := store.GetLogs(context.Background(), ledgerstore.NewLogsQuery()) - require.NoError(t, err) - require.Equal(t, ledgerstore.QueryDefaultPageSize, cursor.PageSize) - - require.Equal(t, 3, len(cursor.Data)) - require.Equal(t, uint64(2), cursor.Data[0].ID) - require.Equal(t, tx3.Postings, cursor.Data[0].Data.(core.NewTransactionLogPayload).Transaction.Postings) - require.Equal(t, tx3.Reference, cursor.Data[0].Data.(core.NewTransactionLogPayload).Transaction.Reference) - require.Equal(t, tx3.Timestamp, cursor.Data[0].Data.(core.NewTransactionLogPayload).Transaction.Timestamp) - - cursor, err = store.GetLogs(context.Background(), ledgerstore.NewLogsQuery().WithPageSize(1)) - require.NoError(t, err) - // Should get only the first log. - require.Equal(t, 1, cursor.PageSize) - require.Equal(t, uint64(2), cursor.Data[0].ID) - - cursor, err = store.GetLogs(context.Background(), ledgerstore.NewLogsQuery(). - WithStartTimeFilter(now.Add(-2*time.Hour)). - WithEndTimeFilter(now.Add(-1*time.Hour)). - WithPageSize(10)) - require.NoError(t, err) - require.Equal(t, 10, cursor.PageSize) - // Should get only the second log, as StartTime is inclusive and EndTime exclusive. - require.Len(t, cursor.Data, 1) - require.Equal(t, uint64(1), cursor.Data[0].ID) -} - -func TestGetBalanceFromLogs(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - const ( - batchNumber = 100 - batchSize = 10 - input = 100 - output = 10 - ) - - logs := make([]*core.ActiveLog, 0) - var previousLog *core.ChainedLog - for i := 0; i < batchNumber; i++ { - for j := 0; j < batchSize; j++ { - activeLog := core.NewActiveLog(core.NewTransactionLog( - core.NewTransaction().WithPostings( - core.NewPosting("world", fmt.Sprintf("account:%d", j), "EUR/2", big.NewInt(input)), - core.NewPosting(fmt.Sprintf("account:%d", j), "starbucks", "EUR/2", big.NewInt(output)), - ).WithID(uint64(i*batchSize+j)), - map[string]metadata.Metadata{}, - ).ChainLog(previousLog)) - logs = append(logs, activeLog) - previousLog = activeLog.ChainedLog - } - } - err := store.InsertLogs(context.Background(), logs...) - require.NoError(t, err) - - balance, err := store.GetBalanceFromLogs(context.Background(), "account:1", "EUR/2") - require.NoError(t, err) - require.Equal(t, big.NewInt((input-output)*batchNumber), balance) -} - -func TestGetMetadataFromLogs(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - logs := make([]*core.ActiveLog, 0) - logs = append(logs, core.NewActiveLog(core.NewTransactionLog( - core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "EUR/2", big.NewInt(100)), - core.NewPosting("bank", "starbucks", "EUR/2", big.NewInt(10)), - ), - map[string]metadata.Metadata{}, - ).ChainLog(nil))) - logs = append(logs, core.NewActiveLog(core.NewSetMetadataLog(core.Now(), core.SetMetadataLogPayload{ - TargetType: core.MetaTargetTypeAccount, - TargetID: "bank", - Metadata: metadata.Metadata{ - "foo": "bar", - }, - }).ChainLog(logs[0].ChainedLog))) - logs = append(logs, core.NewActiveLog(core.NewTransactionLog( - core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "EUR/2", big.NewInt(100)), - core.NewPosting("bank", "starbucks", "EUR/2", big.NewInt(10)), - ).WithID(1), - map[string]metadata.Metadata{}, - ).ChainLog(logs[1].ChainedLog))) - logs = append(logs, core.NewActiveLog(core.NewSetMetadataLog(core.Now(), core.SetMetadataLogPayload{ - TargetType: core.MetaTargetTypeAccount, - TargetID: "bank", - Metadata: metadata.Metadata{ - "role": "admin", - }, - }).ChainLog(logs[2].ChainedLog))) - logs = append(logs, core.NewActiveLog(core.NewTransactionLog( - core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "EUR/2", big.NewInt(100)), - core.NewPosting("bank", "starbucks", "EUR/2", big.NewInt(10)), - ).WithID(2), - map[string]metadata.Metadata{}, - ).ChainLog(logs[3].ChainedLog))) - - err := store.InsertLogs(context.Background(), logs...) - require.NoError(t, err) - - metadata, err := store.GetMetadataFromLogs(context.Background(), "bank", "foo") - require.NoError(t, err) - require.Equal(t, "bar", metadata) -} diff --git a/components/ledger/pkg/storage/ledgerstore/main_test.go b/components/ledger/pkg/storage/ledgerstore/main_test.go deleted file mode 100644 index 23a1dc04b..000000000 --- a/components/ledger/pkg/storage/ledgerstore/main_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package ledgerstore_test - -import ( - "context" - "database/sql" - "fmt" - "os" - "strings" - "testing" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/driver" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - _ "github.com/formancehq/ledger/pkg/storage/ledgerstore/migrates/0-init-schema" - "github.com/formancehq/stack/libs/go-libs/logging" - "github.com/formancehq/stack/libs/go-libs/pgtesting" - "github.com/google/uuid" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestMain(m *testing.M) { - if err := pgtesting.CreatePostgresServer(); err != nil { - logging.Error(err) - os.Exit(1) - } - - code := m.Run() - if err := pgtesting.DestroyPostgresServer(); err != nil { - logging.Error(err) - } - os.Exit(code) -} - -func newLedgerStore(t *testing.T) *ledgerstore.Store { - t.Helper() - - pgServer := pgtesting.NewPostgresDatabase(t) - db, err := storage.OpenSQLDB(storage.ConnectionOptions{ - DatabaseSourceName: pgServer.ConnString(), - Debug: testing.Verbose(), - Trace: testing.Verbose(), - }, - //&explainHook{}, - ) - require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, db.Close()) - }) - - driver := driver.New(storage.NewDatabase(db)) - require.NoError(t, driver.Initialize(context.Background())) - ledgerStore, err := driver.CreateLedgerStore(context.Background(), uuid.NewString()) - require.NoError(t, err) - - _, err = ledgerStore.Migrate(context.Background()) - require.NoError(t, err) - - return ledgerStore -} - -func appendLog(t *testing.T, store *ledgerstore.Store, log *core.ChainedLog) *core.ChainedLog { - err := store.InsertLogs(context.Background(), core.NewActiveLog(log)) - require.NoError(t, err) - return log -} - -type explainHook struct{} - -func (h *explainHook) AfterQuery(ctx context.Context, event *bun.QueryEvent) {} - -func (h *explainHook) BeforeQuery(ctx context.Context, event *bun.QueryEvent) context.Context { - lowerQuery := strings.ToLower(event.Query) - if strings.HasPrefix(lowerQuery, "explain") || - strings.HasPrefix(lowerQuery, "create") || - strings.HasPrefix(lowerQuery, "begin") || - strings.HasPrefix(lowerQuery, "alter") || - strings.HasPrefix(lowerQuery, "rollback") || - strings.HasPrefix(lowerQuery, "commit") { - return ctx - } - - event.DB.RunInTx(context.Background(), &sql.TxOptions{}, func(ctx context.Context, tx bun.Tx) error { - rows, err := tx.Query("explain analyze " + event.Query) - if err != nil { - return err - } - defer rows.Next() - - for rows.Next() { - var line string - if err := rows.Scan(&line); err != nil { - return err - } - fmt.Println(line) - } - - return tx.Rollback() - - }) - - return ctx -} diff --git a/components/ledger/pkg/storage/ledgerstore/migrates/0-init-schema/any.go b/components/ledger/pkg/storage/ledgerstore/migrates/0-init-schema/any.go deleted file mode 100644 index cebe58186..000000000 --- a/components/ledger/pkg/storage/ledgerstore/migrates/0-init-schema/any.go +++ /dev/null @@ -1,332 +0,0 @@ -package initschema - -import ( - "context" - "database/sql" - "encoding/json" - "fmt" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/ledger/pkg/storage/migrations" - "github.com/lib/pq" - "github.com/pkg/errors" - flag "github.com/spf13/pflag" - "github.com/spf13/viper" - "github.com/uptrace/bun" -) - -func init() { - migrations.RegisterGoMigration(UpgradeLogs) -} - -const ( - LogTableName = "log" - - LogsMigrationBatchSizeFlag = "logs-migration-batch-size" - OldSchemaRenameSuffixFlag = "old-schema-rename-prefix" -) - -var ( - batchSize uint64 = 10000 - oldSchemaRenameSuffix = "_save_v2_0_0" -) - -func InitMigrationConfigCLIFlags(flags *flag.FlagSet) { - flags.Uint64(LogsMigrationBatchSizeFlag, 10000, "Batch size for logs migration") - flags.String(OldSchemaRenameSuffixFlag, "save_v2_0_0", "Name of the old schema (to be renamed)") -} - -type Log struct { - bun.BaseModel `bun:"log,alias:log"` - - ID uint64 `bun:"id,unique,type:bigint"` - Type string `bun:"type,type:varchar"` - Hash string `bun:"hash,type:varchar"` - Date core.Time `bun:"date,type:timestamptz"` - Data json.RawMessage `bun:"data,type:jsonb"` -} - -func isLogTableExisting( - ctx context.Context, - schema storage.Schema, - sqlTx *storage.Tx, -) (bool, error) { - row := sqlTx.QueryRowContext(ctx, fmt.Sprintf(` - SELECT EXISTS ( - SELECT FROM - pg_tables - WHERE - schemaname = '%s' AND - tablename = 'log' - ) - `, schema.Name())) - if row.Err() != nil { - return false, errors.Wrap(row.Err(), "checking if log table exists") - } - - var exists bool - if err := row.Scan(&exists); err != nil { - return false, errors.Wrap(err, "scanning if log table exists") - } - - return exists, nil -} - -func readLogsRange( - ctx context.Context, - sqlTx *storage.Tx, - idMin, idMax uint64, -) ([]Log, error) { - rawLogs := make([]Log, 0) - if err := sqlTx. - NewSelect(LogTableName). - Where("id >= ?", idMin). - Where("id < ?", idMax). - Model(&rawLogs). - Scan(ctx); err != nil { - return nil, err - } - - return rawLogs, nil -} - -func convertMetadata(data []byte) any { - ret := make(map[string]any) - if err := json.Unmarshal(data, &ret); err != nil { - panic(err) - } - oldMetadata := ret["metadata"].(map[string]any) - newMetadata := make(map[string]string) - for k, v := range oldMetadata { - newMetadata[k] = fmt.Sprint(v) - } - ret["metadata"] = newMetadata - - return ret -} - -func (l *Log) ToLogsV2() (ledgerstore.LogsV2, error) { - logType, err := core.LogTypeFromString(l.Type) - if err != nil { - return ledgerstore.LogsV2{}, errors.Wrap(err, "converting log type") - } - - var data any - switch logType { - case core.NewTransactionLogType: - data = map[string]any{ - "transaction": convertMetadata(l.Data), - "accountMetadata": map[string]any{}, - } - case core.SetMetadataLogType: - data = convertMetadata(l.Data) - case core.RevertedTransactionLogType: - data = l.Data - default: - panic("unknown type " + logType.String()) - } - - asJson, err := json.Marshal(data) - if err != nil { - panic(err) - } - - return ledgerstore.LogsV2{ - ID: l.ID, - Type: int16(logType), - Hash: []byte(l.Hash), - Date: l.Date, - Data: asJson, - }, nil -} - -func batchLogs( - ctx context.Context, - schema storage.Schema, - sqlTx *storage.Tx, - logs []ledgerstore.LogsV2, -) error { - txn, err := sqlTx.BeginTx(ctx, &sql.TxOptions{}) - if err != nil { - return err - } - - // Beware: COPY query is not supported by bun if the pgx driver is used. - stmt, err := txn.Prepare(pq.CopyInSchema( - schema.Name(), - ledgerstore.LogTableName, - "id", "type", "hash", "date", "data", - )) - if err != nil { - return err - } - - for _, l := range logs { - _, err = stmt.Exec(l.ID, l.Type, l.Hash, l.Date, ledgerstore.RawMessage(l.Data)) - if err != nil { - return err - } - } - - _, err = stmt.Exec() - if err != nil { - return err - } - - err = stmt.Close() - if err != nil { - return err - } - - return txn.Commit() -} - -func cleanSchema( - ctx context.Context, - schemaV1 storage.Schema, - schemaV2 storage.Schema, - sqlTx *storage.Tx, -) error { - _, err := sqlTx.ExecContext(ctx, fmt.Sprintf(`ALTER SCHEMA "%s" RENAME TO "%s"`, - schemaV1.Name(), schemaV1.Name()+oldSchemaRenameSuffix)) - if err != nil { - return err - } - - _, err = sqlTx.ExecContext(ctx, fmt.Sprintf(`ALTER SCHEMA "%s" RENAME TO "%s"`, - schemaV2.Name(), schemaV1.Name())) - - return err -} - -func migrateLogs( - ctx context.Context, - schemaV1 storage.Schema, - schemaV2 storage.Schema, - store *ledgerstore.Store, - sqlTx *storage.Tx, -) error { - exists, err := isLogTableExisting(ctx, schemaV1, sqlTx) - if err != nil { - return err - } - - if !exists { - return nil - } - - var idMin uint64 - var idMax = idMin + batchSize - for { - logs, err := readLogsRange(ctx, sqlTx, idMin, idMax) - if err != nil { - return err - } - - if len(logs) == 0 { - break - } - - logsV2 := make([]ledgerstore.LogsV2, 0, len(logs)) - for _, l := range logs { - logV2, err := l.ToLogsV2() - if err != nil { - return err - } - - logsV2 = append(logsV2, logV2) - } - - err = batchLogs(ctx, schemaV2, sqlTx, logsV2) - if err != nil { - return err - } - - for _, log := range logsV2 { - coreLog := log.ToCore() - switch payload := coreLog.Data.(type) { - case core.NewTransactionLogPayload: - if err := store.InsertTransactions(ctx, *payload.Transaction); err != nil { - return err - } - if err := store.InsertMoves(ctx, payload.Transaction.GetMoves()...); err != nil { - return err - } - case core.SetMetadataLogPayload: - switch payload.TargetType { - case core.MetaTargetTypeTransaction: - if err := store.UpdateTransactionsMetadata(ctx, core.TransactionWithMetadata{ - ID: payload.TargetID.(uint64), - Metadata: payload.Metadata, - }); err != nil { - return err - } - case core.MetaTargetTypeAccount: - if err := store.UpdateAccountsMetadata(ctx, core.Account{ - Address: payload.TargetID.(string), - Metadata: payload.Metadata, - }); err != nil { - return err - } - } - case core.RevertedTransactionLogPayload: - if err := store.InsertTransactions(ctx, *payload.RevertTransaction); err != nil { - return err - } - if err := store.InsertMoves(ctx, payload.RevertTransaction.GetMoves()...); err != nil { - return err - } - if err := store.UpdateTransactionsMetadata(ctx, core.TransactionWithMetadata{ - ID: payload.RevertedTransactionID, - Metadata: core.RevertedMetadata(payload.RevertTransaction.ID), - }); err != nil { - return err - } - } - if err := store.MarkedLogsAsProjected(ctx, log.ID); err != nil { - return err - } - } - - idMin = idMax - idMax = idMin + batchSize - } - - return nil -} - -func UpgradeLogs( - ctx context.Context, - schemaV1 storage.Schema, - sqlTx *storage.Tx, -) error { - b := viper.GetUint64(LogsMigrationBatchSizeFlag) - if b != 0 { - batchSize = b - } - - suffix := viper.GetString(OldSchemaRenameSuffixFlag) - if suffix != "" { - oldSchemaRenameSuffix = suffix - } - - // Create schema v2 - schemaV2 := storage.NewSchema(sqlTx.Tx, schemaV1.Name()+"_v2_0_0") - store, err := ledgerstore.New( - schemaV2, - func(ctx context.Context) error { - return nil - }, - ) - if err != nil { - return errors.Wrap(err, "creating store") - } - - if err := migrateLogs(ctx, schemaV1, schemaV2, store, sqlTx); err != nil { - return errors.Wrap(err, "migrating logs") - } - - return cleanSchema(ctx, schemaV1, schemaV2, sqlTx) -} diff --git a/components/ledger/pkg/storage/ledgerstore/migrates/0-init-schema/postgres.sql b/components/ledger/pkg/storage/ledgerstore/migrates/0-init-schema/postgres.sql deleted file mode 100644 index dc67fd1af..000000000 --- a/components/ledger/pkg/storage/ledgerstore/migrates/0-init-schema/postgres.sql +++ /dev/null @@ -1,127 +0,0 @@ ---statement -create schema "VAR_LEDGER_NAME_v2_0_0"; - ---statement -create function "VAR_LEDGER_NAME_v2_0_0".meta_compare(metadata jsonb, value boolean, variadic path text[]) returns boolean - language plpgsql immutable - as $$ begin return jsonb_extract_path(metadata, variadic path)::bool = value::bool; exception when others then raise info 'Error Name: %', SQLERRM; raise info 'Error State: %', SQLSTATE; return false; END $$; - ---statement -create function "VAR_LEDGER_NAME_v2_0_0".meta_compare(metadata jsonb, value numeric, variadic path text[]) returns boolean - language plpgsql immutable - as $$ begin return jsonb_extract_path(metadata, variadic path)::numeric = value::numeric; exception when others then raise info 'Error Name: %', SQLERRM; raise info 'Error State: %', SQLSTATE; return false; END $$; - ---statement -create function "VAR_LEDGER_NAME_v2_0_0".meta_compare(metadata jsonb, value character varying, variadic path text[]) returns boolean - language plpgsql immutable - as $$ begin return jsonb_extract_path_text(metadata, variadic path)::varchar = value::varchar; exception when others then raise info 'Error Name: %', SQLERRM; raise info 'Error State: %', SQLSTATE; return false; END $$; - ---statement -create table "VAR_LEDGER_NAME_v2_0_0".accounts ( - address character varying not null primary key, - address_json jsonb not null, - metadata jsonb default '{}'::jsonb -); - ---statement -create table "VAR_LEDGER_NAME_v2_0_0".logs ( - id numeric primary key , - type smallint, - hash bytea, - date timestamp with time zone, - data jsonb, - idempotency_key varchar(255), - projected boolean default false -); - ---statement -create table "VAR_LEDGER_NAME_v2_0_0".migrations ( - version character varying primary key, - date character varying -); - ---statement -create table "VAR_LEDGER_NAME_v2_0_0".transactions ( - id bigint unique primary key , - "timestamp" timestamp with time zone not null, - reference character varying unique, - metadata jsonb default '{}'::jsonb -); - ---statement -create table "VAR_LEDGER_NAME_v2_0_0".moves ( - posting_index int8, - transaction_id bigint, - account varchar, - account_array jsonb not null, - asset varchar, - post_commit_input_value numeric, - post_commit_output_value numeric, - timestamp timestamp with time zone, - amount numeric not null, - is_source boolean, - - primary key (transaction_id, posting_index, is_source) -); - ---statement -create index logsv2_type on "VAR_LEDGER_NAME_v2_0_0".logs (type); - ---statement -create index logsv2_projected on "VAR_LEDGER_NAME_v2_0_0".logs (projected); - ---statement -create index logsv2_data on "VAR_LEDGER_NAME_v2_0_0".logs using gin (data); - ---statement -create index logsv2_new_transaction_postings on "VAR_LEDGER_NAME_v2_0_0".logs using gin ((data->'transaction'->'postings') jsonb_path_ops); - ---statement -create index logsv2_set_metadata on "VAR_LEDGER_NAME_v2_0_0".logs using btree (type, (data->>'targetId'), (data->>'targetType')); - ---statement -create index transactions_id_timestamp on "VAR_LEDGER_NAME_v2_0_0".transactions(id, timestamp); - ---statement -create index transactions_timestamp on "VAR_LEDGER_NAME_v2_0_0".transactions(timestamp); - ---statement -create index transactions_reference on "VAR_LEDGER_NAME_v2_0_0".transactions(reference); - ---statement -create index transactions_metadata on "VAR_LEDGER_NAME_v2_0_0".transactions using gin(metadata); - ---statement -create index moves_transaction_id on "VAR_LEDGER_NAME_v2_0_0".moves(transaction_id, posting_index); - ---statement -create index moves_account_array on "VAR_LEDGER_NAME_v2_0_0".moves using gin(account_array); - ---statement -create index moves_account on "VAR_LEDGER_NAME_v2_0_0".moves(account, asset, timestamp); - ---statement -create index moves_is_source on "VAR_LEDGER_NAME_v2_0_0".moves(account, is_source); - ---statement -create index accounts_address_json on "VAR_LEDGER_NAME_v2_0_0".accounts using GIN(address_json); - ---statement -create function "VAR_LEDGER_NAME_v2_0_0".first_agg (anyelement, anyelement) - returns anyelement - language sql immutable strict parallel safe as -'select $1'; - ---statement -create aggregate "VAR_LEDGER_NAME_v2_0_0".first (anyelement) ( - sfunc = "VAR_LEDGER_NAME_v2_0_0".first_agg -, stype = anyelement -, parallel = safe -); - ---statement -create aggregate "VAR_LEDGER_NAME_v2_0_0".aggregate_objects(jsonb) ( - sfunc = jsonb_concat, - stype = jsonb, - initcond = '{}' -); diff --git a/components/ledger/pkg/storage/ledgerstore/migration.go b/components/ledger/pkg/storage/ledgerstore/migration.go deleted file mode 100644 index 7b3bb7d54..000000000 --- a/components/ledger/pkg/storage/ledgerstore/migration.go +++ /dev/null @@ -1,36 +0,0 @@ -package ledgerstore - -import ( - "context" - "embed" - - "github.com/formancehq/ledger/pkg/core" - sqlerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/migrations" - "github.com/pkg/errors" -) - -func (s *Store) GetMigrationsDone(ctx context.Context) ([]core.MigrationInfo, error) { - migrations, err := migrations.GetMigrations(ctx, s.schema) - return migrations, sqlerrors.PostgresError(err) -} - -func (s *Store) GetMigrationsAvailable() ([]core.MigrationInfo, error) { - migrations, err := migrations.CollectMigrationFiles(MigrationsFS) - if err != nil { - return []core.MigrationInfo{}, errors.Wrap(err, "collecting migration files") - } - - res := make([]core.MigrationInfo, 0) - for _, m := range migrations { - res = append(res, core.MigrationInfo{ - Version: m.Version, - Name: m.Name, - }) - } - - return res, nil -} - -//go:embed migrates -var MigrationsFS embed.FS diff --git a/components/ledger/pkg/storage/ledgerstore/pagination.go b/components/ledger/pkg/storage/ledgerstore/pagination.go deleted file mode 100644 index 760e3101a..000000000 --- a/components/ledger/pkg/storage/ledgerstore/pagination.go +++ /dev/null @@ -1,82 +0,0 @@ -package ledgerstore - -import ( - "encoding/base64" - "encoding/json" -) - -const ( - OrderAsc = iota - OrderDesc - - QueryDefaultPageSize = 15 -) - -type Order int - -func (o Order) String() string { - switch o { - case OrderAsc: - return "ASC" - case OrderDesc: - return "DESC" - } - panic("should not happen") -} - -func (o Order) Reverse() Order { - return (o + 1) % 2 -} - -type ColumnPaginatedQuery[FILTERS any] struct { - PageSize uint64 `json:"pageSize"` - Bottom *uint64 `json:"bottom"` - Column string `json:"column"` - PaginationID *uint64 `json:"paginationID"` - Order Order `json:"order"` - Filters FILTERS `json:"filters"` - Reverse bool `json:"reverse"` -} - -func (q *ColumnPaginatedQuery[PAYLOAD]) EncodeAsCursor() string { - return encodeCursor(q) -} - -type OffsetPaginatedQuery[FILTERS any] struct { - Offset uint64 `json:"offset"` - Order Order `json:"order"` - PageSize uint64 `json:"pageSize"` - Filters FILTERS `json:"filters"` -} - -func (q *OffsetPaginatedQuery[PAYLOAD]) EncodeAsCursor() string { - return encodeCursor(q) -} - -func encodeCursor[T any](v *T) string { - if v == nil { - return "" - } - return EncodeCursor(*v) -} - -func EncodeCursor[T any](v T) string { - data, err := json.Marshal(v) - if err != nil { - panic(err) - } - return base64.RawURLEncoding.EncodeToString(data) -} - -func UnmarshalCursor(v string, to any) error { - res, err := base64.RawURLEncoding.DecodeString(v) - if err != nil { - return err - } - - if err := json.Unmarshal(res, &to); err != nil { - return err - } - - return nil -} diff --git a/components/ledger/pkg/storage/ledgerstore/pagination_column_test.go b/components/ledger/pkg/storage/ledgerstore/pagination_column_test.go deleted file mode 100644 index 7d2a80585..000000000 --- a/components/ledger/pkg/storage/ledgerstore/pagination_column_test.go +++ /dev/null @@ -1,349 +0,0 @@ -package ledgerstore_test - -import ( - "context" - "testing" - - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/stack/libs/go-libs/pgtesting" - "github.com/formancehq/stack/libs/go-libs/pointer" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestColumnPagination(t *testing.T) { - t.Parallel() - - pgServer := pgtesting.NewPostgresDatabase(t) - db, err := storage.OpenSQLDB(storage.ConnectionOptions{ - DatabaseSourceName: pgServer.ConnString(), - Debug: testing.Verbose(), - Trace: testing.Verbose(), - }) - require.NoError(t, err) - - _, err = db.Exec(` - CREATE TABLE "models" (id int, pair boolean); - `) - require.NoError(t, err) - - type model struct { - ID uint64 `bun:"id"` - Pair bool `bun:"pair"` - } - - models := make([]model, 0) - for i := 0; i < 100; i++ { - models = append(models, model{ - ID: uint64(i), - Pair: i%2 == 0, - }) - } - - _, err = db.NewInsert(). - Model(&models). - Exec(context.Background()) - require.NoError(t, err) - - type testCase struct { - name string - query ledgerstore.ColumnPaginatedQuery[bool] - expectedNext *ledgerstore.ColumnPaginatedQuery[bool] - expectedPrevious *ledgerstore.ColumnPaginatedQuery[bool] - expectedNumberOfItems uint64 - } - testCases := []testCase{ - { - name: "asc first page", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - Order: ledgerstore.OrderAsc, - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(10)), - Order: ledgerstore.OrderAsc, - Bottom: pointer.For(uint64(0)), - }, - expectedNumberOfItems: 10, - }, - { - name: "asc second page using next cursor", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(10)), - Order: ledgerstore.OrderAsc, - Bottom: pointer.For(uint64(0)), - }, - expectedPrevious: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - Order: ledgerstore.OrderAsc, - Bottom: pointer.For(uint64(0)), - PaginationID: pointer.For(uint64(10)), - Reverse: true, - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(20)), - Order: ledgerstore.OrderAsc, - Bottom: pointer.For(uint64(0)), - }, - expectedNumberOfItems: 10, - }, - { - name: "asc last page using next cursor", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(90)), - Order: ledgerstore.OrderAsc, - Bottom: pointer.For(uint64(0)), - }, - expectedPrevious: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - Order: ledgerstore.OrderAsc, - PaginationID: pointer.For(uint64(90)), - Bottom: pointer.For(uint64(0)), - Reverse: true, - }, - expectedNumberOfItems: 10, - }, - { - name: "desc first page", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - Order: ledgerstore.OrderDesc, - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(99)), - Column: "id", - PaginationID: pointer.For(uint64(89)), - Order: ledgerstore.OrderDesc, - }, - expectedNumberOfItems: 10, - }, - { - name: "desc second page using next cursor", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(99)), - Column: "id", - PaginationID: pointer.For(uint64(89)), - Order: ledgerstore.OrderDesc, - }, - expectedPrevious: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(99)), - Column: "id", - PaginationID: pointer.For(uint64(89)), - Order: ledgerstore.OrderDesc, - Reverse: true, - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(99)), - Column: "id", - PaginationID: pointer.For(uint64(79)), - Order: ledgerstore.OrderDesc, - }, - expectedNumberOfItems: 10, - }, - { - name: "desc last page using next cursor", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(99)), - Column: "id", - PaginationID: pointer.For(uint64(9)), - Order: ledgerstore.OrderDesc, - }, - expectedPrevious: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(99)), - Column: "id", - PaginationID: pointer.For(uint64(9)), - Order: ledgerstore.OrderDesc, - Reverse: true, - }, - expectedNumberOfItems: 10, - }, - { - name: "asc first page using previous cursor", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(0)), - Column: "id", - PaginationID: pointer.For(uint64(10)), - Order: ledgerstore.OrderAsc, - Reverse: true, - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(0)), - Column: "id", - PaginationID: pointer.For(uint64(10)), - Order: ledgerstore.OrderAsc, - }, - expectedNumberOfItems: 10, - }, - { - name: "desc first page using previous cursor", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(99)), - Column: "id", - PaginationID: pointer.For(uint64(89)), - Order: ledgerstore.OrderDesc, - Reverse: true, - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Bottom: pointer.For(uint64(99)), - Column: "id", - PaginationID: pointer.For(uint64(89)), - Order: ledgerstore.OrderDesc, - }, - expectedNumberOfItems: 10, - }, - { - name: "asc first page with filter", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - Order: ledgerstore.OrderAsc, - Filters: true, - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(20)), - Order: ledgerstore.OrderAsc, - Filters: true, - Bottom: pointer.For(uint64(0)), - }, - expectedNumberOfItems: 10, - }, - { - name: "asc second page with filter", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(20)), - Order: ledgerstore.OrderAsc, - Filters: true, - Bottom: pointer.For(uint64(0)), - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(40)), - Order: ledgerstore.OrderAsc, - Filters: true, - Bottom: pointer.For(uint64(0)), - }, - expectedPrevious: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(20)), - Order: ledgerstore.OrderAsc, - Filters: true, - Bottom: pointer.For(uint64(0)), - Reverse: true, - }, - expectedNumberOfItems: 10, - }, - { - name: "desc first page with filter", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - Order: ledgerstore.OrderDesc, - Filters: true, - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(78)), - Order: ledgerstore.OrderDesc, - Filters: true, - Bottom: pointer.For(uint64(98)), - }, - expectedNumberOfItems: 10, - }, - { - name: "desc second page with filter", - query: ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(78)), - Order: ledgerstore.OrderDesc, - Filters: true, - Bottom: pointer.For(uint64(98)), - }, - expectedNext: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(58)), - Order: ledgerstore.OrderDesc, - Filters: true, - Bottom: pointer.For(uint64(98)), - }, - expectedPrevious: &ledgerstore.ColumnPaginatedQuery[bool]{ - PageSize: 10, - Column: "id", - PaginationID: pointer.For(uint64(78)), - Order: ledgerstore.OrderDesc, - Filters: true, - Bottom: pointer.For(uint64(98)), - Reverse: true, - }, - expectedNumberOfItems: 10, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - cursor, err := ledgerstore.UsingColumn( - context.Background(), - func(filters bool, models *[]model) *bun.SelectQuery { - query := db.NewSelect().Model(models).Column("id") - if tc.query.Filters { - query = query.Where("pair = ?", true) - } - return query - }, - tc.query) - require.NoError(t, err) - - if tc.expectedNext == nil { - require.Empty(t, cursor.Next) - } else { - require.NotEmpty(t, cursor.Next) - - q := ledgerstore.ColumnPaginatedQuery[bool]{} - require.NoError(t, ledgerstore.UnmarshalCursor(cursor.Next, &q)) - require.EqualValues(t, *tc.expectedNext, q) - } - - if tc.expectedPrevious == nil { - require.Empty(t, cursor.Previous) - } else { - require.NotEmpty(t, cursor.Previous) - - q := ledgerstore.ColumnPaginatedQuery[bool]{} - require.NoError(t, ledgerstore.UnmarshalCursor(cursor.Previous, &q)) - require.EqualValues(t, *tc.expectedPrevious, q) - } - }) - } -} diff --git a/components/ledger/pkg/storage/ledgerstore/pagination_offset_test.go b/components/ledger/pkg/storage/ledgerstore/pagination_offset_test.go deleted file mode 100644 index ddd53961c..000000000 --- a/components/ledger/pkg/storage/ledgerstore/pagination_offset_test.go +++ /dev/null @@ -1,171 +0,0 @@ -package ledgerstore_test - -import ( - "context" - "testing" - - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/stack/libs/go-libs/pgtesting" - "github.com/stretchr/testify/require" -) - -func TestOffsetPagination(t *testing.T) { - t.Parallel() - - pgServer := pgtesting.NewPostgresDatabase(t) - db, err := storage.OpenSQLDB(storage.ConnectionOptions{ - DatabaseSourceName: pgServer.ConnString(), - Debug: testing.Verbose(), - Trace: testing.Verbose(), - }) - require.NoError(t, err) - - _, err = db.Exec(` - CREATE TABLE "models" (id int, pair boolean); - `) - require.NoError(t, err) - - type model struct { - ID uint64 `bun:"id"` - Pair bool `bun:"pair"` - } - - models := make([]model, 0) - for i := 0; i < 100; i++ { - models = append(models, model{ - ID: uint64(i), - Pair: i%2 == 0, - }) - } - - _, err = db.NewInsert(). - Model(&models). - Exec(context.Background()) - require.NoError(t, err) - - type testCase struct { - name string - query ledgerstore.OffsetPaginatedQuery[bool] - expectedNext *ledgerstore.OffsetPaginatedQuery[bool] - expectedPrevious *ledgerstore.OffsetPaginatedQuery[bool] - expectedNumberOfItems uint64 - } - testCases := []testCase{ - { - name: "asc first page", - query: ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Order: ledgerstore.OrderAsc, - }, - expectedNext: &ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Offset: 10, - Order: ledgerstore.OrderAsc, - }, - expectedNumberOfItems: 10, - }, - { - name: "asc second page using next cursor", - query: ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Offset: 10, - Order: ledgerstore.OrderAsc, - }, - expectedPrevious: &ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Order: ledgerstore.OrderAsc, - Offset: 0, - }, - expectedNext: &ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Order: ledgerstore.OrderAsc, - Offset: 20, - }, - expectedNumberOfItems: 10, - }, - { - name: "asc last page using next cursor", - query: ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Offset: 90, - Order: ledgerstore.OrderAsc, - }, - expectedPrevious: &ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Order: ledgerstore.OrderAsc, - Offset: 80, - }, - expectedNumberOfItems: 10, - }, - { - name: "asc last page partial", - query: ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Offset: 95, - Order: ledgerstore.OrderAsc, - }, - expectedPrevious: &ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Order: ledgerstore.OrderAsc, - Offset: 85, - }, - expectedNumberOfItems: 10, - }, - { - name: "asc fist page partial", - query: ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Offset: 5, - Order: ledgerstore.OrderAsc, - }, - expectedPrevious: &ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Order: ledgerstore.OrderAsc, - Offset: 0, - }, - expectedNext: &ledgerstore.OffsetPaginatedQuery[bool]{ - PageSize: 10, - Order: ledgerstore.OrderAsc, - Offset: 15, - }, - expectedNumberOfItems: 10, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - - query := db.NewSelect().Model(&models).Column("id") - if tc.query.Filters { - query = query.Where("pair = ?", true) - } - cursor, err := ledgerstore.UsingOffset[bool, model]( - context.Background(), - query, - tc.query) - require.NoError(t, err) - - if tc.expectedNext == nil { - require.Empty(t, cursor.Next) - } else { - require.NotEmpty(t, cursor.Next) - - q := ledgerstore.OffsetPaginatedQuery[bool]{} - require.NoError(t, ledgerstore.UnmarshalCursor(cursor.Next, &q)) - require.EqualValues(t, *tc.expectedNext, q) - } - - if tc.expectedPrevious == nil { - require.Empty(t, cursor.Previous) - } else { - require.NotEmpty(t, cursor.Previous) - - q := ledgerstore.OffsetPaginatedQuery[bool]{} - require.NoError(t, ledgerstore.UnmarshalCursor(cursor.Previous, &q)) - require.EqualValues(t, *tc.expectedPrevious, q) - } - }) - } -} diff --git a/components/ledger/pkg/storage/ledgerstore/store.go b/components/ledger/pkg/storage/ledgerstore/store.go deleted file mode 100644 index 74e28e0f9..000000000 --- a/components/ledger/pkg/storage/ledgerstore/store.go +++ /dev/null @@ -1,67 +0,0 @@ -package ledgerstore - -import ( - "context" - "sync" - - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/migrations" - _ "github.com/jackc/pgx/v5/stdlib" - "github.com/pkg/errors" -) - -const ( - SQLCustomFuncMetaCompare = "meta_compare" -) - -type Store struct { - schema storage.Schema - onDelete func(ctx context.Context) error - - once sync.Once - - isInitialized bool -} - -func (s *Store) Schema() storage.Schema { - return s.schema -} - -func (s *Store) Name() string { - return s.schema.Name() -} - -func (s *Store) Delete(ctx context.Context) error { - if err := s.schema.Delete(ctx); err != nil { - return err - } - return errors.Wrap(s.onDelete(ctx), "deleting ledger store") -} - -func (s *Store) Migrate(ctx context.Context) (bool, error) { - ms, err := migrations.CollectMigrationFiles(MigrationsFS) - if err != nil { - return false, err - } - - modified, err := migrations.Migrate(ctx, s.schema, ms...) - if err == nil { - s.isInitialized = true - } - - return modified, err -} - -func (s *Store) IsInitialized() bool { - return s.isInitialized -} - -func New( - schema storage.Schema, - onDelete func(ctx context.Context) error, -) (*Store, error) { - return &Store{ - schema: schema, - onDelete: onDelete, - }, nil -} diff --git a/components/ledger/pkg/storage/ledgerstore/store_test.go b/components/ledger/pkg/storage/ledgerstore/store_test.go deleted file mode 100644 index 5d991856f..000000000 --- a/components/ledger/pkg/storage/ledgerstore/store_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package ledgerstore_test - -import ( - "context" - "testing" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/stack/libs/go-libs/collectionutils" - "github.com/stretchr/testify/require" -) - -func TestInitializeStore(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - modified, err := store.Migrate(context.Background()) - require.NoError(t, err) - require.False(t, modified) -} - -func insertTransactions(ctx context.Context, s *ledgerstore.Store, txs ...core.Transaction) error { - if err := s.InsertTransactions(ctx, txs...); err != nil { - return err - } - moves := collectionutils.Flatten(collectionutils.Map(txs, core.Transaction.GetMoves)) - if err := s.InsertMoves(ctx, moves...); err != nil { - return err - } - return nil -} diff --git a/components/ledger/pkg/storage/ledgerstore/transactions.go b/components/ledger/pkg/storage/ledgerstore/transactions.go deleted file mode 100644 index 8e6f6591a..000000000 --- a/components/ledger/pkg/storage/ledgerstore/transactions.go +++ /dev/null @@ -1,548 +0,0 @@ -package ledgerstore - -import ( - "context" - "database/sql" - "database/sql/driver" - "encoding/json" - "fmt" - "math/big" - "sort" - "strings" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/formancehq/stack/libs/go-libs/pointer" - "github.com/uptrace/bun" -) - -const ( - TransactionsTableName = "transactions" - MovesTableName = "moves" -) - -type TransactionsQuery ColumnPaginatedQuery[TransactionsQueryFilters] - -func NewTransactionsQuery() TransactionsQuery { - return TransactionsQuery{ - PageSize: QueryDefaultPageSize, - Column: "id", - Order: OrderDesc, - Filters: TransactionsQueryFilters{ - Metadata: metadata.Metadata{}, - }, - } -} - -type TransactionsQueryFilters struct { - AfterTxID uint64 `json:"afterTxID,omitempty"` - Reference string `json:"reference,omitempty"` - Destination string `json:"destination,omitempty"` - Source string `json:"source,omitempty"` - Account string `json:"account,omitempty"` - EndTime core.Time `json:"endTime,omitempty"` - StartTime core.Time `json:"startTime,omitempty"` - Metadata metadata.Metadata `json:"metadata,omitempty"` -} - -func (a TransactionsQuery) WithPageSize(pageSize uint64) TransactionsQuery { - if pageSize != 0 { - a.PageSize = pageSize - } - - return a -} - -func (a TransactionsQuery) WithAfterTxID(after uint64) TransactionsQuery { - a.Filters.AfterTxID = after - - return a -} - -func (a TransactionsQuery) WithStartTimeFilter(start core.Time) TransactionsQuery { - if !start.IsZero() { - a.Filters.StartTime = start - } - - return a -} - -func (a TransactionsQuery) WithEndTimeFilter(end core.Time) TransactionsQuery { - if !end.IsZero() { - a.Filters.EndTime = end - } - - return a -} - -func (a TransactionsQuery) WithAccountFilter(account string) TransactionsQuery { - a.Filters.Account = account - - return a -} - -func (a TransactionsQuery) WithDestinationFilter(dest string) TransactionsQuery { - a.Filters.Destination = dest - - return a -} - -func (a TransactionsQuery) WithReferenceFilter(ref string) TransactionsQuery { - a.Filters.Reference = ref - - return a -} - -func (a TransactionsQuery) WithSourceFilter(source string) TransactionsQuery { - a.Filters.Source = source - - return a -} - -func (a TransactionsQuery) WithMetadataFilter(metadata metadata.Metadata) TransactionsQuery { - a.Filters.Metadata = metadata - - return a -} - -type Transaction struct { - bun.BaseModel `bun:"transactions,alias:transactions"` - - ID uint64 `bun:"id,type:bigint,pk"` - Timestamp core.Time `bun:"timestamp,type:timestamptz"` - Reference string `bun:"reference,type:varchar,unique,nullzero"` - Moves []Move `bun:"rel:has-many,join:id=transaction_id"` - Metadata metadata.Metadata `bun:"metadata,type:jsonb,default:'{}'"` -} - -func (t Transaction) toCore() core.ExpandedTransaction { - //data, _ := json.MarshalIndent(t, "", " ") - //fmt.Println(string(data)) - ret := core.ExpandedTransaction{ - Transaction: core.Transaction{ - TransactionData: core.TransactionData{ - Reference: t.Reference, - Metadata: t.Metadata, - Timestamp: t.Timestamp, - Postings: make(core.Postings, len(t.Moves)/2), - }, - ID: t.ID, - }, - PreCommitVolumes: map[string]core.VolumesByAssets{}, - PostCommitVolumes: map[string]core.VolumesByAssets{}, - } - for _, m := range t.Moves { - ret.Postings[m.PostingIndex].Amount = (*big.Int)(m.Amount) - ret.Postings[m.PostingIndex].Asset = m.Asset - if m.IsSource { - ret.Postings[m.PostingIndex].Source = m.Account - } else { - ret.Postings[m.PostingIndex].Destination = m.Account - } - if _, ok := ret.PostCommitVolumes[m.Account]; !ok { - ret.PostCommitVolumes[m.Account] = map[string]*core.Volumes{} - ret.PreCommitVolumes[m.Account] = map[string]*core.Volumes{} - } - if _, ok := ret.PostCommitVolumes[m.Account][m.Asset]; !ok { - ret.PostCommitVolumes[m.Account][m.Asset] = core.NewEmptyVolumes() - ret.PreCommitVolumes[m.Account][m.Asset] = core.NewEmptyVolumes() - } - - ret.PostCommitVolumes[m.Account][m.Asset].Output = NewInt().Set(m.PostCommitOutputVolume).ToMathBig() - ret.PostCommitVolumes[m.Account][m.Asset].Input = NewInt().Set(m.PostCommitInputVolume).ToMathBig() - if m.IsSource { - ret.PreCommitVolumes[m.Account][m.Asset].Output = NewInt().Sub(m.PostCommitOutputVolume, m.Amount).ToMathBig() - ret.PreCommitVolumes[m.Account][m.Asset].Input = NewInt().Set(m.PostCommitInputVolume).ToMathBig() - } else { - ret.PreCommitVolumes[m.Account][m.Asset].Output = NewInt().Set(m.PostCommitOutputVolume).ToMathBig() - ret.PreCommitVolumes[m.Account][m.Asset].Input = NewInt().Sub(m.PostCommitInputVolume, m.Amount).ToMathBig() - } - } - return ret -} - -type account string - -var _ driver.Valuer = account("") - -func (m1 account) Value() (driver.Value, error) { - ret, err := json.Marshal(strings.Split(string(m1), ":")) - if err != nil { - return nil, err - } - return string(ret), nil -} - -// Scan - Implement the database/sql scanner interface -func (m1 *account) Scan(value interface{}) error { - if value == nil { - return nil - } - v, err := driver.String.ConvertValue(value) - if err != nil { - return err - } - - array := make([]string, 0) - switch vv := v.(type) { - case []uint8: - err = json.Unmarshal(vv, &array) - case string: - err = json.Unmarshal([]byte(vv), &array) - default: - panic("not handled type") - } - if err != nil { - return err - } - *m1 = account(strings.Join(array, ":")) - return nil -} - -type Move struct { - bun.BaseModel `bun:"moves,alias:m"` - - TransactionID uint64 `bun:"transaction_id,type:bigint" json:"transaction_id"` - Amount *Int `bun:"amount,type:bigint" json:"amount"` - Asset string `bun:"asset,type:varchar" json:"asset"` - Account string `bun:"account,type:varchar" json:"account"` - AccountArray []string `bun:"account_array,type:jsonb" json:"account_array"` - PostingIndex uint8 `bun:"posting_index,type:int8" json:"posting_index"` - IsSource bool `bun:"is_source,type:bool" json:"is_source"` - Timestamp core.Time `bun:"timestamp,type:timestamp" json:"timestamp"` - PostCommitInputVolume *Int `bun:"post_commit_input_value,type:numeric" json:"post_commit_input_value"` - PostCommitOutputVolume *Int `bun:"post_commit_output_value,type:numeric" json:"post_commit_output_value"` -} - -func (s *Store) buildTransactionsQuery(p TransactionsQueryFilters, models *[]Transaction) *bun.SelectQuery { - - selectMatchingTransactions := s.schema.NewSelect(TransactionsTableName). - ColumnExpr("distinct on(transactions.id) transactions.id as transaction_id") - if p.Reference != "" { - selectMatchingTransactions.Where("transactions.reference = ?", p.Reference) - } - if !p.StartTime.IsZero() { - selectMatchingTransactions.Where("transactions.timestamp >= ?", p.StartTime) - } - if !p.EndTime.IsZero() { - selectMatchingTransactions.Where("transactions.timestamp < ?", p.EndTime) - } - if p.AfterTxID != 0 { - selectMatchingTransactions.Where("transactions.id > ?", p.AfterTxID) - } - if p.Metadata != nil && len(p.Metadata) > 0 { - selectMatchingTransactions.Where("transactions.metadata @> ?", p.Metadata) - } - if p.Source != "" || p.Destination != "" || p.Account != "" { - selectMatchingTransactions.Join(fmt.Sprintf("join %s m on transactions.id = m.transaction_id", s.schema.Table("moves"))) - if p.Source != "" { - parts := strings.Split(p.Source, ":") - selectMatchingTransactions.Where(fmt.Sprintf("m.is_source and jsonb_array_length(m.account_array) = %d", len(parts))) - for index, segment := range parts { - if len(segment) == 0 { - continue - } - selectMatchingTransactions.Where(fmt.Sprintf(`m.account_array @@ ('$[%d] == "%s"')`, index, segment)) - } - } - if p.Destination != "" { - parts := strings.Split(p.Destination, ":") - selectMatchingTransactions.Where(fmt.Sprintf("not m.is_source and jsonb_array_length(m.account_array) = %d", len(parts))) - for index, segment := range parts { - if len(segment) == 0 { - continue - } - selectMatchingTransactions.Where(fmt.Sprintf(`m.account_array @@ ('$[%d] == "%s"')`, index, segment)) - } - } - if p.Account != "" { - parts := strings.Split(p.Account, ":") - selectMatchingTransactions.Where(fmt.Sprintf("jsonb_array_length(m.account_array) = %d", len(parts))) - for index, segment := range parts { - if len(segment) == 0 { - continue - } - selectMatchingTransactions.Where(fmt.Sprintf(`m.account_array @@ ('$[%d] == "%s"')`, index, segment)) - } - } - } - - return s.schema.NewSelect(TransactionsTableName). - Model(models). - Column("transactions.id", "transactions.reference", "transactions.metadata", "transactions.timestamp"). - ColumnExpr(`json_agg(json_build_object( - 'posting_index', m.posting_index, - 'transaction_id', m.transaction_id, - 'account', m.account, - 'account_array', m.account_array, - 'asset', m.asset, - 'post_commit_input_value', m.post_commit_input_value, - 'post_commit_output_value', m.post_commit_output_value, - 'timestamp', m.timestamp, - 'amount', m.amount, - 'is_source', m.is_source - )) as moves`). - Join(fmt.Sprintf("join %s m on transactions.id = m.transaction_id", s.schema.Table("moves"))). - Join(fmt.Sprintf(`join (%s) ids on ids.transaction_id = transactions.id`, selectMatchingTransactions.String())). - Group("transactions.id") -} - -func (s *Store) GetTransactions(ctx context.Context, q TransactionsQuery) (*api.Cursor[core.ExpandedTransaction], error) { - cursor, err := UsingColumn[TransactionsQueryFilters, Transaction](ctx, - s.buildTransactionsQuery, ColumnPaginatedQuery[TransactionsQueryFilters](q), - ) - if err != nil { - return nil, err - } - - return api.MapCursor(cursor, Transaction.toCore), nil -} - -func (s *Store) CountTransactions(ctx context.Context, q TransactionsQuery) (uint64, error) { - models := make([]Transaction, 0) - count, err := s.buildTransactionsQuery(q.Filters, &models).Count(ctx) - - return uint64(count), storageerrors.PostgresError(err) -} - -func (s *Store) GetTransaction(ctx context.Context, txId uint64) (*core.ExpandedTransaction, error) { - tx := &Transaction{} - err := s.schema.NewSelect(TransactionsTableName). - Model(tx). - Relation("Moves", func(query *bun.SelectQuery) *bun.SelectQuery { - return query.With("moves", s.schema.NewSelect(MovesTableName)) - }). - Where("id = ?", txId). - OrderExpr("id DESC"). - Scan(ctx) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - - return pointer.For(tx.toCore()), nil - -} - -func (s *Store) InsertTransactions(ctx context.Context, txs ...core.Transaction) error { - - ts := make([]Transaction, len(txs)) - - for i, tx := range txs { - ts[i].ID = tx.ID - ts[i].Timestamp = tx.Timestamp - ts[i].Metadata = tx.Metadata - ts[i].Reference = "" - if tx.Reference != "" { - cp := tx.Reference - ts[i].Reference = cp - } - } - - _, err := s.schema.NewInsert(TransactionsTableName). - Model(&ts). - On("CONFLICT (id) DO NOTHING"). - Exec(ctx) - - return storageerrors.PostgresError(err) -} - -func (s *Store) InsertMoves(ctx context.Context, objects ...*core.Move) error { - type moveValue struct { - Move - AmountInputBefore *big.Int `bun:"amount_input_before,type:numeric"` - AmountOutputBefore *big.Int `bun:"amount_output_before,type:numeric"` - AccumulatedPostingAmount *big.Int `bun:"accumulated_posting_amount,type:numeric"` - } - - transactionIds := make([]uint64, 0) - moves := make([]moveValue, 0) - - sort.Slice(objects, func(i, j int) bool { - if objects[i].Timestamp.Equal(objects[j].Timestamp) { - if objects[i].TransactionID == objects[j].TransactionID { - if objects[i].PostingIndex == objects[j].PostingIndex { - if objects[i].IsSource { - return false - } - } - return objects[i].PostingIndex < objects[j].PostingIndex - } - return objects[i].TransactionID < objects[j].TransactionID - } - return objects[i].Timestamp.Before(objects[j].Timestamp) - }) - - var ( - accumulatedAmounts core.AccountsAssetsVolumes - actualTransactionID *uint64 - actualAccumulatedVolumesOnTransaction core.AccountsAssetsVolumes - ) - - for i := 0; i < len(objects); { - - if actualTransactionID == nil || objects[i].TransactionID != *actualTransactionID { - actualTransactionID = &objects[i].TransactionID - actualAccumulatedVolumesOnTransaction = core.AccountsAssetsVolumes{} - transactionIds = append(transactionIds, *actualTransactionID) - } - - for j := i; j < len(objects) && objects[j].TransactionID == *actualTransactionID; j++ { - if objects[j].IsSource { - actualAccumulatedVolumesOnTransaction.AddOutput(objects[j].Account, objects[j].Asset, objects[j].Amount) - } else { - actualAccumulatedVolumesOnTransaction.AddInput(objects[j].Account, objects[j].Asset, objects[j].Amount) - } - } - - j := i - for ; j < len(objects) && objects[j].TransactionID == *actualTransactionID; j++ { - if objects[j].IsSource { - moves = append(moves, moveValue{ - Move: Move{ - TransactionID: *actualTransactionID, - Amount: (*Int)(objects[j].Amount), - Asset: objects[j].Asset, - Account: objects[j].Account, - AccountArray: strings.Split(objects[j].Account, ":"), - PostingIndex: objects[j].PostingIndex, - IsSource: true, - Timestamp: objects[j].Timestamp, - }, - AmountOutputBefore: accumulatedAmounts.GetVolumes(objects[j].Account, objects[j].Asset).Output, - AmountInputBefore: accumulatedAmounts.GetVolumes(objects[j].Account, objects[j].Asset).Input, - AccumulatedPostingAmount: actualAccumulatedVolumesOnTransaction.GetVolumes(objects[j].Account, objects[j].Asset).Output, - }) - } else { - moves = append(moves, moveValue{ - Move: Move{ - TransactionID: *actualTransactionID, - Amount: (*Int)(objects[j].Amount), - Asset: objects[j].Asset, - Account: objects[j].Account, - AccountArray: strings.Split(objects[j].Account, ":"), - PostingIndex: objects[j].PostingIndex, - IsSource: false, - Timestamp: objects[j].Timestamp, - }, - AmountOutputBefore: accumulatedAmounts.GetVolumes(objects[j].Account, objects[j].Asset).Output, - AmountInputBefore: accumulatedAmounts.GetVolumes(objects[j].Account, objects[j].Asset).Input, - AccumulatedPostingAmount: actualAccumulatedVolumesOnTransaction.GetVolumes(objects[j].Account, objects[j].Asset).Input, - }) - } - - if objects[j].IsSource { - accumulatedAmounts.AddOutput(objects[j].Account, objects[j].Asset, objects[j].Amount) - } else { - accumulatedAmounts.AddInput(objects[j].Account, objects[j].Asset, objects[j].Amount) - } - } - - i = j - } - - type insertedMove struct { - TransactionID uint64 `bun:"transaction_id"` - PostingIndex uint8 `bun:"posting_index"` - IsSource bool `bun:"is_source"` - } - insertedMoves := make([]insertedMove, 0) - - tx, err := s.schema.BeginTx(ctx, &sql.TxOptions{}) - if err != nil { - return err - } - - err = tx.NewInsert(MovesTableName). - With("cte1", s.schema.NewValues(&moves)). - Column( - "posting_index", - "transaction_id", - "account", - "post_commit_input_value", - "post_commit_output_value", - "timestamp", - "asset", - "account_array", - "amount", - "is_source", - ). - TableExpr(fmt.Sprintf(` - (select cte1.posting_index, cte1.transaction_id::numeric, cte1.account, coalesce( - (select post_commit_input_value - from %s - where account = cte1.account and asset = cte1.asset and timestamp <= cte1.timestamp - order by timestamp desc, transaction_id desc - limit 1) - , 0) + cte1.amount_input_before + (case when not cte1.is_source then cte1.accumulated_posting_amount else 0 end) as post_commit_input_value, coalesce( - (select post_commit_output_value - from %s - where account = cte1.account and asset = cte1.asset and timestamp <= cte1.timestamp - order by timestamp desc, transaction_id desc - limit 1) - , 0) + cte1.amount_output_before + (case when cte1.is_source then cte1.accumulated_posting_amount else 0 end) as post_commit_output_value, cte1.timestamp, cte1.asset, cte1.account_array, cte1.amount, cte1.is_source - from cte1) data - `, s.schema.Table(MovesTableName), s.schema.Table(MovesTableName))). - On("CONFLICT DO NOTHING"). - Returning("transaction_id, posting_index, is_source"). - Scan(ctx, &insertedMoves) - if err != nil { - return storageerrors.PostgresError(err) - } - - if len(insertedMoves) != len(moves) { // Some conflict (maybe after a crash?), we need to filter already inserted moves - ind := 0 - l: - for _, move := range moves { - for _, insertedMove := range insertedMoves { - if move.TransactionID == insertedMove.TransactionID && - move.PostingIndex == insertedMove.PostingIndex && - move.IsSource == insertedMove.IsSource { - ind++ - continue l - } - } - if ind < len(moves)-1 { - moves = append(moves[:ind], moves[ind+1:]...) - } else { - moves = moves[:ind] - } - } - } - - if len(moves) > 0 { - _, err = tx.NewUpdate(MovesTableName). - With("cte1", s.schema.NewValues(&moves)). - Set("post_commit_output_value = moves.post_commit_output_value + (case when cte1.is_source then cte1.amount else 0 end)"). - Set("post_commit_input_value = moves.post_commit_input_value + (case when not cte1.is_source then cte1.amount else 0 end)"). - Table("cte1"). - Where("moves.timestamp > cte1.timestamp and moves.account = cte1.account and moves.asset = cte1.asset and moves.transaction_id not in (?)", bun.In(transactionIds)). - Exec(ctx) - if err != nil { - return storageerrors.PostgresError(err) - } - } - - return storageerrors.PostgresError(tx.Commit()) -} - -func (s *Store) UpdateTransactionsMetadata(ctx context.Context, transactionsWithMetadata ...core.TransactionWithMetadata) error { - txs := make([]*Transaction, 0, len(transactionsWithMetadata)) - for _, tx := range transactionsWithMetadata { - txs = append(txs, &Transaction{ - ID: tx.ID, - Metadata: tx.Metadata, - }) - } - - _, err := s.schema.NewUpdate(TransactionsTableName). - With("_data", s.schema.NewValues(&txs)). - Model((*Transaction)(nil)). - TableExpr("_data"). - Set("metadata = transactions.metadata || _data.metadata"). - Where(fmt.Sprintf("%s.id = _data.id", TransactionsTableName)). - Exec(ctx) - - return storageerrors.PostgresError(err) -} diff --git a/components/ledger/pkg/storage/ledgerstore/transactions_test.go b/components/ledger/pkg/storage/ledgerstore/transactions_test.go deleted file mode 100644 index 86eb95a0c..000000000 --- a/components/ledger/pkg/storage/ledgerstore/transactions_test.go +++ /dev/null @@ -1,804 +0,0 @@ -package ledgerstore_test - -import ( - "context" - "math/big" - "testing" - "time" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/stack/libs/go-libs/api" - "github.com/formancehq/stack/libs/go-libs/metadata" - "github.com/google/go-cmp/cmp" - "github.com/stretchr/testify/require" -) - -func bigIntComparer(v1 *big.Int, v2 *big.Int) bool { - return v1.String() == v2.String() -} - -func RequireEqual(t *testing.T, expected, actual any) { - t.Helper() - if diff := cmp.Diff(expected, actual, cmp.Comparer(bigIntComparer)); diff != "" { - require.Failf(t, "Content not matching", diff) - } -} - -func ExpandTransactions(txs ...*core.Transaction) []core.ExpandedTransaction { - ret := make([]core.ExpandedTransaction, len(txs)) - accumulatedVolumes := core.AccountsAssetsVolumes{} - for ind, tx := range txs { - ret[ind].Transaction = *tx - for _, posting := range tx.Postings { - ret[ind].PreCommitVolumes.AddInput(posting.Destination, posting.Asset, accumulatedVolumes.GetVolumes(posting.Destination, posting.Asset).Input) - ret[ind].PreCommitVolumes.AddOutput(posting.Source, posting.Asset, accumulatedVolumes.GetVolumes(posting.Source, posting.Asset).Output) - } - for _, posting := range tx.Postings { - accumulatedVolumes.AddOutput(posting.Source, posting.Asset, posting.Amount) - accumulatedVolumes.AddInput(posting.Destination, posting.Asset, posting.Amount) - } - for _, posting := range tx.Postings { - ret[ind].PostCommitVolumes.AddInput(posting.Destination, posting.Asset, accumulatedVolumes.GetVolumes(posting.Destination, posting.Asset).Input) - ret[ind].PostCommitVolumes.AddOutput(posting.Source, posting.Asset, accumulatedVolumes.GetVolumes(posting.Source, posting.Asset).Output) - } - } - return ret -} - -func Reverse[T any](values ...T) []T { - for i := 0; i < len(values)/2; i++ { - values[i], values[len(values)-i-1] = values[len(values)-i-1], values[i] - } - return values -} - -func TestGetTransaction(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - TransactionData: core.TransactionData{ - Postings: []core.Posting{ - { - Source: "world", - Destination: "central_bank", - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - Reference: "tx1", - Timestamp: now.Add(-3 * time.Hour), - }, - }, - PostCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(100), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(100), - Output: big.NewInt(0), - }, - }, - }, - PreCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(0), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(0), - }, - }, - }, - } - tx2 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 1, - TransactionData: core.TransactionData{ - Postings: []core.Posting{ - { - Source: "world", - Destination: "central_bank", - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - Reference: "tx2", - Timestamp: now.Add(-2 * time.Hour), - }, - }, - PostCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(200), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(200), - Output: big.NewInt(0), - }, - }, - }, - PreCommitVolumes: core.AccountsAssetsVolumes{ - "world": { - "USD": { - Input: big.NewInt(0), - Output: big.NewInt(100), - }, - }, - "central_bank": { - "USD": { - Input: big.NewInt(100), - Output: big.NewInt(0), - }, - }, - }, - } - - require.NoError(t, insertTransactions(context.Background(), store, tx1.Transaction, tx2.Transaction)) - - tx, err := store.GetTransaction(context.Background(), tx1.ID) - require.NoError(t, err) - require.Equal(t, tx1.Postings, tx.Postings) - require.Equal(t, tx1.Reference, tx.Reference) - require.Equal(t, tx1.Timestamp, tx.Timestamp) -} - -func TestInsertTransactions(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - t.Run("success inserting transaction", func(t *testing.T) { - tx1 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 0, - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "alice", - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - Timestamp: now.Add(-3 * time.Hour), - Metadata: metadata.Metadata{}, - }, - }, - PreCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - "alice": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - }, - PostCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(100), - }, - "alice": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithInputInt64(100), - }, - }, - } - - err := insertTransactions(context.Background(), store, tx1.Transaction) - require.NoError(t, err, "inserting transaction should not fail") - - tx, err := store.GetTransaction(context.Background(), 0) - RequireEqual(t, tx1, *tx) - }) - - t.Run("success inserting multiple transactions", func(t *testing.T) { - tx2 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 1, - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "polo", - Amount: big.NewInt(200), - Asset: "USD", - }, - }, - Timestamp: now.Add(-2 * time.Hour), - Metadata: metadata.Metadata{}, - }, - }, - PreCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(100), - }, - "polo": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - }, - PostCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(300), - }, - "polo": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithInputInt64(200), - }, - }, - } - - tx3 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 2, - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "gfyrag", - Amount: big.NewInt(150), - Asset: "USD", - }, - }, - Timestamp: now.Add(-1 * time.Hour), - Metadata: metadata.Metadata{}, - }, - }, - PreCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(300), - }, - "gfyrag": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - }, - PostCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(450), - }, - "gfyrag": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithInputInt64(150), - }, - }, - } - - err := insertTransactions(context.Background(), store, tx2.Transaction, tx3.Transaction) - require.NoError(t, err, "inserting multiple transactions should not fail") - - tx, err := store.GetTransaction(context.Background(), 1) - require.NoError(t, err, "getting transaction should not fail") - RequireEqual(t, tx2, *tx) - - tx, err = store.GetTransaction(context.Background(), 2) - require.NoError(t, err, "getting transaction should not fail") - RequireEqual(t, tx3, *tx) - }) -} - -func TestCountTransactions(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 0, - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "alice", - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - Timestamp: now.Add(-3 * time.Hour), - Metadata: metadata.Metadata{}, - }, - }, - PreCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - "alice": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - }, - PostCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(100), - }, - "alice": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithInputInt64(100), - }, - }, - } - tx2 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 1, - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "polo", - Amount: big.NewInt(200), - Asset: "USD", - }, - }, - Timestamp: now.Add(-2 * time.Hour), - Metadata: metadata.Metadata{}, - }, - }, - PreCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(100), - }, - "polo": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - }, - PostCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(300), - }, - "polo": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithInputInt64(200), - }, - }, - } - - tx3 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 2, - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "gfyrag", - Amount: big.NewInt(150), - Asset: "USD", - }, - }, - Timestamp: now.Add(-1 * time.Hour), - Metadata: metadata.Metadata{}, - }, - }, - PreCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(300), - }, - "gfyrag": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - }, - PostCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(450), - }, - "gfyrag": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithInputInt64(150), - }, - }, - } - - err := insertTransactions(context.Background(), store, tx1.Transaction, tx2.Transaction, tx3.Transaction) - require.NoError(t, err, "inserting transaction should not fail") - - count, err := store.CountTransactions(context.Background(), ledgerstore.TransactionsQuery{}) - require.NoError(t, err, "counting transactions should not fail") - require.Equal(t, uint64(3), count, "count should be equal") -} - -func TestUpdateTransactionsMetadata(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 0, - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "alice", - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - Timestamp: now.Add(-3 * time.Hour), - Metadata: metadata.Metadata{}, - }, - }, - PreCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - "alice": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - }, - PostCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(100), - }, - "alice": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithInputInt64(100), - }, - }, - } - tx2 := core.ExpandedTransaction{ - Transaction: core.Transaction{ - ID: 1, - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "polo", - Amount: big.NewInt(200), - Asset: "USD", - }, - }, - Timestamp: now.Add(-2 * time.Hour), - Metadata: metadata.Metadata{}, - }, - }, - PreCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(100), - }, - "polo": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes(), - }, - }, - PostCommitVolumes: map[string]core.VolumesByAssets{ - "world": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithOutputInt64(300), - }, - "polo": map[string]*core.Volumes{ - "USD": core.NewEmptyVolumes().WithInputInt64(200), - }, - }, - } - - err := insertTransactions(context.Background(), store, tx1.Transaction, tx2.Transaction) - require.NoError(t, err, "inserting transaction should not fail") - - txToUpdate1 := core.TransactionWithMetadata{ - ID: 0, - Metadata: metadata.Metadata{"foo1": "bar2"}, - } - txToUpdate2 := core.TransactionWithMetadata{ - ID: 1, - Metadata: metadata.Metadata{"foo2": "bar2"}, - } - txs := []core.TransactionWithMetadata{txToUpdate1, txToUpdate2} - - err = store.UpdateTransactionsMetadata(context.Background(), txs...) - require.NoError(t, err, "updating multiple transaction metadata should not fail") - - tx, err := store.GetTransaction(context.Background(), 0) - require.NoError(t, err, "getting transaction should not fail") - require.Equal(t, tx.Metadata, txToUpdate1.Metadata, "metadata should be equal") - - tx, err = store.GetTransaction(context.Background(), 1) - require.NoError(t, err, "getting transaction should not fail") - require.Equal(t, tx.Metadata, txToUpdate2.Metadata, "metadata should be equal") -} - -func TestInsertTransactionInPast(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD/2", big.NewInt(100)), - ).WithTimestamp(now) - - tx2 := core.NewTransaction().WithPostings( - core.NewPosting("bank", "user1", "USD/2", big.NewInt(50)), - ).WithTimestamp(now.Add(time.Hour)).WithID(1) - - // Insert in past must modify pre/post commit volumes of tx2 - tx3 := core.NewTransaction().WithPostings( - core.NewPosting("bank", "user2", "USD/2", big.NewInt(50)), - ).WithTimestamp(now.Add(30 * time.Minute)).WithID(2) - - require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2)) - require.NoError(t, insertTransactions(context.Background(), store, *tx3)) - - tx2FromDatabase, err := store.GetTransaction(context.Background(), tx2.ID) - require.NoError(t, err) - - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 50), - }, - "user1": { - "USD/2": core.NewVolumesInt64(0, 0), - }, - }, tx2FromDatabase.PreCommitVolumes) - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 100), - }, - "user1": { - "USD/2": core.NewVolumesInt64(50, 0), - }, - }, tx2FromDatabase.PostCommitVolumes) -} - -func TestInsertTransactionInPastInOneBatch(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD/2", big.NewInt(100)), - ).WithTimestamp(now) - - tx2 := core.NewTransaction().WithPostings( - core.NewPosting("bank", "user1", "USD/2", big.NewInt(50)), - ).WithTimestamp(now.Add(time.Hour)).WithID(1) - - // Insert in past must modify pre/post commit volumes of tx2 - tx3 := core.NewTransaction().WithPostings( - core.NewPosting("bank", "user2", "USD/2", big.NewInt(50)), - ).WithTimestamp(now.Add(30 * time.Minute)).WithID(2) - - require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2, *tx3)) - - tx2FromDatabase, err := store.GetTransaction(context.Background(), tx2.ID) - require.NoError(t, err) - - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 50), - }, - "user1": { - "USD/2": core.NewVolumesInt64(0, 0), - }, - }, tx2FromDatabase.PreCommitVolumes) - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 100), - }, - "user1": { - "USD/2": core.NewVolumesInt64(50, 0), - }, - }, tx2FromDatabase.PostCommitVolumes) -} - -func TestInsertTwoTransactionAtSameDateInSameBatch(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD/2", big.NewInt(100)), - ).WithTimestamp(now.Add(-time.Hour)) - - tx2 := core.NewTransaction().WithPostings( - core.NewPosting("bank", "user1", "USD/2", big.NewInt(10)), - ).WithTimestamp(now).WithID(1) - - tx3 := core.NewTransaction().WithPostings( - core.NewPosting("bank", "user2", "USD/2", big.NewInt(10)), - ).WithTimestamp(now).WithID(2) - - require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2, *tx3)) - - tx2FromDatabase, err := store.GetTransaction(context.Background(), tx2.ID) - require.NoError(t, err) - - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 0), - }, - "user1": { - "USD/2": core.NewVolumesInt64(0, 0), - }, - }, tx2FromDatabase.PreCommitVolumes) - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 10), - }, - "user1": { - "USD/2": core.NewVolumesInt64(10, 0), - }, - }, tx2FromDatabase.PostCommitVolumes) - - tx3FromDatabase, err := store.GetTransaction(context.Background(), tx3.ID) - require.NoError(t, err) - - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 10), - }, - "user2": { - "USD/2": core.NewVolumesInt64(0, 0), - }, - }, tx3FromDatabase.PreCommitVolumes) - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 20), - }, - "user2": { - "USD/2": core.NewVolumesInt64(10, 0), - }, - }, tx3FromDatabase.PostCommitVolumes) -} - -func TestInsertTwoTransactionAtSameDateInTwoBatch(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD/2", big.NewInt(100)), - ).WithTimestamp(now.Add(-time.Hour)) - - tx2 := core.NewTransaction().WithPostings( - core.NewPosting("bank", "user1", "USD/2", big.NewInt(10)), - ).WithTimestamp(now).WithID(1) - - require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2)) - - tx3 := core.NewTransaction().WithPostings( - core.NewPosting("bank", "user2", "USD/2", big.NewInt(10)), - ).WithTimestamp(now).WithID(2) - - require.NoError(t, insertTransactions(context.Background(), store, *tx3)) - - tx3FromDatabase, err := store.GetTransaction(context.Background(), tx3.ID) - require.NoError(t, err) - - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 10), - }, - "user2": { - "USD/2": core.NewVolumesInt64(0, 0), - }, - }, tx3FromDatabase.PreCommitVolumes) - RequireEqual(t, core.AccountsAssetsVolumes{ - "bank": { - "USD/2": core.NewVolumesInt64(100, 20), - }, - "user2": { - "USD/2": core.NewVolumesInt64(10, 0), - }, - }, tx3FromDatabase.PostCommitVolumes) -} - -func TestListTransactions(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.NewTransaction(). - WithID(0). - WithPostings( - core.NewPosting("world", "alice", "USD", big.NewInt(100)), - ). - WithTimestamp(now.Add(-3 * time.Hour)) - tx2 := core.NewTransaction(). - WithID(1). - WithPostings( - core.NewPosting("world", "bob", "USD", big.NewInt(100)), - ). - WithTimestamp(now.Add(-2 * time.Hour)) - tx3 := core.NewTransaction(). - WithID(2). - WithPostings( - core.NewPosting("world", "users:marley", "USD", big.NewInt(100)), - ). - WithTimestamp(now.Add(-time.Hour)) - - require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2, *tx3)) - - type testCase struct { - name string - query ledgerstore.TransactionsQuery - expected *api.Cursor[core.ExpandedTransaction] - } - testCases := []testCase{ - { - name: "nominal", - query: ledgerstore.NewTransactionsQuery(), - expected: &api.Cursor[core.ExpandedTransaction]{ - PageSize: 15, - HasMore: false, - Data: Reverse(ExpandTransactions(tx1, tx2, tx3)...), - }, - }, - { - name: "address filter", - query: ledgerstore.NewTransactionsQuery(). - WithAccountFilter("bob"), - expected: &api.Cursor[core.ExpandedTransaction]{ - PageSize: 15, - HasMore: false, - Data: ExpandTransactions(tx1, tx2)[1:], - }, - }, - { - name: "address filter using segment", - query: ledgerstore.NewTransactionsQuery(). - WithAccountFilter("users:"), - expected: &api.Cursor[core.ExpandedTransaction]{ - PageSize: 15, - HasMore: false, - Data: ExpandTransactions(tx1, tx2, tx3)[2:], - }, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - cursor, err := store.GetTransactions(context.Background(), tc.query) - require.NoError(t, err) - RequireEqual(t, *tc.expected, *cursor) - - count, err := store.CountTransactions(context.Background(), tc.query) - require.NoError(t, err) - require.EqualValues(t, len(tc.expected.Data), count) - }) - } -} - -func TestInsertTransactionsWithConflict(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - - now := core.Now() - - tx1 := core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD/2", big.NewInt(100)), - ).WithTimestamp(now) - tx2 := core.NewTransaction().WithPostings( - core.NewPosting("world", "bank", "USD/2", big.NewInt(100)), - ).WithID(1).WithTimestamp(now.Add(time.Minute)) - - require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2)) - - checkTx2 := func() { - tx2FromDB, err := store.GetTransaction(context.Background(), tx2.ID) - require.NoError(t, err) - require.Equal(t, core.ExpandedTransaction{ - Transaction: *tx2, - PreCommitVolumes: core.AccountsAssetsVolumes{ - "world": map[string]*core.Volumes{ - "USD/2": core.NewVolumesInt64(0, 100), - }, - "bank": map[string]*core.Volumes{ - "USD/2": core.NewVolumesInt64(100, 0), - }, - }, - PostCommitVolumes: core.AccountsAssetsVolumes{ - "world": map[string]*core.Volumes{ - "USD/2": core.NewVolumesInt64(0, 200), - }, - "bank": map[string]*core.Volumes{ - "USD/2": core.NewVolumesInt64(200, 0), - }, - }, - }, *tx2FromDB) - } - - checkTx2() - require.NoError(t, insertTransactions(context.Background(), store, *tx1)) - checkTx2() -} diff --git a/components/ledger/pkg/storage/ledgerstore/volumes.go b/components/ledger/pkg/storage/ledgerstore/volumes.go deleted file mode 100644 index 9be4e08e4..000000000 --- a/components/ledger/pkg/storage/ledgerstore/volumes.go +++ /dev/null @@ -1,35 +0,0 @@ -package ledgerstore - -import ( - "context" - "fmt" - "math/big" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" -) - -func (s *Store) GetAssetsVolumes(ctx context.Context, accountAddress string) (core.VolumesByAssets, error) { - moves := make([]Move, 0) - - err := s.schema.NewSelect(MovesTableName). - Model(&moves). - Where("account = ?", accountAddress). - ColumnExpr("asset"). - ColumnExpr(fmt.Sprintf(`"%s".first(post_commit_input_value order by timestamp desc) as post_commit_input_value`, s.schema.Name())). - ColumnExpr(fmt.Sprintf(`"%s".first(post_commit_output_value order by timestamp desc) as post_commit_output_value`, s.schema.Name())). - GroupExpr("account, asset"). - Scan(ctx) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - - volumes := core.VolumesByAssets{} - for _, move := range moves { - volumes[move.Asset] = core.NewEmptyVolumes(). - WithInput((*big.Int)(move.PostCommitInputVolume)). - WithOutput((*big.Int)(move.PostCommitOutputVolume)) - } - - return volumes, nil -} diff --git a/components/ledger/pkg/storage/ledgerstore/volumes_test.go b/components/ledger/pkg/storage/ledgerstore/volumes_test.go deleted file mode 100644 index 64afabae9..000000000 --- a/components/ledger/pkg/storage/ledgerstore/volumes_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package ledgerstore_test - -import ( - "context" - "math/big" - "testing" - "time" - - "github.com/formancehq/ledger/pkg/core" - "github.com/stretchr/testify/require" -) - -func TestGetAssetsVolumes(t *testing.T) { - t.Parallel() - store := newLedgerStore(t) - now := core.Now() - - tx1 := core.NewTransaction(). - WithID(0). - WithPostings( - core.NewPosting("world", "alice", "USD", big.NewInt(100)), - ). - WithTimestamp(now.Add(-3 * time.Hour)) - tx2 := core.NewTransaction(). - WithID(1). - WithPostings( - core.NewPosting("world", "bob", "USD", big.NewInt(100)), - ). - WithTimestamp(now.Add(-2 * time.Hour)) - tx3 := core.NewTransaction(). - WithID(2). - WithPostings( - core.NewPosting("world", "users:marley", "USD", big.NewInt(100)), - ). - WithTimestamp(now.Add(-time.Hour)) - - require.NoError(t, insertTransactions(context.Background(), store, *tx1, *tx2, *tx3)) - - assetVolumesForWorld, err := store.GetAssetsVolumes(context.Background(), "world") - require.NoError(t, err, "get asset volumes should not fail") - require.Equal(t, core.VolumesByAssets{ - "USD": core.NewEmptyVolumes().WithOutputInt64(300), - }, assetVolumesForWorld, "asset volumes should be equal") - - assetVolumesForBob, err := store.GetAssetsVolumes(context.Background(), "bob") - require.NoError(t, err, "get asset volumes should not fail") - require.Equal(t, core.VolumesByAssets{ - "USD": core.NewEmptyVolumes().WithInputInt64(100), - }, assetVolumesForBob, "asset volumes should be equal") -} diff --git a/components/ledger/pkg/storage/migrations/migrations.go b/components/ledger/pkg/storage/migrations/migrations.go deleted file mode 100644 index 039a1bec0..000000000 --- a/components/ledger/pkg/storage/migrations/migrations.go +++ /dev/null @@ -1,291 +0,0 @@ -package migrations - -import ( - "context" - "database/sql" - "io/fs" - "path" - "path/filepath" - "regexp" - "runtime" - "sort" - "strconv" - "strings" - "time" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/opentelemetry/tracer" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/stack/libs/go-libs/logging" - "github.com/pkg/errors" - "github.com/uptrace/bun" -) - -const migrationsTableName = "migrations" - -type table struct { - bun.BaseModel `bun:"migrations,alias:migrations"` - - Version string `bun:"version,type:varchar,unique"` - Date string `bun:"date,type:varchar"` -} - -func createMigrationsTable(ctx context.Context, schema storage.Schema) error { - _, err := schema.NewCreateTable(migrationsTableName). - Model((*table)(nil)). - IfNotExists(). - Exec(ctx) - - return err -} - -func Migrate(ctx context.Context, s storage.Schema, migrations ...Migration) (bool, error) { - ctx, span := tracer.Start(ctx, "Migrate") - defer span.End() - - if err := createMigrationsTable(ctx, s); err != nil { - return false, storage.PostgresError(err) - } - - tx, err := s.BeginTx(ctx, &sql.TxOptions{}) - if err != nil { - return false, storage.PostgresError(err) - } - defer func(tx *storage.Tx) { - _ = tx.Rollback() - }(tx) - - logging.FromContext(ctx).Debugf("Checking migrations...") - modified := false - for _, m := range migrations { - logging.FromContext(ctx).Debugf("Checking if version %s is applied", m.Version) - sb := s.NewSelect(migrationsTableName). - Model((*table)(nil)). - Column("version"). - Where("version = ?", m.Version) - - // Does not use sql transaction because if the table does not exist, postgres will mark transaction as invalid - row := s.QueryRowContext(ctx, sb.String()) - var v string - if err = row.Scan(&v); err != nil { - logging.FromContext(ctx).Debugf("Migration %s: %s", m.Version, err) - } - if v != "" { - logging.FromContext(ctx).Debugf("Migration %s: already up to date", m.Version) - continue - } - modified = true - - logging.FromContext(ctx).Debugf("Running migration %s", m.Version) - - handlersForCurrentEngine, ok := m.Handlers["postgres"] - if ok { - for _, h := range handlersForCurrentEngine { - err := h(ctx, s, tx) - if err != nil { - return false, err - } - } - } - - handlersForAnyEngine, ok := m.Handlers["any"] - if ok { - for num, h := range handlersForAnyEngine { - err := h(logging.ContextWithField(ctx, "migrations", num), s, tx) - if err != nil { - return false, err - } - } - } - - m := table{ - Version: m.Version, - Date: core.Now().Format(time.RFC3339), - } - sbInsert := s.NewInsert(migrationsTableName).Model(&m) - - if _, err := tx.ExecContext(ctx, sbInsert.String()); err != nil { - logging.FromContext(ctx).Errorf("Failed to insert migration version %s: %s", m.Version, err) - return false, storage.PostgresError(err) - } - - } - - return modified, storage.PostgresError(tx.Commit()) -} - -func GetMigrations(ctx context.Context, schema storage.Schema) ([]core.MigrationInfo, error) { - sb := schema.NewSelect(migrationsTableName). - Model((*table)(nil)). - Column("version", "date") - - rows, err := schema.QueryContext(ctx, sb.String()) - if err != nil { - return []core.MigrationInfo{}, err - } - defer rows.Close() - - res := make([]core.MigrationInfo, 0) - for rows.Next() { - var version, date string - if err := rows.Scan(&version, &date); err != nil { - return []core.MigrationInfo{}, err - } - t, err := core.ParseTime(date) - if err != nil { - return []core.MigrationInfo{}, - errors.Wrap(err, "parsing migration date") - } - res = append(res, core.MigrationInfo{ - Version: version, - Date: t, - }) - } - if rows.Err() != nil { - return []core.MigrationInfo{}, err - } - - return res, nil -} - -func RegisterGoMigration(fn MigrationFunc) { - _, filename, _, _ := runtime.Caller(1) - RegisterGoMigrationFromFilename(filename, fn) -} - -func PurgeGoMigrations() { - RegisteredGoMigrations = []Migration{} -} - -func RegisterGoMigrationFromFilename(filename string, fn MigrationFunc) { - rest, goFile := filepath.Split(filename) - directory := filepath.Base(rest) - - version, name := extractMigrationInformation(directory) - engine := strings.Split(goFile, ".")[0] - - RegisteredGoMigrations = append(RegisteredGoMigrations, Migration{ - MigrationInfo: core.MigrationInfo{ - Version: version, - Name: name, - }, - Handlers: map[string][]MigrationFunc{ - engine: {fn}, - }, - }) -} - -func extractMigrationInformation(filename string) (string, string) { - parts := strings.SplitN(filename, "-", 2) - number := parts[0] - name := parts[1] - return number, name -} - -func CollectMigrationFiles(migrationsFS fs.FS) ([]Migration, error) { - directories, err := fs.ReadDir(migrationsFS, "migrates") - if err != nil { - return nil, err - } - - migrations := Migrations{} - for _, directory := range directories { - directoryName := directory.Name() - - version, name := extractMigrationInformation(directoryName) - - migrationDirectoryName := path.Join("migrates", directoryName) - units := make(map[string][]MigrationFunc) - unitsFiles, err := fs.ReadDir(migrationsFS, migrationDirectoryName) - if err != nil { - return nil, err - } - - for _, unit := range unitsFiles { - parts := strings.SplitN(unit.Name(), ".", 2) - extension := parts[1] - engine := parts[0] - switch extension { - case "sql": - content, err := fs.ReadFile(migrationsFS, path.Join(migrationDirectoryName, unit.Name())) - if err != nil { - return nil, err - } - - for _, statement := range strings.Split(string(content), "--statement") { - statement = strings.TrimSpace(statement) - if statement != "" { - units[engine] = append(units[engine], SQLMigrationFunc(statement)) - } - } - - case "go": - for _, registeredGoMigration := range RegisteredGoMigrations { - if registeredGoMigration.Version == version { - for engine, goMigrationUnits := range registeredGoMigration.Handlers { - units[engine] = append(units[engine], goMigrationUnits...) - } - } - } - } - } - - migrations = append(migrations, Migration{ - MigrationInfo: core.MigrationInfo{ - Version: version, - Name: name, - }, - Handlers: units, - }) - } - - sort.Sort(migrations) - - return migrations, nil -} - -func SQLMigrationFunc(content string) MigrationFunc { - return func(ctx context.Context, schema storage.Schema, tx *storage.Tx) error { - plain := strings.ReplaceAll(content, "VAR_LEDGER_NAME", schema.Name()) - r := regexp.MustCompile(`[\n\t\s]+`) - plain = r.ReplaceAllString(plain, " ") - _, err := tx.ExecContext(ctx, plain) - - return err - } -} - -var RegisteredGoMigrations []Migration - -type MigrationFunc func(ctx context.Context, schema storage.Schema, tx *storage.Tx) error - -type HandlersByEngine map[string][]MigrationFunc - -type Migration struct { - core.MigrationInfo `json:"inline"` - Handlers HandlersByEngine `json:"-"` -} - -type Migrations []Migration - -func (m Migrations) Len() int { - return len(m) -} - -func (m Migrations) Less(i, j int) bool { - iNumber, err := strconv.ParseInt(m[i].Version, 10, 64) - if err != nil { - panic(err) - } - jNumber, err := strconv.ParseInt(m[j].Version, 10, 64) - if err != nil { - panic(err) - } - return iNumber < jNumber -} - -func (m Migrations) Swap(i, j int) { - m[i], m[j] = m[j], m[i] -} - -var _ sort.Interface = &Migrations{} diff --git a/components/ledger/pkg/storage/migrations/migrations_test.go b/components/ledger/pkg/storage/migrations/migrations_test.go deleted file mode 100644 index e31c8e9e0..000000000 --- a/components/ledger/pkg/storage/migrations/migrations_test.go +++ /dev/null @@ -1,173 +0,0 @@ -package migrations_test - -import ( - "context" - "fmt" - "os" - "path/filepath" - "testing" - - "github.com/formancehq/ledger/pkg/core" - "github.com/formancehq/ledger/pkg/storage" - "github.com/formancehq/ledger/pkg/storage/ledgerstore" - "github.com/formancehq/ledger/pkg/storage/migrations" - "github.com/formancehq/stack/libs/go-libs/logging" - "github.com/formancehq/stack/libs/go-libs/pgtesting" - "github.com/psanford/memfs" - "github.com/stretchr/testify/require" -) - -func TestMain(t *testing.M) { - if err := pgtesting.CreatePostgresServer(); err != nil { - logging.Error(err) - os.Exit(1) - } - code := t.Run() - if err := pgtesting.DestroyPostgresServer(); err != nil { - logging.Error(err) - } - os.Exit(code) -} - -func TestCollectMigrations(t *testing.T) { - migrations.PurgeGoMigrations() - - mfs := memfs.New() - require.NoError(t, mfs.MkdirAll("migrates/0-first-migration", 0666)) - require.NoError(t, mfs.WriteFile("migrates/0-first-migration/postgres.sql", []byte(` - --statement - NO SQL; - `), 0666)) - require.NoError(t, mfs.WriteFile("migrates/0-first-migration/sqlite.go", []byte{}, 0666)) - require.NoError(t, mfs.MkdirAll("migrates/1-second-migration", 0666)) - require.NoError(t, mfs.WriteFile("migrates/1-second-migration/any.sql", []byte(` - --statement - NO SQL; - `), 0666)) - - migrations.RegisterGoMigrationFromFilename("migrates/0-first-migration/sqlite.go", func(ctx context.Context, schema storage.Schema, tx *storage.Tx) error { - return nil - }) - - migrations, err := migrations.CollectMigrationFiles(mfs) - require.NoError(t, err) - require.Len(t, migrations, 2) - - require.Equal(t, "0", migrations[0].Version) - require.Equal(t, "first-migration", migrations[0].Name) - require.Len(t, migrations[0].Handlers, 2) - require.Len(t, migrations[0].Handlers["sqlite"], 1) - require.Len(t, migrations[0].Handlers["postgres"], 1) - - require.Equal(t, "1", migrations[1].Version) - require.Equal(t, "second-migration", migrations[1].Name) - require.Len(t, migrations[1].Handlers, 1) - require.Len(t, migrations[1].Handlers["any"], 1) -} - -func TestMigrationsOrders(t *testing.T) { - mfs := memfs.New() - for i := 0; i < 1000; i++ { - dir := fmt.Sprintf("migrates/%d-migration", i) - require.NoError(t, mfs.MkdirAll(dir, 0666)) - require.NoError(t, mfs.WriteFile(fmt.Sprintf("%s/postgres.sql", dir), []byte(` - --statement - NO SQL; - `), 0666)) - } - - migrations, err := migrations.CollectMigrationFiles(mfs) - require.NoError(t, err) - for i, m := range migrations { - require.Equal(t, fmt.Sprintf("%d", i), m.Version) - } -} - -func TestMigrates(t *testing.T) { - pgServer := pgtesting.NewPostgresDatabase(t) - sqlDB, err := storage.OpenSQLDB(storage.ConnectionOptions{ - DatabaseSourceName: pgServer.ConnString(), - Debug: testing.Verbose(), - Trace: testing.Verbose(), - }) - if err != nil { - t.Fatal(err) - } - db := storage.NewDatabase(sqlDB) - - s, err := db.Schema("testing") - require.NoError(t, err) - - require.NoError(t, s.Create(context.Background())) - - ms := []migrations.Migration{ - { - MigrationInfo: core.MigrationInfo{ - Version: "0", - Name: "create-schema", - }, - Handlers: migrations.HandlersByEngine{ - "any": { - migrations.SQLMigrationFunc(`CREATE TABLE IF NOT EXISTS testing.transactions ( - "id" integer, - "reference" varchar, - "hash" varchar, - - UNIQUE("id"), - UNIQUE("reference") - );`), - migrations.SQLMigrationFunc(`INSERT INTO testing.transactions VALUES (0, '', '')`), - }, - }, - }, - { - MigrationInfo: core.MigrationInfo{ - Version: "1", - Name: "update-column", - }, - Handlers: migrations.HandlersByEngine{ - "postgres": { - migrations.SQLMigrationFunc(` - ALTER TABLE testing.transactions - ADD COLUMN timestamp date;`), - }, - }, - }, - { - MigrationInfo: core.MigrationInfo{ - Version: "2", - Name: "init-timestamp", - }, - Handlers: migrations.HandlersByEngine{ - "any": { - func(ctx context.Context, schema storage.Schema, tx *storage.Tx) error { - sb := s.NewUpdate(ledgerstore.TransactionsTableName). - Model((*ledgerstore.Transaction)(nil)). - Set("timestamp = ?", core.Now()). - Where("TRUE") - - _, err := tx.ExecContext(ctx, sb.String()) - - return err - }, - }, - }, - }, - } - - modified, err := migrations.Migrate(context.Background(), s, ms...) - require.NoError(t, err) - require.True(t, modified) - -} - -func TestRegister(t *testing.T) { - fn := func(ctx context.Context, schema storage.Schema, tx *storage.Tx) error { - return nil - } - - migrations.PurgeGoMigrations() - migrations.RegisterGoMigrationFromFilename(filepath.Join("XXX", "0-init-schema", "any.go"), fn) - require.Len(t, migrations.RegisteredGoMigrations, 1) - migrations.PurgeGoMigrations() -} diff --git a/components/ledger/pkg/storage/schema.go b/components/ledger/pkg/storage/schema.go deleted file mode 100644 index 558f90941..000000000 --- a/components/ledger/pkg/storage/schema.go +++ /dev/null @@ -1,77 +0,0 @@ -package storage - -import ( - "context" - "database/sql" - "fmt" - - "github.com/uptrace/bun" -) - -const ( - createSchemaQuery = `CREATE SCHEMA IF NOT EXISTS "%s"` - deleteSchemaQuery = `DROP SCHEMA "%s" CASCADE` -) - -type Schema struct { - bun.IDB - name string -} - -func NewSchema(db bun.IDB, name string) Schema { - return Schema{ - IDB: db, - name: name, - } -} - -func (s *Schema) Name() string { - return s.name -} - -func (s *Schema) Table(name string) string { - return fmt.Sprintf(`"%s".%s`, s.name, name) -} - -func (s *Schema) Create(ctx context.Context) error { - _, err := s.ExecContext(ctx, fmt.Sprintf(createSchemaQuery, s.name)) - return PostgresError(err) -} - -func (s *Schema) Delete(ctx context.Context) error { - _, err := s.ExecContext(ctx, fmt.Sprintf(deleteSchemaQuery, s.name)) - return PostgresError(err) -} - -func (s *Schema) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) { - bunTx, err := s.IDB.BeginTx(ctx, opts) - if err != nil { - return nil, PostgresError(err) - } - return &Tx{ - schema: s, - Tx: bunTx, - }, nil -} - -// Override all bun methods to use the schema name - -func (s *Schema) NewInsert(tableName string) *bun.InsertQuery { - return s.IDB.NewInsert().ModelTableExpr("?0.?1", bun.Ident(s.Name()), bun.Ident(tableName)) -} - -func (s *Schema) NewUpdate(tableName string) *bun.UpdateQuery { - return s.IDB.NewUpdate().ModelTableExpr("?0.?1", bun.Ident(s.Name()), bun.Ident(tableName)) -} - -func (s *Schema) NewSelect(tableName string) *bun.SelectQuery { - return s.IDB.NewSelect().ModelTableExpr("?0.?1 as ?1", bun.Ident(s.Name()), bun.Ident(tableName)) -} - -func (s *Schema) NewCreateTable(tableName string) *bun.CreateTableQuery { - return s.IDB.NewCreateTable().ModelTableExpr("?0.?1", bun.Ident(s.Name()), bun.Ident(tableName)) -} - -func (s *Schema) NewDelete(tableName string) *bun.DeleteQuery { - return s.IDB.NewDelete().ModelTableExpr("?0.?1", bun.Ident(s.Name()), bun.Ident(tableName)) -} diff --git a/components/ledger/pkg/storage/systemstore/configuration.go b/components/ledger/pkg/storage/systemstore/configuration.go deleted file mode 100644 index 4a9967e2f..000000000 --- a/components/ledger/pkg/storage/systemstore/configuration.go +++ /dev/null @@ -1,62 +0,0 @@ -package systemstore - -import ( - "context" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/uptrace/bun" -) - -const configTableName = "configuration" - -type configuration struct { - bun.BaseModel `bun:"configuration,alias:configuration"` - - Key string `bun:"key,type:varchar(255),pk"` // Primary key - Value string `bun:"value,type:text"` - AddedAt core.Time `bun:"addedAt,type:timestamp"` -} - -func (s *Store) CreateConfigurationTable(ctx context.Context) error { - _, err := s.schema.NewCreateTable(configTableName). - Model((*configuration)(nil)). - IfNotExists(). - Exec(ctx) - - return storageerrors.PostgresError(err) -} - -func (s *Store) GetConfiguration(ctx context.Context, key string) (string, error) { - query := s.schema.NewSelect(configTableName). - Model((*configuration)(nil)). - Column("value"). - Where("key = ?", key). - Limit(1). - String() - - row := s.schema.QueryRowContext(ctx, query) - if row.Err() != nil { - return "", storageerrors.PostgresError(row.Err()) - } - var value string - if err := row.Scan(&value); err != nil { - return "", storageerrors.PostgresError(err) - } - - return value, nil -} - -func (s *Store) InsertConfiguration(ctx context.Context, key, value string) error { - config := &configuration{ - Key: key, - Value: value, - AddedAt: core.Now(), - } - - _, err := s.schema.NewInsert(configTableName). - Model(config). - Exec(ctx) - - return storageerrors.PostgresError(err) -} diff --git a/components/ledger/pkg/storage/systemstore/ledgers.go b/components/ledger/pkg/storage/systemstore/ledgers.go deleted file mode 100644 index cb3c64fa1..000000000 --- a/components/ledger/pkg/storage/systemstore/ledgers.go +++ /dev/null @@ -1,103 +0,0 @@ -package systemstore - -import ( - "context" - - "github.com/formancehq/ledger/pkg/core" - storageerrors "github.com/formancehq/ledger/pkg/storage" - "github.com/pkg/errors" - "github.com/uptrace/bun" -) - -const ledgersTableName = "ledgers" - -type Ledgers struct { - bun.BaseModel `bun:"ledgers,alias:ledgers"` - - Ledger string `bun:"ledger,type:varchar(255),pk"` // Primary key - AddedAt core.Time `bun:"addedAt,type:timestamp"` -} - -func (s *Store) CreateLedgersTable(ctx context.Context) error { - _, err := s.schema.NewCreateTable(ledgersTableName). - Model((*Ledgers)(nil)). - IfNotExists(). - Exec(ctx) - - return storageerrors.PostgresError(err) -} - -func (s *Store) ListLedgers(ctx context.Context) ([]string, error) { - query := s.schema.NewSelect(ledgersTableName). - Model((*Ledgers)(nil)). - Column("ledger"). - String() - - rows, err := s.schema.QueryContext(ctx, query) - if err != nil { - return nil, storageerrors.PostgresError(err) - } - defer rows.Close() - - res := make([]string, 0) - for rows.Next() { - var ledger string - if err := rows.Scan(&ledger); err != nil { - return nil, storageerrors.PostgresError(err) - } - res = append(res, ledger) - } - return res, nil -} - -func (s *Store) DeleteLedger(ctx context.Context, name string) error { - _, err := s.schema.NewDelete(ledgersTableName). - Model((*Ledgers)(nil)). - Where("ledger = ?", name). - Exec(ctx) - - return errors.Wrap(storageerrors.PostgresError(err), "delete ledger from system store") -} - -func (s *Store) Register(ctx context.Context, ledger string) (bool, error) { - l := &Ledgers{ - Ledger: ledger, - AddedAt: core.Now(), - } - - ret, err := s.schema.NewInsert(ledgersTableName). - Model(l). - Ignore(). - Exec(ctx) - if err != nil { - return false, storageerrors.PostgresError(err) - } - - affected, err := ret.RowsAffected() - if err != nil { - return false, storageerrors.PostgresError(err) - } - - return affected > 0, nil -} - -func (s *Store) Exists(ctx context.Context, ledger string) (bool, error) { - query := s.schema.NewSelect(ledgersTableName). - Model((*Ledgers)(nil)). - Column("ledger"). - Where("ledger = ?", ledger). - String() - - ret := s.schema.QueryRowContext(ctx, query) - if ret.Err() != nil { - return false, nil - } - - var t string - _ = ret.Scan(&t) // Trigger close - - if t == "" { - return false, nil - } - return true, nil -} diff --git a/components/ledger/pkg/storage/systemstore/store.go b/components/ledger/pkg/storage/systemstore/store.go deleted file mode 100644 index 0a3097eea..000000000 --- a/components/ledger/pkg/storage/systemstore/store.go +++ /dev/null @@ -1,23 +0,0 @@ -package systemstore - -import ( - "context" - - "github.com/formancehq/ledger/pkg/storage" -) - -type Store struct { - schema storage.Schema -} - -func NewStore(schema storage.Schema) *Store { - return &Store{schema: schema} -} - -func (s *Store) Initialize(ctx context.Context) error { - if err := s.CreateLedgersTable(ctx); err != nil { - return storage.PostgresError(err) - } - - return storage.PostgresError(s.CreateConfigurationTable(ctx)) -} diff --git a/components/ledger/pkg/storage/tx.go b/components/ledger/pkg/storage/tx.go deleted file mode 100644 index d21717322..000000000 --- a/components/ledger/pkg/storage/tx.go +++ /dev/null @@ -1,22 +0,0 @@ -package storage - -import ( - "github.com/uptrace/bun" -) - -type Tx struct { - schema *Schema - bun.Tx -} - -func (s *Tx) NewSelect(tableName string) *bun.SelectQuery { - return s.Tx.NewSelect().ModelTableExpr("?0.?1 as ?1", bun.Ident(s.schema.Name()), bun.Ident(tableName)) -} - -func (s *Tx) NewInsert(tableName string) *bun.InsertQuery { - return s.Tx.NewInsert().ModelTableExpr("?0.?1 as ?1", bun.Ident(s.schema.Name()), bun.Ident(tableName)) -} - -func (s *Tx) NewUpdate(tableName string) *bun.UpdateQuery { - return s.Tx.NewUpdate().ModelTableExpr("?0.?1 as ?1", bun.Ident(s.schema.Name()), bun.Ident(tableName)) -} diff --git a/components/ledger/pkg/storage/utils.go b/components/ledger/pkg/storage/utils.go deleted file mode 100644 index 2d0553599..000000000 --- a/components/ledger/pkg/storage/utils.go +++ /dev/null @@ -1,61 +0,0 @@ -package storage - -import ( - "database/sql" - "io" - "os" - "time" - - "github.com/uptrace/bun" - "github.com/uptrace/bun/dialect/pgdialect" - "github.com/uptrace/bun/extra/bundebug" - "github.com/uptrace/bun/extra/bunotel" -) - -type ConnectionOptions struct { - DatabaseSourceName string - Debug bool - Trace bool - Writer io.Writer - MaxIdleConns int - MaxOpenConns int - ConnMaxIdleTime time.Duration -} - -func OpenSQLDB(options ConnectionOptions, hooks ...bun.QueryHook) (*bun.DB, error) { - sqldb, err := sql.Open("postgres", options.DatabaseSourceName) - if err != nil { - return nil, err - } - if options.MaxIdleConns != 0 { - sqldb.SetMaxIdleConns(options.MaxIdleConns) - } - if options.ConnMaxIdleTime != 0 { - sqldb.SetConnMaxIdleTime(options.ConnMaxIdleTime) - } - if options.MaxOpenConns != 0 { - sqldb.SetMaxOpenConns(options.MaxOpenConns) - } - - db := bun.NewDB(sqldb, pgdialect.New()) - if options.Trace { - writer := options.Writer - if writer == nil { - writer = os.Stdout - } - db.AddQueryHook(bundebug.NewQueryHook( - bundebug.WithVerbose(true), - bundebug.WithWriter(writer), - )) - } - db.AddQueryHook(bunotel.NewQueryHook()) - for _, hook := range hooks { - db.AddQueryHook(hook) - } - - if err := db.Ping(); err != nil { - return nil, err - } - - return db, nil -} diff --git a/components/operator/go.sum b/components/operator/go.sum index df9c4a8c1..57a9eeb76 100644 --- a/components/operator/go.sum +++ b/components/operator/go.sum @@ -388,7 +388,6 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/numary/auth/authclient v0.0.0-20220811153653-6335dd9658f2 h1:mBe5Xrlwtkmc/RkyLedf2LPFsFRZzpZNMgORW7rFmxs= github.com/numary/auth/authclient v0.0.0-20220811153653-6335dd9658f2/go.mod h1:T9ZJ+ndCyM0UDKLyiAYobE9/now0KdqHBW+pGpthNGU= -github.com/numary/ledger v1.8.1 h1:XoFOw74R5w7SwOTVrT4omBpuGo5uQSuvhfhPPcGdAuo= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= diff --git a/components/operator/internal/controllers/stack/testdata/monopod-disabled-one-service/results/configmaps--v1/search-benthos-streams.yaml b/components/operator/internal/controllers/stack/testdata/monopod-disabled-one-service/results/configmaps--v1/search-benthos-streams.yaml index cdf03954f..bc1f77436 100644 --- a/components/operator/internal/controllers/stack/testdata/monopod-disabled-one-service/results/configmaps--v1/search-benthos-streams.yaml +++ b/components/operator/internal/controllers/stack/testdata/monopod-disabled-one-service/results/configmaps--v1/search-benthos-streams.yaml @@ -13,6 +13,8 @@ data: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -33,18 +35,18 @@ data: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), @@ -241,7 +243,7 @@ data: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -252,7 +254,7 @@ data: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/operator/internal/controllers/stack/testdata/monopod-latest/results/configmaps--v1/search-benthos-streams.yaml b/components/operator/internal/controllers/stack/testdata/monopod-latest/results/configmaps--v1/search-benthos-streams.yaml index e7b5cbdb4..3fe4efeb0 100644 --- a/components/operator/internal/controllers/stack/testdata/monopod-latest/results/configmaps--v1/search-benthos-streams.yaml +++ b/components/operator/internal/controllers/stack/testdata/monopod-latest/results/configmaps--v1/search-benthos-streams.yaml @@ -13,6 +13,8 @@ data: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -33,18 +35,18 @@ data: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), @@ -241,7 +243,7 @@ data: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -252,7 +254,7 @@ data: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/operator/internal/controllers/stack/testdata/monopod-ledgerv1/results/configmaps--v1/search-benthos-streams.yaml b/components/operator/internal/controllers/stack/testdata/monopod-ledgerv1/results/configmaps--v1/search-benthos-streams.yaml index e2c337bcb..dc0a0552e 100644 --- a/components/operator/internal/controllers/stack/testdata/monopod-ledgerv1/results/configmaps--v1/search-benthos-streams.yaml +++ b/components/operator/internal/controllers/stack/testdata/monopod-ledgerv1/results/configmaps--v1/search-benthos-streams.yaml @@ -13,6 +13,8 @@ data: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -33,18 +35,18 @@ data: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), @@ -241,7 +243,7 @@ data: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -252,7 +254,7 @@ data: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/operator/internal/controllers/stack/testdata/monopod-search-before-v0.7.0/results/configmaps--v1/search-benthos-streams.yaml b/components/operator/internal/controllers/stack/testdata/monopod-search-before-v0.7.0/results/configmaps--v1/search-benthos-streams.yaml index 6b1f39f59..7f1b029e7 100644 --- a/components/operator/internal/controllers/stack/testdata/monopod-search-before-v0.7.0/results/configmaps--v1/search-benthos-streams.yaml +++ b/components/operator/internal/controllers/stack/testdata/monopod-search-before-v0.7.0/results/configmaps--v1/search-benthos-streams.yaml @@ -13,6 +13,8 @@ data: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -33,18 +35,18 @@ data: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), @@ -241,7 +243,7 @@ data: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -252,7 +254,7 @@ data: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/operator/internal/controllers/stack/testdata/multipod-debug/results/configmaps--v1/search-benthos-streams.yaml b/components/operator/internal/controllers/stack/testdata/multipod-debug/results/configmaps--v1/search-benthos-streams.yaml index 5b5c4f674..fc0fa2686 100644 --- a/components/operator/internal/controllers/stack/testdata/multipod-debug/results/configmaps--v1/search-benthos-streams.yaml +++ b/components/operator/internal/controllers/stack/testdata/multipod-debug/results/configmaps--v1/search-benthos-streams.yaml @@ -13,6 +13,8 @@ data: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -33,18 +35,18 @@ data: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), @@ -241,7 +243,7 @@ data: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -252,7 +254,7 @@ data: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/operator/internal/controllers/stack/testdata/multipod-disabled-one-service/results/configmaps--v1/search-benthos-streams.yaml b/components/operator/internal/controllers/stack/testdata/multipod-disabled-one-service/results/configmaps--v1/search-benthos-streams.yaml index ec62dc998..d761cfc02 100644 --- a/components/operator/internal/controllers/stack/testdata/multipod-disabled-one-service/results/configmaps--v1/search-benthos-streams.yaml +++ b/components/operator/internal/controllers/stack/testdata/multipod-disabled-one-service/results/configmaps--v1/search-benthos-streams.yaml @@ -13,6 +13,8 @@ data: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -33,18 +35,18 @@ data: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), @@ -241,7 +243,7 @@ data: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -252,7 +254,7 @@ data: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/operator/internal/controllers/stack/testdata/multipod-latest-no-monitoring/results/configmaps--v1/search-benthos-streams.yaml b/components/operator/internal/controllers/stack/testdata/multipod-latest-no-monitoring/results/configmaps--v1/search-benthos-streams.yaml index 03120046d..eb18d94b1 100644 --- a/components/operator/internal/controllers/stack/testdata/multipod-latest-no-monitoring/results/configmaps--v1/search-benthos-streams.yaml +++ b/components/operator/internal/controllers/stack/testdata/multipod-latest-no-monitoring/results/configmaps--v1/search-benthos-streams.yaml @@ -13,6 +13,8 @@ data: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -33,18 +35,18 @@ data: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), @@ -241,7 +243,7 @@ data: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -252,7 +254,7 @@ data: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/operator/internal/controllers/stack/testdata/multipod-latest/results/configmaps--v1/search-benthos-streams.yaml b/components/operator/internal/controllers/stack/testdata/multipod-latest/results/configmaps--v1/search-benthos-streams.yaml index 12f5c96eb..39d7aaf07 100644 --- a/components/operator/internal/controllers/stack/testdata/multipod-latest/results/configmaps--v1/search-benthos-streams.yaml +++ b/components/operator/internal/controllers/stack/testdata/multipod-latest/results/configmaps--v1/search-benthos-streams.yaml @@ -13,6 +13,8 @@ data: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -33,18 +35,18 @@ data: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), @@ -241,7 +243,7 @@ data: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -252,7 +254,7 @@ data: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/operator/internal/controllers/stack/testdata/multipod-service-annotation/results/configmaps--v1/search-benthos-streams.yaml b/components/operator/internal/controllers/stack/testdata/multipod-service-annotation/results/configmaps--v1/search-benthos-streams.yaml index ae352bfd6..767dc6852 100644 --- a/components/operator/internal/controllers/stack/testdata/multipod-service-annotation/results/configmaps--v1/search-benthos-streams.yaml +++ b/components/operator/internal/controllers/stack/testdata/multipod-service-annotation/results/configmaps--v1/search-benthos-streams.yaml @@ -13,6 +13,8 @@ data: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -33,18 +35,18 @@ data: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), @@ -241,7 +243,7 @@ data: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -252,7 +254,7 @@ data: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/orchestration/internal/workflow/activities/activity_ledger_revert_transaction.go b/components/orchestration/internal/workflow/activities/activity_ledger_revert_transaction.go index 147bb75f6..5c0657882 100644 --- a/components/orchestration/internal/workflow/activities/activity_ledger_revert_transaction.go +++ b/components/orchestration/internal/workflow/activities/activity_ledger_revert_transaction.go @@ -13,7 +13,7 @@ import ( type RevertTransactionRequest struct { Ledger string `json:"ledger"` - TxID int64 `json:"txId"` + ID int64 `json:"txId"` } func (a Activities) RevertTransaction(ctx context.Context, request RevertTransactionRequest) (*shared.Transaction, error) { @@ -22,7 +22,7 @@ func (a Activities) RevertTransaction(ctx context.Context, request RevertTransac ctx, operations.RevertTransactionRequest{ Ledger: request.Ledger, - Txid: request.TxID, + ID: request.ID, }, ) if err != nil { @@ -50,7 +50,7 @@ func RevertTransaction(ctx workflow.Context, ledger string, txID int64) (*shared tx := &shared.Transaction{} if err := executeActivity(ctx, RevertTransactionActivity, tx, RevertTransactionRequest{ Ledger: ledger, - TxID: txID, + ID: txID, }); err != nil { return nil, err } diff --git a/components/orchestration/internal/workflow/stages/send/run_test.go b/components/orchestration/internal/workflow/stages/send/run_test.go index ab11665d8..c022c66ae 100644 --- a/components/orchestration/internal/workflow/stages/send/run_test.go +++ b/components/orchestration/internal/workflow/stages/send/run_test.go @@ -8,6 +8,7 @@ import ( "github.com/formancehq/orchestration/internal/workflow/activities" "github.com/formancehq/orchestration/internal/workflow/stages/internal/stagestesting" "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/formancehq/stack/libs/go-libs/pointer" "github.com/stretchr/testify/mock" "go.temporal.io/sdk/temporal" ) @@ -146,7 +147,7 @@ var ( Destination: paymentAccountName("payment1"), Source: "world", }}, - Reference: ptrString(paymentAccountName("payment1")), + Reference: pointer.For(paymentAccountName("payment1")), Metadata: metadata.Metadata{}, }, }, @@ -208,7 +209,7 @@ var ( }, Type: shared.SubjectTypeAccount, }}, - Balance: ptrString("main"), + Balance: pointer.For("main"), Metadata: metadata.Metadata{ moveFromLedgerMetadata: internalLedger, }, @@ -265,7 +266,7 @@ var ( Destination: paymentAccountName("payment1"), Source: "world", }}, - Reference: ptrString(paymentAccountName("payment1")), + Reference: pointer.For(paymentAccountName("payment1")), Metadata: metadata.Metadata{}, }, }, @@ -366,7 +367,7 @@ var ( Destination: paymentAccountName("payment1"), Source: "world", }}, - Reference: ptrString(paymentAccountName("payment1")), + Reference: pointer.For(paymentAccountName("payment1")), Metadata: metadata.Metadata{}, }, }, @@ -566,7 +567,7 @@ var ( }, Type: shared.SubjectTypeAccount, }}, - Balance: ptrString("main"), + Balance: pointer.For("main"), }, }, }, @@ -641,7 +642,7 @@ var ( }, Type: shared.SubjectTypeAccount, }}, - Balance: ptrString("main"), + Balance: pointer.For("main"), Metadata: metadata.Metadata{ moveFromLedgerMetadata: "ledger1", }, @@ -689,8 +690,8 @@ var ( Args: []any{ mock.Anything, shared.StripeTransferRequest{ Amount: big.NewInt(100), - Asset: ptrString("USD"), - Destination: ptrString("abcd"), + Asset: pointer.For("USD"), + Destination: pointer.For("abcd"), }, }, Returns: []any{nil}, @@ -899,11 +900,11 @@ var ( WalletSubject: &shared.WalletSubject{ Type: "WALLET", Identifier: "foo", - Balance: ptrString("main"), + Balance: pointer.For("main"), }, Type: shared.SubjectTypeWallet, }}, - Balance: ptrString("main"), + Balance: pointer.For("main"), Metadata: map[string]string{}, }, }, @@ -980,7 +981,7 @@ var ( Asset: "USD", Amount: big.NewInt(100), }, - Balance: ptrString("main"), + Balance: pointer.For("main"), Metadata: metadata.Metadata{ moveFromLedgerMetadata: "ledger1", }, @@ -1026,8 +1027,8 @@ var ( Args: []any{ mock.Anything, shared.StripeTransferRequest{ Amount: big.NewInt(100), - Asset: ptrString("USD"), - Destination: ptrString("abcd"), + Asset: pointer.For("USD"), + Destination: pointer.For("abcd"), }, }, Returns: []any{nil}, @@ -1071,11 +1072,3 @@ var testCases = []stagestesting.WorkflowTestCase[Send]{ func TestSend(t *testing.T) { stagestesting.RunWorkflows(t, testCases...) } - -func ptrString(s string) *string { - return &s -} - -func ptrInt64(i int64) *int64 { - return &i -} diff --git a/components/search/benthos/messages/saved_metadata.json b/components/search/benthos/messages/saved_metadata.json deleted file mode 100644 index e69de29bb..000000000 diff --git a/components/search/benthos/messages/saved_payment.json b/components/search/benthos/messages/saved_payment.json deleted file mode 100644 index e69de29bb..000000000 diff --git a/components/search/benthos/streams/ledger_ingestion.yaml b/components/search/benthos/streams/ledger_ingestion.yaml index 236a77886..9dcf3a731 100644 --- a/components/search/benthos/streams/ledger_ingestion.yaml +++ b/components/search/benthos/streams/ledger_ingestion.yaml @@ -10,6 +10,8 @@ pipeline: events: - label: COMMITTED_TRANSACTIONS processors: + - log: + message: "receive message: ${! this }" - bloblang: | map account { root = this.map_each(v -> v.value.map_each(v2 -> { @@ -30,18 +32,18 @@ pipeline: map tx { root = { "action": "index", - "id": "%s".format(this.txid), + "id": if this.exists("txid") { "%s".format(this.txid) } else { "%s".format(this.id) }, "document": { "data": { "postings": this.postings, "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "metadata": if this.metadata { this.metadata } else {{}} }, "indexed": { "reference": this.reference, - "txid": this.txid, + "txid": if this.exists("txid") { this.txid } else { this.id }, "timestamp": this.timestamp, "asset": this.postings.map_each(p -> p.asset), "source": this.postings.map_each(p -> p.source), diff --git a/components/search/benthos/streams/ledger_reindex_transactions.yaml b/components/search/benthos/streams/ledger_reindex_transactions.yaml index 6f09bca75..e6878315d 100644 --- a/components/search/benthos/streams/ledger_reindex_transactions.yaml +++ b/components/search/benthos/streams/ledger_reindex_transactions.yaml @@ -9,7 +9,7 @@ pipeline: - postgres_query: service: ledger query: | - select id, timestamp, reference, metadata, postings + select id::varchar as id, timestamp, reference, metadata, postings from "${! meta("ledger") }".transactions; - unarchive: format: json_array @@ -20,7 +20,7 @@ pipeline: }) - bloblang: | meta action = "upsert" - meta id = "TRANSACTION-%s-%d".format(meta("ledger"), this.id) + meta id = "TRANSACTION-%s-%s".format(meta("ledger"), this.id) root = { "data": { "postings": this.postings, diff --git a/components/search/go.mod b/components/search/go.mod index e99d680b4..ec8946790 100644 --- a/components/search/go.mod +++ b/components/search/go.mod @@ -5,15 +5,11 @@ go 1.19 require ( github.com/aquasecurity/esquery v0.2.0 github.com/bombsimon/logrusr/v3 v3.1.0 - github.com/elastic/go-elasticsearch/v7 v7.17.7 github.com/formancehq/stack/libs/go-libs v0.0.0-20230221161632-e6dc6a89a85e github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.0 - github.com/numary/ledger v1.8.1 github.com/opensearch-project/opensearch-go v1.1.0 - github.com/ory/dockertest/v3 v3.9.1 github.com/pkg/errors v0.9.1 - github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.6.1 github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.3 @@ -26,37 +22,24 @@ require ( ) require ( - github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/Microsoft/go-winio v0.6.0 // indirect - github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/containerd/continuity v0.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/cli v20.10.17+incompatible // indirect - github.com/docker/docker v20.10.17+incompatible // indirect - github.com/docker/go-connections v0.4.0 // indirect - github.com/docker/go-units v0.4.0 // indirect + github.com/elastic/go-elasticsearch/v7 v7.17.7 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.0.2 // indirect - github.com/opencontainers/runc v1.1.3 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -66,9 +49,6 @@ require ( github.com/tidwall/pretty v1.2.1 // indirect github.com/uptrace/opentelemetry-go-extra/otellogrus v0.1.21 // indirect github.com/uptrace/opentelemetry-go-extra/otelutil v0.1.21 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.14.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.16.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect @@ -83,18 +63,17 @@ require ( go.uber.org/dig v1.16.1 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/mod v0.8.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.6.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) replace github.com/formancehq/stack/libs/go-libs => ../../libs/go-libs + +replace github.com/formancehq/ledger => ../../components/ledger diff --git a/components/search/go.sum b/components/search/go.sum index 79e4ac46c..273772a31 100644 --- a/components/search/go.sum +++ b/components/search/go.sum @@ -36,14 +36,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= -github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aquasecurity/esquery v0.2.0 h1:9WWXve95TE8hbm3736WB7nS6Owl8UGDeu+0jiyE9ttA= @@ -57,11 +51,9 @@ github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -71,27 +63,11 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= -github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= -github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE= -github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/elastic/go-elasticsearch/v7 v7.6.0/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4= github.com/elastic/go-elasticsearch/v7 v7.17.7 h1:pcYNfITNPusl+cLwLN6OLmVT+F73Els0nbaWOmYachs= github.com/elastic/go-elasticsearch/v7 v7.17.7/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4= @@ -108,7 +84,6 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= @@ -121,11 +96,6 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= @@ -185,8 +155,6 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -205,8 +173,6 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -218,7 +184,6 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -229,33 +194,15 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= -github.com/numary/ledger v1.8.1 h1:XoFOw74R5w7SwOTVrT4omBpuGo5uQSuvhfhPPcGdAuo= -github.com/numary/ledger v1.8.1/go.mod h1:jDWhSjPgF+3Atp4KiRev8ZjyOIlumx0KbDiU77Eh+0Q= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= -github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opensearch-project/opensearch-go v1.1.0 h1:eG5sh3843bbU1itPRjA9QXbxcg8LaZ+DjEzQH9aLN3M= github.com/opensearch-project/opensearch-go v1.1.0/go.mod h1:+6/XHCuTH+fwsMJikZEWsucZ4eZMma3zNSeLrTtVGbo= -github.com/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY= -github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= @@ -266,11 +213,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -282,7 +225,6 @@ github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= @@ -292,7 +234,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -303,7 +244,6 @@ github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gt github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -315,16 +255,6 @@ github.com/uptrace/opentelemetry-go-extra/otellogrus v0.1.21 h1:OXsouNDvuET5o1A4 github.com/uptrace/opentelemetry-go-extra/otellogrus v0.1.21/go.mod h1:Xm3wlRGm5xzdAGPOvqydXPiGj0Da1q0OlUNm7Utoda4= github.com/uptrace/opentelemetry-go-extra/otelutil v0.1.21 h1:HCqo51kNF8wxDMDhxcN5S6DlfZXigMtptRpkvjBCeVc= github.com/uptrace/opentelemetry-go-extra/otelutil v0.1.21/go.mod h1:2MNqrUmDrt5E0glMuoJI/9FyGVpBKo1FqjSH60UOZFg= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -415,8 +345,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -472,7 +400,6 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -480,12 +407,9 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -507,17 +431,12 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= @@ -547,7 +466,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -574,7 +492,6 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -583,11 +500,8 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -705,14 +619,9 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/components/search/openapi.yaml b/components/search/openapi.yaml index d86e754a6..96eb3052d 100644 --- a/components/search/openapi.yaml +++ b/components/search/openapi.yaml @@ -75,7 +75,7 @@ components: example: "destination=central_bank1" sort: type: string - example: "txid:asc" + example: "id:asc" policy: type: string example: "OR" diff --git a/components/search/pkg/searchengine/engine_test.go b/components/search/pkg/searchengine/engine_test.go deleted file mode 100644 index cadb89a25..000000000 --- a/components/search/pkg/searchengine/engine_test.go +++ /dev/null @@ -1,400 +0,0 @@ -package searchengine - -import ( - "context" - "encoding/json" - "fmt" - "testing" - "time" - - "github.com/aquasecurity/esquery" - "github.com/numary/ledger/pkg/core" - "github.com/stretchr/testify/require" -) - -func testEngine(t *testing.T) { - ledger := "quickstart" - insertTransaction(t, ledger, "transaction0", time.Now(), - core.Transaction{ - TransactionData: core.TransactionData{ - Metadata: core.Metadata{ - "foo": json.RawMessage(`{"foo": "bar"}`), - }, - Postings: core.Postings{ - { - Source: "world", - Destination: "central:bank", - Asset: "USD", - Amount: core.NewMonetaryInt(100), - }, - }, - }, - }) - - q := NewSingleDocTypeSearch("TRANSACTION") - q.WithLedgers(ledger) - q.WithTerms("central:bank") - response, err := q.Do(context.Background(), engine) - require.NoError(t, err) - require.Len(t, response.Items, 1) -} - -func testMatchingAllFields(t *testing.T) { - now := time.Now().Round(time.Second).UTC() - insertTransaction(t, "quickstart", "transaction0", now.Add(-time.Minute), - core.Transaction{ - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "central_bank", - Amount: core.NewMonetaryInt(100), - Asset: "USD", - }, - }, - }, - }) - insertTransaction(t, "quickstart", "transaction1", now, core.Transaction{}) - insertTransaction(t, "quickstart", "transaction2", now.Add(time.Minute), core.Transaction{}) - - q := NewMultiDocTypeSearch() - q.WithLedgers("quickstart") - q.WithTerms("USD") - - response, err := q.Do(context.Background(), engine) - require.NoError(t, err) - require.Len(t, response["TRANSACTION"], 1) - - q = NewMultiDocTypeSearch() - q.WithLedgers("quickstart") - q.WithTerms("US") - response, err = q.Do(context.Background(), engine) - require.NoError(t, err) - require.Len(t, response["TRANSACTION"], 1) -} - -func testSort(t *testing.T) { - now := time.Now().Round(time.Second).UTC() - const count = 20 - for i := 0; i < count; i++ { - insertTransaction(t, "quickstart", - fmt.Sprintf("transaction%d", i), - now.Add(time.Duration(i)*time.Minute), core.Transaction{}) - } - - q := NewSingleDocTypeSearch("TRANSACTION") - q.WithLedgers("quickstart") - q.WithPageSize(20) - q.WithSort("txid", esquery.OrderAsc) - - _, err := openSearchClient.Indices.GetMapping() - require.NoError(t, err) - - response, err := q.Do(context.Background(), engine) - require.NoError(t, err) - require.Len(t, response.Items, count) -} - -func testPagination(t *testing.T) { - now := time.Now().Round(time.Second).UTC() - - for i := 0; i < 20; i++ { - at := now.Add(time.Duration(i) * time.Minute) - insertTransaction(t, "quickstart", - fmt.Sprintf("transaction%d", i), at, - core.Transaction{ - TransactionData: core.TransactionData{ - Timestamp: at, - }, - }) - } - - searchAfter := []interface{}{} - for i := 0; ; i++ { - q := NewSingleDocTypeSearch("TRANSACTION") - q.WithLedgers("quickstart") - q.WithPageSize(5) - q.WithSort("timestamp", esquery.OrderDesc) - q.WithSearchAfter(searchAfter) - - _, err := openSearchClient.Indices.GetMapping() - require.NoError(t, err) - - response, err := q.Do(context.Background(), engine) - require.NoError(t, err) - - tx := core.Transaction{} - require.NoError(t, json.Unmarshal(response.Items[0], &tx)) - - if i < 3 { - require.Len(t, response.Items, 5) - require.Equal(t, tx.Timestamp, now.Add(19*time.Minute).Add(-time.Duration(i)*5*time.Minute).UTC()) - } else { - require.Len(t, response.Items, 5) - require.Equal(t, tx.Timestamp, now.Add(19*time.Minute).Add(-time.Duration(i)*5*time.Minute).UTC()) - break - } - - lastTx := core.Transaction{} - require.NoError(t, json.Unmarshal(response.Items[4], &lastTx)) - - searchAfter = []interface{}{lastTx.Timestamp} - } - -} - -func testMatchingSpecificField(t *testing.T) { - now := time.Now().Round(time.Second).UTC() - insertTransaction(t, "quickstart", "transaction0", now.Add(-time.Minute), - core.Transaction{ - TransactionData: core.TransactionData{ - Timestamp: now.Add(-time.Minute), - Postings: core.Postings{ - { - Source: "world", - Destination: "central_bank", - Amount: core.NewMonetaryInt(100), - Asset: "USD", - }, - }, - }, - }) - insertTransaction(t, "quickstart", "transaction1", now.Add(time.Minute), - core.Transaction{ - TransactionData: core.TransactionData{ - Timestamp: now.Add(time.Minute), - Postings: core.Postings{ - { - Source: "central_bank", - Destination: "user:001", - Amount: core.NewMonetaryInt(1000), - Asset: "USD", - }, - { - Source: "world", - Destination: "central_bank", - Amount: core.NewMonetaryInt(10000), - Asset: "USD", - }, - }, - }, - }) - - type testCase struct { - name string - term string - expectedCount int - } - - testCases := []testCase{ - { - name: "equality-using-equal", - term: "amount=100", - expectedCount: 1, - }, - { - name: "greater-than-on-long", - term: "amount>500", - expectedCount: 1, - }, - { - name: "greater-than-on-date-millis", - term: fmt.Sprintf("timestamp>%d", now.UnixMilli()), - expectedCount: 1, - }, - { - name: "greater-than-on-date-rfc3339", - term: fmt.Sprintf("timestamp>%s", now.Format(time.RFC3339)), - expectedCount: 1, - }, - { - name: "lower-than", - term: "amount<5000", - expectedCount: 2, - }, - { - name: "greater-than-or-equal", - term: "amount>=1000", - expectedCount: 1, - }, - { - name: "lower-than-or-equal", - term: "amount<=100", - expectedCount: 1, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - - q := NewMultiDocTypeSearch() - q.WithLedgers("quickstart") - q.WithTerms(tc.term) - - response, err := q.Do(context.Background(), engine) - require.NoError(t, err) - require.Len(t, response["TRANSACTION"], tc.expectedCount) - }) - } -} - -func testUsingOrPolicy(t *testing.T) { - now := time.Now().Round(time.Second).UTC() - insertTransaction(t, "quickstart", "transaction0", now.Add(-time.Minute), - core.Transaction{ - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "central_bank1", - Amount: core.NewMonetaryInt(100), - Asset: "USD", - }, - }, - }, - }) - insertTransaction(t, "quickstart", "transaction1", now.Add(time.Minute), - core.Transaction{ - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "central_bank2", - Amount: core.NewMonetaryInt(1000), - Asset: "USD", - }, - }, - }, - }) - insertTransaction(t, "quickstart", "transaction2", now.Add(time.Minute), - core.Transaction{ - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "central_bank3", - Amount: core.NewMonetaryInt(1000), - Asset: "USD", - }, - }, - }, - }) - - q := NewSingleDocTypeSearch("TRANSACTION") - q.WithLedgers("quickstart") - q.WithTerms("destination=central_bank1", "destination=central_bank2") - q.WithPolicy(TermPolicyOR) - - response, err := q.Do(context.Background(), engine) - require.NoError(t, err) - require.Len(t, response.Items, 2) -} - -func testAssetDecimals(t *testing.T) { - now := time.Now().Round(time.Second).UTC() - insertTransaction(t, "quickstart", "transaction0", now.Add(-time.Minute), - core.Transaction{ - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "central_bank", - Amount: core.NewMonetaryInt(10045), - Asset: "USD/2", - }, - }, - }, - }) - insertTransaction(t, "quickstart", "transaction1", now.Add(-time.Minute), - core.Transaction{ - TransactionData: core.TransactionData{ - Postings: core.Postings{ - { - Source: "world", - Destination: "central_bank", - Amount: core.NewMonetaryInt(1000), - Asset: "USD", - }, - }, - }, - }) - - type testCase struct { - name string - term string - expectedCount int - } - - testCases := []testCase{ - { - name: "colon", - term: "amount=100.45", - expectedCount: 1, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - - q := NewMultiDocTypeSearch() - q.WithTerms(tc.term) - q.WithLedgers("quickstart") - - response, err := q.Do(context.Background(), engine) - require.NoError(t, err) - require.Len(t, response["TRANSACTION"], tc.expectedCount) - }) - } - -} - -func testSearchInTransactionMetadata(t *testing.T) { - now := time.Now().Round(time.Second).UTC() - metadata := core.Metadata{ - "Hello": "guys!", - "John": "Snow!", - } - insertTransaction(t, "quickstart", "transaction0", now, - core.Transaction{ - TransactionData: core.TransactionData{ - Metadata: metadata, - }, - }) - insertTransaction(t, "quickstart", "transaction1", now, - core.Transaction{}) - - q := NewMultiDocTypeSearch() - q.WithTerms("John") - response, err := q.Do(context.Background(), engine) - require.NoError(t, err) - require.Len(t, response["TRANSACTION"], 1) - - tx := core.Transaction{} - require.NoError(t, json.Unmarshal(response["TRANSACTION"][0], &tx)) - require.Equal(t, metadata, tx.Metadata) -} - -func testKeepOnlyLastDocument(t *testing.T) { - now := time.Now().Round(time.Hour) - for i := 0; i < 10; i++ { - insertAccount(t, "quickstart", fmt.Sprintf("account%d", i), now, core.Account{ - Address: fmt.Sprintf("user:00%d", i), - }) - } - for i := 0; i < 20; i++ { - insertTransaction(t, "quickstart", fmt.Sprintf("transaction%d", i), now.Add(2*time.Minute), core.Transaction{ - ID: uint64(i), - TransactionData: core.TransactionData{ - Timestamp: now.Add(time.Hour), - }, - }) - } - - q := NewMultiDocTypeSearch() - q.WithPageSize(5) - - response, err := q.Do(context.Background(), engine) - require.NoError(t, err) - require.Len(t, response["TRANSACTION"], 5) - require.Len(t, response["ACCOUNT"], 5) -} diff --git a/components/search/pkg/searchengine/indexed_mapping.json b/components/search/pkg/searchengine/indexed_mapping.json index 1b91e75cb..8bee60e01 100644 --- a/components/search/pkg/searchengine/indexed_mapping.json +++ b/components/search/pkg/searchengine/indexed_mapping.json @@ -17,8 +17,8 @@ "destination" : { "type": "keyword" }, - "id" : { - "type": "keyword" + "txid" : { + "type": "long" }, "initialAmount" : { "type" : "long" @@ -47,8 +47,8 @@ "timestamp" : { "type" : "date" }, - "txid" : { - "type" : "long" + "id" : { + "type" : "keyword" }, "type" : { "type": "keyword" diff --git a/components/search/pkg/searchengine/main_test.go b/components/search/pkg/searchengine/main_test.go deleted file mode 100644 index 55e8fe577..000000000 --- a/components/search/pkg/searchengine/main_test.go +++ /dev/null @@ -1,179 +0,0 @@ -package searchengine - -import ( - "bytes" - "context" - "crypto/tls" - "encoding/json" - "net/http" - "os" - "path" - "strings" - "testing" - "time" - - "github.com/elastic/go-elasticsearch/v7/esapi" - "github.com/formancehq/stack/libs/go-libs/httpclient" - "github.com/numary/ledger/pkg/core" - goOpensearch "github.com/opensearch-project/opensearch-go" - "github.com/ory/dockertest/v3" - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" -) - -var ( - engine *DefaultEngine - openSearchClient *goOpensearch.Client -) - -type testCase struct { - name string - fn func(t *testing.T) -} - -var tests = []testCase{ - { - name: "nominal", - fn: testEngine, - }, - { - name: "all-fields", - fn: testMatchingAllFields, - }, - { - name: "pagination", - fn: testPagination, - }, - { - name: "specific-field", - fn: testMatchingSpecificField, - }, - { - name: "assets", - fn: testAssetDecimals, - }, - { - name: "search-in-transaction-metadata", - fn: testSearchInTransactionMetadata, - }, - { - name: "keep-only-last-document", - fn: testKeepOnlyLastDocument, - }, - { - name: "using-or-policy", - fn: testUsingOrPolicy, - }, - { - name: "sort", - fn: testSort, - }, -} - -func indexName(t *testing.T) string { - return strings.Split(t.Name(), "/")[1] -} - -func insertESDocument(t *testing.T, id string, pipeline string, doc map[string]interface{}) { - data, err := json.Marshal(doc) - require.NoError(t, err) - - index := indexName(t) - req := esapi.IndexRequest{ - Index: index, - DocumentID: id, - Refresh: "true", - Body: bytes.NewReader(data), - Pipeline: pipeline, - } - res, err := req.Do(context.Background(), openSearchClient) - require.NoError(t, err) - defer res.Body.Close() - - if res.IsError() { - require.FailNowf(t, "error inserting es", "Error inserting es index: %s [%d]", res.Status(), res.String()) - } -} - -func insertTransaction(t *testing.T, ledgerName, id string, when time.Time, transaction core.Transaction) { - insertESDocument(t, id, "TRANSACTION", map[string]interface{}{ - "kind": "TRANSACTION", - "ledger": ledgerName, - "when": when, - "data": transaction, - "stack": "", - }) -} - -func insertAccount(t *testing.T, ledgerName, id string, when time.Time, payload core.Account) { - insertESDocument(t, id, "ACCOUNT", map[string]interface{}{ - "kind": "ACCOUNT", - "ledger": ledgerName, - "when": when, - "data": payload, - "stack": "", - }) -} - -func TestSearchEngine(t *testing.T) { - - if testing.Verbose() { - logrus.StandardLogger().Level = logrus.DebugLevel - } - logrus.Debugln("starting opensearch container") - - pool, err := dockertest.NewPool("") - require.NoError(t, err) - - resource, err := pool.Run("opensearchproject/opensearch", "1.2.3", []string{ - "discovery.type=single-node", - "DISABLE_SECURITY_PLUGIN=true", - "DISABLE_INSTALL_DEMO_CONFIG=true", - }) - require.NoError(t, err) - - defer func() { - err := pool.Purge(resource) - require.NoError(t, err) - }() - - esAddress := "http://localhost:" + resource.GetPort("9200/tcp") - openSearchClient, err = goOpensearch.NewClient(goOpensearch.Config{ - Addresses: []string{esAddress}, - Transport: httpclient.NewDebugHTTPTransport(&http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - }), - }) - require.NoError(t, err) - - err = pool.Retry(func() error { - _, err = openSearchClient.Ping() - return err - }) - require.NoError(t, err) - - pipelineDir := "../../tests/pipelines" - dir, err := os.ReadDir(pipelineDir) - require.NoError(t, err) - - for _, pipelineFile := range dir { - filename := pipelineFile.Name() - objectType := strings.TrimSuffix(filename, ".json") - data, err := os.ReadFile(path.Join(pipelineDir, filename)) - require.NoError(t, err) - - rsp, err := openSearchClient.Ingest.PutPipeline(objectType, bytes.NewBuffer(data)) - require.NoError(t, err) - require.False(t, rsp.IsError()) - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require.NoError(t, CreateIndex(context.TODO(), openSearchClient, test.name)) - engine = NewDefaultEngine(openSearchClient, "", WithESIndex(test.name)) - test.fn(t) - }) - } -} diff --git a/components/search/pkg/searchhttp/http_test.go b/components/search/pkg/searchhttp/http_test.go index 31a384b43..71c4b034c 100644 --- a/components/search/pkg/searchhttp/http_test.go +++ b/components/search/pkg/searchhttp/http_test.go @@ -14,7 +14,6 @@ import ( "github.com/formancehq/search/pkg/es" "github.com/formancehq/search/pkg/searchengine" "github.com/formancehq/stack/libs/go-libs/api" - "github.com/numary/ledger/pkg/core" "github.com/stretchr/testify/require" ) @@ -59,33 +58,30 @@ func TestMultiSearch(t *testing.T) { name: "nominal", results: map[string][]interface{}{ "ACCOUNT": { - core.Account{ - Address: "user:001", + map[string]any{ + "address": "user:001", + "metadata": nil, }, - core.Account{ - Address: "user:002", - Metadata: core.Metadata{ - "foo": json.RawMessage(`"bar"`), + map[string]any{ + "address": "user:002", + "metadata": map[string]any{ + "foo": "bar", }, }, }, "TRANSACTION": { - core.Transaction{ - ID: 1, - TransactionData: core.TransactionData{ - Postings: []core.Posting{ - { - Source: "world", - Destination: "central_bank", - Amount: core.NewMonetaryInt(100), - Asset: "USD", - }, - }, - Reference: "tx1", - Timestamp: now, - Metadata: core.Metadata{ - "foo": json.RawMessage(`"bar"`), - }, + map[string]any{ + "txid": 1, + "postings": []map[string]any{{ + "source": "world", + "destination": "central_bank", + "amount": 100, + "asset": "USD", + }}, + "reference": "tx1", + "timestamp": now, + "metadata": map[string]any{ + "foo": "bar", }, }, }, @@ -213,13 +209,14 @@ func TestSingleDocTypeSearch(t *testing.T) { kind: "ACCOUNT", query: map[string]interface{}{}, results: []interface{}{ - core.Account{ - Address: "user:001", + map[string]any{ + "address": "user:001", + "metadata": nil, }, - core.Account{ - Address: "user:002", - Metadata: core.Metadata{ - "foo": json.RawMessage(`"bar"`), + map[string]any{ + "address": "user:002", + "metadata": map[string]any{ + "foo": "bar", }, }, }, @@ -261,10 +258,10 @@ func TestSingleDocTypeSearch(t *testing.T) { }), }, results: []interface{}{ - core.Account{ - Address: "user:002", - Metadata: core.Metadata{ - "foo": json.RawMessage(`"bar"`), + map[string]any{ + "address": "user:002", + "metadata": map[string]any{ + "foo": "bar", }, }, }, @@ -305,8 +302,9 @@ func TestSingleDocTypeSearch(t *testing.T) { hasSearchAfter("user:002"), }, results: []interface{}{ - core.Account{ - Address: "user:001", + map[string]any{ + "address": "user:001", + "metadata": nil, }, }, expected: BaseResponse[map[string]interface{}]{ @@ -355,8 +353,9 @@ func TestSingleDocTypeSearch(t *testing.T) { hasSearchAfter("user:002"), }, results: []interface{}{ - core.Account{ - Address: "user:001", + map[string]any{ + "address": "user:001", + "metadata": nil, }, }, expected: BaseResponse[map[string]interface{}]{ diff --git a/components/search/tests/pipelines/TRANSACTION.json b/components/search/tests/pipelines/TRANSACTION.json index d5689a2aa..7797774b7 100644 --- a/components/search/tests/pipelines/TRANSACTION.json +++ b/components/search/tests/pipelines/TRANSACTION.json @@ -27,13 +27,13 @@ }, { "set": { - "field": "indexed.txid", - "value": "{{data.txid}}" + "field": "indexed.id", + "value": "{{data.id}}" } }, { "convert": { - "field": "indexed.txid", + "field": "indexed.id", "type": "long" } }, diff --git a/components/wallets/openapi.yaml b/components/wallets/openapi.yaml index 391c4d95f..8d1780b47 100644 --- a/components/wallets/openapi.yaml +++ b/components/wallets/openapi.yaml @@ -694,7 +694,7 @@ components: additionalProperties: type: string description: Metadata associated with the wallet. - txid: + id: type: integer format: int64 minimum: 0 @@ -705,7 +705,7 @@ components: required: - postings - timestamp - - txid + - ix - metadata Cursor: type: object diff --git a/components/wallets/pkg/transaction.go b/components/wallets/pkg/transaction.go index f95b99568..764bed4a6 100644 --- a/components/wallets/pkg/transaction.go +++ b/components/wallets/pkg/transaction.go @@ -26,7 +26,7 @@ type ExpandedTransaction struct { Postings []Posting `json:"postings"` Reference *string `json:"reference,omitempty"` Metadata metadata.Metadata `json:"metadata"` - Txid int64 `json:"txid"` + ID int64 `json:"id"` PreCommitVolumes map[string]map[string]Volume `json:"preCommitVolumes"` PostCommitVolumes map[string]map[string]Volume `json:"postCommitVolumes"` } diff --git a/components/webhooks/pkg/worker/module.go b/components/webhooks/pkg/worker/module.go index 059635401..66ec36363 100644 --- a/components/webhooks/pkg/worker/module.go +++ b/components/webhooks/pkg/worker/module.go @@ -100,7 +100,7 @@ func processMessages(store storage.Store, httpClient *http.Client, retriesSchedu "event_types": ev.Type, "active": true, } - logging.FromContext(context.Background()).Infof("searching configs with event types: %+v", ev.Type) + logging.FromContext(context.Background()).Debugf("searching configs with event types: %+v", ev.Type) cfgs, err := store.FindManyConfigs(context.Background(), filter) if err != nil { logging.FromContext(context.Background()).Error(err) diff --git a/docs/diagrams/.gitignore b/docs/diagrams/.gitignore new file mode 100644 index 000000000..fb8705a7c --- /dev/null +++ b/docs/diagrams/.gitignore @@ -0,0 +1 @@ +# Directory populated by draw.io \ No newline at end of file diff --git a/docs/diagrams/Diagramme sans nom.drawio b/docs/diagrams/Diagramme sans nom.drawio new file mode 100644 index 000000000..e2c5cc0fe --- /dev/null +++ b/docs/diagrams/Diagramme sans nom.drawio @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/diagrams/model.drawio b/docs/diagrams/model.drawio new file mode 100644 index 000000000..276d20c88 --- /dev/null +++ b/docs/diagrams/model.drawio @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/go.mod b/go.mod index 52aa5c1c7..f8616444c 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.19 require ( github.com/pkg/errors v0.9.1 github.com/xeipuuv/gojsonschema v1.2.0 + golang.org/x/mod v0.12.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index 9c7699f98..a662cb900 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/libs/events/v1/base/base.yaml b/libs/events/base.yaml similarity index 100% rename from libs/events/v1/base/base.yaml rename to libs/events/base.yaml diff --git a/libs/events/events.go b/libs/events/events.go index 9e3e409f5..c40411abe 100644 --- a/libs/events/events.go +++ b/libs/events/events.go @@ -3,30 +3,47 @@ package events import ( "embed" "fmt" - "io/fs" + "path/filepath" "github.com/pkg/errors" "github.com/xeipuuv/gojsonschema" - yaml "gopkg.in/yaml.v3" + "golang.org/x/mod/semver" + "gopkg.in/yaml.v3" ) -//go:embed v1 -var V1 embed.FS +//go:embed base.yaml +var baseEvent string + +//go:embed services +var services embed.FS func ComputeSchema(serviceName, eventName string) (*gojsonschema.Schema, error) { - baseData, err := fs.ReadFile(V1, "v1/base/base.yaml") - if err != nil { - return nil, err - } base := map[string]any{} - if err := yaml.Unmarshal(baseData, &base); err != nil { + if err := yaml.Unmarshal([]byte(baseEvent), &base); err != nil { return nil, err } - eventData, err := fs.ReadFile(V1, fmt.Sprintf("v1/%s/%s.yaml", serviceName, eventName)) + ls, err := services.ReadDir(filepath.Join("services", serviceName)) + if err != nil { + return nil, errors.Wrapf(err, "reading events directory for service '%s'", serviceName) + } + + var moreRecent string + for _, directory := range ls { + if moreRecent == "" || semver.Compare(directory.Name(), moreRecent) > 0 { + moreRecent = directory.Name() + } + } + + if moreRecent == "" { + return nil, fmt.Errorf("error retrieving more recent version directory for service '%s'", serviceName) + } + + eventData, err := services.ReadFile(fmt.Sprintf("services/%s/%s/%s.yaml", serviceName, moreRecent, eventName)) if err != nil { return nil, err } + event := map[string]any{} if err := yaml.Unmarshal(eventData, &event); err != nil { return nil, err diff --git a/libs/events/generated/ledger-v1.0.0-COMMITTED_TRANSACTIONS.yaml.json b/libs/events/generated/ledger-v1.0.0-COMMITTED_TRANSACTIONS.yaml.json new file mode 100644 index 000000000..b3d975827 --- /dev/null +++ b/libs/events/generated/ledger-v1.0.0-COMMITTED_TRANSACTIONS.yaml.json @@ -0,0 +1 @@ +{"type":"object","properties":{"app":{"type":"string"},"version":{"type":"string"},"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"ledger":{"type":"string"},"payload":{"type":"object","properties":{"ledger":{"type":"string"},"transactions":{"type":"array","items":{"type":"object","properties":{"postings":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"destination":{"type":"string"},"amount":{"type":"number"},"asset":{"type":"string"}},"required":["source","destination","amount","asset"]}},"reference":{"type":"string"},"metadata":{"type":"object","properties":{},"required":[]},"txid":{"type":"number"},"timestamp":{"type":"string"}},"required":["postings","reference","metadata","txid","timestamp"]}}},"required":["ledger","transactions"]}},"required":["date","app","version","type","payload"]} \ No newline at end of file diff --git a/libs/events/generated/ledger-v1.0.0-REVERTED_TRANSACTION.yaml.json b/libs/events/generated/ledger-v1.0.0-REVERTED_TRANSACTION.yaml.json new file mode 100644 index 000000000..6ee7be5e7 --- /dev/null +++ b/libs/events/generated/ledger-v1.0.0-REVERTED_TRANSACTION.yaml.json @@ -0,0 +1 @@ +{"type":"object","properties":{"app":{"type":"string"},"version":{"type":"string"},"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"ledger":{"type":"string"},"payload":{"type":"object","properties":{"ledger":{"type":"string"},"revertedTransaction":{"type":"object","properties":{"postings":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"destination":{"type":"string"},"amount":{"type":"number"},"asset":{"type":"string"}},"required":["source","destination","amount","asset"]}},"reference":{"type":"string"},"metadata":{"type":"object","properties":{},"required":[]},"txid":{"type":"number"},"timestamp":{"type":"string"}},"required":["postings","reference","metadata","txid","timestamp"]},"revertTransaction":{"type":"object","properties":{"postings":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"destination":{"type":"string"},"amount":{"type":"number"},"asset":{"type":"string"}},"required":["source","destination","amount","asset"]}},"reference":{"type":"string"},"metadata":{"type":"object","properties":{},"required":[]},"txid":{"type":"number"},"timestamp":{"type":"string"}},"required":["postings","reference","metadata","txid","timestamp"]}},"required":["ledger","revertedTransaction","revertTransaction"]}},"required":["date","app","version","type","payload"]} \ No newline at end of file diff --git a/libs/events/generated/ledger-v1.0.0-SAVED_METADATA.yaml.json b/libs/events/generated/ledger-v1.0.0-SAVED_METADATA.yaml.json new file mode 100644 index 000000000..1fa2012b3 --- /dev/null +++ b/libs/events/generated/ledger-v1.0.0-SAVED_METADATA.yaml.json @@ -0,0 +1 @@ +{"type":"object","properties":{"app":{"type":"string"},"version":{"type":"string"},"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"ledger":{"type":"string"},"payload":{"type":"object","properties":{"ledger":{"type":"string"},"targetType":{"type":"string"},"targetId":{"type":"string"},"metadata":{"type":"object","additionalProperties":{}}},"required":["ledger","targetType","targetId","metadata"]}},"required":["date","app","version","type","payload"]} \ No newline at end of file diff --git a/libs/events/generated/ledger-v2.0.0-COMMITTED_TRANSACTIONS.yaml.json b/libs/events/generated/ledger-v2.0.0-COMMITTED_TRANSACTIONS.yaml.json new file mode 100644 index 000000000..3e4ff79ef --- /dev/null +++ b/libs/events/generated/ledger-v2.0.0-COMMITTED_TRANSACTIONS.yaml.json @@ -0,0 +1 @@ +{"type":"object","properties":{"app":{"type":"string"},"version":{"type":"string"},"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"ledger":{"type":"string"},"payload":{"type":"object","properties":{"ledger":{"type":"string"},"transactions":{"type":"array","items":{"type":"object","properties":{"postings":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"destination":{"type":"string"},"amount":{"type":"number"},"asset":{"type":"string"}},"required":["source","destination","amount","asset"]}},"reference":{"type":"string"},"metadata":{"type":"object","properties":{},"required":[]},"id":{"type":"number"},"timestamp":{"type":"string"},"reverted":{"type":"boolean"}},"required":["postings","reference","metadata","id","timestamp","reverted"]}}},"required":["ledger","transactions"]}},"required":["date","app","version","type","payload"]} \ No newline at end of file diff --git a/libs/events/generated/ledger-v2.0.0-DELETED_METADATA.yaml.json b/libs/events/generated/ledger-v2.0.0-DELETED_METADATA.yaml.json new file mode 100644 index 000000000..2d8feb330 --- /dev/null +++ b/libs/events/generated/ledger-v2.0.0-DELETED_METADATA.yaml.json @@ -0,0 +1 @@ +{"type":"object","properties":{"app":{"type":"string"},"version":{"type":"string"},"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"ledger":{"type":"string"},"payload":{"type":"object","properties":{"ledger":{"type":"string"},"targetType":{"type":"string"},"targetId":{"type":"string"},"key":{"type":"string"}},"required":["ledger","targetType","targetId","key"]}},"required":["date","app","version","type","payload"]} \ No newline at end of file diff --git a/libs/events/generated/ledger-v2.0.0-REVERTED_TRANSACTION.yaml.json b/libs/events/generated/ledger-v2.0.0-REVERTED_TRANSACTION.yaml.json new file mode 100644 index 000000000..eb551f292 --- /dev/null +++ b/libs/events/generated/ledger-v2.0.0-REVERTED_TRANSACTION.yaml.json @@ -0,0 +1 @@ +{"type":"object","properties":{"app":{"type":"string"},"version":{"type":"string"},"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"ledger":{"type":"string"},"payload":{"type":"object","properties":{"ledger":{"type":"string"},"revertedTransaction":{"type":"object","properties":{"postings":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"destination":{"type":"string"},"amount":{"type":"number"},"asset":{"type":"string"}},"required":["source","destination","amount","asset"]}},"reference":{"type":"string"},"metadata":{"type":"object","properties":{},"required":[]},"id":{"type":"number"},"timestamp":{"type":"string"},"reverted":{"type":"boolean"}},"required":["postings","reference","metadata","id","timestamp","reverted"]},"revertTransaction":{"type":"object","properties":{"postings":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"destination":{"type":"string"},"amount":{"type":"number"},"asset":{"type":"string"}},"required":["source","destination","amount","asset"]}},"reference":{"type":"string"},"metadata":{"type":"object","properties":{},"required":[]},"id":{"type":"number"},"timestamp":{"type":"string"}},"required":["postings","reference","metadata","id","timestamp"]}},"required":["ledger","revertedTransaction","revertTransaction"]}},"required":["date","app","version","type","payload"]} \ No newline at end of file diff --git a/libs/events/generated/ledger-v2.0.0-SAVED_METADATA.yaml.json b/libs/events/generated/ledger-v2.0.0-SAVED_METADATA.yaml.json new file mode 100644 index 000000000..1fa2012b3 --- /dev/null +++ b/libs/events/generated/ledger-v2.0.0-SAVED_METADATA.yaml.json @@ -0,0 +1 @@ +{"type":"object","properties":{"app":{"type":"string"},"version":{"type":"string"},"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"ledger":{"type":"string"},"payload":{"type":"object","properties":{"ledger":{"type":"string"},"targetType":{"type":"string"},"targetId":{"type":"string"},"metadata":{"type":"object","additionalProperties":{}}},"required":["ledger","targetType","targetId","metadata"]}},"required":["date","app","version","type","payload"]} \ No newline at end of file diff --git a/libs/events/generated/payments-v1.0.0-CONNECTOR_RESET.yaml.json b/libs/events/generated/payments-v1.0.0-CONNECTOR_RESET.yaml.json new file mode 100644 index 000000000..ee60cdfea --- /dev/null +++ b/libs/events/generated/payments-v1.0.0-CONNECTOR_RESET.yaml.json @@ -0,0 +1 @@ +{"type":"object","properties":{"app":{"type":"string"},"version":{"type":"string"},"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"ledger":{"type":"string"},"payload":{"type":"object","properties":{"createdAt":{"type":"string"},"connector":{"type":"string"}},"required":["createdAt","connector"]}},"required":["date","app","version","type","payload"]} \ No newline at end of file diff --git a/libs/events/generated/payments-v1.0.0-SAVED_PAYMENT.yaml.json b/libs/events/generated/payments-v1.0.0-SAVED_PAYMENT.yaml.json new file mode 100644 index 000000000..1334ed60a --- /dev/null +++ b/libs/events/generated/payments-v1.0.0-SAVED_PAYMENT.yaml.json @@ -0,0 +1 @@ +{"type":"object","properties":{"app":{"type":"string"},"version":{"type":"string"},"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"ledger":{"type":"string"},"payload":{"type":"object","properties":{"provider":{"type":"string"},"reference":{"type":"string"},"scheme":{"type":"string","enum":["unknown","other","visa","mastercard","amex","diners","discover","jcb","unionpay","sepa debit","sepa credit","sepa","apple pay","google pay","a2a","ach debit","ach","rtp"]},"type":{"type":"string","enum":["PAY-IN","PAYOUT","TRANSFER","OTHER"]},"status":{"type":"string"},"id":{"type":"string"},"initialAmount":{"type":"number"},"createdAt":{"type":"string","format":"date-time"}}}},"required":["date","app","version","type","payload"]} \ No newline at end of file diff --git a/libs/events/index.js b/libs/events/index.js new file mode 100644 index 000000000..79f76b848 --- /dev/null +++ b/libs/events/index.js @@ -0,0 +1,19 @@ +const fs = require("fs/promises"); +const yaml = require('yaml') +const JsonSchemaStaticDocs = require("json-schema-static-docs"); + +(async () => { + + const rawBase = await fs.readFile("./base.yaml", { encoding: 'utf8' }); + const base = yaml.parse(rawBase); + + for(const service of await fs.readdir("services")) { + for(const version of await fs.readdir('services/' + service)) { + for(const event of await fs.readdir('services/' + service + '/' + version)) { + const rawEventData = await fs.readFile('services/' + service + '/' + version + '/' + event, { encoding: 'utf8' }); + base.properties.payload = yaml.parse(rawEventData); + fs.writeFile('generated/' + service + '-' + version + '-' + event + '.json', JSON.stringify(base)); + } + } + } +})(); \ No newline at end of file diff --git a/libs/events/node_modules/.bin/handlebars b/libs/events/node_modules/.bin/handlebars new file mode 120000 index 000000000..fb7d090fc --- /dev/null +++ b/libs/events/node_modules/.bin/handlebars @@ -0,0 +1 @@ +../handlebars/bin/handlebars \ No newline at end of file diff --git a/libs/events/node_modules/.bin/js-yaml b/libs/events/node_modules/.bin/js-yaml new file mode 120000 index 000000000..9dbd010d4 --- /dev/null +++ b/libs/events/node_modules/.bin/js-yaml @@ -0,0 +1 @@ +../js-yaml/bin/js-yaml.js \ No newline at end of file diff --git a/libs/events/node_modules/.bin/json-schema-static-docs b/libs/events/node_modules/.bin/json-schema-static-docs new file mode 120000 index 000000000..9482997f2 --- /dev/null +++ b/libs/events/node_modules/.bin/json-schema-static-docs @@ -0,0 +1 @@ +../json-schema-static-docs/cli.js \ No newline at end of file diff --git a/libs/events/node_modules/.bin/mkdirp b/libs/events/node_modules/.bin/mkdirp new file mode 120000 index 000000000..0fd51939d --- /dev/null +++ b/libs/events/node_modules/.bin/mkdirp @@ -0,0 +1 @@ +../mkdirp/dist/cjs/src/bin.js \ No newline at end of file diff --git a/libs/events/node_modules/.bin/rimraf b/libs/events/node_modules/.bin/rimraf new file mode 120000 index 000000000..3445a8a7b --- /dev/null +++ b/libs/events/node_modules/.bin/rimraf @@ -0,0 +1 @@ +../rimraf/dist/cjs/src/bin.js \ No newline at end of file diff --git a/libs/events/node_modules/.bin/semver b/libs/events/node_modules/.bin/semver new file mode 120000 index 000000000..5aaadf42c --- /dev/null +++ b/libs/events/node_modules/.bin/semver @@ -0,0 +1 @@ +../semver/bin/semver.js \ No newline at end of file diff --git a/libs/events/node_modules/.bin/uglifyjs b/libs/events/node_modules/.bin/uglifyjs new file mode 120000 index 000000000..fef3468b6 --- /dev/null +++ b/libs/events/node_modules/.bin/uglifyjs @@ -0,0 +1 @@ +../uglify-js/bin/uglifyjs \ No newline at end of file diff --git a/libs/events/node_modules/.package-lock.json b/libs/events/node_modules/.package-lock.json new file mode 100644 index 000000000..06ee75244 --- /dev/null +++ b/libs/events/node_modules/.package-lock.json @@ -0,0 +1,609 @@ +{ + "name": "formancehq-events", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-10.1.0.tgz", + "integrity": "sha512-3e+viyMuXdrcK8v5pvP+SDoAQ77FH6OyRmuK48SZKmdHJRFm87RsSs8qm6kP39a/pOPURByJw+OXzQIqcfmKtA==", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.11", + "@types/lodash.clonedeep": "^4.5.7", + "js-yaml": "^4.1.0", + "lodash.clonedeep": "^4.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", + "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==" + }, + "node_modules/@types/lodash": { + "version": "4.14.198", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", + "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==" + }, + "node_modules/@types/lodash.clonedeep": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.7.tgz", + "integrity": "sha512-ccNqkPptFIXrpVqUECi60/DFxjNKsfoQxSQsgcBJCX/fuX1wgyQieojkcWH/KpE3xzLoWN/2k+ZeGqIN3paSvw==", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-static-docs": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/json-schema-static-docs/-/json-schema-static-docs-0.24.1.tgz", + "integrity": "sha512-rNcAuIPkQeqtJy012ycclJlf5AFJeimp2Ui6wwP+xEVndckOW5EfoCtr59cnyfPtF5RuP80gNPvHQ//sVux7Tg==", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^10.1.0", + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "extend": "^3.0.2", + "fast-glob": "^3.3.1", + "handlebars": "^4.7.7", + "jsonpointer": "^5.0.1", + "lodash": ">=4.17.21", + "make-dir": "^3.1.0", + "mkdirp": "^2.1.6", + "optimist": "^0.5.2", + "rimraf": "^4.4.1", + "yaml": "^2.2.2" + }, + "bin": { + "json-schema-static-docs": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/optimist": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.5.2.tgz", + "integrity": "sha512-r9M8ZpnM9SXV5Wii7TCqienfcaY3tAiJe9Jchof87icbmbruKgK0xKXngmrnowTDnEawmmI1Qbha59JEoBkBGA==", + "dependencies": { + "wordwrap": "~0.0.2" + } + }, + "node_modules/optimist/node_modules/wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, + "node_modules/yaml": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", + "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/LICENSE b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/LICENSE new file mode 100644 index 000000000..853473ae9 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 James Messinger + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/README.md b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/README.md new file mode 100644 index 000000000..6a2d23ffe --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/README.md @@ -0,0 +1,166 @@ +# JSON Schema $Ref Parser + +_**This package needs [a new maintainer](https://github.com/APIDevTools/json-schema-ref-parser/issues/285) or at least some contributors. For more information [please read this article](https://phil.tech/2022/bundling-openapi-with-javascript/). As of v10.0.0 I am no longer spending any time working on this tool, so I can focus on scaling up my [reforestation charity](https://protect.earth/) instead of burning myself out trying to maintain a whole load of OSS projects I don't use in my vanishingly small spare time. Get in touch if you'd like to take over.** - [Phil Sturgeon](https://github.com/philsturgeon)_ + +#### Parse, Resolve, and Dereference JSON Schema $ref pointers + +[![Build Status](https://github.com/APIDevTools/json-schema-ref-parser/workflows/CI-CD/badge.svg?branch=master)](https://github.com/APIDevTools/json-schema-ref-parser/actions) +[![Coverage Status](https://coveralls.io/repos/github/APIDevTools/json-schema-ref-parser/badge.svg?branch=master)](https://coveralls.io/github/APIDevTools/json-schema-ref-parser) + +[![npm](https://img.shields.io/npm/v/@apidevtools/json-schema-ref-parser.svg)](https://www.npmjs.com/package/@apidevtools/json-schema-ref-parser) +[![License](https://img.shields.io/npm/l/@apidevtools/json-schema-ref-parser.svg)](LICENSE) +[![Buy us a tree](https://img.shields.io/badge/Treeware-%F0%9F%8C%B3-lightgreen)](https://plant.treeware.earth/APIDevTools/json-schema-ref-parser) + +The Problem: +-------------------------- +You've got a JSON Schema with `$ref` pointers to other files and/or URLs. Maybe you know all the referenced files ahead of time. Maybe you don't. Maybe some are local files, and others are remote URLs. Maybe they are a mix of JSON and YAML format. Maybe some of the files contain cross-references to each other. + +```javascript +{ + "definitions": { + "person": { + // references an external file + "$ref": "schemas/people/Bruce-Wayne.json" + }, + "place": { + // references a sub-schema in an external file + "$ref": "schemas/places.yaml#/definitions/Gotham-City" + }, + "thing": { + // references a URL + "$ref": "http://wayne-enterprises.com/things/batmobile" + }, + "color": { + // references a value in an external file via an internal reference + "$ref": "#/definitions/thing/properties/colors/black-as-the-night" + } + } +} +``` + + +The Solution: +-------------------------- +JSON Schema $Ref Parser is a full [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03) and [JSON Pointer](https://tools.ietf.org/html/rfc6901) implementation that crawls even the most complex [JSON Schemas](http://json-schema.org/latest/json-schema-core.html) and gives you simple, straightforward JavaScript objects. + +- Use **JSON** or **YAML** schemas — or even a mix of both! +- Supports `$ref` pointers to external files and URLs, as well as [custom sources](https://apitools.dev/json-schema-ref-parser/docs/plugins/resolvers.html) such as databases +- Can [bundle](https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#bundlepath-options-callback) multiple files into a single schema that only has _internal_ `$ref` pointers +- Can [dereference](https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#dereferencepath-options-callback) your schema, producing a plain-old JavaScript object that's easy to work with +- Supports [circular references](https://apitools.dev/json-schema-ref-parser/docs/#circular-refs), nested references, back-references, and cross-references between files +- Maintains object reference equality — `$ref` pointers to the same value always resolve to the same object instance +- Tested in Node v10, v12, & v14, and all major web browsers on Windows, Mac, and Linux + + +Example +-------------------------- + +```javascript +$RefParser.dereference(mySchema, (err, schema) => { + if (err) { + console.error(err); + } + else { + // `schema` is just a normal JavaScript object that contains your entire JSON Schema, + // including referenced files, combined into a single object + console.log(schema.definitions.person.properties.firstName); + } +}) +``` + +Or use `async`/`await` syntax instead. The following example is the same as above: + +```javascript +try { + let schema = await $RefParser.dereference(mySchema); + console.log(schema.definitions.person.properties.firstName); +} +catch(err) { + console.error(err); +} +``` + +For more detailed examples, please see the [API Documentation](https://apitools.dev/json-schema-ref-parser/docs/) + + + +Installation +-------------------------- +Install using [npm](https://docs.npmjs.com/about-npm/): + +```bash +npm install @apidevtools/json-schema-ref-parser +``` + + + +Usage +-------------------------- +When using JSON Schema $Ref Parser in Node.js apps, you'll probably want to use **CommonJS** syntax: + +```javascript +const $RefParser = require("@apidevtools/json-schema-ref-parser"); +``` + +When using a transpiler such as [Babel](https://babeljs.io/) or [TypeScript](https://www.typescriptlang.org/), or a bundler such as [Webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/), you can use **ECMAScript modules** syntax instead: + +```javascript +import $RefParser from "@apidevtools/json-schema-ref-parser"; +``` + +If you are using Node.js < 18, you'll need a polyfill for `fetch`, like [node-fetch](https://github.com/node-fetch/node-fetch): +```javascript +import fetch from "node-fetch"; + +globalThis.fetch = fetch; +``` + + + +Browser support +-------------------------- +JSON Schema $Ref Parser supports recent versions of every major web browser. Older browsers may require [Babel](https://babeljs.io/) and/or [polyfills](https://babeljs.io/docs/en/next/babel-polyfill). + +To use JSON Schema $Ref Parser in a browser, you'll need to use a bundling tool such as [Webpack](https://webpack.js.org/), [Rollup](https://rollupjs.org/), [Parcel](https://parceljs.org/), or [Browserify](http://browserify.org/). Some bundlers may require a bit of configuration, such as setting `browser: true` in [rollup-plugin-resolve](https://github.com/rollup/rollup-plugin-node-resolve). + + + +API Documentation +-------------------------- +Full API documentation is available [right here](https://apitools.dev/json-schema-ref-parser/docs/) + + + +Contributing +-------------------------- +I welcome any contributions, enhancements, and bug-fixes. [Open an issue](https://github.com/APIDevTools/json-schema-ref-parser/issues) on GitHub and [submit a pull request](https://github.com/APIDevTools/json-schema-ref-parser/pulls). + +#### Building/Testing +To build/test the project locally on your computer: + +1. __Clone this repo__
+`git clone https://github.com/APIDevTools/json-schema-ref-parser.git` + +2. __Install dependencies__
+`npm install` + +3. __Run the tests__
+`npm test` + + + +License +-------------------------- +JSON Schema $Ref Parser is 100% free and open-source, under the [MIT license](LICENSE). Use it however you want. + +This package is [Treeware](http://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/APIDevTools/json-schema-ref-parser) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats. + + + +Big Thanks To +-------------------------- +Thanks to these awesome companies for their support of Open Source developers ❤ + +[![Stoplight](https://svgshare.com/i/TK5.svg)](https://stoplight.io/?utm_source=github&utm_medium=readme&utm_campaign=json_schema_ref_parser) +[![SauceLabs](https://jstools.dev/img/badges/sauce-labs.svg)](https://saucelabs.com) +[![Coveralls](https://jstools.dev/img/badges/coveralls.svg)](https://coveralls.io) diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/bundle.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/bundle.ts new file mode 100644 index 000000000..9c9ee2b4d --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/bundle.ts @@ -0,0 +1,263 @@ +import $Ref from "./ref.js"; +import Pointer from "./pointer.js"; +import * as url from "./util/url.js"; +import type $RefParserOptions from "./options.js"; +import type $Refs from "./refs.js"; + +export default bundle; + +/** + * Bundles all external JSON references into the main JSON schema, thus resulting in a schema that + * only has *internal* references, not any *external* references. + * This method mutates the JSON schema object, adding new references and re-mapping existing ones. + * + * @param parser + * @param options + */ +function bundle(parser: any, options: any) { + // console.log('Bundling $ref pointers in %s', parser.$refs._root$Ref.path); + + // Build an inventory of all $ref pointers in the JSON Schema + const inventory: any = []; + crawl(parser, "schema", parser.$refs._root$Ref.path + "#", "#", 0, inventory, parser.$refs, options); + + // Remap all $ref pointers + remap(inventory); +} + +/** + * Recursively crawls the given value, and inventories all JSON references. + * + * @param parent - The object containing the value to crawl. If the value is not an object or array, it will be ignored. + * @param key - The property key of `parent` to be crawled + * @param path - The full path of the property being crawled, possibly with a JSON Pointer in the hash + * @param pathFromRoot - The path of the property being crawled, from the schema root + * @param inventory - An array of already-inventoried $ref pointers + * @param $refs + * @param options + */ +function crawl( + parent: any, + key: any, + path: any, + pathFromRoot: any, + indirections: any, + inventory: any, + $refs: any, + options: any, +) { + const obj = key === null ? parent : parent[key]; + + if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj)) { + // @ts-expect-error TS(2554): Expected 2 arguments, but got 1. + if ($Ref.isAllowed$Ref(obj)) { + inventory$Ref(parent, key, path, pathFromRoot, indirections, inventory, $refs, options); + } else { + // Crawl the object in a specific order that's optimized for bundling. + // This is important because it determines how `pathFromRoot` gets built, + // which later determines which keys get dereferenced and which ones get remapped + const keys = Object.keys(obj).sort((a, b) => { + // Most people will expect references to be bundled into the the "definitions" property, + // so we always crawl that property first, if it exists. + if (a === "definitions") { + return -1; + } else if (b === "definitions") { + return 1; + } else { + // Otherwise, crawl the keys based on their length. + // This produces the shortest possible bundled references + return a.length - b.length; + } + }); + + // eslint-disable-next-line no-shadow + for (const key of keys) { + const keyPath = Pointer.join(path, key); + const keyPathFromRoot = Pointer.join(pathFromRoot, key); + const value = obj[key]; + + // @ts-expect-error TS(2554): Expected 2 arguments, but got 1. + if ($Ref.isAllowed$Ref(value)) { + inventory$Ref(obj, key, path, keyPathFromRoot, indirections, inventory, $refs, options); + } else { + crawl(obj, key, keyPath, keyPathFromRoot, indirections, inventory, $refs, options); + } + } + } + } +} + +/** + * Inventories the given JSON Reference (i.e. records detailed information about it so we can + * optimize all $refs in the schema), and then crawls the resolved value. + * + * @param $refParent - The object that contains a JSON Reference as one of its keys + * @param $refKey - The key in `$refParent` that is a JSON Reference + * @param path - The full path of the JSON Reference at `$refKey`, possibly with a JSON Pointer in the hash + * @param pathFromRoot - The path of the JSON Reference at `$refKey`, from the schema root + * @param inventory - An array of already-inventoried $ref pointers + * @param $refs + * @param options + */ +function inventory$Ref( + $refParent: any, + $refKey: any, + path: string, + pathFromRoot: any, + indirections: any, + inventory: any, + $refs: $Refs, + options: $RefParserOptions, +) { + const $ref = $refKey === null ? $refParent : $refParent[$refKey]; + const $refPath = url.resolve(path, $ref.$ref); + const pointer = $refs._resolve($refPath, pathFromRoot, options); + if (pointer === null) { + return; + } + const depth = Pointer.parse(pathFromRoot).length; + const file = url.stripHash(pointer.path); + const hash = url.getHash(pointer.path); + const external = file !== $refs._root$Ref.path; + const extended = $Ref.isExtended$Ref($ref); + indirections += pointer.indirections; + + const existingEntry = findInInventory(inventory, $refParent, $refKey); + if (existingEntry) { + // This $Ref has already been inventoried, so we don't need to process it again + if (depth < existingEntry.depth || indirections < existingEntry.indirections) { + removeFromInventory(inventory, existingEntry); + } else { + return; + } + } + + inventory.push({ + $ref, // The JSON Reference (e.g. {$ref: string}) + parent: $refParent, // The object that contains this $ref pointer + key: $refKey, // The key in `parent` that is the $ref pointer + pathFromRoot, // The path to the $ref pointer, from the JSON Schema root + depth, // How far from the JSON Schema root is this $ref pointer? + file, // The file that the $ref pointer resolves to + hash, // The hash within `file` that the $ref pointer resolves to + value: pointer.value, // The resolved value of the $ref pointer + circular: pointer.circular, // Is this $ref pointer DIRECTLY circular? (i.e. it references itself) + extended, // Does this $ref extend its resolved value? (i.e. it has extra properties, in addition to "$ref") + external, // Does this $ref pointer point to a file other than the main JSON Schema file? + indirections, // The number of indirect references that were traversed to resolve the value + }); + + // Recursively crawl the resolved value + if (!existingEntry || external) { + crawl(pointer.value, null, pointer.path, pathFromRoot, indirections + 1, inventory, $refs, options); + } +} + +/** + * Re-maps every $ref pointer, so that they're all relative to the root of the JSON Schema. + * Each referenced value is dereferenced EXACTLY ONCE. All subsequent references to the same + * value are re-mapped to point to the first reference. + * + * @example: { + * first: { $ref: somefile.json#/some/part }, + * second: { $ref: somefile.json#/another/part }, + * third: { $ref: somefile.json }, + * fourth: { $ref: somefile.json#/some/part/sub/part } + * } + * + * In this example, there are four references to the same file, but since the third reference points + * to the ENTIRE file, that's the only one we need to dereference. The other three can just be + * remapped to point inside the third one. + * + * On the other hand, if the third reference DIDN'T exist, then the first and second would both need + * to be dereferenced, since they point to different parts of the file. The fourth reference does NOT + * need to be dereferenced, because it can be remapped to point inside the first one. + * + * @param inventory + */ +function remap(inventory: any) { + // Group & sort all the $ref pointers, so they're in the order that we need to dereference/remap them + inventory.sort((a: any, b: any) => { + if (a.file !== b.file) { + // Group all the $refs that point to the same file + return a.file < b.file ? -1 : +1; + } else if (a.hash !== b.hash) { + // Group all the $refs that point to the same part of the file + return a.hash < b.hash ? -1 : +1; + } else if (a.circular !== b.circular) { + // If the $ref points to itself, then sort it higher than other $refs that point to this $ref + return a.circular ? -1 : +1; + } else if (a.extended !== b.extended) { + // If the $ref extends the resolved value, then sort it lower than other $refs that don't extend the value + return a.extended ? +1 : -1; + } else if (a.indirections !== b.indirections) { + // Sort direct references higher than indirect references + return a.indirections - b.indirections; + } else if (a.depth !== b.depth) { + // Sort $refs by how close they are to the JSON Schema root + return a.depth - b.depth; + } else { + // Determine how far each $ref is from the "definitions" property. + // Most people will expect references to be bundled into the the "definitions" property if possible. + const aDefinitionsIndex = a.pathFromRoot.lastIndexOf("/definitions"); + const bDefinitionsIndex = b.pathFromRoot.lastIndexOf("/definitions"); + + if (aDefinitionsIndex !== bDefinitionsIndex) { + // Give higher priority to the $ref that's closer to the "definitions" property + return bDefinitionsIndex - aDefinitionsIndex; + } else { + // All else is equal, so use the shorter path, which will produce the shortest possible reference + return a.pathFromRoot.length - b.pathFromRoot.length; + } + } + }); + + let file, hash, pathFromRoot; + for (const entry of inventory) { + // console.log('Re-mapping $ref pointer "%s" at %s', entry.$ref.$ref, entry.pathFromRoot); + + if (!entry.external) { + // This $ref already resolves to the main JSON Schema file + entry.$ref.$ref = entry.hash; + } else if (entry.file === file && entry.hash === hash) { + // This $ref points to the same value as the prevous $ref, so remap it to the same path + entry.$ref.$ref = pathFromRoot; + } else if (entry.file === file && entry.hash.indexOf(hash + "/") === 0) { + // This $ref points to a sub-value of the prevous $ref, so remap it beneath that path + entry.$ref.$ref = Pointer.join(pathFromRoot, Pointer.parse(entry.hash.replace(hash, "#"))); + } else { + // We've moved to a new file or new hash + file = entry.file; + hash = entry.hash; + pathFromRoot = entry.pathFromRoot; + + // This is the first $ref to point to this value, so dereference the value. + // Any other $refs that point to the same value will point to this $ref instead + entry.$ref = entry.parent[entry.key] = $Ref.dereference(entry.$ref, entry.value); + + if (entry.circular) { + // This $ref points to itself + entry.$ref.$ref = entry.pathFromRoot; + } + } + + // console.log(' new value: %s', (entry.$ref && entry.$ref.$ref) ? entry.$ref.$ref : '[object Object]'); + } +} + +/** + * TODO + */ +function findInInventory(inventory: any, $refParent: any, $refKey: any) { + for (let i = 0; i < inventory.length; i++) { + const existingEntry = inventory[i]; + if (existingEntry.parent === $refParent && existingEntry.key === $refKey) { + return existingEntry; + } + } +} + +function removeFromInventory(inventory: any, entry: any) { + const index = inventory.indexOf(entry); + inventory.splice(index, 1); +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/dereference.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/dereference.ts new file mode 100644 index 000000000..f07216ad1 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/dereference.ts @@ -0,0 +1,267 @@ +import $Ref from "./ref.js"; +import Pointer from "./pointer.js"; +import { ono } from "@jsdevtools/ono"; +import * as url from "./util/url.js"; +import type $Refs from "./refs.js"; +import type $RefParserOptions from "./options.js"; + +export default dereference; + +/** + * Crawls the JSON schema, finds all JSON references, and dereferences them. + * This method mutates the JSON schema object, replacing JSON references with their resolved value. + * + * @param parser + * @param options + */ +function dereference(parser: any, options: any) { + // console.log('Dereferencing $ref pointers in %s', parser.$refs._root$Ref.path); + const dereferenced = crawl( + parser.schema, + parser.$refs._root$Ref.path, + "#", + new Set(), + new Set(), + new Map(), + parser.$refs, + options, + ); + parser.$refs.circular = dereferenced.circular; + parser.schema = dereferenced.value; +} + +/** + * Recursively crawls the given value, and dereferences any JSON references. + * + * @param obj - The value to crawl. If it's not an object or array, it will be ignored. + * @param path - The full path of `obj`, possibly with a JSON Pointer in the hash + * @param pathFromRoot - The path of `obj` from the schema root + * @param parents - An array of the parent objects that have already been dereferenced + * @param processedObjects - An array of all the objects that have already been processed + * @param dereferencedCache - An map of all the dereferenced objects + * @param $refs + * @param options + * @returns + */ +function crawl( + obj: any, + path: string, + pathFromRoot: string, + parents: Set, + processedObjects: Set, + dereferencedCache: any, + $refs: $Refs, + options: $RefParserOptions, +) { + let dereferenced; + const result = { + value: obj, + circular: false, + }; + + const isExcludedPath = options.dereference.excludedPathMatcher || (() => false); + + if (options.dereference.circular === "ignore" || !processedObjects.has(obj)) { + if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj) && !isExcludedPath(pathFromRoot)) { + parents.add(obj); + processedObjects.add(obj); + + if ($Ref.isAllowed$Ref(obj, options)) { + dereferenced = dereference$Ref( + obj, + path, + pathFromRoot, + parents, + processedObjects, + dereferencedCache, + $refs, + options, + ); + result.circular = dereferenced.circular; + result.value = dereferenced.value; + } else { + for (const key of Object.keys(obj)) { + const keyPath = Pointer.join(path, key); + const keyPathFromRoot = Pointer.join(pathFromRoot, key); + + if (isExcludedPath(keyPathFromRoot)) { + continue; + } + + const value = obj[key]; + let circular = false; + + if ($Ref.isAllowed$Ref(value, options)) { + dereferenced = dereference$Ref( + value, + keyPath, + keyPathFromRoot, + parents, + processedObjects, + dereferencedCache, + $refs, + options, + ); + circular = dereferenced.circular; + // Avoid pointless mutations; breaks frozen objects to no profit + if (obj[key] !== dereferenced.value) { + obj[key] = dereferenced.value; + if (options.dereference.onDereference) { + options.dereference.onDereference(value.$ref, obj[key]); + } + } + } else { + if (!parents.has(value)) { + dereferenced = crawl( + value, + keyPath, + keyPathFromRoot, + parents, + processedObjects, + dereferencedCache, + $refs, + options, + ); + circular = dereferenced.circular; + // Avoid pointless mutations; breaks frozen objects to no profit + if (obj[key] !== dereferenced.value) { + obj[key] = dereferenced.value; + } + } else { + circular = foundCircularReference(keyPath, $refs, options); + } + } + + // Set the "isCircular" flag if this or any other property is circular + result.circular = result.circular || circular; + } + } + + parents.delete(obj); + } + } + + return result; +} + +/** + * Dereferences the given JSON Reference, and then crawls the resulting value. + * + * @param $ref - The JSON Reference to resolve + * @param path - The full path of `$ref`, possibly with a JSON Pointer in the hash + * @param pathFromRoot - The path of `$ref` from the schema root + * @param parents - An array of the parent objects that have already been dereferenced + * @param processedObjects - An array of all the objects that have already been dereferenced + * @param dereferencedCache - An map of all the dereferenced objects + * @param $refs + * @param options + * @returns + */ +function dereference$Ref( + $ref: any, + path: any, + pathFromRoot: any, + parents: any, + processedObjects: any, + dereferencedCache: any, + $refs: any, + options: any, +) { + // console.log('Dereferencing $ref pointer "%s" at %s', $ref.$ref, path); + + const $refPath = url.resolve(path, $ref.$ref); + + const cache = dereferencedCache.get($refPath); + if (cache) { + const refKeys = Object.keys($ref); + if (refKeys.length > 1) { + const extraKeys = {}; + for (const key of refKeys) { + if (key !== "$ref" && !(key in cache.value)) { + // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message + extraKeys[key] = $ref[key]; + } + } + return { + circular: cache.circular, + value: Object.assign({}, cache.value, extraKeys), + }; + } + + return cache; + } + + const pointer = $refs._resolve($refPath, path, options); + + if (pointer === null) { + return { + circular: false, + value: null, + }; + } + + // Check for circular references + const directCircular = pointer.circular; + let circular = directCircular || parents.has(pointer.value); + circular && foundCircularReference(path, $refs, options); + + // Dereference the JSON reference + let dereferencedValue = $Ref.dereference($ref, pointer.value); + + // Crawl the dereferenced value (unless it's circular) + if (!circular) { + // Determine if the dereferenced value is circular + const dereferenced = crawl( + dereferencedValue, + pointer.path, + pathFromRoot, + parents, + processedObjects, + dereferencedCache, + $refs, + options, + ); + circular = dereferenced.circular; + dereferencedValue = dereferenced.value; + } + + if (circular && !directCircular && options.dereference.circular === "ignore") { + // The user has chosen to "ignore" circular references, so don't change the value + dereferencedValue = $ref; + } + + if (directCircular) { + // The pointer is a DIRECT circular reference (i.e. it references itself). + // So replace the $ref path with the absolute path from the JSON Schema root + dereferencedValue.$ref = pathFromRoot; + } + + const dereferencedObject = { + circular, + value: dereferencedValue, + }; + + // only cache if no extra properties than $ref + if (Object.keys($ref).length === 1) { + dereferencedCache.set($refPath, dereferencedObject); + } + + return dereferencedObject; +} + +/** + * Called when a circular reference is found. + * It sets the {@link $Refs#circular} flag, and throws an error if options.dereference.circular is false. + * + * @param keyPath - The JSON Reference path of the circular reference + * @param $refs + * @param options + * @returns - always returns true, to indicate that a circular reference was found + */ +function foundCircularReference(keyPath: any, $refs: any, options: any) { + $refs.circular = true; + if (!options.dereference.circular) { + throw ono.reference(`Circular $ref pointer found at ${keyPath}`); + } + return true; +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/index.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/index.ts new file mode 100644 index 000000000..ae770b1d6 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/index.ts @@ -0,0 +1,413 @@ +import $Refs from "./refs.js"; +import _parse from "./parse.js"; +import normalizeArgs from "./normalize-args.js"; +import resolveExternal from "./resolve-external.js"; +import _bundle from "./bundle.js"; +import _dereference from "./dereference.js"; +import * as url from "./util/url.js"; +import { + JSONParserError, + InvalidPointerError, + MissingPointerError, + ResolverError, + ParserError, + UnmatchedParserError, + UnmatchedResolverError, + isHandledError, + JSONParserErrorGroup, +} from "./util/errors.js"; +import { ono } from "@jsdevtools/ono"; +import maybe from "./util/maybe.js"; +import type { ParserOptions } from "./options.js"; +import type { $RefsCallback, JSONSchema, SchemaCallback } from "./types/index.js"; + +export { JSONParserError }; +export { InvalidPointerError }; +export { MissingPointerError }; +export { ResolverError }; +export { ParserError }; +export { UnmatchedParserError }; +export { UnmatchedResolverError }; + +type RefParserSchema = string | JSONSchema; + +/** + * This class parses a JSON schema, builds a map of its JSON references and their resolved values, + * and provides methods for traversing, manipulating, and dereferencing those references. + * + * @class + */ +export class $RefParser { + /** + * The parsed (and possibly dereferenced) JSON schema object + * + * @type {object} + * @readonly + */ + public schema: JSONSchema | null = null; + + /** + * The resolved JSON references + * + * @type {$Refs} + * @readonly + */ + $refs = new $Refs(); + + /** + * Parses the given JSON schema. + * This method does not resolve any JSON references. + * It just reads a single file in JSON or YAML format, and parse it as a JavaScript object. + * + * @param [path] - The file path or URL of the JSON schema + * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`. + * @param [options] - Options that determine how the schema is parsed + * @param [callback] - An error-first callback. The second parameter is the parsed JSON schema object. + * @returns - The returned promise resolves with the parsed JSON schema object. + */ + public parse(schema: RefParserSchema): Promise; + public parse(schema: RefParserSchema, callback: SchemaCallback): Promise; + public parse(schema: RefParserSchema, options: ParserOptions): Promise; + public parse(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise; + public parse(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise; + public parse( + baseUrl: string, + schema: RefParserSchema, + options: ParserOptions, + callback: SchemaCallback, + ): Promise; + + async parse() { + const args = normalizeArgs(arguments as any); + let promise; + + if (!args.path && !args.schema) { + const err = ono(`Expected a file path, URL, or object. Got ${args.path || args.schema}`); + return maybe(args.callback, Promise.reject(err)); + } + + // Reset everything + this.schema = null; + this.$refs = new $Refs(); + + // If the path is a filesystem path, then convert it to a URL. + // NOTE: According to the JSON Reference spec, these should already be URLs, + // but, in practice, many people use local filesystem paths instead. + // So we're being generous here and doing the conversion automatically. + // This is not intended to be a 100% bulletproof solution. + // If it doesn't work for your use-case, then use a URL instead. + let pathType = "http"; + if (url.isFileSystemPath(args.path)) { + args.path = url.fromFileSystemPath(args.path); + pathType = "file"; + } + + // Resolve the absolute path of the schema + args.path = url.resolve(url.cwd(), args.path); + + if (args.schema && typeof args.schema === "object") { + // A schema object was passed-in. + // So immediately add a new $Ref with the schema object as its value + const $ref = this.$refs._add(args.path); + $ref.value = args.schema; + $ref.pathType = pathType; + promise = Promise.resolve(args.schema); + } else { + // Parse the schema file/url + promise = _parse(args.path, this.$refs, args.options); + } + + try { + const result = await promise; + + if (result !== null && typeof result === "object" && !Buffer.isBuffer(result)) { + this.schema = result; + return maybe(args.callback, Promise.resolve(this.schema!)); + } else if (args.options.continueOnError) { + this.schema = null; // it's already set to null at line 79, but let's set it again for the sake of readability + return maybe(args.callback, Promise.resolve(this.schema!)); + } else { + throw ono.syntax(`"${this.$refs._root$Ref.path || result}" is not a valid JSON Schema`); + } + } catch (err) { + if (!args.options.continueOnError || !isHandledError(err)) { + return maybe(args.callback, Promise.reject(err)); + } + + if (this.$refs._$refs[url.stripHash(args.path)]) { + this.$refs._$refs[url.stripHash(args.path)].addError(err); + } + + return maybe(args.callback, Promise.resolve(null)); + } + } + + public static parse(schema: RefParserSchema): Promise; + public static parse(schema: RefParserSchema, callback: SchemaCallback): Promise; + public static parse(schema: RefParserSchema, options: ParserOptions): Promise; + public static parse(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise; + public static parse(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise; + public static parse( + baseUrl: string, + schema: RefParserSchema, + options: ParserOptions, + callback: SchemaCallback, + ): Promise; + public static parse(): Promise | Promise { + const parser = new $RefParser(); + return parser.parse.apply(parser, arguments as any); + } + + /** + * *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.* + * + * Resolves all JSON references (`$ref` pointers) in the given JSON Schema file. If it references any other files/URLs, then they will be downloaded and resolved as well. This method **does not** dereference anything. It simply gives you a `$Refs` object, which is a map of all the resolved references and their values. + * + * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#resolveschema-options-callback + * + * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info. + * @param options (optional) + * @param callback (optional) A callback that will receive a `$Refs` object + */ + public resolve(schema: RefParserSchema): Promise<$Refs>; + public resolve(schema: RefParserSchema, callback: $RefsCallback): Promise; + public resolve(schema: RefParserSchema, options: ParserOptions): Promise<$Refs>; + public resolve(schema: RefParserSchema, options: ParserOptions, callback: $RefsCallback): Promise; + public resolve(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<$Refs>; + public resolve( + baseUrl: string, + schema: RefParserSchema, + options: ParserOptions, + callback: $RefsCallback, + ): Promise; + /** + * Parses the given JSON schema and resolves any JSON references, including references in + * externally-referenced files. + * + * @param [path] - The file path or URL of the JSON schema + * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`. + * @param [options] - Options that determine how the schema is parsed and resolved + * @param [callback] + * - An error-first callback. The second parameter is a {@link $Refs} object containing the resolved JSON references + * + * @returns + * The returned promise resolves with a {@link $Refs} object containing the resolved JSON references + */ + async resolve() { + const args = normalizeArgs(arguments); + + try { + await this.parse(args.path, args.schema, args.options); + await resolveExternal(this, args.options); + finalize(this); + return maybe(args.callback, Promise.resolve(this.$refs)); + } catch (err) { + return maybe(args.callback, Promise.reject(err)); + } + } + + /** + * *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.* + * + * Resolves all JSON references (`$ref` pointers) in the given JSON Schema file. If it references any other files/URLs, then they will be downloaded and resolved as well. This method **does not** dereference anything. It simply gives you a `$Refs` object, which is a map of all the resolved references and their values. + * + * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#resolveschema-options-callback + * + * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info. + * @param options (optional) + * @param callback (optional) A callback that will receive a `$Refs` object + */ + public static resolve(schema: RefParserSchema): Promise<$Refs>; + public static resolve(schema: RefParserSchema, callback: $RefsCallback): Promise; + public static resolve(schema: RefParserSchema, options: ParserOptions): Promise<$Refs>; + public static resolve(schema: RefParserSchema, options: ParserOptions, callback: $RefsCallback): Promise; + public static resolve(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<$Refs>; + public static resolve( + baseUrl: string, + schema: RefParserSchema, + options: ParserOptions, + callback: $RefsCallback, + ): Promise; + static resolve(): Promise | Promise { + const instance = new $RefParser(); + return instance.resolve.apply(instance, arguments as any); + } + + /** + * Parses the given JSON schema, resolves any JSON references, and bundles all external references + * into the main JSON schema. This produces a JSON schema that only has *internal* references, + * not any *external* references. + * + * @param [path] - The file path or URL of the JSON schema + * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`. + * @param [options] - Options that determine how the schema is parsed, resolved, and dereferenced + * @param [callback] - An error-first callback. The second parameter is the bundled JSON schema object + * @returns - The returned promise resolves with the bundled JSON schema object. + */ + /** + * Bundles all referenced files/URLs into a single schema that only has internal `$ref` pointers. This lets you split-up your schema however you want while you're building it, but easily combine all those files together when it's time to package or distribute the schema to other people. The resulting schema size will be small, since it will still contain internal JSON references rather than being fully-dereferenced. + * + * This also eliminates the risk of circular references, so the schema can be safely serialized using `JSON.stringify()`. + * + * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#bundleschema-options-callback + * + * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info. + * @param options (optional) + * @param callback (optional) A callback that will receive the bundled schema object + */ + public static bundle(schema: RefParserSchema): Promise; + public static bundle(schema: RefParserSchema, callback: SchemaCallback): Promise; + public static bundle(schema: RefParserSchema, options: ParserOptions): Promise; + public static bundle(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise; + public static bundle(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise; + public static bundle( + baseUrl: string, + schema: RefParserSchema, + options: ParserOptions, + callback: SchemaCallback, + ): Promise; + static bundle(): Promise | Promise { + const instance = new $RefParser(); + return instance.bundle.apply(instance, arguments as any); + } + + /** + * Parses the given JSON schema, resolves any JSON references, and bundles all external references + * into the main JSON schema. This produces a JSON schema that only has *internal* references, + * not any *external* references. + * + * @param [path] - The file path or URL of the JSON schema + * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`. + * @param [options] - Options that determine how the schema is parsed, resolved, and dereferenced + * @param [callback] - An error-first callback. The second parameter is the bundled JSON schema object + * @returns - The returned promise resolves with the bundled JSON schema object. + */ + /** + * Bundles all referenced files/URLs into a single schema that only has internal `$ref` pointers. This lets you split-up your schema however you want while you're building it, but easily combine all those files together when it's time to package or distribute the schema to other people. The resulting schema size will be small, since it will still contain internal JSON references rather than being fully-dereferenced. + * + * This also eliminates the risk of circular references, so the schema can be safely serialized using `JSON.stringify()`. + * + * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#bundleschema-options-callback + * + * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info. + * @param options (optional) + * @param callback (optional) A callback that will receive the bundled schema object + */ + public bundle(schema: RefParserSchema): Promise; + public bundle(schema: RefParserSchema, callback: SchemaCallback): Promise; + public bundle(schema: RefParserSchema, options: ParserOptions): Promise; + public bundle(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise; + public bundle(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise; + public bundle( + baseUrl: string, + schema: RefParserSchema, + options: ParserOptions, + callback: SchemaCallback, + ): Promise; + async bundle() { + const args = normalizeArgs(arguments); + try { + await this.resolve(args.path, args.schema, args.options); + _bundle(this, args.options); + finalize(this); + return maybe(args.callback, Promise.resolve(this.schema!)); + } catch (err) { + return maybe(args.callback, Promise.reject(err)); + } + } + + /** + * Parses the given JSON schema, resolves any JSON references, and dereferences the JSON schema. + * That is, all JSON references are replaced with their resolved values. + * + * @param [path] - The file path or URL of the JSON schema + * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`. + * @param [options] - Options that determine how the schema is parsed, resolved, and dereferenced + * @param [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object + * @returns - The returned promise resolves with the dereferenced JSON schema object. + */ + /** + * Dereferences all `$ref` pointers in the JSON Schema, replacing each reference with its resolved value. This results in a schema object that does not contain any `$ref` pointers. Instead, it's a normal JavaScript object tree that can easily be crawled and used just like any other JavaScript object. This is great for programmatic usage, especially when using tools that don't understand JSON references. + * + * The dereference method maintains object reference equality, meaning that all `$ref` pointers that point to the same object will be replaced with references to the same object. Again, this is great for programmatic usage, but it does introduce the risk of circular references, so be careful if you intend to serialize the schema using `JSON.stringify()`. Consider using the bundle method instead, which does not create circular references. + * + * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#dereferenceschema-options-callback + * + * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info. + * @param options (optional) + * @param callback (optional) A callback that will receive the dereferenced schema object + */ + public static dereference(schema: RefParserSchema): Promise; + public static dereference(schema: RefParserSchema, callback: SchemaCallback): Promise; + public static dereference(schema: RefParserSchema, options: ParserOptions): Promise; + public static dereference(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise; + public static dereference(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise; + public static dereference( + baseUrl: string, + schema: RefParserSchema, + options: ParserOptions, + callback: SchemaCallback, + ): Promise; + static dereference(): Promise | Promise { + const instance = new $RefParser(); + return instance.dereference.apply(instance, arguments as any); + } + + /** + * Parses the given JSON schema, resolves any JSON references, and dereferences the JSON schema. + * That is, all JSON references are replaced with their resolved values. + * + * @param [path] - The file path or URL of the JSON schema + * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`. + * @param [options] - Options that determine how the schema is parsed, resolved, and dereferenced + * @param [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object + * @returns - The returned promise resolves with the dereferenced JSON schema object. + */ + /** + * Dereferences all `$ref` pointers in the JSON Schema, replacing each reference with its resolved value. This results in a schema object that does not contain any `$ref` pointers. Instead, it's a normal JavaScript object tree that can easily be crawled and used just like any other JavaScript object. This is great for programmatic usage, especially when using tools that don't understand JSON references. + * + * The dereference method maintains object reference equality, meaning that all `$ref` pointers that point to the same object will be replaced with references to the same object. Again, this is great for programmatic usage, but it does introduce the risk of circular references, so be careful if you intend to serialize the schema using `JSON.stringify()`. Consider using the bundle method instead, which does not create circular references. + * + * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#dereferenceschema-options-callback + * + * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info. + * @param options (optional) + * @param callback (optional) A callback that will receive the dereferenced schema object + */ + public dereference( + baseUrl: string, + schema: RefParserSchema, + options: ParserOptions, + callback: SchemaCallback, + ): Promise; + public dereference(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise; + public dereference(schema: RefParserSchema, callback: SchemaCallback): Promise; + public dereference(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise; + public dereference(schema: RefParserSchema, options: ParserOptions): Promise; + public dereference(schema: RefParserSchema): Promise; + async dereference() { + const args = normalizeArgs(arguments); + + try { + await this.resolve(args.path, args.schema, args.options); + _dereference(this, args.options); + finalize(this); + return maybe(args.callback, Promise.resolve(this.schema)); + } catch (err) { + return maybe(args.callback, Promise.reject(err)); + } + } +} +export default $RefParser; + +function finalize(parser: any) { + const errors = JSONParserErrorGroup.getParserErrors(parser); + if (errors.length > 0) { + throw new JSONParserErrorGroup(parser); + } +} + +export const parse = $RefParser.parse; +export const resolve = $RefParser.resolve; +export const bundle = $RefParser.bundle; +export const dereference = $RefParser.dereference; diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/normalize-args.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/normalize-args.ts new file mode 100644 index 000000000..d72e5550a --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/normalize-args.ts @@ -0,0 +1,44 @@ +import { getNewOptions } from "./options.js"; + +export default normalizeArgs; + +/** + * Normalizes the given arguments, accounting for optional args. + */ +function normalizeArgs(_args: Partial) { + let path, schema, options, callback; + const args = Array.prototype.slice.call(_args) as any[]; + + if (typeof args[args.length - 1] === "function") { + // The last parameter is a callback function + callback = args.pop(); + } + + if (typeof args[0] === "string") { + // The first parameter is the path + path = args[0]; + if (typeof args[2] === "object") { + // The second parameter is the schema, and the third parameter is the options + schema = args[1]; + options = args[2]; + } else { + // The second parameter is the options + schema = undefined; + options = args[1]; + } + } else { + // The first parameter is the schema + path = ""; + schema = args[0]; + options = args[1]; + } + + options = getNewOptions(options); + + return { + path, + schema, + options, + callback, + }; +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/options.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/options.ts new file mode 100644 index 000000000..62afe6bf2 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/options.ts @@ -0,0 +1,202 @@ +import jsonParser from "./parsers/json.js"; +import yamlParser from "./parsers/yaml.js"; +import textParser from "./parsers/text.js"; +import binaryParser from "./parsers/binary.js"; +import fileResolver from "./resolvers/file.js"; +import httpResolver from "./resolvers/http.js"; +import cloneDeep from "lodash.clonedeep"; + +import type { HTTPResolverOptions, JSONSchemaObject, Plugin, ResolverOptions } from "./types/index.js"; + +type DeepPartial = T extends object + ? { + [P in keyof T]?: DeepPartial; + } + : T; +/** + * Options that determine how JSON schemas are parsed, resolved, and dereferenced. + * + * @param [options] - Overridden options + * @class + */ +interface $RefParserOptions { + /** + * The `parse` options determine how different types of files will be parsed. + * + * JSON Schema `$Ref` Parser comes with built-in JSON, YAML, plain-text, and binary parsers, any of which you can configure or disable. You can also add your own custom parsers if you want. + */ + parse: { + json?: Plugin | boolean; + yaml?: Plugin | boolean; + binary?: Plugin | boolean; + text?: (Plugin & { encoding?: string }) | boolean; + [key: string]: Plugin | boolean | undefined; + }; + + /** + * The `resolve` options control how JSON Schema $Ref Parser will resolve file paths and URLs, and how those files will be read/downloaded. + * + * JSON Schema `$Ref` Parser comes with built-in support for HTTP and HTTPS, as well as support for local files (when running in Node.js). You can configure or disable either of these built-in resolvers. You can also add your own custom resolvers if you want. + */ + resolve: { + /** + * Determines whether external $ref pointers will be resolved. If this option is disabled, then external `$ref` pointers will simply be ignored. + */ + external?: boolean; + file?: Partial | boolean; + http?: HTTPResolverOptions | boolean; + } & { + [key: string]: Partial | HTTPResolverOptions | boolean | undefined; + }; + + /** + * By default, JSON Schema $Ref Parser throws the first error it encounters. Setting `continueOnError` to `true` + * causes it to keep processing as much as possible and then throw a single error that contains all errors + * that were encountered. + */ + continueOnError: boolean; + + /** + * The `dereference` options control how JSON Schema `$Ref` Parser will dereference `$ref` pointers within the JSON schema. + */ + dereference: { + /** + * Determines whether circular `$ref` pointers are handled. + * + * If set to `false`, then a `ReferenceError` will be thrown if the schema contains any circular references. + * + * If set to `"ignore"`, then circular references will simply be ignored. No error will be thrown, but the `$Refs.circular` property will still be set to `true`. + */ + circular?: boolean | "ignore"; + + /** + * A function, called for each path, which can return true to stop this path and all + * subpaths from being dereferenced further. This is useful in schemas where some + * subpaths contain literal $ref keys that should not be dereferenced. + */ + excludedPathMatcher?(path: string): boolean; + + /** + * Callback invoked during dereferencing. + * + * @argument {string} path The path being dereferenced (ie. the `$ref` string). + * @argument {JSONSchemaObject} object The JSON-Schema that the `$ref` resolved to. + */ + onDereference?(path: string, value: JSONSchemaObject): void; + }; +} + +const getDefaults = () => { + const defaults = { + /** + * Determines how different types of files will be parsed. + * + * You can add additional parsers of your own, replace an existing one with + * your own implementation, or disable any parser by setting it to false. + */ + parse: { + json: jsonParser, + yaml: yamlParser, + text: textParser, + binary: binaryParser, + }, + + /** + * Determines how JSON References will be resolved. + * + * You can add additional resolvers of your own, replace an existing one with + * your own implementation, or disable any resolver by setting it to false. + */ + resolve: { + file: fileResolver, + http: httpResolver, + + /** + * Determines whether external $ref pointers will be resolved. + * If this option is disabled, then none of above resolvers will be called. + * Instead, external $ref pointers will simply be ignored. + * + * @type {boolean} + */ + external: true, + }, + + /** + * By default, JSON Schema $Ref Parser throws the first error it encounters. Setting `continueOnError` to `true` + * causes it to keep processing as much as possible and then throw a single error that contains all errors + * that were encountered. + */ + continueOnError: false, + + /** + * Determines the types of JSON references that are allowed. + */ + dereference: { + /** + * Dereference circular (recursive) JSON references? + * If false, then a {@link ReferenceError} will be thrown if a circular reference is found. + * If "ignore", then circular references will not be dereferenced. + * + * @type {boolean|string} + */ + circular: true, + + /** + * A function, called for each path, which can return true to stop this path and all + * subpaths from being dereferenced further. This is useful in schemas where some + * subpaths contain literal $ref keys that should not be dereferenced. + * + * @type {function} + */ + excludedPathMatcher: () => false, + }, + }; + return cloneDeep(defaults); +}; + +export const getNewOptions = (options: DeepPartial<$RefParserOptions>): $RefParserOptions => { + const newOptions = getDefaults(); + if (options) { + merge(newOptions, options); + } + return newOptions; +}; +export type Options = $RefParserOptions; +export type ParserOptions = DeepPartial<$RefParserOptions>; +/** + * Merges the properties of the source object into the target object. + * + * @param target - The object that we're populating + * @param source - The options that are being merged + * @returns + */ +function merge(target: any, source: any) { + if (isMergeable(source)) { + const keys = Object.keys(source); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const sourceSetting = source[key]; + const targetSetting = target[key]; + + if (isMergeable(sourceSetting)) { + // It's a nested object, so merge it recursively + target[key] = merge(targetSetting || {}, sourceSetting); + } else if (sourceSetting !== undefined) { + // It's a scalar value, function, or array. No merging necessary. Just overwrite the target value. + target[key] = sourceSetting; + } + } + } + return target; +} +/** + * Determines whether the given value can be merged, + * or if it is a scalar value that should just override the target value. + * + * @param val + * @returns + */ +function isMergeable(val: any) { + return val && typeof val === "object" && !Array.isArray(val) && !(val instanceof RegExp) && !(val instanceof Date); +} +export default $RefParserOptions; diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parse.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parse.ts new file mode 100644 index 000000000..2f8142171 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parse.ts @@ -0,0 +1,153 @@ +import { ono } from "@jsdevtools/ono"; +import * as url from "./util/url.js"; +import * as plugins from "./util/plugins.js"; +import { + ResolverError, + ParserError, + UnmatchedParserError, + UnmatchedResolverError, + isHandledError, +} from "./util/errors.js"; +import type $Refs from "./refs.js"; +import type { Options } from "./options.js"; +import type { FileInfo } from "./types/index.js"; + +export default parse; + +/** + * Reads and parses the specified file path or URL. + */ +async function parse(path: string, $refs: $Refs, options: Options) { + // Remove the URL fragment, if any + path = url.stripHash(path); + + // Add a new $Ref for this file, even though we don't have the value yet. + // This ensures that we don't simultaneously read & parse the same file multiple times + const $ref = $refs._add(path); + + // This "file object" will be passed to all resolvers and parsers. + const file = { + url: path, + extension: url.getExtension(path), + } as FileInfo; + + // Read the file and then parse the data + try { + const resolver = await readFile(file, options, $refs); + $ref.pathType = resolver.plugin.name; + file.data = resolver.result; + + const parser = await parseFile(file, options, $refs); + $ref.value = parser.result; + + return parser.result; + } catch (err) { + if (isHandledError(err)) { + $ref.value = err; + } + + throw err; + } +} + +/** + * Reads the given file, using the configured resolver plugins + * + * @param file - An object containing information about the referenced file + * @param file.url - The full URL of the referenced file + * @param file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.) + * @param options + * + * @returns + * The promise resolves with the raw file contents and the resolver that was used. + */ +async function readFile(file: FileInfo, options: Options, $refs: $Refs): Promise { + // console.log('Reading %s', file.url); + + // Find the resolvers that can read this file + let resolvers = plugins.all(options.resolve); + resolvers = plugins.filter(resolvers, "canRead", file); + + // Run the resolvers, in order, until one of them succeeds + plugins.sort(resolvers); + try { + const data = await plugins.run(resolvers, "read", file, $refs); + return data; + } catch (err: any) { + if (!err && options.continueOnError) { + // No resolver could be matched + throw new UnmatchedResolverError(file.url); + } else if (!err || !("error" in err)) { + // Throw a generic, friendly error. + throw ono.syntax(`Unable to resolve $ref pointer "${file.url}"`); + } + // Throw the original error, if it's one of our own (user-friendly) errors. + else if (err.error instanceof ResolverError) { + throw err.error; + } else { + throw new ResolverError(err, file.url); + } + } +} + +/** + * Parses the given file's contents, using the configured parser plugins. + * + * @param file - An object containing information about the referenced file + * @param file.url - The full URL of the referenced file + * @param file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.) + * @param file.data - The file contents. This will be whatever data type was returned by the resolver + * @param options + * + * @returns + * The promise resolves with the parsed file contents and the parser that was used. + */ +async function parseFile(file: FileInfo, options: Options, $refs: $Refs) { + // console.log('Parsing %s', file.url); + + // Find the parsers that can read this file type. + // If none of the parsers are an exact match for this file, then we'll try ALL of them. + // This handles situations where the file IS a supported type, just with an unknown extension. + const allParsers = plugins.all(options.parse); + const filteredParsers = plugins.filter(allParsers, "canParse", file); + const parsers = filteredParsers.length > 0 ? filteredParsers : allParsers; + + // Run the parsers, in order, until one of them succeeds + plugins.sort(parsers); + try { + const parser = await plugins.run(parsers, "parse", file, $refs); + if (!parser.plugin.allowEmpty && isEmpty(parser.result)) { + throw ono.syntax(`Error parsing "${file.url}" as ${parser.plugin.name}. \nParsed value is empty`); + } else { + return parser; + } + } catch (err: any) { + if (!err && options.continueOnError) { + // No resolver could be matched + throw new UnmatchedParserError(file.url); + } else if (err && err.message && err.message.startsWith("Error parsing")) { + throw err; + } else if (!err || !("error" in err)) { + throw ono.syntax(`Unable to parse ${file.url}`); + } else if (err.error instanceof ParserError) { + throw err.error; + } else { + throw new ParserError(err.error.message, file.url); + } + } +} + +/** + * Determines whether the parsed value is "empty". + * + * @param value + * @returns + */ +function isEmpty(value: any) { + return ( + value === undefined || + (typeof value === "object" && Object.keys(value).length === 0) || + (typeof value === "string" && value.trim().length === 0) || + (Buffer.isBuffer(value) && value.length === 0) + ); +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/binary.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/binary.ts new file mode 100644 index 000000000..1dc8a4f9d --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/binary.ts @@ -0,0 +1,39 @@ +import type { FileInfo } from "../types/index.js"; +import type { Plugin } from "../types/index.js"; + +const BINARY_REGEXP = /\.(jpeg|jpg|gif|png|bmp|ico)$/i; + +export default { + /** + * The order that this parser will run, in relation to other parsers. + */ + order: 400, + + /** + * Whether to allow "empty" files (zero bytes). + */ + allowEmpty: true, + + /** + * Determines whether this parser can parse a given file reference. + * Parsers that return true will be tried, in order, until one successfully parses the file. + * Parsers that return false will be skipped, UNLESS all parsers returned false, in which case + * every parser will be tried. + */ + canParse(file: FileInfo) { + // Use this parser if the file is a Buffer, and has a known binary extension + return Buffer.isBuffer(file.data) && BINARY_REGEXP.test(file.url); + }, + + /** + * Parses the given data as a Buffer (byte array). + */ + parse(file: FileInfo) { + if (Buffer.isBuffer(file.data)) { + return file.data; + } else { + // This will reject if data is anything other than a string or typed array + return Buffer.from(file.data); + } + }, +} as Plugin; diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/json.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/json.ts new file mode 100644 index 000000000..aadfd200e --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/json.ts @@ -0,0 +1,48 @@ +import { ParserError } from "../util/errors.js"; +import type { FileInfo } from "../types/index.js"; +import type { Plugin } from "../types/index.js"; + +export default { + /** + * The order that this parser will run, in relation to other parsers. + */ + order: 100, + + /** + * Whether to allow "empty" files. This includes zero-byte files, as well as empty JSON objects. + */ + allowEmpty: true, + + /** + * Determines whether this parser can parse a given file reference. + * Parsers that match will be tried, in order, until one successfully parses the file. + * Parsers that don't match will be skipped, UNLESS none of the parsers match, in which case + * every parser will be tried. + */ + canParse: ".json", + + /** + * Parses the given file as JSON + */ + async parse(file: FileInfo): Promise { + let data = file.data; + if (Buffer.isBuffer(data)) { + data = data.toString(); + } + + if (typeof data === "string") { + if (data.trim().length === 0) { + return; // This mirrors the YAML behavior + } else { + try { + return JSON.parse(data); + } catch (e: any) { + throw new ParserError(e.message, file.url); + } + } + } else { + // data is already a JavaScript value (object, array, number, null, NaN, etc.) + return data as object; + } + }, +} as Plugin; diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/text.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/text.ts new file mode 100644 index 000000000..19edf8b7d --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/text.ts @@ -0,0 +1,46 @@ +import { ParserError } from "../util/errors.js"; +import type { FileInfo } from "../types/index.js"; +import type { Plugin } from "../types/index.js"; + +const TEXT_REGEXP = /\.(txt|htm|html|md|xml|js|min|map|css|scss|less|svg)$/i; + +export default { + /** + * The order that this parser will run, in relation to other parsers. + */ + order: 300, + + /** + * Whether to allow "empty" files (zero bytes). + */ + allowEmpty: true, + + /** + * The encoding that the text is expected to be in. + */ + encoding: "utf8" as BufferEncoding, + + /** + * Determines whether this parser can parse a given file reference. + * Parsers that return true will be tried, in order, until one successfully parses the file. + * Parsers that return false will be skipped, UNLESS all parsers returned false, in which case + * every parser will be tried. + */ + canParse(file: FileInfo) { + // Use this parser if the file is a string or Buffer, and has a known text-based extension + return (typeof file.data === "string" || Buffer.isBuffer(file.data)) && TEXT_REGEXP.test(file.url); + }, + + /** + * Parses the given file as text + */ + parse(file: FileInfo) { + if (typeof file.data === "string") { + return file.data; + } else if (Buffer.isBuffer(file.data)) { + return file.data.toString(this.encoding); + } else { + throw new ParserError("data is not text", file.url); + } + }, +} as Plugin; diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/yaml.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/yaml.ts new file mode 100644 index 000000000..be4406112 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/parsers/yaml.ts @@ -0,0 +1,54 @@ +import { ParserError } from "../util/errors.js"; +import yaml from "js-yaml"; +import { JSON_SCHEMA } from "js-yaml"; +import type { FileInfo } from "../types/index.js"; +import type { Plugin } from "../types/index.js"; + +export default { + /** + * The order that this parser will run, in relation to other parsers. + */ + order: 200, + + /** + * Whether to allow "empty" files. This includes zero-byte files, as well as empty JSON objects. + */ + allowEmpty: true, + + /** + * Determines whether this parser can parse a given file reference. + * Parsers that match will be tried, in order, until one successfully parses the file. + * Parsers that don't match will be skipped, UNLESS none of the parsers match, in which case + * every parser will be tried. + */ + canParse: [".yaml", ".yml", ".json"], // JSON is valid YAML + + /** + * Parses the given file as YAML + * + * @param file - An object containing information about the referenced file + * @param file.url - The full URL of the referenced file + * @param file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.) + * @param file.data - The file contents. This will be whatever data type was returned by the resolver + * @returns + */ + async parse(file: FileInfo) { + // eslint-disable-line require-await + let data = file.data; + if (Buffer.isBuffer(data)) { + data = data.toString(); + } + + if (typeof data === "string") { + try { + return yaml.load(data, { schema: JSON_SCHEMA }); + } catch (e) { + // @ts-expect-error TS(2571): Object is of type 'unknown'. + throw new ParserError(e.message, file.url); + } + } else { + // data is already a JavaScript value (object, array, number, null, NaN, etc.) + return data; + } + }, +} as Plugin; diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/pointer.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/pointer.ts new file mode 100644 index 000000000..b2a1e0d2d --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/pointer.ts @@ -0,0 +1,296 @@ +import type $RefParserOptions from "./options.js"; + +import $Ref from "./ref.js"; +import * as url from "./util/url.js"; +import { JSONParserError, InvalidPointerError, MissingPointerError, isHandledError } from "./util/errors.js"; +const slashes = /\//g; +const tildes = /~/g; +const escapedSlash = /~1/g; +const escapedTilde = /~0/g; + +/** + * This class represents a single JSON pointer and its resolved value. + * + * @param $ref + * @param path + * @param [friendlyPath] - The original user-specified path (used for error messages) + * @class + */ +class Pointer { + /** + * The {@link $Ref} object that contains this {@link Pointer} object. + */ + $ref: $Ref; + + /** + * The file path or URL, containing the JSON pointer in the hash. + * This path is relative to the path of the main JSON schema file. + */ + path: string; + + /** + * The original path or URL, used for error messages. + */ + originalPath: string; + + /** + * The value of the JSON pointer. + * Can be any JSON type, not just objects. Unknown file types are represented as Buffers (byte arrays). + */ + + value: any; + /** + * Indicates whether the pointer references itself. + */ + circular: boolean; + /** + * The number of indirect references that were traversed to resolve the value. + * Resolving a single pointer may require resolving multiple $Refs. + */ + indirections: number; + + constructor($ref: any, path: any, friendlyPath: any) { + this.$ref = $ref; + + this.path = path; + + this.originalPath = friendlyPath || path; + + this.value = undefined; + + this.circular = false; + + this.indirections = 0; + } + + /** + * Resolves the value of a nested property within the given object. + * + * @param obj - The object that will be crawled + * @param options + * @param pathFromRoot - the path of place that initiated resolving + * + * @returns + * Returns a JSON pointer whose {@link Pointer#value} is the resolved value. + * If resolving this value required resolving other JSON references, then + * the {@link Pointer#$ref} and {@link Pointer#path} will reflect the resolution path + * of the resolved value. + */ + resolve(obj: any, options: any, pathFromRoot: any) { + const tokens = Pointer.parse(this.path, this.originalPath); + + // Crawl the object, one token at a time + this.value = unwrapOrThrow(obj); + + for (let i = 0; i < tokens.length; i++) { + if (resolveIf$Ref(this, options)) { + // The $ref path has changed, so append the remaining tokens to the path + this.path = Pointer.join(this.path, tokens.slice(i)); + } + + if (typeof this.value === "object" && this.value !== null && "$ref" in this.value) { + return this; + } + + const token = tokens[i]; + if (this.value[token] === undefined || this.value[token] === null) { + this.value = null; + throw new MissingPointerError(token, decodeURI(this.originalPath)); + } else { + this.value = this.value[token]; + } + } + + // Resolve the final value + if (!this.value || (this.value.$ref && url.resolve(this.path, this.value.$ref) !== pathFromRoot)) { + resolveIf$Ref(this, options); + } + + return this; + } + + /** + * Sets the value of a nested property within the given object. + * + * @param obj - The object that will be crawled + * @param value - the value to assign + * @param options + * + * @returns + * Returns the modified object, or an entirely new object if the entire object is overwritten. + */ + set(obj: any, value: any, options?: $RefParserOptions) { + const tokens = Pointer.parse(this.path); + let token; + + if (tokens.length === 0) { + // There are no tokens, replace the entire object with the new value + this.value = value; + return value; + } + + // Crawl the object, one token at a time + this.value = unwrapOrThrow(obj); + + for (let i = 0; i < tokens.length - 1; i++) { + resolveIf$Ref(this, options); + + token = tokens[i]; + if (this.value && this.value[token] !== undefined) { + // The token exists + this.value = this.value[token]; + } else { + // The token doesn't exist, so create it + this.value = setValue(this, token, {}); + } + } + + // Set the value of the final token + resolveIf$Ref(this, options); + token = tokens[tokens.length - 1]; + setValue(this, token, value); + + // Return the updated object + return obj; + } + + /** + * Parses a JSON pointer (or a path containing a JSON pointer in the hash) + * and returns an array of the pointer's tokens. + * (e.g. "schema.json#/definitions/person/name" => ["definitions", "person", "name"]) + * + * The pointer is parsed according to RFC 6901 + * {@link https://tools.ietf.org/html/rfc6901#section-3} + * + * @param path + * @param [originalPath] + * @returns + */ + static parse(path: string, originalPath?: string) { + // Get the JSON pointer from the path's hash + let pointer = url.getHash(path).substr(1); + + // If there's no pointer, then there are no tokens, + // so return an empty array + if (!pointer) { + return []; + } + + // Split into an array + pointer = pointer.split("/"); + + // Decode each part, according to RFC 6901 + for (let i = 0; i < pointer.length; i++) { + pointer[i] = decodeURIComponent(pointer[i].replace(escapedSlash, "/").replace(escapedTilde, "~")); + } + + if (pointer[0] !== "") { + throw new InvalidPointerError(pointer, originalPath === undefined ? path : originalPath); + } + + return pointer.slice(1); + } + + /** + * Creates a JSON pointer path, by joining one or more tokens to a base path. + * + * @param base - The base path (e.g. "schema.json#/definitions/person") + * @param tokens - The token(s) to append (e.g. ["name", "first"]) + * @returns + */ + static join(base: any, tokens: any) { + // Ensure that the base path contains a hash + if (base.indexOf("#") === -1) { + base += "#"; + } + + // Append each token to the base path + tokens = Array.isArray(tokens) ? tokens : [tokens]; + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + // Encode the token, according to RFC 6901 + base += "/" + encodeURIComponent(token.replace(tildes, "~0").replace(slashes, "~1")); + } + + return base; + } +} + +/** + * If the given pointer's {@link Pointer#value} is a JSON reference, + * then the reference is resolved and {@link Pointer#value} is replaced with the resolved value. + * In addition, {@link Pointer#path} and {@link Pointer#$ref} are updated to reflect the + * resolution path of the new value. + * + * @param pointer + * @param options + * @returns - Returns `true` if the resolution path changed + */ +function resolveIf$Ref(pointer: any, options: any) { + // Is the value a JSON reference? (and allowed?) + + if ($Ref.isAllowed$Ref(pointer.value, options)) { + const $refPath = url.resolve(pointer.path, pointer.value.$ref); + + if ($refPath === pointer.path) { + // The value is a reference to itself, so there's nothing to do. + pointer.circular = true; + } else { + const resolved = pointer.$ref.$refs._resolve($refPath, pointer.path, options); + if (resolved === null) { + return false; + } + + pointer.indirections += resolved.indirections + 1; + + if ($Ref.isExtended$Ref(pointer.value)) { + // This JSON reference "extends" the resolved value, rather than simply pointing to it. + // So the resolved path does NOT change. Just the value does. + pointer.value = $Ref.dereference(pointer.value, resolved.value); + return false; + } else { + // Resolve the reference + pointer.$ref = resolved.$ref; + pointer.path = resolved.path; + pointer.value = resolved.value; + } + + return true; + } + } +} +export default Pointer; + +/** + * Sets the specified token value of the {@link Pointer#value}. + * + * The token is evaluated according to RFC 6901. + * {@link https://tools.ietf.org/html/rfc6901#section-4} + * + * @param pointer - The JSON Pointer whose value will be modified + * @param token - A JSON Pointer token that indicates how to modify `obj` + * @param value - The value to assign + * @returns - Returns the assigned value + */ +function setValue(pointer: any, token: any, value: any) { + if (pointer.value && typeof pointer.value === "object") { + if (token === "-" && Array.isArray(pointer.value)) { + pointer.value.push(value); + } else { + pointer.value[token] = value; + } + } else { + throw new JSONParserError( + `Error assigning $ref pointer "${pointer.path}". \nCannot set "${token}" of a non-object.`, + ); + } + return value; +} + +function unwrapOrThrow(value: any) { + if (isHandledError(value)) { + throw value; + } + + return value; +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/ref.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/ref.ts new file mode 100644 index 000000000..3679892df --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/ref.ts @@ -0,0 +1,288 @@ +import Pointer from "./pointer.js"; +import type { JSONParserError, MissingPointerError, ParserError, ResolverError } from "./util/errors.js"; +import { InvalidPointerError, isHandledError, normalizeError } from "./util/errors.js"; +import { safePointerToPath, stripHash, getHash } from "./util/url.js"; +import type $Refs from "./refs.js"; +import type $RefParserOptions from "./options.js"; +import type { JSONSchema } from "./types"; + +type $RefError = JSONParserError | ResolverError | ParserError | MissingPointerError; + +/** + * This class represents a single JSON reference and its resolved value. + * + * @class + */ +class $Ref { + /** + * The file path or URL of the referenced file. + * This path is relative to the path of the main JSON schema file. + * + * This path does NOT contain document fragments (JSON pointers). It always references an ENTIRE file. + * Use methods such as {@link $Ref#get}, {@link $Ref#resolve}, and {@link $Ref#exists} to get + * specific JSON pointers within the file. + * + * @type {string} + */ + path: undefined | string; + + /** + * The resolved value of the JSON reference. + * Can be any JSON type, not just objects. Unknown file types are represented as Buffers (byte arrays). + * + * @type {?*} + */ + value: any; + + /** + * The {@link $Refs} object that contains this {@link $Ref} object. + * + * @type {$Refs} + */ + $refs: $Refs; + + /** + * Indicates the type of {@link $Ref#path} (e.g. "file", "http", etc.) + */ + pathType: string | unknown; + + /** + * List of all errors. Undefined if no errors. + */ + errors: Array<$RefError> = []; + + constructor($refs: $Refs) { + this.$refs = $refs; + } + + /** + * Pushes an error to errors array. + * + * @param err - The error to be pushed + * @returns + */ + addError(err: $RefError) { + if (this.errors === undefined) { + this.errors = []; + } + + const existingErrors = this.errors.map(({ footprint }: any) => footprint); + + // the path has been almost certainly set at this point, + // but just in case something went wrong, normalizeError injects path if necessary + // moreover, certain errors might point at the same spot, so filter them out to reduce noise + if ("errors" in err && Array.isArray(err.errors)) { + this.errors.push( + ...err.errors.map(normalizeError).filter(({ footprint }: any) => !existingErrors.includes(footprint)), + ); + } else if (!("footprint" in err) || !existingErrors.includes(err.footprint)) { + this.errors.push(normalizeError(err)); + } + } + + /** + * Determines whether the given JSON reference exists within this {@link $Ref#value}. + * + * @param path - The full path being resolved, optionally with a JSON pointer in the hash + * @param options + * @returns + */ + exists(path: string, options: any) { + try { + this.resolve(path, options); + return true; + } catch (e) { + return false; + } + } + + /** + * Resolves the given JSON reference within this {@link $Ref#value} and returns the resolved value. + * + * @param path - The full path being resolved, optionally with a JSON pointer in the hash + * @param options + * @returns - Returns the resolved value + */ + get(path: any, options: any) { + return this.resolve(path, options)?.value; + } + + /** + * Resolves the given JSON reference within this {@link $Ref#value}. + * + * @param path - The full path being resolved, optionally with a JSON pointer in the hash + * @param options + * @param friendlyPath - The original user-specified path (used for error messages) + * @param pathFromRoot - The path of `obj` from the schema root + * @returns + */ + resolve(path: any, options?: $RefParserOptions, friendlyPath?: string, pathFromRoot?: string) { + const pointer = new Pointer(this, path, friendlyPath); + try { + return pointer.resolve(this.value, options, pathFromRoot); + } catch (err: any) { + if (!options || !options.continueOnError || !isHandledError(err)) { + throw err; + } + + if (err.path === null) { + err.path = safePointerToPath(getHash(pathFromRoot)); + } + + if (err instanceof InvalidPointerError) { + err.source = decodeURI(stripHash(pathFromRoot)); + } + + this.addError(err); + return null; + } + } + + /** + * Sets the value of a nested property within this {@link $Ref#value}. + * If the property, or any of its parents don't exist, they will be created. + * + * @param path - The full path of the property to set, optionally with a JSON pointer in the hash + * @param value - The value to assign + */ + set(path: any, value: any) { + // @ts-expect-error TS(2554): Expected 3 arguments, but got 2. + const pointer = new Pointer(this, path); + this.value = pointer.set(this.value, value); + } + + /** + * Determines whether the given value is a JSON reference. + * + * @param value - The value to inspect + * @returns + */ + static is$Ref(value: any): value is { $ref: string; length?: number } { + return value && typeof value === "object" && typeof value.$ref === "string" && value.$ref.length > 0; + } + + /** + * Determines whether the given value is an external JSON reference. + * + * @param value - The value to inspect + * @returns + */ + static isExternal$Ref(value: any): value is JSONSchema { + return $Ref.is$Ref(value) && value.$ref![0] !== "#"; + } + + /** + * Determines whether the given value is a JSON reference, and whether it is allowed by the options. + * For example, if it references an external file, then options.resolve.external must be true. + * + * @param value - The value to inspect + * @param options + * @returns + */ + static isAllowed$Ref(value: any, options: any) { + if (this.is$Ref(value)) { + if (value.$ref.substring(0, 2) === "#/" || value.$ref === "#") { + // It's a JSON Pointer reference, which is always allowed + return true; + } else if (value.$ref[0] !== "#" && (!options || options.resolve.external)) { + // It's an external reference, which is allowed by the options + return true; + } + } + } + + /** + * Determines whether the given value is a JSON reference that "extends" its resolved value. + * That is, it has extra properties (in addition to "$ref"), so rather than simply pointing to + * an existing value, this $ref actually creates a NEW value that is a shallow copy of the resolved + * value, plus the extra properties. + * + * @example: { + person: { + properties: { + firstName: { type: string } + lastName: { type: string } + } + } + employee: { + properties: { + $ref: #/person/properties + salary: { type: number } + } + } + } + * In this example, "employee" is an extended $ref, since it extends "person" with an additional + * property (salary). The result is a NEW value that looks like this: + * + * { + * properties: { + * firstName: { type: string } + * lastName: { type: string } + * salary: { type: number } + * } + * } + * + * @param value - The value to inspect + * @returns + */ + static isExtended$Ref(value: any) { + return $Ref.is$Ref(value) && Object.keys(value).length > 1; + } + + /** + * Returns the resolved value of a JSON Reference. + * If necessary, the resolved value is merged with the JSON Reference to create a new object + * + * @example: { + person: { + properties: { + firstName: { type: string } + lastName: { type: string } + } + } + employee: { + properties: { + $ref: #/person/properties + salary: { type: number } + } + } + } When "person" and "employee" are merged, you end up with the following object: + * + * { + * properties: { + * firstName: { type: string } + * lastName: { type: string } + * salary: { type: number } + * } + * } + * + * @param $ref - The JSON reference object (the one with the "$ref" property) + * @param resolvedValue - The resolved value, which can be any type + * @returns - Returns the dereferenced value + */ + static dereference($ref: $Ref, resolvedValue: any) { + if (resolvedValue && typeof resolvedValue === "object" && $Ref.isExtended$Ref($ref)) { + const merged = {}; + for (const key of Object.keys($ref)) { + if (key !== "$ref") { + // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message + merged[key] = $ref[key]; + } + } + + for (const key of Object.keys(resolvedValue)) { + if (!(key in merged)) { + // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message + merged[key] = resolvedValue[key]; + } + } + + return merged; + } else { + // Completely replace the original reference with the resolved value + return resolvedValue; + } + } +} + +export default $Ref; diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/refs.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/refs.ts new file mode 100644 index 000000000..ec1a5e4b0 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/refs.ts @@ -0,0 +1,238 @@ +import { ono } from "@jsdevtools/ono"; +import $Ref from "./ref.js"; +import * as url from "./util/url.js"; +import type { JSONSchema4Type, JSONSchema6Type, JSONSchema7Type } from "json-schema"; +import type { JSONSchema } from "./types/index.js"; +import type $RefParserOptions from "./options.js"; + +const isWindows = /^win/.test(globalThis.process ? globalThis.process.platform : ""); +const getPathFromOs = (filePath: string): string => (isWindows ? filePath.replace(/\\/g, "/") : filePath); + +interface $RefsMap { + [url: string]: $Ref; +} +/** + * When you call the resolve method, the value that gets passed to the callback function (or Promise) is a $Refs object. This same object is accessible via the parser.$refs property of $RefParser objects. + * + * This object is a map of JSON References and their resolved values. It also has several convenient helper methods that make it easy for you to navigate and manipulate the JSON References. + * + * See https://apitools.dev/json-schema-ref-parser/docs/refs.html + */ +export default class $Refs { + /** + * This property is true if the schema contains any circular references. You may want to check this property before serializing the dereferenced schema as JSON, since JSON.stringify() does not support circular references by default. + * + * See https://apitools.dev/json-schema-ref-parser/docs/refs.html#circular + */ + public circular: boolean; + + /** + * Returns the paths/URLs of all the files in your schema (including the main schema file). + * + * See https://apitools.dev/json-schema-ref-parser/docs/refs.html#pathstypes + * + * @param types (optional) Optionally only return certain types of paths ("file", "http", etc.) + */ + paths(...types: string[]): string[] { + const paths = getPaths(this._$refs, types); + return paths.map((path) => { + return getPathFromOs(path.decoded); + }); + } + + /** + * Returns a map of paths/URLs and their correspond values. + * + * See https://apitools.dev/json-schema-ref-parser/docs/refs.html#valuestypes + * + * @param types (optional) Optionally only return values from certain locations ("file", "http", etc.) + */ + values(...types: string[]): JSONSchema { + const $refs = this._$refs; + const paths = getPaths($refs, types); + return paths.reduce>((obj, path) => { + obj[getPathFromOs(path.decoded)] = $refs[path.encoded].value; + return obj; + }, {}); + } + + /** + * Returns `true` if the given path exists in the schema; otherwise, returns `false` + * + * See https://apitools.dev/json-schema-ref-parser/docs/refs.html#existsref + * + * @param $ref The JSON Reference path, optionally with a JSON Pointer in the hash + */ + /** + * Determines whether the given JSON reference exists. + * + * @param path - The path being resolved, optionally with a JSON pointer in the hash + * @param [options] + * @returns + */ + exists(path: string, options: any) { + try { + this._resolve(path, "", options); + return true; + } catch (e) { + return false; + } + } + + /** + * Resolves the given JSON reference and returns the resolved value. + * + * @param path - The path being resolved, with a JSON pointer in the hash + * @param [options] + * @returns - Returns the resolved value + */ + get(path: string, options?: $RefParserOptions): JSONSchema4Type | JSONSchema6Type | JSONSchema7Type { + return this._resolve(path, "", options)!.value; + } + + /** + * Sets the value at the given path in the schema. If the property, or any of its parents, don't exist, they will be created. + * + * @param $ref The JSON Reference path, optionally with a JSON Pointer in the hash + * @param value The value to assign. Can be anything (object, string, number, etc.) + */ + set(path: any, value: JSONSchema4Type | JSONSchema6Type | JSONSchema7Type) { + const absPath = url.resolve(this._root$Ref.path, path); + const withoutHash = url.stripHash(absPath); + const $ref = this._$refs[withoutHash]; + + if (!$ref) { + throw ono(`Error resolving $ref pointer "${path}". \n"${withoutHash}" not found.`); + } + + $ref.set(absPath, value); + } + /** + * Returns the specified {@link $Ref} object, or undefined. + * + * @param path - The path being resolved, optionally with a JSON pointer in the hash + * @returns + * @protected + */ + _get$Ref(path: any) { + path = url.resolve(this._root$Ref.path, path); + const withoutHash = url.stripHash(path); + return this._$refs[withoutHash]; + } + + /** + * Creates a new {@link $Ref} object and adds it to this {@link $Refs} object. + * + * @param path - The file path or URL of the referenced file + */ + _add(path: string) { + const withoutHash = url.stripHash(path); + + const $ref = new $Ref(this); + $ref.path = withoutHash; + + this._$refs[withoutHash] = $ref; + this._root$Ref = this._root$Ref || $ref; + + return $ref; + } + + /** + * Resolves the given JSON reference. + * + * @param path - The path being resolved, optionally with a JSON pointer in the hash + * @param pathFromRoot - The path of `obj` from the schema root + * @param [options] + * @returns + * @protected + */ + _resolve(path: string, pathFromRoot: string, options?: any) { + const absPath = url.resolve(this._root$Ref.path, path); + const withoutHash = url.stripHash(absPath); + const $ref = this._$refs[withoutHash]; + + if (!$ref) { + throw ono(`Error resolving $ref pointer "${path}". \n"${withoutHash}" not found.`); + } + + return $ref.resolve(absPath, options, path, pathFromRoot); + } + + /** + * A map of paths/urls to {@link $Ref} objects + * + * @type {object} + * @protected + */ + _$refs: $RefsMap = {}; + + /** + * The {@link $Ref} object that is the root of the JSON schema. + * + * @type {$Ref} + * @protected + */ + _root$Ref: $Ref; + + constructor() { + /** + * Indicates whether the schema contains any circular references. + * + * @type {boolean} + */ + this.circular = false; + + this._$refs = {}; + + // @ts-ignore + this._root$Ref = null; + } + + /** + * Returns the paths of all the files/URLs that are referenced by the JSON schema, + * including the schema itself. + * + * @param [types] - Only return paths of the given types ("file", "http", etc.) + * @returns + */ + /** + * Returns the map of JSON references and their resolved values. + * + * @param [types] - Only return references of the given types ("file", "http", etc.) + * @returns + */ + + /** + * Returns a POJO (plain old JavaScript object) for serialization as JSON. + * + * @returns {object} + */ + toJSON = this.values; +} + +/** + * Returns the encoded and decoded paths keys of the given object. + * + * @param $refs - The object whose keys are URL-encoded paths + * @param [types] - Only return paths of the given types ("file", "http", etc.) + * @returns + */ +function getPaths($refs: $RefsMap, types: string[]) { + let paths = Object.keys($refs); + + // Filter the paths by type + types = Array.isArray(types[0]) ? types[0] : Array.prototype.slice.call(types); + if (types.length > 0 && types[0]) { + paths = paths.filter((key) => { + return types.includes($refs[key].pathType as string); + }); + } + + // Decode local filesystem paths + return paths.map((path) => { + return { + encoded: path, + decoded: $refs[path].pathType === "file" ? url.toFileSystemPath(path, true) : path, + }; + }); +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/resolve-external.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/resolve-external.ts new file mode 100644 index 000000000..7b9dce631 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/resolve-external.ts @@ -0,0 +1,130 @@ +import $Ref from "./ref.js"; +import Pointer from "./pointer.js"; +import parse from "./parse.js"; +import * as url from "./util/url.js"; +import { isHandledError } from "./util/errors.js"; +import type $Refs from "./refs.js"; +import type { Options } from "./options.js"; +import type { JSONSchema } from "./types/index.js"; +import type $RefParser from "./index.js"; + +export default resolveExternal; + +/** + * Crawls the JSON schema, finds all external JSON references, and resolves their values. + * This method does not mutate the JSON schema. The resolved values are added to {@link $RefParser#$refs}. + * + * NOTE: We only care about EXTERNAL references here. INTERNAL references are only relevant when dereferencing. + * + * @returns + * The promise resolves once all JSON references in the schema have been resolved, + * including nested references that are contained in externally-referenced files. + */ +function resolveExternal(parser: $RefParser, options: Options) { + if (!options.resolve.external) { + // Nothing to resolve, so exit early + return Promise.resolve(); + } + + try { + // console.log('Resolving $ref pointers in %s', parser.$refs._root$Ref.path); + const promises = crawl(parser.schema, parser.$refs._root$Ref.path + "#", parser.$refs, options); + return Promise.all(promises); + } catch (e) { + return Promise.reject(e); + } +} + +/** + * Recursively crawls the given value, and resolves any external JSON references. + * + * @param obj - The value to crawl. If it's not an object or array, it will be ignored. + * @param path - The full path of `obj`, possibly with a JSON Pointer in the hash + * @param $refs + * @param options + * @param seen - Internal. + * + * @returns + * Returns an array of promises. There will be one promise for each JSON reference in `obj`. + * If `obj` does not contain any JSON references, then the array will be empty. + * If any of the JSON references point to files that contain additional JSON references, + * then the corresponding promise will internally reference an array of promises. + */ +function crawl( + obj: string | Buffer | JSONSchema | undefined | null, + path: string, + $refs: $Refs, + options: Options, + seen?: Set, +) { + seen ||= new Set(); + let promises: any = []; + + if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj) && !seen.has(obj)) { + seen.add(obj); // Track previously seen objects to avoid infinite recursion + if ($Ref.isExternal$Ref(obj)) { + promises.push(resolve$Ref(obj, path, $refs, options)); + } else { + for (const key of Object.keys(obj)) { + const keyPath = Pointer.join(path, key); + const value = obj[key] as string | JSONSchema | Buffer | undefined; + + if ($Ref.isExternal$Ref(value)) { + promises.push(resolve$Ref(value, keyPath, $refs, options)); + } else { + promises = promises.concat(crawl(value, keyPath, $refs, options, seen)); + } + } + } + } + + return promises; +} + +/** + * Resolves the given JSON Reference, and then crawls the resulting value. + * + * @param $ref - The JSON Reference to resolve + * @param path - The full path of `$ref`, possibly with a JSON Pointer in the hash + * @param $refs + * @param options + * + * @returns + * The promise resolves once all JSON references in the object have been resolved, + * including nested references that are contained in externally-referenced files. + */ +async function resolve$Ref($ref: JSONSchema, path: string, $refs: $Refs, options: Options) { + // console.log('Resolving $ref pointer "%s" at %s', $ref.$ref, path); + + const resolvedPath = url.resolve(path, $ref.$ref); + const withoutHash = url.stripHash(resolvedPath); + + // Do we already have this $ref? + $ref = $refs._$refs[withoutHash]; + if ($ref) { + // We've already parsed this $ref, so use the existing value + return Promise.resolve($ref.value); + } + + // Parse the $referenced file/url + try { + const result = await parse(resolvedPath, $refs, options); + + // Crawl the parsed value + // console.log('Resolving $ref pointers in %s', withoutHash); + const promises = crawl(result, withoutHash + "#", $refs, options); + + return Promise.all(promises); + } catch (err) { + if (!options?.continueOnError || !isHandledError(err)) { + throw err; + } + + if ($refs._$refs[withoutHash]) { + err.source = decodeURI(url.stripHash(path)); + err.path = url.safePointerToPath(url.getHash(path)); + } + + return []; + } +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/resolvers/file.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/resolvers/file.ts new file mode 100644 index 000000000..c78b267a6 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/resolvers/file.ts @@ -0,0 +1,40 @@ +import fs from "fs/promises"; +import { ono } from "@jsdevtools/ono"; +import * as url from "../util/url.js"; +import { ResolverError } from "../util/errors.js"; +import type { ResolverOptions } from "../types/index.js"; +import type { FileInfo } from "../types/index.js"; + +export default { + /** + * The order that this resolver will run, in relation to other resolvers. + */ + order: 100, + + /** + * Determines whether this resolver can read a given file reference. + * Resolvers that return true will be tried, in order, until one successfully resolves the file. + * Resolvers that return false will not be given a chance to resolve the file. + */ + canRead(file: FileInfo) { + return url.isFileSystemPath(file.url); + }, + + /** + * Reads the given file and returns its raw contents as a Buffer. + */ + async read(file: FileInfo): Promise { + let path: string | undefined; + try { + path = url.toFileSystemPath(file.url); + } catch (err: any) { + throw new ResolverError(ono.uri(err, `Malformed URI: ${file.url}`), file.url); + } + try { + const data = await fs.readFile(path); + return data; + } catch (err: any) { + throw new ResolverError(ono(err, `Error opening file "${path}"`), path); + } + }, +} as ResolverOptions; diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/resolvers/http.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/resolvers/http.ts new file mode 100644 index 000000000..202192dec --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/resolvers/http.ts @@ -0,0 +1,136 @@ +import { ono } from "@jsdevtools/ono"; +import * as url from "../util/url.js"; +import { ResolverError } from "../util/errors.js"; +import type { FileInfo, HTTPResolverOptions } from "../types/index.js"; + +export default { + /** + * The order that this resolver will run, in relation to other resolvers. + */ + order: 200, + + /** + * HTTP headers to send when downloading files. + * + * @example: + * { + * "User-Agent": "JSON Schema $Ref Parser", + * Accept: "application/json" + * } + */ + headers: null, + + /** + * HTTP request timeout (in milliseconds). + */ + timeout: 5000, // 5 seconds + + /** + * The maximum number of HTTP redirects to follow. + * To disable automatic following of redirects, set this to zero. + */ + redirects: 5, + + /** + * The `withCredentials` option of XMLHttpRequest. + * Set this to `true` if you're downloading files from a CORS-enabled server that requires authentication + */ + withCredentials: false, + + /** + * Determines whether this resolver can read a given file reference. + * Resolvers that return true will be tried in order, until one successfully resolves the file. + * Resolvers that return false will not be given a chance to resolve the file. + */ + canRead(file: FileInfo) { + return url.isHttp(file.url); + }, + + /** + * Reads the given URL and returns its raw contents as a Buffer. + */ + read(file: FileInfo) { + const u = url.parse(file.url); + + if (typeof window !== "undefined" && !u.protocol) { + // Use the protocol of the current page + u.protocol = url.parse(location.href).protocol; + } + + return download(u, this); + }, +} as HTTPResolverOptions; + +/** + * Downloads the given file. + * @returns + * The promise resolves with the raw downloaded data, or rejects if there is an HTTP error. + */ +async function download(u: URL | string, httpOptions: HTTPResolverOptions, _redirects?: string[]): Promise { + u = url.parse(u); + const redirects = _redirects || []; + redirects.push(u.href); + + try { + const res = await get(u, httpOptions); + if (res.status >= 400) { + throw ono({ status: res.status }, `HTTP ERROR ${res.status}`); + } else if (res.status >= 300) { + if (!Number.isNaN(httpOptions.redirects) && redirects.length > httpOptions.redirects!) { + throw new ResolverError( + ono( + { status: res.status }, + `Error downloading ${redirects[0]}. \nToo many redirects: \n ${redirects.join(" \n ")}`, + ), + ); + } else if (!("location" in res.headers) || !res.headers.location) { + throw ono({ status: res.status }, `HTTP ${res.status} redirect with no location header`); + } else { + const redirectTo = url.resolve(u, res.headers.location); + return download(redirectTo, httpOptions, redirects); + } + } else { + if (res.body) { + const buf = await res.arrayBuffer(); + return Buffer.from(buf); + } + return Buffer.alloc(0); + } + } catch (err: any) { + throw new ResolverError(ono(err, `Error downloading ${u.href}`), u.href); + } +} + +/** + * Sends an HTTP GET request. + * The promise resolves with the HTTP Response object. + */ +async function get(u: RequestInfo | URL, httpOptions: HTTPResolverOptions) { + let controller: any; + let timeoutId: any; + if (httpOptions.timeout) { + controller = new AbortController(); + timeoutId = setTimeout(() => controller.abort(), httpOptions.timeout); + } + + if (!global.fetch) { + const { default: fetch, Request, Headers } = await import("node-fetch"); + // @ts-ignore + global.fetch = fetch; + // @ts-ignore + global.Request = Request; + // @ts-ignore + global.Headers = Headers; + } + const response = await fetch(u, { + method: "GET", + headers: httpOptions.headers || {}, + credentials: httpOptions.withCredentials ? "include" : "same-origin", + signal: controller ? controller.signal : null, + }); + if (timeoutId) { + clearTimeout(timeoutId); + } + + return response; +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/tsconfig.json b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/tsconfig.json new file mode 100644 index 000000000..75dcaeac2 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/tsconfig.json @@ -0,0 +1,103 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/types/index.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/types/index.ts new file mode 100644 index 000000000..91772c32f --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/types/index.ts @@ -0,0 +1,135 @@ +import type { + JSONSchema4, + JSONSchema4Object, + JSONSchema6, + JSONSchema6Object, + JSONSchema7, + JSONSchema7Object, +} from "json-schema"; +import type $Refs from "../refs.js"; + +export type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7; +export type JSONSchemaObject = JSONSchema4Object | JSONSchema6Object | JSONSchema7Object; +export type SchemaCallback = (err: Error | null, schema?: JSONSchema | object) => any; +export type $RefsCallback = (err: Error | null, $refs?: $Refs) => any; + +/** + * See https://apitools.dev/json-schema-ref-parser/docs/options.html + */ + +export interface HTTPResolverOptions extends Partial { + /** + * You can specify any HTTP headers that should be sent when downloading files. For example, some servers may require you to set the `Accept` or `Referrer` header. + */ + headers?: HeadersInit | null; + + /** + * The amount of time (in milliseconds) to wait for a response from the server when downloading files. The default is 5 seconds. + */ + timeout?: number; + + /** + * The maximum number of HTTP redirects to follow per file. The default is 5. To disable automatic following of redirects, set this to zero. + */ + redirects?: number; + + /** + * Set this to `true` if you're downloading files from a CORS-enabled server that requires authentication + */ + withCredentials?: boolean; +} + +/** + * JSON Schema `$Ref` Parser comes with built-in resolvers for HTTP and HTTPS URLs, as well as local filesystem paths (when running in Node.js). You can add your own custom resolvers to support additional protocols, or even replace any of the built-in resolvers with your own custom implementation. + * + * See https://apitools.dev/json-schema-ref-parser/docs/plugins/resolvers.html + */ +export interface ResolverOptions { + name?: string; + /** + * All resolvers have an order property, even the built-in resolvers. If you don't specify an order property, then your resolver will run last. Specifying `order: 1`, like we did in this example, will make your resolver run first. Or you can squeeze your resolver in-between some of the built-in resolvers. For example, `order: 101` would make it run after the file resolver, but before the HTTP resolver. You can see the order of all the built-in resolvers by looking at their source code. + * + * The order property and canRead property are related to each other. For each file that JSON Schema $Ref Parser needs to resolve, it first determines which resolvers can read that file by checking their canRead property. If only one resolver matches a file, then only that one resolver is called, regardless of its order. If multiple resolvers match a file, then those resolvers are tried in order until one of them successfully reads the file. Once a resolver successfully reads the file, the rest of the resolvers are skipped. + */ + order?: number; + + /** + * The `canRead` property tells JSON Schema `$Ref` Parser what kind of files your resolver can read. In this example, we've simply specified a regular expression that matches "mogodb://" URLs, but we could have used a simple boolean, or even a function with custom logic to determine which files to resolve. Here are examples of each approach: + */ + canRead: boolean | RegExp | string | string[] | ((file: FileInfo) => boolean); + + /** + * This is where the real work of a resolver happens. The `read` method accepts the same file info object as the `canRead` function, but rather than returning a boolean value, the `read` method should return the contents of the file. The file contents should be returned in as raw a form as possible, such as a string or a byte array. Any further parsing or processing should be done by parsers. + * + * Unlike the `canRead` function, the `read` method can also be asynchronous. This might be important if your resolver needs to read data from a database or some other external source. You can return your asynchronous value using either an ES6 Promise or a Node.js-style error-first callback. Of course, if your resolver has the ability to return its data synchronously, then that's fine too. Here are examples of all three approaches: + */ + read: + | string + | object + | (( + file: FileInfo, + callback?: (error: Error | null, data: string | null) => any, + ) => string | Buffer | JSONSchema | Promise); +} + +export interface Plugin { + name?: string; + /** + * Parsers run in a specific order, relative to other parsers. For example, a parser with `order: 5` will run before a parser with `order: 10`. If a parser is unable to successfully parse a file, then the next parser is tried, until one succeeds or they all fail. + * + * You can change the order in which parsers run, which is useful if you know that most of your referenced files will be a certain type, or if you add your own custom parser that you want to run first. + */ + order?: number; + + /** + * All of the built-in parsers allow empty files by default. The JSON and YAML parsers will parse empty files as `undefined`. The text parser will parse empty files as an empty string. The binary parser will parse empty files as an empty byte array. + * + * You can set `allowEmpty: false` on any parser, which will cause an error to be thrown if a file empty. + */ + allowEmpty?: boolean; + + /** + * The encoding that the text is expected to be in. + */ + encoding?: BufferEncoding; + /** + * Determines which parsers will be used for which files. + * + * A regular expression can be used to match files by their full path. A string (or array of strings) can be used to match files by their file extension. Or a function can be used to perform more complex matching logic. See the custom parser docs for details. + */ + canParse?: boolean | RegExp | string | string[] | ((file: FileInfo) => boolean); + + /** + * This is where the real work of a parser happens. The `parse` method accepts the same file info object as the `canParse` function, but rather than returning a boolean value, the `parse` method should return a JavaScript representation of the file contents. For our CSV parser, that is a two-dimensional array of lines and values. For your parser, it might be an object, a string, a custom class, or anything else. + * + * Unlike the `canParse` function, the `parse` method can also be asynchronous. This might be important if your parser needs to retrieve data from a database or if it relies on an external HTTP service to return the parsed value. You can return your asynchronous value via a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or a Node.js-style error-first callback. Here are examples of both approaches: + */ + parse: + | ((file: FileInfo, callback?: (error: Error | null, data: string | null) => any) => unknown | Promise) + | number + | string; +} + +/** + * JSON Schema `$Ref` Parser supports plug-ins, such as resolvers and parsers. These plug-ins can have methods such as `canRead()`, `read()`, `canParse()`, and `parse()`. All of these methods accept the same object as their parameter: an object containing information about the file being read or parsed. + * + * The file info object currently only consists of a few properties, but it may grow in the future if plug-ins end up needing more information. + * + * See https://apitools.dev/json-schema-ref-parser/docs/plugins/file-info-object.html + */ +export interface FileInfo { + /** + * The full URL of the file. This could be any type of URL, including "http://", "https://", "file://", "ftp://", "mongodb://", or even a local filesystem path (when running in Node.js). + */ + url: string; + + /** + * The lowercase file extension, such as ".json", ".yaml", ".txt", etc. + */ + extension: string; + + /** + * The raw file contents, in whatever form they were returned by the resolver that read the file. + */ + data: string | Buffer; +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/errors.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/errors.ts new file mode 100644 index 000000000..6ae62216e --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/errors.ts @@ -0,0 +1,141 @@ +import { Ono } from "@jsdevtools/ono"; +import { stripHash, toFileSystemPath } from "./url.js"; +import type $RefParser from "../index.js"; + +export type JSONParserErrorType = + | "EUNKNOWN" + | "EPARSER" + | "EUNMATCHEDPARSER" + | "ERESOLVER" + | "EUNMATCHEDRESOLVER" + | "EMISSINGPOINTER" + | "EINVALIDPOINTER"; +export class JSONParserError extends Error { + public readonly name: string; + public readonly message: string; + public source: string | undefined; + public path: Array | null; + public readonly code: JSONParserErrorType; + public constructor(message: string, source?: string) { + super(); + + this.code = "EUNKNOWN"; + this.name = "JSONParserError"; + this.message = message; + this.source = source; + this.path = null; + + Ono.extend(this); + } + + get footprint() { + return `${this.path}+${this.source}+${this.code}+${this.message}`; + } +} + +export class JSONParserErrorGroup extends Error { + files: $RefParser; + + constructor(parser: $RefParser) { + super(); + + this.files = parser; + this.name = "JSONParserErrorGroup"; + this.message = `${this.errors.length} error${ + this.errors.length > 1 ? "s" : "" + } occurred while reading '${toFileSystemPath(parser.$refs._root$Ref!.path)}'`; + + Ono.extend(this); + } + + static getParserErrors(parser: any) { + const errors = []; + + for (const $ref of Object.values(parser.$refs._$refs)) { + // @ts-expect-error TS(2571): Object is of type 'unknown'. + if ($ref.errors) { + // @ts-expect-error TS(2571): Object is of type 'unknown'. + errors.push(...$ref.errors); + } + } + + return errors; + } + + get errors(): Array< + | JSONParserError + | InvalidPointerError + | ResolverError + | ParserError + | MissingPointerError + | UnmatchedParserError + | UnmatchedResolverError + > { + return JSONParserErrorGroup.getParserErrors(this.files); + } +} + +export class ParserError extends JSONParserError { + code = "EPARSER" as JSONParserErrorType; + name = "ParserError"; + constructor(message: any, source: any) { + super(`Error parsing ${source}: ${message}`, source); + } +} + +export class UnmatchedParserError extends JSONParserError { + code = "EUNMATCHEDPARSER" as JSONParserErrorType; + name = "UnmatchedParserError"; + + constructor(source: string) { + super(`Could not find parser for "${source}"`, source); + } +} + +export class ResolverError extends JSONParserError { + code = "ERESOLVER" as JSONParserErrorType; + name = "ResolverError"; + ioErrorCode?: string; + constructor(ex: Error | any, source?: string) { + super(ex.message || `Error reading file "${source}"`, source); + if ("code" in ex) { + this.ioErrorCode = String(ex.code); + } + } +} + +export class UnmatchedResolverError extends JSONParserError { + code = "EUNMATCHEDRESOLVER" as JSONParserErrorType; + name = "UnmatchedResolverError"; + constructor(source: any) { + super(`Could not find resolver for "${source}"`, source); + } +} + +export class MissingPointerError extends JSONParserError { + code = "EUNMATCHEDRESOLVER" as JSONParserErrorType; + name = "MissingPointerError"; + constructor(token: any, path: any) { + super(`Token "${token}" does not exist.`, stripHash(path)); + } +} + +export class InvalidPointerError extends JSONParserError { + code = "EUNMATCHEDRESOLVER" as JSONParserErrorType; + name = "InvalidPointerError"; + constructor(pointer: any, path: any) { + super(`Invalid $ref pointer "${pointer}". Pointers must begin with "#/"`, stripHash(path)); + } +} + +export function isHandledError(err: any): err is JSONParserError { + return err instanceof JSONParserError || err instanceof JSONParserErrorGroup; +} + +export function normalizeError(err: any) { + if (err.path === null) { + err.path = []; + } + + return err; +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/maybe.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/maybe.ts new file mode 100644 index 000000000..5e24ec213 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/maybe.ts @@ -0,0 +1,22 @@ +import next from "./next.js"; + +type MaybeParams = (err: Error | any | null, result?: T) => void; +export default function maybe(cb: MaybeParams | undefined, promise: Promise): Promise | void { + if (cb) { + promise.then( + function (result) { + next(function () { + cb(null, result); + }); + }, + function (err) { + next(function () { + cb(err); + }); + }, + ); + return undefined; + } else { + return promise; + } +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/next.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/next.ts new file mode 100644 index 000000000..d460a3fc2 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/next.ts @@ -0,0 +1,13 @@ +function makeNext() { + if (typeof process === "object" && typeof process.nextTick === "function") { + return process.nextTick; + } else if (typeof setImmediate === "function") { + return setImmediate; + } else { + return function next(f: () => void) { + setTimeout(f, 0); + }; + } +} + +export default makeNext(); diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/plugins.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/plugins.ts new file mode 100644 index 000000000..6901d21d6 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/plugins.ts @@ -0,0 +1,158 @@ +import type { FileInfo } from "../types/index.js"; +import type $RefParserOptions from "../options.js"; +import type { ResolverOptions } from "../types/index.js"; +import type $Refs from "../refs.js"; +import type { Plugin } from "../types/index.js"; +import type { JSONSchema } from "../types/index.js"; + +/** + * Returns the given plugins as an array, rather than an object map. + * All other methods in this module expect an array of plugins rather than an object map. + * + * @returns + */ +export function all(plugins: $RefParserOptions["resolve"]): Plugin[] { + return Object.keys(plugins) + .filter((key) => { + return typeof plugins[key] === "object"; + }) + .map((key) => { + (plugins[key] as ResolverOptions)!.name = key; + return plugins[key] as Plugin; + }); +} + +/** + * Filters the given plugins, returning only the ones return `true` for the given method. + */ +export function filter(plugins: Plugin[], method: any, file: any) { + return plugins.filter((plugin: Plugin) => { + return !!getResult(plugin, method, file); + }); +} + +/** + * Sorts the given plugins, in place, by their `order` property. + */ +export function sort(plugins: Plugin[]) { + for (const plugin of plugins) { + plugin.order = plugin.order || Number.MAX_SAFE_INTEGER; + } + + return plugins.sort((a: any, b: any) => { + return a.order - b.order; + }); +} + +export interface PluginResult { + plugin: Plugin; + result?: string | Buffer | JSONSchema; + error?: any; +} + +/** + * Runs the specified method of the given plugins, in order, until one of them returns a successful result. + * Each method can return a synchronous value, a Promise, or call an error-first callback. + * If the promise resolves successfully, or the callback is called without an error, then the result + * is immediately returned and no further plugins are called. + * If the promise rejects, or the callback is called with an error, then the next plugin is called. + * If ALL plugins fail, then the last error is thrown. + */ +export async function run( + plugins: Plugin[], + method: keyof Plugin | keyof ResolverOptions, + file: FileInfo, + $refs: $Refs, +) { + let plugin: Plugin; + let lastError: PluginResult; + let index = 0; + + return new Promise((resolve, reject) => { + runNextPlugin(); + + function runNextPlugin() { + plugin = plugins[index++]; + if (!plugin) { + // There are no more functions, so re-throw the last error + return reject(lastError); + } + + try { + // console.log(' %s', plugin.name); + const result = getResult(plugin, method, file, callback, $refs); + if (result && typeof result.then === "function") { + // A promise was returned + result.then(onSuccess, onError); + } else if (result !== undefined) { + // A synchronous result was returned + onSuccess(result); + } else if (index === plugins.length) { + throw new Error("No promise has been returned or callback has been called."); + } + } catch (e) { + onError(e); + } + } + + function callback(err: PluginResult["error"], result: PluginResult["result"]) { + if (err) { + onError(err); + } else { + onSuccess(result); + } + } + + function onSuccess(result: PluginResult["result"]) { + // console.log(' success'); + resolve({ + plugin, + result, + }); + } + + function onError(error: PluginResult["error"]) { + // console.log(' %s', err.message || err); + lastError = { + plugin, + error, + }; + runNextPlugin(); + } + }); +} + +/** + * Returns the value of the given property. + * If the property is a function, then the result of the function is returned. + * If the value is a RegExp, then it will be tested against the file URL. + * If the value is an array, then it will be compared against the file extension. + */ +function getResult( + obj: Plugin, + prop: keyof Plugin | keyof ResolverOptions, + file: FileInfo, + callback?: (err?: Error, result?: any) => void, + $refs?: any, +) { + const value = obj[prop as keyof typeof obj] as unknown; + + if (typeof value === "function") { + return value.apply(obj, [file, callback, $refs]); + } + + if (!callback) { + // The synchronous plugin functions (canParse and canRead) + // allow a "shorthand" syntax, where the user can match + // files by RegExp or by file extension. + if (value instanceof RegExp) { + return value.test(file.url); + } else if (typeof value === "string") { + return value === file.extension; + } else if (Array.isArray(value)) { + return value.indexOf(file.extension) !== -1; + } + } + + return value; +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/url.ts b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/url.ts new file mode 100644 index 000000000..c63974bc2 --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/lib/util/url.ts @@ -0,0 +1,272 @@ +const isWindows = /^win/.test(globalThis.process ? globalThis.process.platform : ""), + forwardSlashPattern = /\//g, + protocolPattern = /^(\w{2,}):\/\//i, + jsonPointerSlash = /~1/g, + jsonPointerTilde = /~0/g; +import { join } from "path"; + +const projectDir = join(__dirname, "..", ".."); +// RegExp patterns to URL-encode special characters in local filesystem paths +const urlEncodePatterns = [/\?/g, "%3F", /#/g, "%23"]; + +// RegExp patterns to URL-decode special characters for local filesystem paths +const urlDecodePatterns = [/%23/g, "#", /%24/g, "$", /%26/g, "&", /%2C/g, ",", /%40/g, "@"]; + +export const parse = (u: any) => new URL(u); + +/** + * Returns resolved target URL relative to a base URL in a manner similar to that of a Web browser resolving an anchor tag HREF. + * + * @returns + */ +export function resolve(from: any, to: any) { + const resolvedUrl = new URL(to, new URL(from, "resolve://")); + if (resolvedUrl.protocol === "resolve:") { + // `from` is a relative URL. + const { pathname, search, hash } = resolvedUrl; + return pathname + search + hash; + } + return resolvedUrl.toString(); +} + +/** + * Returns the current working directory (in Node) or the current page URL (in browsers). + * + * @returns + */ +export function cwd() { + if (typeof window !== "undefined") { + return location.href; + } + + const path = process.cwd(); + + const lastChar = path.slice(-1); + if (lastChar === "/" || lastChar === "\\") { + return path; + } else { + return path + "/"; + } +} + +/** + * Returns the protocol of the given URL, or `undefined` if it has no protocol. + * + * @param path + * @returns + */ +export function getProtocol(path: any) { + const match = protocolPattern.exec(path); + if (match) { + return match[1].toLowerCase(); + } +} + +/** + * Returns the lowercased file extension of the given URL, + * or an empty string if it has no extension. + * + * @param path + * @returns + */ +export function getExtension(path: any) { + const lastDot = path.lastIndexOf("."); + if (lastDot >= 0) { + return stripQuery(path.substr(lastDot).toLowerCase()); + } + return ""; +} + +/** + * Removes the query, if any, from the given path. + * + * @param path + * @returns + */ +export function stripQuery(path: any) { + const queryIndex = path.indexOf("?"); + if (queryIndex >= 0) { + path = path.substr(0, queryIndex); + } + return path; +} + +/** + * Returns the hash (URL fragment), of the given path. + * If there is no hash, then the root hash ("#") is returned. + * + * @param path + * @returns + */ +export function getHash(path: any) { + const hashIndex = path.indexOf("#"); + if (hashIndex >= 0) { + return path.substr(hashIndex); + } + return "#"; +} + +/** + * Removes the hash (URL fragment), if any, from the given path. + * + * @param path + * @returns + */ +export function stripHash(path: any) { + const hashIndex = path.indexOf("#"); + if (hashIndex >= 0) { + path = path.substr(0, hashIndex); + } + return path; +} + +/** + * Determines whether the given path is an HTTP(S) URL. + * + * @param path + * @returns + */ +export function isHttp(path: any) { + const protocol = getProtocol(path); + if (protocol === "http" || protocol === "https") { + return true; + } else if (protocol === undefined) { + // There is no protocol. If we're running in a browser, then assume it's HTTP. + return typeof window !== "undefined"; + } else { + // It's some other protocol, such as "ftp://", "mongodb://", etc. + return false; + } +} + +/** + * Determines whether the given path is a filesystem path. + * This includes "file://" URLs. + * + * @param path + * @returns + */ +export function isFileSystemPath(path: any) { + // @ts-ignore + if (typeof window !== "undefined" || process.browser) { + // We're running in a browser, so assume that all paths are URLs. + // This way, even relative paths will be treated as URLs rather than as filesystem paths + return false; + } + + const protocol = getProtocol(path); + return protocol === undefined || protocol === "file"; +} + +/** + * Converts a filesystem path to a properly-encoded URL. + * + * This is intended to handle situations where JSON Schema $Ref Parser is called + * with a filesystem path that contains characters which are not allowed in URLs. + * + * @example + * The following filesystem paths would be converted to the following URLs: + * + * <"!@#$%^&*+=?'>.json ==> %3C%22!@%23$%25%5E&*+=%3F\'%3E.json + * C:\\My Documents\\File (1).json ==> C:/My%20Documents/File%20(1).json + * file://Project #42/file.json ==> file://Project%20%2342/file.json + * + * @param path + * @returns + */ +export function fromFileSystemPath(path: any) { + // Step 1: On Windows, replace backslashes with forward slashes, + // rather than encoding them as "%5C" + if (isWindows) { + const hasProjectDir = path.toUpperCase().includes(projectDir.replace(/\\/g, "\\").toUpperCase()); + const hasProjectUri = path.toUpperCase().includes(projectDir.replace(/\\/g, "/").toUpperCase()); + if (hasProjectDir || hasProjectUri) { + path = path.replace(/\\/g, "/"); + } else { + path = `${projectDir}/${path}`.replace(/\\/g, "/"); + } + } + + // Step 2: `encodeURI` will take care of MOST characters + path = encodeURI(path); + + // Step 3: Manually encode characters that are not encoded by `encodeURI`. + // This includes characters such as "#" and "?", which have special meaning in URLs, + // but are just normal characters in a filesystem path. + for (let i = 0; i < urlEncodePatterns.length; i += 2) { + path = path.replace(urlEncodePatterns[i], urlEncodePatterns[i + 1]); + } + + return path; +} + +/** + * Converts a URL to a local filesystem path. + */ +export function toFileSystemPath(path: string | undefined, keepFileProtocol?: boolean): string { + // Step 1: `decodeURI` will decode characters such as Cyrillic characters, spaces, etc. + path = decodeURI(path!); + + // Step 2: Manually decode characters that are not decoded by `decodeURI`. + // This includes characters such as "#" and "?", which have special meaning in URLs, + // but are just normal characters in a filesystem path. + for (let i = 0; i < urlDecodePatterns.length; i += 2) { + path = path.replace(urlDecodePatterns[i], urlDecodePatterns[i + 1] as string); + } + + // Step 3: If it's a "file://" URL, then format it consistently + // or convert it to a local filesystem path + let isFileUrl = path.substr(0, 7).toLowerCase() === "file://"; + if (isFileUrl) { + // Strip-off the protocol, and the initial "/", if there is one + path = path[7] === "/" ? path.substr(8) : path.substr(7); + + // insert a colon (":") after the drive letter on Windows + if (isWindows && path[1] === "/") { + path = path[0] + ":" + path.substr(1); + } + + if (keepFileProtocol) { + // Return the consistently-formatted "file://" URL + path = "file:///" + path; + } else { + // Convert the "file://" URL to a local filesystem path. + // On Windows, it will start with something like "C:/". + // On Posix, it will start with "/" + isFileUrl = false; + path = isWindows ? path : "/" + path; + } + } + + // Step 4: Normalize Windows paths (unless it's a "file://" URL) + if (isWindows && !isFileUrl) { + // Replace forward slashes with backslashes + path = path.replace(forwardSlashPattern, "\\"); + + // Capitalize the drive letter + if (path.substr(1, 2) === ":\\") { + path = path[0].toUpperCase() + path.substr(1); + } + } + + return path; +} + +/** + * Converts a $ref pointer to a valid JSON Path. + * + * @param pointer + * @returns + */ +export function safePointerToPath(pointer: any) { + if (pointer.length <= 1 || pointer[0] !== "#" || pointer[1] !== "/") { + return []; + } + + return pointer + .slice(2) + .split("/") + .map((value: any) => { + return decodeURIComponent(value).replace(jsonPointerSlash, "/").replace(jsonPointerTilde, "~"); + }); +} diff --git a/libs/events/node_modules/@apidevtools/json-schema-ref-parser/package.json b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/package.json new file mode 100644 index 000000000..7dfa6950d --- /dev/null +++ b/libs/events/node_modules/@apidevtools/json-schema-ref-parser/package.json @@ -0,0 +1,112 @@ +{ + "name": "@apidevtools/json-schema-ref-parser", + "version": "10.1.0", + "description": "Parse, Resolve, and Dereference JSON Schema $ref pointers", + "keywords": [ + "json", + "schema", + "jsonschema", + "json-schema", + "json-pointer", + "$ref", + "dereference", + "resolve" + ], + "author": { + "name": "James Messinger", + "url": "https://jamesmessinger.com" + }, + "contributors": [ + { + "name": "Boris Cherny", + "email": "boris@performancejs.com" + }, + { + "name": "Phil Sturgeon", + "email": "phil@apisyouwonthate.com" + }, + { + "name": "Jakub Rożek", + "email": "jakub@stoplight.io" + }, + { + "name": "JonLuca DeCaro", + "email": "apis@jonlu.ca" + } + ], + "homepage": "https://apitools.dev/json-schema-ref-parser/", + "repository": { + "type": "git", + "url": "https://github.com/APIDevTools/json-schema-ref-parser.git" + }, + "license": "MIT", + "funding": "https://github.com/sponsors/philsturgeon", + "types": "dist/lib/index.d.ts", + "main": "dist/lib/index.js", + "browser": { + "fs": false + }, + "engines": { + "node": ">= 16" + }, + "files": [ + "lib", + "dist", + "cjs" + ], + "scripts": { + "prepublishOnly": "yarn build", + "lint": "eslint lib", + "build": "rm -fr dist/* && tsc", + "typecheck": "tsc --noEmit", + "prettier": "prettier --write \"**/*.+(js|jsx|ts|tsx|har||json|css|md)\"", + "test": "vitest --coverage", + "test:node": "yarn test", + "test:browser": "cross-env BROWSER=\"true\" yarn test", + "test:update": "vitest -u", + "test:watch": "vitest -w" + }, + "devDependencies": { + "@types/eslint": "8.4.10", + "@types/js-yaml": "^4.0.5", + "@types/node": "^18.11.18", + "@typescript-eslint/eslint-plugin": "^5.48.2", + "@typescript-eslint/eslint-plugin-tslint": "^5.48.2", + "@typescript-eslint/parser": "^5.48.2", + "@vitest/coverage-c8": "^0.28.1", + "abortcontroller-polyfill": "^1.7.5", + "c8": "^7.12.0", + "cross-env": "^7.0.3", + "eslint": "^8.32.0", + "eslint-config-prettier": "^8.6.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-unused-imports": "^2.0.0", + "jsdom": "^21.1.0", + "lint-staged": "^13.1.0", + "node-fetch": "^3.3.0", + "prettier": "^2.8.3", + "typescript": "^4.9.4", + "vitest": "^0.28.1" + }, + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.11", + "@types/lodash.clonedeep": "^4.5.7", + "js-yaml": "^4.1.0", + "lodash.clonedeep": "^4.5.0" + }, + "release": { + "branches": [ + "main" + ], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/npm", + "@semantic-release/github" + ] + } +} diff --git a/libs/events/node_modules/@jsdevtools/ono/CHANGELOG.md b/libs/events/node_modules/@jsdevtools/ono/CHANGELOG.md new file mode 100644 index 000000000..cb7b82021 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/CHANGELOG.md @@ -0,0 +1,122 @@ +Change Log +======================================= +All notable changes will be documented in this file. +`ono` adheres to [Semantic Versioning](http://semver.org/). + + + +[v7.1.0](https://github.com/JS-DevTools/ono/tree/v7.1.0) (2020-03-03) +---------------------------------------------------------------------------------------------------- + +- Added a static `Ono.extend()` method that allows Ono to extend errors that were created outside of Ono. The extended error gets all the Ono functionality, including nested stack traces, custom properties, improved support for `JSON.stringify()`, etc. + + +[Full Changelog](https://github.com/JS-DevTools/ono/compare/v7.0.1...v7.1.0) + + + +[v7.0.0](https://github.com/JS-DevTools/ono/tree/v7.0.0) (2020-02-16) +---------------------------------------------------------------------------------------------------- + +- Moved Ono to the [@JSDevTools scope](https://www.npmjs.com/org/jsdevtools) on NPM + +- The "ono" NPM package is now just a wrapper around the scoped "@jsdevtools/ono" package + + +[Full Changelog](https://github.com/JS-DevTools/ono/compare/v6.0.1...v7.0.0) + + + +[v6.0.0](https://github.com/JS-DevTools/ono/tree/v6.0.0) (2019-12-28) +---------------------------------------------------------------------------------------------------- + +### Breaking Changes + +- Dropped support for IE8 and other JavaScript engines that don't support [`Object.getOwnPropertyDescriptor()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor) + +- Removed `ono.formatter`. It has been replaced with [the `format` option](https://github.com/JS-DevTools/ono#format-option) + +- When using the default `ono()` function to wrap an error, it will now try to match the error's type, rather than simply using the base `Error` class. + +### New Features + +- The [`Ono` constructor](https://github.com/JS-DevTools/ono#onoerror-options) now accepts an optional [options parameter](https://github.com/JS-DevTools/ono#options), which lets you customize the behavior of Ono + +- The [`concatMessages` option](https://github.com/JS-DevTools/ono#concatmessages-option) lets you control whether the original error's message is appended to your error message + +- The [`format` option](https://github.com/JS-DevTools/ono#format-option) lets you provide a custom function for replacing placeholders in error messages + +[Full Changelog](https://github.com/JS-DevTools/ono/compare/v5.1.0...v6.0.0) + + + +[v5.1.0](https://github.com/JS-DevTools/ono/tree/v5.1.0) (2019-09-10) +---------------------------------------------------------------------------------------------------- + +- Added a static `Ono.toJSON()` method that accepts any `Error` (even a non-Ono error) and returns a POJO that can be used with `JSON.stringify()`. Ono errors already have a built-in `toJSON()` method, but this exposes that enhanced functionality in a way that can be used with _any_ error. + +[Full Changelog](https://github.com/JS-DevTools/ono/compare/v5.0.2...v5.1.0) + + + +[v5.0.0](https://github.com/JS-DevTools/ono/tree/v5.0.0) (2019-02-18) +---------------------------------------------------------------------------------------------------- +### Breaking Changes + +#### in Node.js + +- Ono errors previously included an `inspect()` method to support Node's [`util.inspect()` function](https://nodejs.org/api/util.html#util_util_inspect_object_options). As of Node v6.6.0, the `inspect()` method is deprecated in favor of a [`util.inspect.custom`](https://nodejs.org/api/util.html#util_util_inspect_custom). Ono has updated accordingly, so errors no longer have an `inspect()` method. + +#### in Web Browsers + +- We no longer automatically include a polyfill for [Node's `util.format()` function](https://nodejs.org/api/util.html#util_util_format_format_args). We recommend using [ES6 template strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) instead. Or you can import [a polyfill](https://github.com/tmpfs/format-util) yourself and assign it to [the `ono.formatter` property](https://jstools.dev/ono/#onoformatter). + +### New Features + +- Completely rewritten in TypeScript. + +- Ono is now completely dependency free. + +- You can now create your own Ono functions for custom error classes. See [the docs](https://jstools.dev/ono/#custom-error-classes) for details. + +- Symbol-keyed properties are now supported. If the `originalError` and/or `props` objects has Symbol-keyed properties, they will be copied to the Ono error. + +[Full Changelog](https://github.com/JS-DevTools/ono/compare/v4.0.11...v5.0.0) + + + +[v4.0.0](https://github.com/JS-DevTools/ono/tree/v4.0.0) (2017-07-07) +---------------------------------------------------------------------------------------------------- +The `err` parameter (see [the API docs](https://github.com/JS-DevTools/ono#api)) can now be any type of object, not just an `instanceof Error`. This allows for errors that don't extend from the `Error` class, such as [`DOMError`](https://developer.mozilla.org/en-US/docs/Web/API/DOMError), [`DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException), and custom error types. + +> **NOTE:** This should **not** be a breaking change, but I'm bumping the major version number out of an abundance of caution. + +[Full Changelog](https://github.com/JS-DevTools/ono/compare/v3.1.0...v4.0.0) + + + +[v3.1.0](https://github.com/JS-DevTools/ono/tree/v3.1.0) (2017-06-01) +---------------------------------------------------------------------------------------------------- +We removed the direct dependency on [Node's `util.format()`](https://nodejs.org/api/util.html#util_util_format_format_args), which was needlessly bloating the browser bundle. Instead, I now import [`format-util`](https://www.npmjs.com/package/format-util), which a much more [lightweight browser implementation](https://github.com/tmpfs/format-util/blob/f88c550ef10c5aaadc15a7ebab595f891bb385e1/format.js). There's no change when running in Node.js, because `format-util` simply [exports `util.format()`](https://github.com/tmpfs/format-util/blob/392628c5d45e558589f2f19ffb9d79d4b5540010/index.js#L1). + +[Full Changelog](https://github.com/JS-DevTools/ono/compare/v3.0.0...v3.1.0) + + + +[v3.0.0](https://github.com/JS-DevTools/ono/tree/v3.0.0) (2017-06-01) +---------------------------------------------------------------------------------------------------- +- Updated all dependencies and verified support for Node 8.0 +- Ono no longer appears in error stack traces, so errors look like they came directly from your code + +[Full Changelog](https://github.com/JS-DevTools/ono/compare/v2.0.0...v3.0.0) + + + +[v2.0.0](https://github.com/JS-DevTools/ono/tree/v2.0.0) (2015-12-14) +---------------------------------------------------------------------------------------------------- +- Did a major refactoring and code cleanup +- Support for various browser-specific `Error.prototype` properties (`fileName`, `lineNumber`, `sourceURL`, etc.) +- If you define a custom `toJSON()` method on an error object, Ono will no longer overwrite it +- Added support for Node's `util.inspect()` + +[Full Changelog](https://github.com/JS-DevTools/ono/compare/v1.0.22...v2.0.0) diff --git a/libs/events/node_modules/@jsdevtools/ono/LICENSE b/libs/events/node_modules/@jsdevtools/ono/LICENSE new file mode 100644 index 000000000..efc327918 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2015 James Messinger + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +. \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/README.md b/libs/events/node_modules/@jsdevtools/ono/README.md new file mode 100644 index 000000000..db6baa502 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/README.md @@ -0,0 +1,392 @@ +ono (Oh No!) +============================ +### Throw better errors. + +[![npm](https://img.shields.io/npm/v/@jsdevtools/ono.svg)](https://www.npmjs.com/package/@jsdevtools/ono) +[![License](https://img.shields.io/npm/l/@jsdevtools/ono.svg)](LICENSE) +[![Buy us a tree](https://img.shields.io/badge/Treeware-%F0%9F%8C%B3-lightgreen)](https://plant.treeware.earth/JS-DevTools/ono) + +[![Build Status](https://github.com/JS-DevTools/ono/workflows/CI-CD/badge.svg)](https://github.com/JS-DevTools/ono/actions) +[![Coverage Status](https://coveralls.io/repos/github/JS-DevTools/ono/badge.svg?branch=master)](https://coveralls.io/github/JS-DevTools/ono) +[![Dependencies](https://david-dm.org/JS-DevTools/ono.svg)](https://david-dm.org/JS-DevTools/ono) + +[![OS and Browser Compatibility](https://jstools.dev/img/badges/ci-badges-with-ie.svg)](https://github.com/JS-DevTools/ono/actions) + + + +Features +-------------------------- +- Wrap and re-throw an error _without_ losing the original error's type, message, stack trace, and properties + +- Add custom properties to errors — great for error numbers, status codes, etc. + +- Use [format strings](#format-option) for error messages — great for localization + +- Enhanced support for [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) and [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) — great for logging + +- Supports and enhances your own [custom error classes](#custom-error-classes) + +- Tested on Node.js and all modern web browsers on Mac, Windows, and Linux. + + + +Example +-------------------------- + +```javascript +const ono = require("@jsdevtools/ono"); + +// Throw an error with custom properties +throw ono({ code: "NOT_FOUND", status: 404 }, `Resource not found: ${url}`); + +// Wrap an error without losing the original error's stack and props +throw ono(originalError, "An error occurred while saving your changes"); + +// Wrap an error and add custom properties +throw ono(originalError, { code: 404, status: "NOT_FOUND" }); + +// Wrap an error, add custom properties, and change the error message +throw ono(originalError, { code: 404, status: "NOT_FOUND" }, `Resource not found: ${url}`); + +// Throw a specific Error subtype instead +// (works with any of the above signatures) +throw ono.range(...); // RangeError +throw ono.syntax(...); // SyntaxError +throw ono.reference(...); // ReferenceError + +// Create an Ono method for your own custom error class +const { Ono } = require("@jsdevtools/ono"); +class MyErrorClass extends Error {} +ono.myError = new Ono(MyErrorClass); + +// And use it just like any other Ono method +throw ono.myError(...); // MyErrorClass +``` + + + +Installation +-------------------------- +Install using [npm](https://docs.npmjs.com/about-npm/): + +```bash +npm install @jsdevtools/ono +``` + + + +Usage +-------------------------- +When using Ono in Node.js apps, you'll probably want to use **CommonJS** syntax: + +```javascript +const ono = require("@jsdevtools/ono"); +``` + +When using a transpiler such as [Babel](https://babeljs.io/) or [TypeScript](https://www.typescriptlang.org/), or a bundler such as [Webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/), you can use **ECMAScript modules** syntax instead: + +```javascript +import ono from "@jsdevtools/ono"; +``` + + + +Browser support +-------------------------- +Ono supports recent versions of every major web browser. Older browsers may require [Babel](https://babeljs.io/) and/or [polyfills](https://babeljs.io/docs/en/next/babel-polyfill). + +To use Ono in a browser, you'll need to use a bundling tool such as [Webpack](https://webpack.js.org/), [Rollup](https://rollupjs.org/), [Parcel](https://parceljs.org/), or [Browserify](http://browserify.org/). Some bundlers may require a bit of configuration, such as setting `browser: true` in [rollup-plugin-resolve](https://github.com/rollup/rollup-plugin-node-resolve). + + + +API +-------------------------- +### `ono([originalError], [props], [message, ...])` +Creates an [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) object with the given properties. + +* `originalError` - _(optional)_ The original error that occurred, if any. This error's message, stack trace, and properties will be copied to the new error. If this error's type is one of the [known error types](#specific-error-types), then the new error will be of the same type. + +* `props` - _(optional)_ An object whose properties will be copied to the new error. Properties can be anything, including objects and functions. + +* `message` - _(optional)_ The error message string. If it contains placeholders, then pass each placeholder's value as an additional parameter. See the [`format` option](#format-option) for more info. + +### Specific error types +The default `ono()` function may return an instance of the base [`Error` class](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error), or it may return a more specific sub-class, based on the type of the `originalError` argument. If you want to _explicitly_ create a specific type of error, then you can use any of the following methods: + +The method signatures and arguments are exactly the same as [the default `ono()` function](#onooriginalerror-props-message-). + +|Method | Return Type +|:---------------------------|:------------------- +|`ono.error()` |[`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) +|`ono.eval()` |[`EvalError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError) +|`ono.range()` |[`RangeError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError) +|`ono.reference()` |[`ReferenceError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError) +|`ono.syntax()` |[`SyntaxError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError) +|`ono.type()` |[`TypeError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError) +|`ono.uri()` |[`URIError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError) +|`ono.yourCustomErrorHere()` |Add your own [custom error classes](#custom-error-classes) to ono + + + +### `Ono(Error, [options])` +The `Ono` constructor is used to create your own [custom `ono` methods](#custom-error-classes) for custom error types, or to change the default behavior of the built-in methods. + +> **Warning:** Be sure not to confuse `ono` (lowercase) and `Ono` (capitalized). The latter one is a class. + +* `Error` - The Error sub-class that this Ono method will create instances of + +* `options` - _(optional)_ An [options object](#options), which customizes the behavior of the Ono method + + + +Options +--------------------------------- +The `Ono` constructor takes an optional options object as a second parameter. The object can have the following properties, all of which are optional: + +|Option |Type |Default |Description +|-----------------|------------|-------------|--------------------------------------------------------------- +|`concatMessages` |boolean |`true` |When Ono is used to wrap an error, this setting determines whether the inner error's message is appended to the new error message. +|`format` |function or boolean |[`util.format()`](https://nodejs.org/api/util.html#util_util_format_format_args) in Node.js

`false` in web browsers|A function that replaces placeholders like in error messages with values.

If set to `false`, then error messages will be treated as literals and no placeholder replacement will occur. + + +### `concatMessages` Option +When wrapping an error, Ono's default behavior is to append the error's message to your message, with a newline between them. For example: + +```javascript +const ono = require("@jsdevtools/ono"); + +function createArray(length) { + try { + return new Array(length); + } + catch (error) { + // Wrap and re-throw the error + throw ono(error, "Sorry, I was unable to create the array."); + } +} + +// Try to create an array with a negative length +createArray(-5); +``` + +The above code produces the following error message: + +``` +Sorry, I was unable to create the array. +Invalid array length; +``` + +If you'd rather not include the original message, then you can set the `concatMessages` option to `false`. For example: + +```javascript +const { ono, Ono } = require("@jsdevtools/ono"); + +// Override the default behavior for the RangeError +ono.range = new Ono(RangeError, { concatMessages: false }); + +function createArray(length) { + try { + return new Array(length); + } + catch (error) { + // Wrap and re-throw the error + throw ono(error, "Sorry, I was unable to create the array."); + } +} + +// Try to create an array with a negative length +createArray(-5); +``` + +Now the error only includes your message, not the original error message. + +``` +Sorry, I was unable to create the array. +``` + + +### `format` option +The `format` option let you set a format function, which replaces placeholders in error messages with values. + +When running in Node.js, Ono uses [the `util.format()` function](https://nodejs.org/api/util.html#util_util_format_format_args) by default, which lets you use placeholders such as %s, %d, and %j. You can provide the values for these placeholders when calling any Ono method: + +```javascript +throw ono("%s is invalid. Must be at least %d characters.", username, minLength); +``` + +Of course, the above example could be accomplished using [ES6 template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) instead of format strings: + +```javascript +throw ono(`${username} is invalid. Must be at least ${minLength} characters.`); +``` + +Format strings are most useful when you don't alrady know the values at the time that you're writing the string. A common scenario is localization. Here's a simplistic example: + +```javascript +const errorMessages { + invalidLength: { + en: "%s is invalid. Must be at least %d characters.", + es: "%s no es válido. Debe tener al menos %d caracteres.", + zh: "%s 无效。 必须至少%d个字符。", + } +} + +let lang = getCurrentUsersLanguage(); + +throw ono(errorMessages.invalidLength[lang], username, minLength); +``` + +#### The `format` option in web browsers +Web browsers don't have a built-in equivalent of Node's [`util.format()` function](https://nodejs.org/api/util.html#util_util_format_format_args), so format strings are only supported in Node.js by default. However, you can set the `format` option to any compatible polyfill library to enable this functionality in web browsers too. + +Here are some compatible polyfill libraries: + +- [format](https://www.npmjs.com/package/format) +- [format-util](https://github.com/tmpfs/format-util) + + +#### Custom `format` implementation +If the standard [`util.format()`](https://nodejs.org/api/util.html#util_util_format_format_args) functionality isn't sufficient for your needs, then you can set the `format` option to your own custom implementation. Here's a simplistic example: + +```javascript +const { ono, Ono } = require("@jsdevtools/ono"); + +// This is a simple formatter that replaces $0, $1, $2, ... with the corresponding argument +let options = { + format(message, ...args) { + for (let [index, arg] of args.entries()) { + message = message.replace("$" + index, arg); + } + return message; + } +}; + +// Use your custom formatter for all of the built-in error types +ono.error = new Ono(Error, options); +ono.eval = new Ono(EvalError, options); +ono.range = new Ono(RangeError, options); +ono.reference = new Ono(ReferenceError, options); +ono.syntax = new Ono(SyntaxError, options); +ono.type = new Ono(TypeError, options); +ono.uri = new Ono(URIError, options); + +// Now all Ono functions support your custom formatter +throw ono("$0 is invalid. Must be at least $1 characters.", username, minLength); +``` + + + + +Custom Error Classes +----------------------------- +There are two ways to use Ono with your own custom error classes. Which one you choose depends on what parameters your custom error class accepts, and whether you'd prefer to use `ono.myError()` syntax or `new MyError()` syntax. + +### Option 1: Standard Errors +Ono has built-in support for all of [the built-in JavaScript Error types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types). For example, you can use `ono.reference()` to create a `ReferenceError`, or `ono.syntax()` to create a `SyntaxError`. + +All of these built-in JavaScript Error types accept a single parameter: the error message string. If your own error classes also work this way, then you can create Ono methods for your custom error classes. Here's an example: + +```javascript +const { ono, Ono } = require("@jsdevtools/ono"); +let counter = 0; + +// A custom Error class that assigns a unique ID and timestamp to each error +class MyErrorClass extends Error { + constructor(message) { + super(message); + this.id = ++counter; + this.timestamp = new Date(); + } +} + +// Create a new Ono method for your custom Error class +ono.myError = new Ono(MyErrorClass); + +// You can use this method just like any other Ono method +throw ono.myError({ code: 404, status: "NOT_FOUND" }, `Resource not found: ${url}`); +``` + +The code above throws an instance of `MyErrorClass` that looks like this: + +```javascript +{ + "name": "MyErrorClass", + "message": "Resource not found: xyz.html", + "id": 1, + "timestamp": "2019-01-01T12:30:00.456Z", + "code": 404, + "status": "NOT_FOUND", + "stack": "MyErrorClass: Resource not found: xyz.html\n at someFunction (index.js:24:5)", +} +``` + +### Option 2: Enhanced Error Classes +If your custom error classes require more than just an error message string parameter, then you'll need to use Ono differently. Rather than creating a [custom Ono method](#option-1-standard-errors) and using `ono.myError()` syntax, you'll use Ono _inside_ your error class's constructor. This has a few benefits: + +- Your error class can accept whatever parameters you want +- Ono is encapsulated within your error class +- You can use `new MyError()` syntax rather than `ono.myError()` syntax + +```javascript +const { ono, Ono } = require("@jsdevtools/ono"); + +// A custom Error class for 404 Not Found +class NotFoundError extends Error { + constructor(method, url) { + super(`404: ${method} ${url} was not found`); + + // Add custom properties, enhance JSON.stringify() support, etc. + Ono.extend(this, { statusCode: 404, method, url }); + } +} + +// A custom Error class for 500 Server Error +class ServerError extends Error { + constructor(originalError, method, url) { + super(`500: A server error occurred while responding to ${method} ${url}`); + + // Append the stack trace and custom properties of the original error, + // and add new custom properties, enhance JSON.stringify() support, etc. + Ono.extend(this, originalError, { statusCode: 500, method, url }); + } +} +``` + + + +Contributing +-------------------------- +Contributions, enhancements, and bug-fixes are welcome! [Open an issue](https://github.com/JS-DevTools/ono/issues) on GitHub and [submit a pull request](https://github.com/JS-DevTools/ono/pulls). + +#### Building/Testing +To build/test the project locally on your computer: + +1. __Clone this repo__
+`git clone https://github.com/JS-DevTools/ono.git` + +2. __Install dependencies__
+`npm install` + +3. __Run the build script__
+`npm run build` + +4. __Run the tests__
+`npm test` + + + +License +-------------------------- +Ono is 100% free and open-source, under the [MIT license](LICENSE). Use it however you want. + +This package is [Treeware](http://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/JS-DevTools/ono) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats. + + + +Big Thanks To +-------------------------- +Thanks to these awesome companies for their support of Open Source developers ❤ + +[![Travis CI](https://jstools.dev/img/badges/travis-ci.svg)](https://travis-ci.com) +[![SauceLabs](https://jstools.dev/img/badges/sauce-labs.svg)](https://saucelabs.com) +[![Coveralls](https://jstools.dev/img/badges/coveralls.svg)](https://coveralls.io) diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/constructor.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/constructor.d.ts new file mode 100644 index 000000000..74ae3c105 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/constructor.d.ts @@ -0,0 +1,3 @@ +import { OnoConstructor } from "./types"; +declare const constructor: OnoConstructor; +export { constructor as Ono }; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/constructor.js b/libs/events/node_modules/@jsdevtools/ono/cjs/constructor.js new file mode 100644 index 000000000..a4666ea25 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/constructor.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Ono = void 0; +const extend_error_1 = require("./extend-error"); +const normalize_1 = require("./normalize"); +const to_json_1 = require("./to-json"); +const constructor = Ono; +exports.Ono = constructor; +/** + * Creates an `Ono` instance for a specifc error type. + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +function Ono(ErrorConstructor, options) { + options = normalize_1.normalizeOptions(options); + function ono(...args) { + let { originalError, props, message } = normalize_1.normalizeArgs(args, options); + // Create a new error of the specified type + let newError = new ErrorConstructor(message); + // Extend the error with the properties of the original error and the `props` object + return extend_error_1.extendError(newError, originalError, props); + } + ono[Symbol.species] = ErrorConstructor; + return ono; +} +/** + * Returns an object containing all properties of the given Error object, + * which can be used with `JSON.stringify()`. + */ +Ono.toJSON = function toJSON(error) { + return to_json_1.toJSON.call(error); +}; +/** + * Extends the given Error object with enhanced Ono functionality, such as nested stack traces, + * additional properties, and improved support for `JSON.stringify()`. + */ +Ono.extend = function extend(error, originalError, props) { + if (props || originalError instanceof Error) { + return extend_error_1.extendError(error, originalError, props); + } + else if (originalError) { + return extend_error_1.extendError(error, undefined, originalError); + } + else { + return extend_error_1.extendError(error); + } +}; +//# sourceMappingURL=constructor.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/constructor.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/constructor.js.map new file mode 100644 index 000000000..c93cb7fbf --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/constructor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"constructor.js","sourceRoot":"","sources":["../src/constructor.ts"],"names":[],"mappings":";;;AAAA,iDAA6C;AAC7C,2CAA8D;AAC9D,uCAAkD;AAGlD,MAAM,WAAW,GAAG,GAAqB,CAAC;AAClB,0BAAG;AAE3B;;GAEG;AACH,gEAAgE;AAChE,SAAS,GAAG,CAAsB,gBAAyC,EAAE,OAAoB;IAC/F,OAAO,GAAG,4BAAgB,CAAC,OAAO,CAAC,CAAC;IAEpC,SAAS,GAAG,CAAwC,GAAG,IAAe;QACpE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,yBAAa,CAAO,IAAI,EAAE,OAAQ,CAAC,CAAC;QAE5E,2CAA2C;QAC3C,IAAI,QAAQ,GAAG,IAAK,gBAAiD,CAAC,OAAO,CAAC,CAAC;QAE/E,oFAAoF;QACpF,OAAO,0BAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAAC;IACvC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,GAAG,CAAC,MAAM,GAAG,SAAS,MAAM,CAAC,KAAgB;IAC3C,OAAO,gBAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF;;;GAGG;AACH,GAAG,CAAC,MAAM,GAAG,SAAS,MAAM,CAAC,KAAgB,EAAE,aAAyB,EAAE,KAAc;IACtF,IAAI,KAAK,IAAI,aAAa,YAAY,KAAK,EAAE;QAC3C,OAAO,0BAAW,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;KACjD;SACI,IAAI,aAAa,EAAE;QACtB,OAAO,0BAAW,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;KACrD;SACI;QACH,OAAO,0BAAW,CAAC,KAAK,CAAC,CAAC;KAC3B;AACH,CAAC,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/extend-error.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/extend-error.d.ts new file mode 100644 index 000000000..a627b69b7 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/extend-error.d.ts @@ -0,0 +1,9 @@ +import { ErrorLike, OnoError } from "./types"; +/** + * Extends the new error with the properties of the original error and the `props` object. + * + * @param newError - The error object to extend + * @param originalError - The original error object, if any + * @param props - Additional properties to add, if any + */ +export declare function extendError(error: T, originalError?: E, props?: P): T & E & P & OnoError; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/extend-error.js b/libs/events/node_modules/@jsdevtools/ono/cjs/extend-error.js new file mode 100644 index 000000000..bf93d3c2c --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/extend-error.js @@ -0,0 +1,77 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.extendError = void 0; +const isomorphic_node_1 = require("./isomorphic.node"); +const stack_1 = require("./stack"); +const to_json_1 = require("./to-json"); +const protectedProps = ["name", "message", "stack"]; +/** + * Extends the new error with the properties of the original error and the `props` object. + * + * @param newError - The error object to extend + * @param originalError - The original error object, if any + * @param props - Additional properties to add, if any + */ +function extendError(error, originalError, props) { + let onoError = error; + extendStack(onoError, originalError); + // Copy properties from the original error + if (originalError && typeof originalError === "object") { + mergeErrors(onoError, originalError); + } + // The default `toJSON` method doesn't output props like `name`, `message`, `stack`, etc. + // So replace it with one that outputs every property of the error. + onoError.toJSON = to_json_1.toJSON; + // On Node.js, add support for the `util.inspect()` method + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (isomorphic_node_1.addInspectMethod) { + isomorphic_node_1.addInspectMethod(onoError); + } + // Finally, copy custom properties that were specified by the user. + // These props OVERWRITE any previous props + if (props && typeof props === "object") { + Object.assign(onoError, props); + } + return onoError; +} +exports.extendError = extendError; +/** + * Extend the error stack to include its cause + */ +function extendStack(newError, originalError) { + let stackProp = Object.getOwnPropertyDescriptor(newError, "stack"); + if (stack_1.isLazyStack(stackProp)) { + stack_1.lazyJoinStacks(stackProp, newError, originalError); + } + else if (stack_1.isWritableStack(stackProp)) { + newError.stack = stack_1.joinStacks(newError, originalError); + } +} +/** + * Merges properties of the original error with the new error. + * + * @param newError - The error object to extend + * @param originalError - The original error object, if any + */ +function mergeErrors(newError, originalError) { + // Get the original error's keys + // NOTE: We specifically exclude properties that we have already set on the new error. + // This is _especially_ important for the `stack` property, because this property has + // a lazy getter in some environments + let keys = to_json_1.getDeepKeys(originalError, protectedProps); + // HACK: We have to cast the errors to `any` so we can use symbol indexers. + // see https://github.com/Microsoft/TypeScript/issues/1863 + let _newError = newError; + let _originalError = originalError; + for (let key of keys) { + if (_newError[key] === undefined) { + try { + _newError[key] = _originalError[key]; + } + catch (e) { + // This property is read-only, so it can't be copied + } + } + } +} +//# sourceMappingURL=extend-error.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/extend-error.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/extend-error.js.map new file mode 100644 index 000000000..dbbee3292 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/extend-error.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extend-error.js","sourceRoot":"","sources":["../src/extend-error.ts"],"names":[],"mappings":";;;AAAA,uDAAqD;AACrD,mCAAmF;AACnF,uCAAgD;AAGhD,MAAM,cAAc,GAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAE5E;;;;;;GAMG;AACH,SAAgB,WAAW,CAA6D,KAAQ,EAAE,aAAiB,EAAE,KAAS;IAC5H,IAAI,QAAQ,GAAG,KAAmD,CAAC;IAEnE,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAErC,0CAA0C;IAC1C,IAAI,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE;QACtD,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;KACtC;IAED,yFAAyF;IACzF,mEAAmE;IACnE,QAAQ,CAAC,MAAM,GAAG,gBAAM,CAAC;IAEzB,0DAA0D;IAC1D,uEAAuE;IACvE,IAAI,kCAAgB,EAAE;QACpB,kCAAgB,CAAC,QAAQ,CAAC,CAAC;KAC5B;IAED,mEAAmE;IACnE,2CAA2C;IAC3C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACtC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;KAChC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AA3BD,kCA2BC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,QAAmB,EAAE,aAAyB;IACjE,IAAI,SAAS,GAAG,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEnE,IAAI,mBAAW,CAAC,SAAS,CAAC,EAAE;QAC1B,sBAAc,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;KACpD;SACI,IAAI,uBAAe,CAAC,SAAS,CAAC,EAAE;QACnC,QAAQ,CAAC,KAAK,GAAG,kBAAU,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;KACtD;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,QAAmB,EAAE,aAAwB;IAChE,gCAAgC;IAChC,sFAAsF;IACtF,qFAAqF;IACrF,qCAAqC;IACrC,IAAI,IAAI,GAAG,qBAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IAEtD,2EAA2E;IAC3E,0DAA0D;IAC1D,IAAI,SAAS,GAAG,QAAe,CAAC;IAChC,IAAI,cAAc,GAAG,aAAoB,CAAC;IAE1C,KAAK,IAAI,GAAG,IAAI,IAAI,EAAE;QACpB,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;YAChC,IAAI;gBACF,SAAS,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;aACtC;YACD,OAAO,CAAC,EAAE;gBACR,oDAAoD;aACrD;SACF;KACF;AACH,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/index.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/index.d.ts new file mode 100644 index 000000000..e7279dbab --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/index.d.ts @@ -0,0 +1,5 @@ +import { ono } from "./singleton"; +export { Ono } from "./constructor"; +export * from "./types"; +export { ono }; +export default ono; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/index.js b/libs/events/node_modules/@jsdevtools/ono/cjs/index.js new file mode 100644 index 000000000..6c4721874 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/index.js @@ -0,0 +1,25 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ono = void 0; +/* eslint-env commonjs */ +const singleton_1 = require("./singleton"); +Object.defineProperty(exports, "ono", { enumerable: true, get: function () { return singleton_1.ono; } }); +var constructor_1 = require("./constructor"); +Object.defineProperty(exports, "Ono", { enumerable: true, get: function () { return constructor_1.Ono; } }); +__exportStar(require("./types"), exports); +exports.default = singleton_1.ono; +// CommonJS default export hack +if (typeof module === "object" && typeof module.exports === "object") { + module.exports = Object.assign(module.exports.default, module.exports); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/index.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/index.js.map new file mode 100644 index 000000000..b64831f4e --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,yBAAyB;AACzB,2CAAkC;AAIzB,oFAJA,eAAG,OAIA;AAFZ,6CAAoC;AAA3B,kGAAA,GAAG,OAAA;AACZ,0CAAwB;AAGxB,kBAAe,eAAG,CAAC;AAEnB,+BAA+B;AAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE;IACpE,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACxE"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.browser.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.browser.d.ts new file mode 100644 index 000000000..e5d77767c --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.browser.d.ts @@ -0,0 +1,15 @@ +/** + * Ono supports custom formatters for error messages. In Node.js, it defaults + * to the `util.format()` function. In browsers, it defaults to `Array.join()`. + * + * The Node.js functionality can be used in a web browser via a polyfill, + * such as "format-util". + * + * @see https://github.com/tmpfs/format-util + */ +export declare const format = false; +/** + * The `util.inspect()` functionality only applies to Node.js. + * We return the constant `false` here so that the Node-specific code gets removed by tree-shaking. + */ +export declare const addInspectMethod = false; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.browser.js b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.browser.js new file mode 100644 index 000000000..b2fc310d7 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.browser.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.addInspectMethod = exports.format = void 0; +/** + * Ono supports custom formatters for error messages. In Node.js, it defaults + * to the `util.format()` function. In browsers, it defaults to `Array.join()`. + * + * The Node.js functionality can be used in a web browser via a polyfill, + * such as "format-util". + * + * @see https://github.com/tmpfs/format-util + */ +exports.format = false; +/** + * The `util.inspect()` functionality only applies to Node.js. + * We return the constant `false` here so that the Node-specific code gets removed by tree-shaking. + */ +exports.addInspectMethod = false; +//# sourceMappingURL=isomorphic.browser.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.browser.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.browser.js.map new file mode 100644 index 000000000..3fd0a96e2 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.browser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"isomorphic.browser.js","sourceRoot":"","sources":["../src/isomorphic.browser.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;GAQG;AACU,QAAA,MAAM,GAAG,KAAK,CAAC;AAE5B;;;GAGG;AACU,QAAA,gBAAgB,GAAG,KAAK,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.node.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.node.d.ts new file mode 100644 index 000000000..e0ea2c629 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.node.d.ts @@ -0,0 +1,15 @@ +/// +import * as util from "util"; +import { OnoError } from "./types"; +/** + * Ono supports Node's `util.format()` formatting for error messages. + * + * @see https://nodejs.org/api/util.html#util_util_format_format_args + */ +export declare const format: typeof util.format; +/** + * Adds an `inspect()` method to support Node's `util.inspect()` function. + * + * @see https://nodejs.org/api/util.html#util_util_inspect_custom + */ +export declare function addInspectMethod(newError: OnoError): void; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.node.js b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.node.js new file mode 100644 index 000000000..619c937a9 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.node.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.addInspectMethod = exports.format = void 0; +const util = require("util"); +const to_json_1 = require("./to-json"); +// The `inspect()` method is actually a Symbol, not a string key. +// https://nodejs.org/api/util.html#util_util_inspect_custom +const inspectMethod = util.inspect.custom || Symbol.for("nodejs.util.inspect.custom"); +/** + * Ono supports Node's `util.format()` formatting for error messages. + * + * @see https://nodejs.org/api/util.html#util_util_format_format_args + */ +exports.format = util.format; +/** + * Adds an `inspect()` method to support Node's `util.inspect()` function. + * + * @see https://nodejs.org/api/util.html#util_util_inspect_custom + */ +function addInspectMethod(newError) { + // @ts-expect-error - TypeScript doesn't support symbol indexers + newError[inspectMethod] = inspect; +} +exports.addInspectMethod = addInspectMethod; +/** + * Returns a representation of the error for Node's `util.inspect()` method. + * + * @see https://nodejs.org/api/util.html#util_custom_inspection_functions_on_objects + */ +function inspect() { + // HACK: We have to cast the objects to `any` so we can use symbol indexers. + // see https://github.com/Microsoft/TypeScript/issues/1863 + let pojo = {}; + let error = this; + for (let key of to_json_1.getDeepKeys(error)) { + let value = error[key]; + pojo[key] = value; + } + // Don't include the `inspect()` method on the output object, + // otherwise it will cause `util.inspect()` to go into an infinite loop + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete pojo[inspectMethod]; + return pojo; +} +//# sourceMappingURL=isomorphic.node.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.node.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.node.js.map new file mode 100644 index 000000000..2d292408e --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/isomorphic.node.js.map @@ -0,0 +1 @@ +{"version":3,"file":"isomorphic.node.js","sourceRoot":"","sources":["../src/isomorphic.node.ts"],"names":[],"mappings":";;;AAAA,6BAA6B;AAC7B,uCAAwC;AAGxC,iEAAiE;AACjE,4DAA4D;AAC5D,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;AAEtF;;;;GAIG;AACU,QAAA,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AAElC;;;;GAIG;AACH,SAAgB,gBAAgB,CAAI,QAAqB;IACvD,gEAAgE;IAChE,QAAQ,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC;AACpC,CAAC;AAHD,4CAGC;AAED;;;;GAIG;AACH,SAAS,OAAO;IACd,4EAA4E;IAC5E,0DAA0D;IAC1D,IAAI,IAAI,GAAQ,EAAE,CAAC;IACnB,IAAI,KAAK,GAAG,IAAW,CAAC;IAExB,KAAK,IAAI,GAAG,IAAI,qBAAW,CAAC,KAAK,CAAC,EAAE;QAClC,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;KACnB;IAED,6DAA6D;IAC7D,uEAAuE;IACvE,gEAAgE;IAChE,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC;IAE3B,OAAO,IAAqB,CAAC;AAC/B,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/normalize.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/normalize.d.ts new file mode 100644 index 000000000..e5d14d803 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/normalize.d.ts @@ -0,0 +1,13 @@ +import { ErrorLike, OnoOptions } from "./types"; +/** + * Normalizes Ono options, accounting for defaults and optional options. + */ +export declare function normalizeOptions(options?: OnoOptions): OnoOptions; +/** + * Normalizes the Ono arguments, accounting for defaults, options, and optional arguments. + */ +export declare function normalizeArgs(args: unknown[], options: OnoOptions): { + originalError: E | undefined; + props: P | undefined; + message: string; +}; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/normalize.js b/libs/events/node_modules/@jsdevtools/ono/cjs/normalize.js new file mode 100644 index 000000000..ec448c30d --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/normalize.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.normalizeArgs = exports.normalizeOptions = void 0; +const isomorphic_node_1 = require("./isomorphic.node"); +/** + * Normalizes Ono options, accounting for defaults and optional options. + */ +function normalizeOptions(options) { + options = options || {}; + return { + concatMessages: options.concatMessages === undefined ? true : Boolean(options.concatMessages), + format: options.format === undefined ? isomorphic_node_1.format + : (typeof options.format === "function" ? options.format : false), + }; +} +exports.normalizeOptions = normalizeOptions; +/** + * Normalizes the Ono arguments, accounting for defaults, options, and optional arguments. + */ +function normalizeArgs(args, options) { + let originalError; + let props; + let formatArgs; + let message = ""; + // Determine which arguments were actually specified + if (typeof args[0] === "string") { + formatArgs = args; + } + else if (typeof args[1] === "string") { + if (args[0] instanceof Error) { + originalError = args[0]; + } + else { + props = args[0]; + } + formatArgs = args.slice(1); + } + else { + originalError = args[0]; + props = args[1]; + formatArgs = args.slice(2); + } + // If there are any format arguments, then format the error message + if (formatArgs.length > 0) { + if (options.format) { + message = options.format.apply(undefined, formatArgs); + } + else { + message = formatArgs.join(" "); + } + } + if (options.concatMessages && originalError && originalError.message) { + // The inner-error's message will be added to the new message + message += (message ? " \n" : "") + originalError.message; + } + return { originalError, props, message }; +} +exports.normalizeArgs = normalizeArgs; +//# sourceMappingURL=normalize.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/normalize.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/normalize.js.map new file mode 100644 index 000000000..c0923e6ca --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/normalize.js.map @@ -0,0 +1 @@ +{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":";;;AAAA,uDAA2C;AAG3C;;GAEG;AACH,SAAgB,gBAAgB,CAAC,OAAoB;IACnD,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;IACxB,OAAO;QACL,cAAc,EAAE,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;QAC7F,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,wBAAM;YAC3C,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;KACpE,CAAC;AACJ,CAAC;AAPD,4CAOC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAwC,IAAe,EAAE,OAAmB;IACvG,IAAI,aAA4B,CAAC;IACjC,IAAI,KAAoB,CAAC;IACzB,IAAI,UAAqB,CAAC;IAC1B,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,oDAAoD;IACpD,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QAC/B,UAAU,GAAG,IAAI,CAAC;KACnB;SACI,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QACpC,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,KAAK,EAAE;YAC5B,aAAa,GAAG,IAAI,CAAC,CAAC,CAAM,CAAC;SAC9B;aACI;YACH,KAAK,GAAG,IAAI,CAAC,CAAC,CAAM,CAAC;SACtB;QACD,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC5B;SACI;QACH,aAAa,GAAG,IAAI,CAAC,CAAC,CAAM,CAAC;QAC7B,KAAK,GAAG,IAAI,CAAC,CAAC,CAAM,CAAC;QACrB,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC5B;IAED,mEAAmE;IACnE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;QACzB,IAAI,OAAO,CAAC,MAAM,EAAE;YAClB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;SACvD;aACI;YACH,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChC;KACF;IAED,IAAI,OAAO,CAAC,cAAc,IAAI,aAAa,IAAI,aAAa,CAAC,OAAO,EAAE;QACpE,6DAA6D;QAC7D,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC;KAC3D;IAED,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC3C,CAAC;AAzCD,sCAyCC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/singleton.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/singleton.d.ts new file mode 100644 index 000000000..f9ed53d43 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/singleton.d.ts @@ -0,0 +1,3 @@ +import { OnoSingleton } from "./types"; +declare const singleton: OnoSingleton; +export { singleton as ono }; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/singleton.js b/libs/events/node_modules/@jsdevtools/ono/cjs/singleton.js new file mode 100644 index 000000000..57c9f35a9 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/singleton.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ono = void 0; +const constructor_1 = require("./constructor"); +const singleton = ono; +exports.ono = singleton; +ono.error = new constructor_1.Ono(Error); +ono.eval = new constructor_1.Ono(EvalError); +ono.range = new constructor_1.Ono(RangeError); +ono.reference = new constructor_1.Ono(ReferenceError); +ono.syntax = new constructor_1.Ono(SyntaxError); +ono.type = new constructor_1.Ono(TypeError); +ono.uri = new constructor_1.Ono(URIError); +const onoMap = ono; +/** + * Creates a new error with the specified message, properties, and/or inner error. + * If an inner error is provided, then the new error will match its type, if possible. + */ +function ono(...args) { + let originalError = args[0]; + // Is the first argument an Error-like object? + if (typeof originalError === "object" && typeof originalError.name === "string") { + // Try to find an Ono singleton method that matches this error type + for (let typedOno of Object.values(onoMap)) { + if (typeof typedOno === "function" && typedOno.name === "ono") { + let species = typedOno[Symbol.species]; + if (species && species !== Error && (originalError instanceof species || originalError.name === species.name)) { + // Create an error of the same type + return typedOno.apply(undefined, args); + } + } + } + } + // By default, create a base Error object + return ono.error.apply(undefined, args); +} +//# sourceMappingURL=singleton.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/singleton.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/singleton.js.map new file mode 100644 index 000000000..0e284c9b9 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/singleton.js.map @@ -0,0 +1 @@ +{"version":3,"file":"singleton.js","sourceRoot":"","sources":["../src/singleton.ts"],"names":[],"mappings":";;;AACA,+CAAsD;AAGtD,MAAM,SAAS,GAAG,GAAmB,CAAC;AAChB,wBAAG;AAEzB,GAAG,CAAC,KAAK,GAAG,IAAI,iBAAc,CAAC,KAAK,CAAC,CAAC;AACtC,GAAG,CAAC,IAAI,GAAG,IAAI,iBAAc,CAAC,SAAS,CAAC,CAAC;AACzC,GAAG,CAAC,KAAK,GAAG,IAAI,iBAAc,CAAC,UAAU,CAAC,CAAC;AAC3C,GAAG,CAAC,SAAS,GAAG,IAAI,iBAAc,CAAC,cAAc,CAAC,CAAC;AACnD,GAAG,CAAC,MAAM,GAAG,IAAI,iBAAc,CAAC,WAAW,CAAC,CAAC;AAC7C,GAAG,CAAC,IAAI,GAAG,IAAI,iBAAc,CAAC,SAAS,CAAC,CAAC;AACzC,GAAG,CAAC,GAAG,GAAG,IAAI,iBAAc,CAAC,QAAQ,CAAC,CAAC;AAEvC,MAAM,MAAM,GAAG,GAA4C,CAAC;AAE5D;;;GAGG;AACH,SAAS,GAAG,CAAwC,GAAG,IAAe;IACpE,IAAI,aAAa,GAAG,IAAI,CAAC,CAAC,CAA0B,CAAC;IAErD,8CAA8C;IAC9C,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,OAAO,aAAa,CAAC,IAAI,KAAK,QAAQ,EAAE;QAE/E,mEAAmE;QACnE,KAAK,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YAC1C,IAAI,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE;gBAC7D,IAAI,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAEvC,IAAI,OAAO,IAAI,OAAO,KAAK,KAAK,IAAI,CAAC,aAAa,YAAY,OAAO,IAAI,aAAa,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE;oBAC7G,mCAAmC;oBACnC,OAAO,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;iBACxC;aACF;SACF;KACF;IAED,yCAAyC;IACzC,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/stack.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/stack.d.ts new file mode 100644 index 000000000..244878069 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/stack.d.ts @@ -0,0 +1,28 @@ +import { ErrorLike } from "./types"; +/** + * The Property Descriptor of a lazily-computed `stack` property. + */ +interface LazyStack { + configurable: true; + /** + * Lazily computes the error's stack trace. + */ + get(): string | undefined; +} +/** + * Is the property lazily computed? + */ +export declare function isLazyStack(stackProp: PropertyDescriptor | undefined): stackProp is LazyStack; +/** + * Is the stack property writable? + */ +export declare function isWritableStack(stackProp: PropertyDescriptor | undefined): boolean; +/** + * Appends the original `Error.stack` property to the new Error's stack. + */ +export declare function joinStacks(newError: ErrorLike, originalError?: ErrorLike): string | undefined; +/** + * Calls `joinStacks` lazily, when the `Error.stack` property is accessed. + */ +export declare function lazyJoinStacks(lazyStack: LazyStack, newError: ErrorLike, originalError?: ErrorLike): void; +export {}; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/stack.js b/libs/events/node_modules/@jsdevtools/ono/cjs/stack.js new file mode 100644 index 000000000..94350514f --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/stack.js @@ -0,0 +1,102 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.lazyJoinStacks = exports.joinStacks = exports.isWritableStack = exports.isLazyStack = void 0; +const newline = /\r?\n/; +const onoCall = /\bono[ @]/; +/** + * Is the property lazily computed? + */ +function isLazyStack(stackProp) { + return Boolean(stackProp && + stackProp.configurable && + typeof stackProp.get === "function"); +} +exports.isLazyStack = isLazyStack; +/** + * Is the stack property writable? + */ +function isWritableStack(stackProp) { + return Boolean( + // If there is no stack property, then it's writable, since assigning it will create it + !stackProp || + stackProp.writable || + typeof stackProp.set === "function"); +} +exports.isWritableStack = isWritableStack; +/** + * Appends the original `Error.stack` property to the new Error's stack. + */ +function joinStacks(newError, originalError) { + let newStack = popStack(newError.stack); + let originalStack = originalError ? originalError.stack : undefined; + if (newStack && originalStack) { + return newStack + "\n\n" + originalStack; + } + else { + return newStack || originalStack; + } +} +exports.joinStacks = joinStacks; +/** + * Calls `joinStacks` lazily, when the `Error.stack` property is accessed. + */ +function lazyJoinStacks(lazyStack, newError, originalError) { + if (originalError) { + Object.defineProperty(newError, "stack", { + get: () => { + let newStack = lazyStack.get.apply(newError); + return joinStacks({ stack: newStack }, originalError); + }, + enumerable: false, + configurable: true + }); + } + else { + lazyPopStack(newError, lazyStack); + } +} +exports.lazyJoinStacks = lazyJoinStacks; +/** + * Removes Ono from the stack, so that the stack starts at the original error location + */ +function popStack(stack) { + if (stack) { + let lines = stack.split(newline); + // Find the Ono call(s) in the stack, and remove them + let onoStart; + for (let i = 0; i < lines.length; i++) { + let line = lines[i]; + if (onoCall.test(line)) { + if (onoStart === undefined) { + // We found the first Ono call in the stack trace. + // There may be other subsequent Ono calls as well. + onoStart = i; + } + } + else if (onoStart !== undefined) { + // We found the first non-Ono call after one or more Ono calls. + // So remove the Ono call lines from the stack trace + lines.splice(onoStart, i - onoStart); + break; + } + } + if (lines.length > 0) { + return lines.join("\n"); + } + } + // If we get here, then the stack doesn't contain a call to `ono`. + // This may be due to minification or some optimization of the JS engine. + // So just return the stack as-is. + return stack; +} +/** + * Calls `popStack` lazily, when the `Error.stack` property is accessed. + */ +function lazyPopStack(error, lazyStack) { + Object.defineProperty(error, "stack", { + get: () => popStack(lazyStack.get.apply(error)), + enumerable: false, + configurable: true + }); +} +//# sourceMappingURL=stack.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/stack.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/stack.js.map new file mode 100644 index 000000000..c616a3d1e --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/stack.js.map @@ -0,0 +1 @@ +{"version":3,"file":"stack.js","sourceRoot":"","sources":["../src/stack.ts"],"names":[],"mappings":";;;AAEA,MAAM,OAAO,GAAG,OAAO,CAAC;AACxB,MAAM,OAAO,GAAG,WAAW,CAAC;AAc5B;;GAEG;AACH,SAAgB,WAAW,CAAC,SAAyC;IACnE,OAAO,OAAO,CACZ,SAAS;QACT,SAAS,CAAC,YAAY;QACtB,OAAO,SAAS,CAAC,GAAG,KAAK,UAAU,CACpC,CAAC;AACJ,CAAC;AAND,kCAMC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,SAAyC;IACvE,OAAO,OAAO;IACZ,uFAAuF;IACvF,CAAC,SAAS;QACV,SAAS,CAAC,QAAQ;QAClB,OAAO,SAAS,CAAC,GAAG,KAAK,UAAU,CACpC,CAAC;AACJ,CAAC;AAPD,0CAOC;AAED;;GAEG;AACH,SAAgB,UAAU,CAAC,QAAmB,EAAE,aAAyB;IACvE,IAAI,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpE,IAAI,QAAQ,IAAI,aAAa,EAAE;QAC7B,OAAO,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;KAC1C;SACI;QACH,OAAO,QAAQ,IAAI,aAAa,CAAC;KAClC;AACH,CAAC;AAVD,gCAUC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,SAAoB,EAAE,QAAmB,EAAE,aAAyB;IACjG,IAAI,aAAa,EAAE;QACjB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE;YACvC,GAAG,EAAE,GAAG,EAAE;gBACR,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC7C,OAAO,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,aAAa,CAAC,CAAC;YACxD,CAAC;YACD,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;KACJ;SACI;QACH,YAAY,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;KACnC;AACH,CAAC;AAdD,wCAcC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,KAAyB;IACzC,IAAI,KAAK,EAAE;QACT,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEjC,qDAAqD;QACrD,IAAI,QAAQ,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrC,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAEpB,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACtB,IAAI,QAAQ,KAAK,SAAS,EAAE;oBAC1B,kDAAkD;oBAClD,mDAAmD;oBACnD,QAAQ,GAAG,CAAC,CAAC;iBACd;aACF;iBACI,IAAI,QAAQ,KAAK,SAAS,EAAE;gBAC/B,+DAA+D;gBAC/D,oDAAoD;gBACpD,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC;gBACrC,MAAM;aACP;SACF;QAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;YACpB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACzB;KACF;IAED,kEAAkE;IAClE,yEAAyE;IACzE,kCAAkC;IAClC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,KAAgB,EAAE,SAAoB;IAC1D,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE;QACpC,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/C,UAAU,EAAE,KAAK;QACjB,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;AACL,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/to-json.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/to-json.d.ts new file mode 100644 index 000000000..5c065679b --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/to-json.d.ts @@ -0,0 +1,11 @@ +import { ErrorLike, ErrorPOJO } from "./types"; +/** + * Custom JSON serializer for Error objects. + * Returns all built-in error properties, as well as extended properties. + */ +export declare function toJSON(this: E): ErrorPOJO & E; +/** + * Returns own, inherited, enumerable, non-enumerable, string, and symbol keys of `obj`. + * Does NOT return members of the base Object prototype, or the specified omitted keys. + */ +export declare function getDeepKeys(obj: object, omit?: Array): Set; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/to-json.js b/libs/events/node_modules/@jsdevtools/ono/cjs/to-json.js new file mode 100644 index 000000000..2673d287d --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/to-json.js @@ -0,0 +1,48 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getDeepKeys = exports.toJSON = void 0; +const nonJsonTypes = ["function", "symbol", "undefined"]; +const protectedProps = ["constructor", "prototype", "__proto__"]; +const objectPrototype = Object.getPrototypeOf({}); +/** + * Custom JSON serializer for Error objects. + * Returns all built-in error properties, as well as extended properties. + */ +function toJSON() { + // HACK: We have to cast the objects to `any` so we can use symbol indexers. + // see https://github.com/Microsoft/TypeScript/issues/1863 + let pojo = {}; + let error = this; + for (let key of getDeepKeys(error)) { + if (typeof key === "string") { + let value = error[key]; + let type = typeof value; + if (!nonJsonTypes.includes(type)) { + pojo[key] = value; + } + } + } + return pojo; +} +exports.toJSON = toJSON; +/** + * Returns own, inherited, enumerable, non-enumerable, string, and symbol keys of `obj`. + * Does NOT return members of the base Object prototype, or the specified omitted keys. + */ +function getDeepKeys(obj, omit = []) { + let keys = []; + // Crawl the prototype chain, finding all the string and symbol keys + while (obj && obj !== objectPrototype) { + keys = keys.concat(Object.getOwnPropertyNames(obj), Object.getOwnPropertySymbols(obj)); + obj = Object.getPrototypeOf(obj); + } + // De-duplicate the list of keys + let uniqueKeys = new Set(keys); + // Remove any omitted keys + for (let key of omit.concat(protectedProps)) { + uniqueKeys.delete(key); + } + return uniqueKeys; +} +exports.getDeepKeys = getDeepKeys; +//# sourceMappingURL=to-json.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/to-json.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/to-json.js.map new file mode 100644 index 000000000..497ba1a8c --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/to-json.js.map @@ -0,0 +1 @@ +{"version":3,"file":"to-json.js","sourceRoot":"","sources":["../src/to-json.ts"],"names":[],"mappings":";;;AAEA,MAAM,YAAY,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AACzD,MAAM,cAAc,GAAG,CAAC,aAAa,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AACjE,MAAM,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;AAElD;;;GAGG;AACH,SAAgB,MAAM;IACpB,4EAA4E;IAC5E,0DAA0D;IAC1D,IAAI,IAAI,GAAQ,EAAE,CAAC;IACnB,IAAI,KAAK,GAAG,IAAW,CAAC;IAExB,KAAK,IAAI,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE;QAClC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;YAC3B,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,IAAI,GAAG,OAAO,KAAK,CAAC;YAExB,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;gBAChC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aACnB;SACF;KACF;IAED,OAAO,IAAqB,CAAC;AAC/B,CAAC;AAlBD,wBAkBC;AAGD;;;GAGG;AACH,SAAgB,WAAW,CAAC,GAAW,EAAE,OAA+B,EAAE;IACxE,IAAI,IAAI,GAA2B,EAAE,CAAC;IAEtC,oEAAoE;IACpE,OAAO,GAAG,IAAI,GAAG,KAAK,eAAe,EAAE;QACrC,IAAI,GAAG,IAAI,CAAC,MAAM,CAChB,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAC/B,MAAM,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAClC,CAAC;QACF,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAW,CAAC;KAC5C;IAED,gCAAgC;IAChC,IAAI,UAAU,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAE/B,0BAA0B;IAC1B,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;QAC3C,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;KACxB;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AArBD,kCAqBC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/types.d.ts b/libs/events/node_modules/@jsdevtools/ono/cjs/types.d.ts new file mode 100644 index 000000000..d5ce8e05e --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/types.d.ts @@ -0,0 +1,201 @@ +/// +import { inspect } from "util"; +/** + * The default export of the "ono" module. + */ +export interface OnoSingleton extends Ono { + error: Ono; + eval: Ono; + range: Ono; + reference: Ono; + syntax: Ono; + type: Ono; + uri: Ono; +} +/** + * Creates an `Ono` instance for a specifc error type. + */ +export interface OnoConstructor { + (constructor: ErrorLikeConstructor, options?: OnoOptions): Ono; + new (constructor: ErrorLikeConstructor, options?: OnoOptions): Ono; + /** + * Returns an object containing all properties of the given Error object, + * which can be used with `JSON.stringify()`. + */ + toJSON(error: E): ErrorPOJO & E; + /** + * Extends the given Error object with enhanced Ono functionality, such as improved support for + * `JSON.stringify()`. + * + * @param error - The error object to extend. This object instance will be modified and returned. + */ + extend(error: T): T & OnoError; + /** + * Extends the given Error object with enhanced Ono functionality, such as additional properties + * and improved support for `JSON.stringify()`. + * + * @param error - The error object to extend. This object instance will be modified and returned. + * @param props - An object whose properties will be added to the error + */ + extend(error: T, props?: P): T & P & OnoError; + /** + * Extends the given Error object with enhanced Ono functionality, such as nested stack traces + * and improved support for `JSON.stringify()`. + * + * @param error - The error object to extend. This object instance will be modified and returned. + * @param originalError - The original error. This error's stack trace will be added to the error's stack trace. + */ + extend(error: T, originalError?: E): T & E & OnoError; + /** + * Extends the given Error object with enhanced Ono functionality, such as nested stack traces, + * additional properties, and improved support for `JSON.stringify()`. + * + * @param error - The error object to extend. This object instance will be modified and returned. + * @param originalError - The original error. This error's stack trace will be added to the error's stack trace. + * @param props - An object whose properties will be added to the error + */ + extend(error: T, originalError?: E, props?: P): T & E & P & OnoError; +} +/** + * An `Ono` is a function that creates errors of a specific type. + */ +export interface Ono { + /** + * The type of Error that this `Ono` function produces. + */ + readonly [Symbol.species]: ErrorLikeConstructor; + /** + * Creates a new error with the message, stack trace, and properties of another error. + * + * @param error - The original error + */ + (error: E): T & E & OnoError; + /** + * Creates a new error with the message, stack trace, and properties of another error, + * as well as aditional properties. + * + * @param error - The original error + * @param props - An object whose properties will be added to the returned error + */ + (error: E, props: P): T & E & P & OnoError; + /** + * Creates a new error with a formatted message and the stack trace and properties of another error. + * + * @param error - The original error + * @param message - The new error message, possibly including argument placeholders + * @param params - Optional arguments to replace the corresponding placeholders in the message + */ + (error: E, message: string, ...params: unknown[]): T & E & OnoError; + /** + * Creates a new error with a formatted message and the stack trace and properties of another error, + * as well as additional properties. + * + * @param error - The original error + * @param props - An object whose properties will be added to the returned error + * @param message - The new error message, possibly including argument placeholders + * @param params - Optional arguments to replace the corresponding placeholders in the message + */ + (error: E, props: P, message: string, ...params: unknown[]): T & E & P & OnoError; + /** + * Creates an error with a formatted message. + * + * @param message - The new error message, possibly including argument placeholders + * @param params - Optional arguments to replace the corresponding placeholders in the message + */ + (message: string, ...params: unknown[]): T & OnoError; + /** + * Creates an error with additional properties. + * + * @param props - An object whose properties will be added to the returned error + */ +

(props: P): T & P & OnoError; + /** + * Creates an error with a formatted message and additional properties. + * + * @param props - An object whose properties will be added to the returned error + * @param message - The new error message, possibly including argument placeholders + * @param params - Optional arguments to replace the corresponding placeholders in the message + */ +

(props: P, message: string, ...params: unknown[]): T & P & OnoError; +} +/** + * All error objects returned by Ono have these properties. + */ +export interface OnoError extends ErrorPOJO { + /** + * Returns a JSON representation of the error, including all built-in error properties, + * as well as properties that were dynamically added. + */ + toJSON(): ErrorPOJO & T; + /** + * Returns a representation of the error for Node's `util.inspect()` method. + * + * @see https://nodejs.org/api/util.html#util_custom_inspection_functions_on_objects + */ + [inspect.custom](): ErrorPOJO & T; +} +/** + * An error object that doesn't inherit from the `Error` class, such as `DOMError`, `DOMException`, + * and some third-party error types. + */ +export interface ErrorPOJO { + message?: string; + stack?: string; + name?: string; +} +/** + * Any object that "looks like" an `Error` object. + */ +export declare type ErrorLike = Error | ErrorPOJO; +/** + * A constructor for `ErrorLike` objects. + */ +export declare type ErrorLikeConstructor = ErrorLikeConstructorFunction | ErrorLikeConstructorClass; +/** + * A constructor function for `ErrorLike` objects. + * Constructor functions can be called without the `new` keyword. + * + * @example + * throw TypeError(); + */ +export interface ErrorLikeConstructorFunction { + readonly prototype: T; + (): T; +} +/** + * A constructor class for `ErrorLike` objects. + * Constructor classes must be called with the `new` keyword. + * + * @example + * throw new TypeError(); + */ +export interface ErrorLikeConstructorClass { + readonly prototype: T; + new (...args: unknown[]): T; +} +/** + * Options that determine the behavior of an `Ono` instance. + */ +export interface OnoOptions { + /** + * When `Ono` is used to wrap an error, this setting determines whether the inner error's message + * is appended to the new error message. + * + * Defaults to `true`. + */ + concatMessages?: boolean; + /** + * A function that replaces placeholders like "%s" or "%d" in error messages with values. + * If set to `false`, then error messages will be treated as literals and no placeholder replacement will occur. + * + * Defaults to `utils.inspect()` in Node.js. Defaults to `Array.join()` in browsers. + */ + format?: MessageFormatter | false; +} +/** + * A function that accepts a message template and arguments to replace template parameters. + * + * @example + * format("Hello, %s! You have %d unread messages.", "John", 5); + */ +export declare type MessageFormatter = (message: string, ...args: unknown[]) => string; diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/types.js b/libs/events/node_modules/@jsdevtools/ono/cjs/types.js new file mode 100644 index 000000000..85670e7a8 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/types.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = require("util"); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/cjs/types.js.map b/libs/events/node_modules/@jsdevtools/ono/cjs/types.js.map new file mode 100644 index 000000000..9441ac262 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/cjs/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;AAAA,+BAA+B"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/constructor.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/constructor.d.ts new file mode 100644 index 000000000..74ae3c105 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/constructor.d.ts @@ -0,0 +1,3 @@ +import { OnoConstructor } from "./types"; +declare const constructor: OnoConstructor; +export { constructor as Ono }; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/constructor.js b/libs/events/node_modules/@jsdevtools/ono/esm/constructor.js new file mode 100644 index 000000000..bd57bf091 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/constructor.js @@ -0,0 +1,44 @@ +import { extendError } from "./extend-error"; +import { normalizeArgs, normalizeOptions } from "./normalize"; +import { toJSON as errorToJSON } from "./to-json"; +const constructor = Ono; +export { constructor as Ono }; +/** + * Creates an `Ono` instance for a specifc error type. + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +function Ono(ErrorConstructor, options) { + options = normalizeOptions(options); + function ono(...args) { + let { originalError, props, message } = normalizeArgs(args, options); + // Create a new error of the specified type + let newError = new ErrorConstructor(message); + // Extend the error with the properties of the original error and the `props` object + return extendError(newError, originalError, props); + } + ono[Symbol.species] = ErrorConstructor; + return ono; +} +/** + * Returns an object containing all properties of the given Error object, + * which can be used with `JSON.stringify()`. + */ +Ono.toJSON = function toJSON(error) { + return errorToJSON.call(error); +}; +/** + * Extends the given Error object with enhanced Ono functionality, such as nested stack traces, + * additional properties, and improved support for `JSON.stringify()`. + */ +Ono.extend = function extend(error, originalError, props) { + if (props || originalError instanceof Error) { + return extendError(error, originalError, props); + } + else if (originalError) { + return extendError(error, undefined, originalError); + } + else { + return extendError(error); + } +}; +//# sourceMappingURL=constructor.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/constructor.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/constructor.js.map new file mode 100644 index 000000000..167f01030 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/constructor.js.map @@ -0,0 +1 @@ +{"version":3,"file":"constructor.js","sourceRoot":"","sources":["../src/constructor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAGlD,MAAM,WAAW,GAAG,GAAqB,CAAC;AAC1C,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,CAAC;AAE9B;;GAEG;AACH,gEAAgE;AAChE,SAAS,GAAG,CAAsB,gBAAyC,EAAE,OAAoB;IAC/F,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAEpC,SAAS,GAAG,CAAwC,GAAG,IAAe;QACpE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,aAAa,CAAO,IAAI,EAAE,OAAQ,CAAC,CAAC;QAE5E,2CAA2C;QAC3C,IAAI,QAAQ,GAAG,IAAK,gBAAiD,CAAC,OAAO,CAAC,CAAC;QAE/E,oFAAoF;QACpF,OAAO,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAAC;IACvC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,GAAG,CAAC,MAAM,GAAG,SAAS,MAAM,CAAC,KAAgB;IAC3C,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF;;;GAGG;AACH,GAAG,CAAC,MAAM,GAAG,SAAS,MAAM,CAAC,KAAgB,EAAE,aAAyB,EAAE,KAAc;IACtF,IAAI,KAAK,IAAI,aAAa,YAAY,KAAK,EAAE;QAC3C,OAAO,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;KACjD;SACI,IAAI,aAAa,EAAE;QACtB,OAAO,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;KACrD;SACI;QACH,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;KAC3B;AACH,CAAC,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/extend-error.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/extend-error.d.ts new file mode 100644 index 000000000..a627b69b7 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/extend-error.d.ts @@ -0,0 +1,9 @@ +import { ErrorLike, OnoError } from "./types"; +/** + * Extends the new error with the properties of the original error and the `props` object. + * + * @param newError - The error object to extend + * @param originalError - The original error object, if any + * @param props - Additional properties to add, if any + */ +export declare function extendError(error: T, originalError?: E, props?: P): T & E & P & OnoError; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/extend-error.js b/libs/events/node_modules/@jsdevtools/ono/esm/extend-error.js new file mode 100644 index 000000000..651a91daf --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/extend-error.js @@ -0,0 +1,73 @@ +import { addInspectMethod } from "./isomorphic.node"; +import { isLazyStack, isWritableStack, joinStacks, lazyJoinStacks } from "./stack"; +import { getDeepKeys, toJSON } from "./to-json"; +const protectedProps = ["name", "message", "stack"]; +/** + * Extends the new error with the properties of the original error and the `props` object. + * + * @param newError - The error object to extend + * @param originalError - The original error object, if any + * @param props - Additional properties to add, if any + */ +export function extendError(error, originalError, props) { + let onoError = error; + extendStack(onoError, originalError); + // Copy properties from the original error + if (originalError && typeof originalError === "object") { + mergeErrors(onoError, originalError); + } + // The default `toJSON` method doesn't output props like `name`, `message`, `stack`, etc. + // So replace it with one that outputs every property of the error. + onoError.toJSON = toJSON; + // On Node.js, add support for the `util.inspect()` method + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (addInspectMethod) { + addInspectMethod(onoError); + } + // Finally, copy custom properties that were specified by the user. + // These props OVERWRITE any previous props + if (props && typeof props === "object") { + Object.assign(onoError, props); + } + return onoError; +} +/** + * Extend the error stack to include its cause + */ +function extendStack(newError, originalError) { + let stackProp = Object.getOwnPropertyDescriptor(newError, "stack"); + if (isLazyStack(stackProp)) { + lazyJoinStacks(stackProp, newError, originalError); + } + else if (isWritableStack(stackProp)) { + newError.stack = joinStacks(newError, originalError); + } +} +/** + * Merges properties of the original error with the new error. + * + * @param newError - The error object to extend + * @param originalError - The original error object, if any + */ +function mergeErrors(newError, originalError) { + // Get the original error's keys + // NOTE: We specifically exclude properties that we have already set on the new error. + // This is _especially_ important for the `stack` property, because this property has + // a lazy getter in some environments + let keys = getDeepKeys(originalError, protectedProps); + // HACK: We have to cast the errors to `any` so we can use symbol indexers. + // see https://github.com/Microsoft/TypeScript/issues/1863 + let _newError = newError; + let _originalError = originalError; + for (let key of keys) { + if (_newError[key] === undefined) { + try { + _newError[key] = _originalError[key]; + } + catch (e) { + // This property is read-only, so it can't be copied + } + } + } +} +//# sourceMappingURL=extend-error.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/extend-error.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/extend-error.js.map new file mode 100644 index 000000000..29b53ade9 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/extend-error.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extend-error.js","sourceRoot":"","sources":["../src/extend-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGhD,MAAM,cAAc,GAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAE5E;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAA6D,KAAQ,EAAE,aAAiB,EAAE,KAAS;IAC5H,IAAI,QAAQ,GAAG,KAAmD,CAAC;IAEnE,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAErC,0CAA0C;IAC1C,IAAI,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE;QACtD,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;KACtC;IAED,yFAAyF;IACzF,mEAAmE;IACnE,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IAEzB,0DAA0D;IAC1D,uEAAuE;IACvE,IAAI,gBAAgB,EAAE;QACpB,gBAAgB,CAAC,QAAQ,CAAC,CAAC;KAC5B;IAED,mEAAmE;IACnE,2CAA2C;IAC3C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACtC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;KAChC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,QAAmB,EAAE,aAAyB;IACjE,IAAI,SAAS,GAAG,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEnE,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE;QAC1B,cAAc,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;KACpD;SACI,IAAI,eAAe,CAAC,SAAS,CAAC,EAAE;QACnC,QAAQ,CAAC,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;KACtD;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,QAAmB,EAAE,aAAwB;IAChE,gCAAgC;IAChC,sFAAsF;IACtF,qFAAqF;IACrF,qCAAqC;IACrC,IAAI,IAAI,GAAG,WAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IAEtD,2EAA2E;IAC3E,0DAA0D;IAC1D,IAAI,SAAS,GAAG,QAAe,CAAC;IAChC,IAAI,cAAc,GAAG,aAAoB,CAAC;IAE1C,KAAK,IAAI,GAAG,IAAI,IAAI,EAAE;QACpB,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;YAChC,IAAI;gBACF,SAAS,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;aACtC;YACD,OAAO,CAAC,EAAE;gBACR,oDAAoD;aACrD;SACF;KACF;AACH,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/index.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/index.d.ts new file mode 100644 index 000000000..e7279dbab --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/index.d.ts @@ -0,0 +1,5 @@ +import { ono } from "./singleton"; +export { Ono } from "./constructor"; +export * from "./types"; +export { ono }; +export default ono; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/index.js b/libs/events/node_modules/@jsdevtools/ono/esm/index.js new file mode 100644 index 000000000..7e6b46912 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/index.js @@ -0,0 +1,11 @@ +/* eslint-env commonjs */ +import { ono } from "./singleton"; +export { Ono } from "./constructor"; +export * from "./types"; +export { ono }; +export default ono; +// CommonJS default export hack +if (typeof module === "object" && typeof module.exports === "object") { + module.exports = Object.assign(module.exports.default, module.exports); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/index.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/index.js.map new file mode 100644 index 000000000..3865f8b84 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,CAAC;AAEf,eAAe,GAAG,CAAC;AAEnB,+BAA+B;AAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE;IACpE,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACxE"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.browser.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.browser.d.ts new file mode 100644 index 000000000..e5d77767c --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.browser.d.ts @@ -0,0 +1,15 @@ +/** + * Ono supports custom formatters for error messages. In Node.js, it defaults + * to the `util.format()` function. In browsers, it defaults to `Array.join()`. + * + * The Node.js functionality can be used in a web browser via a polyfill, + * such as "format-util". + * + * @see https://github.com/tmpfs/format-util + */ +export declare const format = false; +/** + * The `util.inspect()` functionality only applies to Node.js. + * We return the constant `false` here so that the Node-specific code gets removed by tree-shaking. + */ +export declare const addInspectMethod = false; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.browser.js b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.browser.js new file mode 100644 index 000000000..c863c87a9 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.browser.js @@ -0,0 +1,16 @@ +/** + * Ono supports custom formatters for error messages. In Node.js, it defaults + * to the `util.format()` function. In browsers, it defaults to `Array.join()`. + * + * The Node.js functionality can be used in a web browser via a polyfill, + * such as "format-util". + * + * @see https://github.com/tmpfs/format-util + */ +export const format = false; +/** + * The `util.inspect()` functionality only applies to Node.js. + * We return the constant `false` here so that the Node-specific code gets removed by tree-shaking. + */ +export const addInspectMethod = false; +//# sourceMappingURL=isomorphic.browser.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.browser.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.browser.js.map new file mode 100644 index 000000000..6433a633e --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.browser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"isomorphic.browser.js","sourceRoot":"","sources":["../src/isomorphic.browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC;AAE5B;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.node.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.node.d.ts new file mode 100644 index 000000000..e0ea2c629 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.node.d.ts @@ -0,0 +1,15 @@ +/// +import * as util from "util"; +import { OnoError } from "./types"; +/** + * Ono supports Node's `util.format()` formatting for error messages. + * + * @see https://nodejs.org/api/util.html#util_util_format_format_args + */ +export declare const format: typeof util.format; +/** + * Adds an `inspect()` method to support Node's `util.inspect()` function. + * + * @see https://nodejs.org/api/util.html#util_util_inspect_custom + */ +export declare function addInspectMethod(newError: OnoError): void; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.node.js b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.node.js new file mode 100644 index 000000000..718f1f4c4 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.node.js @@ -0,0 +1,41 @@ +import * as util from "util"; +import { getDeepKeys } from "./to-json"; +// The `inspect()` method is actually a Symbol, not a string key. +// https://nodejs.org/api/util.html#util_util_inspect_custom +const inspectMethod = util.inspect.custom || Symbol.for("nodejs.util.inspect.custom"); +/** + * Ono supports Node's `util.format()` formatting for error messages. + * + * @see https://nodejs.org/api/util.html#util_util_format_format_args + */ +export const format = util.format; +/** + * Adds an `inspect()` method to support Node's `util.inspect()` function. + * + * @see https://nodejs.org/api/util.html#util_util_inspect_custom + */ +export function addInspectMethod(newError) { + // @ts-expect-error - TypeScript doesn't support symbol indexers + newError[inspectMethod] = inspect; +} +/** + * Returns a representation of the error for Node's `util.inspect()` method. + * + * @see https://nodejs.org/api/util.html#util_custom_inspection_functions_on_objects + */ +function inspect() { + // HACK: We have to cast the objects to `any` so we can use symbol indexers. + // see https://github.com/Microsoft/TypeScript/issues/1863 + let pojo = {}; + let error = this; + for (let key of getDeepKeys(error)) { + let value = error[key]; + pojo[key] = value; + } + // Don't include the `inspect()` method on the output object, + // otherwise it will cause `util.inspect()` to go into an infinite loop + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete pojo[inspectMethod]; + return pojo; +} +//# sourceMappingURL=isomorphic.node.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.node.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.node.js.map new file mode 100644 index 000000000..b26cfa2a6 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/isomorphic.node.js.map @@ -0,0 +1 @@ +{"version":3,"file":"isomorphic.node.js","sourceRoot":"","sources":["../src/isomorphic.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxC,iEAAiE;AACjE,4DAA4D;AAC5D,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;AAEtF;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AAElC;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAI,QAAqB;IACvD,gEAAgE;IAChE,QAAQ,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,SAAS,OAAO;IACd,4EAA4E;IAC5E,0DAA0D;IAC1D,IAAI,IAAI,GAAQ,EAAE,CAAC;IACnB,IAAI,KAAK,GAAG,IAAW,CAAC;IAExB,KAAK,IAAI,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE;QAClC,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;KACnB;IAED,6DAA6D;IAC7D,uEAAuE;IACvE,gEAAgE;IAChE,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC;IAE3B,OAAO,IAAqB,CAAC;AAC/B,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/normalize.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/normalize.d.ts new file mode 100644 index 000000000..e5d14d803 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/normalize.d.ts @@ -0,0 +1,13 @@ +import { ErrorLike, OnoOptions } from "./types"; +/** + * Normalizes Ono options, accounting for defaults and optional options. + */ +export declare function normalizeOptions(options?: OnoOptions): OnoOptions; +/** + * Normalizes the Ono arguments, accounting for defaults, options, and optional arguments. + */ +export declare function normalizeArgs(args: unknown[], options: OnoOptions): { + originalError: E | undefined; + props: P | undefined; + message: string; +}; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/normalize.js b/libs/events/node_modules/@jsdevtools/ono/esm/normalize.js new file mode 100644 index 000000000..5ac45f384 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/normalize.js @@ -0,0 +1,54 @@ +import { format } from "./isomorphic.node"; +/** + * Normalizes Ono options, accounting for defaults and optional options. + */ +export function normalizeOptions(options) { + options = options || {}; + return { + concatMessages: options.concatMessages === undefined ? true : Boolean(options.concatMessages), + format: options.format === undefined ? format + : (typeof options.format === "function" ? options.format : false), + }; +} +/** + * Normalizes the Ono arguments, accounting for defaults, options, and optional arguments. + */ +export function normalizeArgs(args, options) { + let originalError; + let props; + let formatArgs; + let message = ""; + // Determine which arguments were actually specified + if (typeof args[0] === "string") { + formatArgs = args; + } + else if (typeof args[1] === "string") { + if (args[0] instanceof Error) { + originalError = args[0]; + } + else { + props = args[0]; + } + formatArgs = args.slice(1); + } + else { + originalError = args[0]; + props = args[1]; + formatArgs = args.slice(2); + } + // If there are any format arguments, then format the error message + if (formatArgs.length > 0) { + if (options.format) { + message = options.format.apply(undefined, formatArgs); + } + else { + message = formatArgs.join(" "); + } + } + if (options.concatMessages && originalError && originalError.message) { + // The inner-error's message will be added to the new message + message += (message ? " \n" : "") + originalError.message; + } + return { originalError, props, message }; +} +//# sourceMappingURL=normalize.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/normalize.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/normalize.js.map new file mode 100644 index 000000000..d66e58e5b --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/normalize.js.map @@ -0,0 +1 @@ +{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACnD,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;IACxB,OAAO;QACL,cAAc,EAAE,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;QAC7F,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM;YAC3C,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;KACpE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAwC,IAAe,EAAE,OAAmB;IACvG,IAAI,aAA4B,CAAC;IACjC,IAAI,KAAoB,CAAC;IACzB,IAAI,UAAqB,CAAC;IAC1B,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,oDAAoD;IACpD,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QAC/B,UAAU,GAAG,IAAI,CAAC;KACnB;SACI,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QACpC,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,KAAK,EAAE;YAC5B,aAAa,GAAG,IAAI,CAAC,CAAC,CAAM,CAAC;SAC9B;aACI;YACH,KAAK,GAAG,IAAI,CAAC,CAAC,CAAM,CAAC;SACtB;QACD,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC5B;SACI;QACH,aAAa,GAAG,IAAI,CAAC,CAAC,CAAM,CAAC;QAC7B,KAAK,GAAG,IAAI,CAAC,CAAC,CAAM,CAAC;QACrB,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC5B;IAED,mEAAmE;IACnE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;QACzB,IAAI,OAAO,CAAC,MAAM,EAAE;YAClB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;SACvD;aACI;YACH,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChC;KACF;IAED,IAAI,OAAO,CAAC,cAAc,IAAI,aAAa,IAAI,aAAa,CAAC,OAAO,EAAE;QACpE,6DAA6D;QAC7D,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC;KAC3D;IAED,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC3C,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/singleton.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/singleton.d.ts new file mode 100644 index 000000000..f9ed53d43 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/singleton.d.ts @@ -0,0 +1,3 @@ +import { OnoSingleton } from "./types"; +declare const singleton: OnoSingleton; +export { singleton as ono }; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/singleton.js b/libs/events/node_modules/@jsdevtools/ono/esm/singleton.js new file mode 100644 index 000000000..950db9d97 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/singleton.js @@ -0,0 +1,34 @@ +import { Ono as OnoConstructor } from "./constructor"; +const singleton = ono; +export { singleton as ono }; +ono.error = new OnoConstructor(Error); +ono.eval = new OnoConstructor(EvalError); +ono.range = new OnoConstructor(RangeError); +ono.reference = new OnoConstructor(ReferenceError); +ono.syntax = new OnoConstructor(SyntaxError); +ono.type = new OnoConstructor(TypeError); +ono.uri = new OnoConstructor(URIError); +const onoMap = ono; +/** + * Creates a new error with the specified message, properties, and/or inner error. + * If an inner error is provided, then the new error will match its type, if possible. + */ +function ono(...args) { + let originalError = args[0]; + // Is the first argument an Error-like object? + if (typeof originalError === "object" && typeof originalError.name === "string") { + // Try to find an Ono singleton method that matches this error type + for (let typedOno of Object.values(onoMap)) { + if (typeof typedOno === "function" && typedOno.name === "ono") { + let species = typedOno[Symbol.species]; + if (species && species !== Error && (originalError instanceof species || originalError.name === species.name)) { + // Create an error of the same type + return typedOno.apply(undefined, args); + } + } + } + } + // By default, create a base Error object + return ono.error.apply(undefined, args); +} +//# sourceMappingURL=singleton.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/singleton.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/singleton.js.map new file mode 100644 index 000000000..751dba106 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/singleton.js.map @@ -0,0 +1 @@ +{"version":3,"file":"singleton.js","sourceRoot":"","sources":["../src/singleton.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,IAAI,cAAc,EAAE,MAAM,eAAe,CAAC;AAGtD,MAAM,SAAS,GAAG,GAAmB,CAAC;AACtC,OAAO,EAAE,SAAS,IAAI,GAAG,EAAE,CAAC;AAE5B,GAAG,CAAC,KAAK,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;AACtC,GAAG,CAAC,IAAI,GAAG,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC;AACzC,GAAG,CAAC,KAAK,GAAG,IAAI,cAAc,CAAC,UAAU,CAAC,CAAC;AAC3C,GAAG,CAAC,SAAS,GAAG,IAAI,cAAc,CAAC,cAAc,CAAC,CAAC;AACnD,GAAG,CAAC,MAAM,GAAG,IAAI,cAAc,CAAC,WAAW,CAAC,CAAC;AAC7C,GAAG,CAAC,IAAI,GAAG,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC;AACzC,GAAG,CAAC,GAAG,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC;AAEvC,MAAM,MAAM,GAAG,GAA4C,CAAC;AAE5D;;;GAGG;AACH,SAAS,GAAG,CAAwC,GAAG,IAAe;IACpE,IAAI,aAAa,GAAG,IAAI,CAAC,CAAC,CAA0B,CAAC;IAErD,8CAA8C;IAC9C,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,OAAO,aAAa,CAAC,IAAI,KAAK,QAAQ,EAAE;QAE/E,mEAAmE;QACnE,KAAK,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YAC1C,IAAI,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE;gBAC7D,IAAI,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAEvC,IAAI,OAAO,IAAI,OAAO,KAAK,KAAK,IAAI,CAAC,aAAa,YAAY,OAAO,IAAI,aAAa,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE;oBAC7G,mCAAmC;oBACnC,OAAO,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;iBACxC;aACF;SACF;KACF;IAED,yCAAyC;IACzC,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/stack.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/stack.d.ts new file mode 100644 index 000000000..244878069 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/stack.d.ts @@ -0,0 +1,28 @@ +import { ErrorLike } from "./types"; +/** + * The Property Descriptor of a lazily-computed `stack` property. + */ +interface LazyStack { + configurable: true; + /** + * Lazily computes the error's stack trace. + */ + get(): string | undefined; +} +/** + * Is the property lazily computed? + */ +export declare function isLazyStack(stackProp: PropertyDescriptor | undefined): stackProp is LazyStack; +/** + * Is the stack property writable? + */ +export declare function isWritableStack(stackProp: PropertyDescriptor | undefined): boolean; +/** + * Appends the original `Error.stack` property to the new Error's stack. + */ +export declare function joinStacks(newError: ErrorLike, originalError?: ErrorLike): string | undefined; +/** + * Calls `joinStacks` lazily, when the `Error.stack` property is accessed. + */ +export declare function lazyJoinStacks(lazyStack: LazyStack, newError: ErrorLike, originalError?: ErrorLike): void; +export {}; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/stack.js b/libs/events/node_modules/@jsdevtools/ono/esm/stack.js new file mode 100644 index 000000000..6f1a6b7b0 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/stack.js @@ -0,0 +1,95 @@ +const newline = /\r?\n/; +const onoCall = /\bono[ @]/; +/** + * Is the property lazily computed? + */ +export function isLazyStack(stackProp) { + return Boolean(stackProp && + stackProp.configurable && + typeof stackProp.get === "function"); +} +/** + * Is the stack property writable? + */ +export function isWritableStack(stackProp) { + return Boolean( + // If there is no stack property, then it's writable, since assigning it will create it + !stackProp || + stackProp.writable || + typeof stackProp.set === "function"); +} +/** + * Appends the original `Error.stack` property to the new Error's stack. + */ +export function joinStacks(newError, originalError) { + let newStack = popStack(newError.stack); + let originalStack = originalError ? originalError.stack : undefined; + if (newStack && originalStack) { + return newStack + "\n\n" + originalStack; + } + else { + return newStack || originalStack; + } +} +/** + * Calls `joinStacks` lazily, when the `Error.stack` property is accessed. + */ +export function lazyJoinStacks(lazyStack, newError, originalError) { + if (originalError) { + Object.defineProperty(newError, "stack", { + get: () => { + let newStack = lazyStack.get.apply(newError); + return joinStacks({ stack: newStack }, originalError); + }, + enumerable: false, + configurable: true + }); + } + else { + lazyPopStack(newError, lazyStack); + } +} +/** + * Removes Ono from the stack, so that the stack starts at the original error location + */ +function popStack(stack) { + if (stack) { + let lines = stack.split(newline); + // Find the Ono call(s) in the stack, and remove them + let onoStart; + for (let i = 0; i < lines.length; i++) { + let line = lines[i]; + if (onoCall.test(line)) { + if (onoStart === undefined) { + // We found the first Ono call in the stack trace. + // There may be other subsequent Ono calls as well. + onoStart = i; + } + } + else if (onoStart !== undefined) { + // We found the first non-Ono call after one or more Ono calls. + // So remove the Ono call lines from the stack trace + lines.splice(onoStart, i - onoStart); + break; + } + } + if (lines.length > 0) { + return lines.join("\n"); + } + } + // If we get here, then the stack doesn't contain a call to `ono`. + // This may be due to minification or some optimization of the JS engine. + // So just return the stack as-is. + return stack; +} +/** + * Calls `popStack` lazily, when the `Error.stack` property is accessed. + */ +function lazyPopStack(error, lazyStack) { + Object.defineProperty(error, "stack", { + get: () => popStack(lazyStack.get.apply(error)), + enumerable: false, + configurable: true + }); +} +//# sourceMappingURL=stack.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/stack.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/stack.js.map new file mode 100644 index 000000000..fabf4aab4 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/stack.js.map @@ -0,0 +1 @@ +{"version":3,"file":"stack.js","sourceRoot":"","sources":["../src/stack.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAAG,OAAO,CAAC;AACxB,MAAM,OAAO,GAAG,WAAW,CAAC;AAc5B;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,SAAyC;IACnE,OAAO,OAAO,CACZ,SAAS;QACT,SAAS,CAAC,YAAY;QACtB,OAAO,SAAS,CAAC,GAAG,KAAK,UAAU,CACpC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,SAAyC;IACvE,OAAO,OAAO;IACZ,uFAAuF;IACvF,CAAC,SAAS;QACV,SAAS,CAAC,QAAQ;QAClB,OAAO,SAAS,CAAC,GAAG,KAAK,UAAU,CACpC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,QAAmB,EAAE,aAAyB;IACvE,IAAI,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpE,IAAI,QAAQ,IAAI,aAAa,EAAE;QAC7B,OAAO,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;KAC1C;SACI;QACH,OAAO,QAAQ,IAAI,aAAa,CAAC;KAClC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,SAAoB,EAAE,QAAmB,EAAE,aAAyB;IACjG,IAAI,aAAa,EAAE;QACjB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE;YACvC,GAAG,EAAE,GAAG,EAAE;gBACR,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC7C,OAAO,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,aAAa,CAAC,CAAC;YACxD,CAAC;YACD,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;KACJ;SACI;QACH,YAAY,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;KACnC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,KAAyB;IACzC,IAAI,KAAK,EAAE;QACT,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEjC,qDAAqD;QACrD,IAAI,QAAQ,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrC,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAEpB,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACtB,IAAI,QAAQ,KAAK,SAAS,EAAE;oBAC1B,kDAAkD;oBAClD,mDAAmD;oBACnD,QAAQ,GAAG,CAAC,CAAC;iBACd;aACF;iBACI,IAAI,QAAQ,KAAK,SAAS,EAAE;gBAC/B,+DAA+D;gBAC/D,oDAAoD;gBACpD,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC;gBACrC,MAAM;aACP;SACF;QAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;YACpB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACzB;KACF;IAED,kEAAkE;IAClE,yEAAyE;IACzE,kCAAkC;IAClC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,KAAgB,EAAE,SAAoB;IAC1D,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE;QACpC,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/C,UAAU,EAAE,KAAK;QACjB,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;AACL,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/to-json.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/to-json.d.ts new file mode 100644 index 000000000..5c065679b --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/to-json.d.ts @@ -0,0 +1,11 @@ +import { ErrorLike, ErrorPOJO } from "./types"; +/** + * Custom JSON serializer for Error objects. + * Returns all built-in error properties, as well as extended properties. + */ +export declare function toJSON(this: E): ErrorPOJO & E; +/** + * Returns own, inherited, enumerable, non-enumerable, string, and symbol keys of `obj`. + * Does NOT return members of the base Object prototype, or the specified omitted keys. + */ +export declare function getDeepKeys(obj: object, omit?: Array): Set; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/to-json.js b/libs/events/node_modules/@jsdevtools/ono/esm/to-json.js new file mode 100644 index 000000000..5ebf0e88a --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/to-json.js @@ -0,0 +1,43 @@ +const nonJsonTypes = ["function", "symbol", "undefined"]; +const protectedProps = ["constructor", "prototype", "__proto__"]; +const objectPrototype = Object.getPrototypeOf({}); +/** + * Custom JSON serializer for Error objects. + * Returns all built-in error properties, as well as extended properties. + */ +export function toJSON() { + // HACK: We have to cast the objects to `any` so we can use symbol indexers. + // see https://github.com/Microsoft/TypeScript/issues/1863 + let pojo = {}; + let error = this; + for (let key of getDeepKeys(error)) { + if (typeof key === "string") { + let value = error[key]; + let type = typeof value; + if (!nonJsonTypes.includes(type)) { + pojo[key] = value; + } + } + } + return pojo; +} +/** + * Returns own, inherited, enumerable, non-enumerable, string, and symbol keys of `obj`. + * Does NOT return members of the base Object prototype, or the specified omitted keys. + */ +export function getDeepKeys(obj, omit = []) { + let keys = []; + // Crawl the prototype chain, finding all the string and symbol keys + while (obj && obj !== objectPrototype) { + keys = keys.concat(Object.getOwnPropertyNames(obj), Object.getOwnPropertySymbols(obj)); + obj = Object.getPrototypeOf(obj); + } + // De-duplicate the list of keys + let uniqueKeys = new Set(keys); + // Remove any omitted keys + for (let key of omit.concat(protectedProps)) { + uniqueKeys.delete(key); + } + return uniqueKeys; +} +//# sourceMappingURL=to-json.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/to-json.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/to-json.js.map new file mode 100644 index 000000000..f5dcdc139 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/to-json.js.map @@ -0,0 +1 @@ +{"version":3,"file":"to-json.js","sourceRoot":"","sources":["../src/to-json.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AACzD,MAAM,cAAc,GAAG,CAAC,aAAa,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AACjE,MAAM,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,MAAM;IACpB,4EAA4E;IAC5E,0DAA0D;IAC1D,IAAI,IAAI,GAAQ,EAAE,CAAC;IACnB,IAAI,KAAK,GAAG,IAAW,CAAC;IAExB,KAAK,IAAI,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE;QAClC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;YAC3B,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,IAAI,GAAG,OAAO,KAAK,CAAC;YAExB,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;gBAChC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aACnB;SACF;KACF;IAED,OAAO,IAAqB,CAAC;AAC/B,CAAC;AAGD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,OAA+B,EAAE;IACxE,IAAI,IAAI,GAA2B,EAAE,CAAC;IAEtC,oEAAoE;IACpE,OAAO,GAAG,IAAI,GAAG,KAAK,eAAe,EAAE;QACrC,IAAI,GAAG,IAAI,CAAC,MAAM,CAChB,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAC/B,MAAM,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAClC,CAAC;QACF,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAW,CAAC;KAC5C;IAED,gCAAgC;IAChC,IAAI,UAAU,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAE/B,0BAA0B;IAC1B,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;QAC3C,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;KACxB;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/types.d.ts b/libs/events/node_modules/@jsdevtools/ono/esm/types.d.ts new file mode 100644 index 000000000..d5ce8e05e --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/types.d.ts @@ -0,0 +1,201 @@ +/// +import { inspect } from "util"; +/** + * The default export of the "ono" module. + */ +export interface OnoSingleton extends Ono { + error: Ono; + eval: Ono; + range: Ono; + reference: Ono; + syntax: Ono; + type: Ono; + uri: Ono; +} +/** + * Creates an `Ono` instance for a specifc error type. + */ +export interface OnoConstructor { + (constructor: ErrorLikeConstructor, options?: OnoOptions): Ono; + new (constructor: ErrorLikeConstructor, options?: OnoOptions): Ono; + /** + * Returns an object containing all properties of the given Error object, + * which can be used with `JSON.stringify()`. + */ + toJSON(error: E): ErrorPOJO & E; + /** + * Extends the given Error object with enhanced Ono functionality, such as improved support for + * `JSON.stringify()`. + * + * @param error - The error object to extend. This object instance will be modified and returned. + */ + extend(error: T): T & OnoError; + /** + * Extends the given Error object with enhanced Ono functionality, such as additional properties + * and improved support for `JSON.stringify()`. + * + * @param error - The error object to extend. This object instance will be modified and returned. + * @param props - An object whose properties will be added to the error + */ + extend(error: T, props?: P): T & P & OnoError; + /** + * Extends the given Error object with enhanced Ono functionality, such as nested stack traces + * and improved support for `JSON.stringify()`. + * + * @param error - The error object to extend. This object instance will be modified and returned. + * @param originalError - The original error. This error's stack trace will be added to the error's stack trace. + */ + extend(error: T, originalError?: E): T & E & OnoError; + /** + * Extends the given Error object with enhanced Ono functionality, such as nested stack traces, + * additional properties, and improved support for `JSON.stringify()`. + * + * @param error - The error object to extend. This object instance will be modified and returned. + * @param originalError - The original error. This error's stack trace will be added to the error's stack trace. + * @param props - An object whose properties will be added to the error + */ + extend(error: T, originalError?: E, props?: P): T & E & P & OnoError; +} +/** + * An `Ono` is a function that creates errors of a specific type. + */ +export interface Ono { + /** + * The type of Error that this `Ono` function produces. + */ + readonly [Symbol.species]: ErrorLikeConstructor; + /** + * Creates a new error with the message, stack trace, and properties of another error. + * + * @param error - The original error + */ + (error: E): T & E & OnoError; + /** + * Creates a new error with the message, stack trace, and properties of another error, + * as well as aditional properties. + * + * @param error - The original error + * @param props - An object whose properties will be added to the returned error + */ + (error: E, props: P): T & E & P & OnoError; + /** + * Creates a new error with a formatted message and the stack trace and properties of another error. + * + * @param error - The original error + * @param message - The new error message, possibly including argument placeholders + * @param params - Optional arguments to replace the corresponding placeholders in the message + */ + (error: E, message: string, ...params: unknown[]): T & E & OnoError; + /** + * Creates a new error with a formatted message and the stack trace and properties of another error, + * as well as additional properties. + * + * @param error - The original error + * @param props - An object whose properties will be added to the returned error + * @param message - The new error message, possibly including argument placeholders + * @param params - Optional arguments to replace the corresponding placeholders in the message + */ + (error: E, props: P, message: string, ...params: unknown[]): T & E & P & OnoError; + /** + * Creates an error with a formatted message. + * + * @param message - The new error message, possibly including argument placeholders + * @param params - Optional arguments to replace the corresponding placeholders in the message + */ + (message: string, ...params: unknown[]): T & OnoError; + /** + * Creates an error with additional properties. + * + * @param props - An object whose properties will be added to the returned error + */ +

(props: P): T & P & OnoError; + /** + * Creates an error with a formatted message and additional properties. + * + * @param props - An object whose properties will be added to the returned error + * @param message - The new error message, possibly including argument placeholders + * @param params - Optional arguments to replace the corresponding placeholders in the message + */ +

(props: P, message: string, ...params: unknown[]): T & P & OnoError; +} +/** + * All error objects returned by Ono have these properties. + */ +export interface OnoError extends ErrorPOJO { + /** + * Returns a JSON representation of the error, including all built-in error properties, + * as well as properties that were dynamically added. + */ + toJSON(): ErrorPOJO & T; + /** + * Returns a representation of the error for Node's `util.inspect()` method. + * + * @see https://nodejs.org/api/util.html#util_custom_inspection_functions_on_objects + */ + [inspect.custom](): ErrorPOJO & T; +} +/** + * An error object that doesn't inherit from the `Error` class, such as `DOMError`, `DOMException`, + * and some third-party error types. + */ +export interface ErrorPOJO { + message?: string; + stack?: string; + name?: string; +} +/** + * Any object that "looks like" an `Error` object. + */ +export declare type ErrorLike = Error | ErrorPOJO; +/** + * A constructor for `ErrorLike` objects. + */ +export declare type ErrorLikeConstructor = ErrorLikeConstructorFunction | ErrorLikeConstructorClass; +/** + * A constructor function for `ErrorLike` objects. + * Constructor functions can be called without the `new` keyword. + * + * @example + * throw TypeError(); + */ +export interface ErrorLikeConstructorFunction { + readonly prototype: T; + (): T; +} +/** + * A constructor class for `ErrorLike` objects. + * Constructor classes must be called with the `new` keyword. + * + * @example + * throw new TypeError(); + */ +export interface ErrorLikeConstructorClass { + readonly prototype: T; + new (...args: unknown[]): T; +} +/** + * Options that determine the behavior of an `Ono` instance. + */ +export interface OnoOptions { + /** + * When `Ono` is used to wrap an error, this setting determines whether the inner error's message + * is appended to the new error message. + * + * Defaults to `true`. + */ + concatMessages?: boolean; + /** + * A function that replaces placeholders like "%s" or "%d" in error messages with values. + * If set to `false`, then error messages will be treated as literals and no placeholder replacement will occur. + * + * Defaults to `utils.inspect()` in Node.js. Defaults to `Array.join()` in browsers. + */ + format?: MessageFormatter | false; +} +/** + * A function that accepts a message template and arguments to replace template parameters. + * + * @example + * format("Hello, %s! You have %d unread messages.", "John", 5); + */ +export declare type MessageFormatter = (message: string, ...args: unknown[]) => string; diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/types.js b/libs/events/node_modules/@jsdevtools/ono/esm/types.js new file mode 100644 index 000000000..e37d5cd7c --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/types.js @@ -0,0 +1,2 @@ +import { inspect } from "util"; +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/esm/types.js.map b/libs/events/node_modules/@jsdevtools/ono/esm/types.js.map new file mode 100644 index 000000000..1dbee1566 --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/esm/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC"} \ No newline at end of file diff --git a/libs/events/node_modules/@jsdevtools/ono/package.json b/libs/events/node_modules/@jsdevtools/ono/package.json new file mode 100644 index 000000000..a5db860ab --- /dev/null +++ b/libs/events/node_modules/@jsdevtools/ono/package.json @@ -0,0 +1,74 @@ +{ + "name": "@jsdevtools/ono", + "version": "7.1.3", + "description": "Throw better errors.", + "keywords": [ + "throw", + "error", + "errors", + "exception", + "printf", + "format", + "wrap", + "inner", + "original", + "stack", + "properties" + ], + "author": { + "name": "James Messinger", + "url": "https://jamesmessinger.com" + }, + "license": "MIT", + "homepage": "https://jstools.dev/ono", + "repository": { + "type": "git", + "url": "https://github.com/JS-DevTools/ono.git" + }, + "main": "cjs/index.js", + "module": "esm/index.js", + "typings": "esm/index.d.ts", + "browser": { + "./cjs/isomorphic.node.js": "./cjs/isomorphic.browser.js", + "./esm/isomorphic.node.js": "./esm/isomorphic.browser.js" + }, + "files": [ + "cjs", + "esm" + ], + "scripts": { + "clean": "shx rm -rf .nyc_output coverage cjs esm", + "lint": "eslint src test", + "build": "npm run build:cjs && npm run build:esm", + "build:esm": "tsc", + "build:cjs": "tsc --module commonjs --outDir cjs", + "test": "npm run test:node && npm run test:typescript && npm run test:browser && npm run lint", + "test:node": "mocha", + "test:browser": "karma start --single-run", + "test:typescript": "tsc --noEmit test/specs/typescript.spec.ts", + "coverage": "npm run coverage:node && npm run coverage:browser", + "coverage:node": "nyc node_modules/mocha/bin/mocha", + "coverage:browser": "npm run test:browser -- --coverage", + "upgrade": "npm-check -u && npm audit fix", + "bump": "bump --tag --push --all", + "release": "npm run upgrade && npm run clean && npm run build && npm test && npm run bump" + }, + "devDependencies": { + "@babel/polyfill": "^7.10.4", + "@jsdevtools/eslint-config": "^1.0.0", + "@jsdevtools/host-environment": "^2.0.3", + "@jsdevtools/karma-config": "^3.1.6", + "@jsdevtools/version-bump-prompt": "^6.0.3", + "@types/node": "^14.0.19", + "chai": "^4.2.0", + "eslint": "^7.4.0", + "karma": "^5.1.0", + "karma-cli": "^2.0.0", + "mocha": "^8.0.1", + "npm-check": "^5.9.2", + "nyc": "^15.1.0", + "shx": "^0.3.2", + "typescript": "^3.9.6" + }, + "dependencies": {} +} diff --git a/libs/events/node_modules/@nodelib/fs.scandir/LICENSE b/libs/events/node_modules/@nodelib/fs.scandir/LICENSE new file mode 100644 index 000000000..65a999460 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Denis Malinochkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/@nodelib/fs.scandir/README.md b/libs/events/node_modules/@nodelib/fs.scandir/README.md new file mode 100644 index 000000000..e0b218b9f --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/README.md @@ -0,0 +1,171 @@ +# @nodelib/fs.scandir + +> List files and directories inside the specified directory. + +## :bulb: Highlights + +The package is aimed at obtaining information about entries in the directory. + +* :moneybag: Returns useful information: `name`, `path`, `dirent` and `stats` (optional). +* :gear: On Node.js 10.10+ uses the mechanism without additional calls to determine the entry type. See [`old` and `modern` mode](#old-and-modern-mode). +* :link: Can safely work with broken symbolic links. + +## Install + +```console +npm install @nodelib/fs.scandir +``` + +## Usage + +```ts +import * as fsScandir from '@nodelib/fs.scandir'; + +fsScandir.scandir('path', (error, stats) => { /* … */ }); +``` + +## API + +### .scandir(path, [optionsOrSettings], callback) + +Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path with standard callback-style. + +```ts +fsScandir.scandir('path', (error, entries) => { /* … */ }); +fsScandir.scandir('path', {}, (error, entries) => { /* … */ }); +fsScandir.scandir('path', new fsScandir.Settings(), (error, entries) => { /* … */ }); +``` + +### .scandirSync(path, [optionsOrSettings]) + +Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path. + +```ts +const entries = fsScandir.scandirSync('path'); +const entries = fsScandir.scandirSync('path', {}); +const entries = fsScandir.scandirSync(('path', new fsScandir.Settings()); +``` + +#### path + +* Required: `true` +* Type: `string | Buffer | URL` + +A path to a file. If a URL is provided, it must use the `file:` protocol. + +#### optionsOrSettings + +* Required: `false` +* Type: `Options | Settings` +* Default: An instance of `Settings` class + +An [`Options`](#options) object or an instance of [`Settings`](#settingsoptions) class. + +> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class. + +### Settings([options]) + +A class of full settings of the package. + +```ts +const settings = new fsScandir.Settings({ followSymbolicLinks: false }); + +const entries = fsScandir.scandirSync('path', settings); +``` + +## Entry + +* `name` — The name of the entry (`unknown.txt`). +* `path` — The path of the entry relative to call directory (`root/unknown.txt`). +* `dirent` — An instance of [`fs.Dirent`](./src/types/index.ts) class. On Node.js below 10.10 will be emulated by [`DirentFromStats`](./src/utils/fs.ts) class. +* `stats` (optional) — An instance of `fs.Stats` class. + +For example, the `scandir` call for `tools` directory with one directory inside: + +```ts +{ + dirent: Dirent { name: 'typedoc', /* … */ }, + name: 'typedoc', + path: 'tools/typedoc' +} +``` + +## Options + +### stats + +* Type: `boolean` +* Default: `false` + +Adds an instance of `fs.Stats` class to the [`Entry`](#entry). + +> :book: Always use `fs.readdir` without the `withFileTypes` option. ??TODO?? + +### followSymbolicLinks + +* Type: `boolean` +* Default: `false` + +Follow symbolic links or not. Call `fs.stat` on symbolic link if `true`. + +### `throwErrorOnBrokenSymbolicLink` + +* Type: `boolean` +* Default: `true` + +Throw an error when symbolic link is broken if `true` or safely use `lstat` call if `false`. + +### `pathSegmentSeparator` + +* Type: `string` +* Default: `path.sep` + +By default, this package uses the correct path separator for your OS (`\` on Windows, `/` on Unix-like systems). But you can set this option to any separator character(s) that you want to use instead. + +### `fs` + +* Type: [`FileSystemAdapter`](./src/adapters/fs.ts) +* Default: A default FS methods + +By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own. + +```ts +interface FileSystemAdapter { + lstat?: typeof fs.lstat; + stat?: typeof fs.stat; + lstatSync?: typeof fs.lstatSync; + statSync?: typeof fs.statSync; + readdir?: typeof fs.readdir; + readdirSync?: typeof fs.readdirSync; +} + +const settings = new fsScandir.Settings({ + fs: { lstat: fakeLstat } +}); +``` + +## `old` and `modern` mode + +This package has two modes that are used depending on the environment and parameters of use. + +### old + +* Node.js below `10.10` or when the `stats` option is enabled + +When working in the old mode, the directory is read first (`fs.readdir`), then the type of entries is determined (`fs.lstat` and/or `fs.stat` for symbolic links). + +### modern + +* Node.js 10.10+ and the `stats` option is disabled + +In the modern mode, reading the directory (`fs.readdir` with the `withFileTypes` option) is combined with obtaining information about its entries. An additional call for symbolic links (`fs.stat`) is still present. + +This mode makes fewer calls to the file system. It's faster. + +## Changelog + +See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version. + +## License + +This software is released under the terms of the MIT license. diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts new file mode 100644 index 000000000..827f1db09 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts @@ -0,0 +1,20 @@ +import type * as fsStat from '@nodelib/fs.stat'; +import type { Dirent, ErrnoException } from '../types'; +export interface ReaddirAsynchronousMethod { + (filepath: string, options: { + withFileTypes: true; + }, callback: (error: ErrnoException | null, files: Dirent[]) => void): void; + (filepath: string, callback: (error: ErrnoException | null, files: string[]) => void): void; +} +export interface ReaddirSynchronousMethod { + (filepath: string, options: { + withFileTypes: true; + }): Dirent[]; + (filepath: string): string[]; +} +export declare type FileSystemAdapter = fsStat.FileSystemAdapter & { + readdir: ReaddirAsynchronousMethod; + readdirSync: ReaddirSynchronousMethod; +}; +export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter; +export declare function createFileSystemAdapter(fsMethods?: Partial): FileSystemAdapter; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/adapters/fs.js b/libs/events/node_modules/@nodelib/fs.scandir/out/adapters/fs.js new file mode 100644 index 000000000..f0fe02202 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/adapters/fs.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0; +const fs = require("fs"); +exports.FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + stat: fs.stat, + lstatSync: fs.lstatSync, + statSync: fs.statSync, + readdir: fs.readdir, + readdirSync: fs.readdirSync +}; +function createFileSystemAdapter(fsMethods) { + if (fsMethods === undefined) { + return exports.FILE_SYSTEM_ADAPTER; + } + return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); +} +exports.createFileSystemAdapter = createFileSystemAdapter; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/constants.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/constants.d.ts new file mode 100644 index 000000000..33f17497d --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/constants.d.ts @@ -0,0 +1,4 @@ +/** + * IS `true` for Node.js 10.10 and greater. + */ +export declare const IS_SUPPORT_READDIR_WITH_FILE_TYPES: boolean; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/constants.js b/libs/events/node_modules/@nodelib/fs.scandir/out/constants.js new file mode 100644 index 000000000..7e3d4411f --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/constants.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = void 0; +const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); +if (NODE_PROCESS_VERSION_PARTS[0] === undefined || NODE_PROCESS_VERSION_PARTS[1] === undefined) { + throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`); +} +const MAJOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); +const MINOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); +const SUPPORTED_MAJOR_VERSION = 10; +const SUPPORTED_MINOR_VERSION = 10; +const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION; +const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION; +/** + * IS `true` for Node.js 10.10 and greater. + */ +exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/index.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/index.d.ts new file mode 100644 index 000000000..b9da83ed1 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/index.d.ts @@ -0,0 +1,12 @@ +import type { FileSystemAdapter, ReaddirAsynchronousMethod, ReaddirSynchronousMethod } from './adapters/fs'; +import * as async from './providers/async'; +import Settings, { Options } from './settings'; +import type { Dirent, Entry } from './types'; +declare type AsyncCallback = async.AsyncCallback; +declare function scandir(path: string, callback: AsyncCallback): void; +declare function scandir(path: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void; +declare namespace scandir { + function __promisify__(path: string, optionsOrSettings?: Options | Settings): Promise; +} +declare function scandirSync(path: string, optionsOrSettings?: Options | Settings): Entry[]; +export { scandir, scandirSync, Settings, AsyncCallback, Dirent, Entry, FileSystemAdapter, ReaddirAsynchronousMethod, ReaddirSynchronousMethod, Options }; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/index.js b/libs/events/node_modules/@nodelib/fs.scandir/out/index.js new file mode 100644 index 000000000..99c70d3d6 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/index.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Settings = exports.scandirSync = exports.scandir = void 0; +const async = require("./providers/async"); +const sync = require("./providers/sync"); +const settings_1 = require("./settings"); +exports.Settings = settings_1.default; +function scandir(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + async.read(path, getSettings(), optionsOrSettingsOrCallback); + return; + } + async.read(path, getSettings(optionsOrSettingsOrCallback), callback); +} +exports.scandir = scandir; +function scandirSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync.read(path, settings); +} +exports.scandirSync = scandirSync; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/providers/async.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/async.d.ts new file mode 100644 index 000000000..5829676df --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/async.d.ts @@ -0,0 +1,7 @@ +/// +import type Settings from '../settings'; +import type { Entry } from '../types'; +export declare type AsyncCallback = (error: NodeJS.ErrnoException, entries: Entry[]) => void; +export declare function read(directory: string, settings: Settings, callback: AsyncCallback): void; +export declare function readdirWithFileTypes(directory: string, settings: Settings, callback: AsyncCallback): void; +export declare function readdir(directory: string, settings: Settings, callback: AsyncCallback): void; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/providers/async.js b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/async.js new file mode 100644 index 000000000..e8e2f0a9c --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/async.js @@ -0,0 +1,104 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.readdir = exports.readdirWithFileTypes = exports.read = void 0; +const fsStat = require("@nodelib/fs.stat"); +const rpl = require("run-parallel"); +const constants_1 = require("../constants"); +const utils = require("../utils"); +const common = require("./common"); +function read(directory, settings, callback) { + if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + readdirWithFileTypes(directory, settings, callback); + return; + } + readdir(directory, settings, callback); +} +exports.read = read; +function readdirWithFileTypes(directory, settings, callback) { + settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => { + if (readdirError !== null) { + callFailureCallback(callback, readdirError); + return; + } + const entries = dirents.map((dirent) => ({ + dirent, + name: dirent.name, + path: common.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator) + })); + if (!settings.followSymbolicLinks) { + callSuccessCallback(callback, entries); + return; + } + const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings)); + rpl(tasks, (rplError, rplEntries) => { + if (rplError !== null) { + callFailureCallback(callback, rplError); + return; + } + callSuccessCallback(callback, rplEntries); + }); + }); +} +exports.readdirWithFileTypes = readdirWithFileTypes; +function makeRplTaskEntry(entry, settings) { + return (done) => { + if (!entry.dirent.isSymbolicLink()) { + done(null, entry); + return; + } + settings.fs.stat(entry.path, (statError, stats) => { + if (statError !== null) { + if (settings.throwErrorOnBrokenSymbolicLink) { + done(statError); + return; + } + done(null, entry); + return; + } + entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); + done(null, entry); + }); + }; +} +function readdir(directory, settings, callback) { + settings.fs.readdir(directory, (readdirError, names) => { + if (readdirError !== null) { + callFailureCallback(callback, readdirError); + return; + } + const tasks = names.map((name) => { + const path = common.joinPathSegments(directory, name, settings.pathSegmentSeparator); + return (done) => { + fsStat.stat(path, settings.fsStatSettings, (error, stats) => { + if (error !== null) { + done(error); + return; + } + const entry = { + name, + path, + dirent: utils.fs.createDirentFromStats(name, stats) + }; + if (settings.stats) { + entry.stats = stats; + } + done(null, entry); + }); + }; + }); + rpl(tasks, (rplError, entries) => { + if (rplError !== null) { + callFailureCallback(callback, rplError); + return; + } + callSuccessCallback(callback, entries); + }); + }); +} +exports.readdir = readdir; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, result) { + callback(null, result); +} diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/providers/common.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/common.d.ts new file mode 100644 index 000000000..2b4d08b57 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/common.d.ts @@ -0,0 +1 @@ +export declare function joinPathSegments(a: string, b: string, separator: string): string; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/providers/common.js b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/common.js new file mode 100644 index 000000000..8724cb59a --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/common.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.joinPathSegments = void 0; +function joinPathSegments(a, b, separator) { + /** + * The correct handling of cases when the first segment is a root (`/`, `C:/`) or UNC path (`//?/C:/`). + */ + if (a.endsWith(separator)) { + return a + b; + } + return a + separator + b; +} +exports.joinPathSegments = joinPathSegments; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/providers/sync.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/sync.d.ts new file mode 100644 index 000000000..e05c8f072 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/sync.d.ts @@ -0,0 +1,5 @@ +import type Settings from '../settings'; +import type { Entry } from '../types'; +export declare function read(directory: string, settings: Settings): Entry[]; +export declare function readdirWithFileTypes(directory: string, settings: Settings): Entry[]; +export declare function readdir(directory: string, settings: Settings): Entry[]; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/providers/sync.js b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/sync.js new file mode 100644 index 000000000..146db3434 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/providers/sync.js @@ -0,0 +1,54 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.readdir = exports.readdirWithFileTypes = exports.read = void 0; +const fsStat = require("@nodelib/fs.stat"); +const constants_1 = require("../constants"); +const utils = require("../utils"); +const common = require("./common"); +function read(directory, settings) { + if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + return readdirWithFileTypes(directory, settings); + } + return readdir(directory, settings); +} +exports.read = read; +function readdirWithFileTypes(directory, settings) { + const dirents = settings.fs.readdirSync(directory, { withFileTypes: true }); + return dirents.map((dirent) => { + const entry = { + dirent, + name: dirent.name, + path: common.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator) + }; + if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { + try { + const stats = settings.fs.statSync(entry.path); + entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); + } + catch (error) { + if (settings.throwErrorOnBrokenSymbolicLink) { + throw error; + } + } + } + return entry; + }); +} +exports.readdirWithFileTypes = readdirWithFileTypes; +function readdir(directory, settings) { + const names = settings.fs.readdirSync(directory); + return names.map((name) => { + const entryPath = common.joinPathSegments(directory, name, settings.pathSegmentSeparator); + const stats = fsStat.statSync(entryPath, settings.fsStatSettings); + const entry = { + name, + path: entryPath, + dirent: utils.fs.createDirentFromStats(name, stats) + }; + if (settings.stats) { + entry.stats = stats; + } + return entry; + }); +} +exports.readdir = readdir; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/settings.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/settings.d.ts new file mode 100644 index 000000000..a0db11559 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/settings.d.ts @@ -0,0 +1,20 @@ +import * as fsStat from '@nodelib/fs.stat'; +import * as fs from './adapters/fs'; +export interface Options { + followSymbolicLinks?: boolean; + fs?: Partial; + pathSegmentSeparator?: string; + stats?: boolean; + throwErrorOnBrokenSymbolicLink?: boolean; +} +export default class Settings { + private readonly _options; + readonly followSymbolicLinks: boolean; + readonly fs: fs.FileSystemAdapter; + readonly pathSegmentSeparator: string; + readonly stats: boolean; + readonly throwErrorOnBrokenSymbolicLink: boolean; + readonly fsStatSettings: fsStat.Settings; + constructor(_options?: Options); + private _getValue; +} diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/settings.js b/libs/events/node_modules/@nodelib/fs.scandir/out/settings.js new file mode 100644 index 000000000..15a3e8cde --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/settings.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); +const fsStat = require("@nodelib/fs.stat"); +const fs = require("./adapters/fs"); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); + this.fs = fs.createFileSystemAdapter(this._options.fs); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); + this.stats = this._getValue(this._options.stats, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + this.fsStatSettings = new fsStat.Settings({ + followSymbolicLink: this.followSymbolicLinks, + fs: this.fs, + throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink + }); + } + _getValue(option, value) { + return option !== null && option !== void 0 ? option : value; + } +} +exports.default = Settings; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/types/index.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/types/index.d.ts new file mode 100644 index 000000000..f326c5e5e --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/types/index.d.ts @@ -0,0 +1,20 @@ +/// +import type * as fs from 'fs'; +export interface Entry { + dirent: Dirent; + name: string; + path: string; + stats?: Stats; +} +export declare type Stats = fs.Stats; +export declare type ErrnoException = NodeJS.ErrnoException; +export interface Dirent { + isBlockDevice: () => boolean; + isCharacterDevice: () => boolean; + isDirectory: () => boolean; + isFIFO: () => boolean; + isFile: () => boolean; + isSocket: () => boolean; + isSymbolicLink: () => boolean; + name: string; +} diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/types/index.js b/libs/events/node_modules/@nodelib/fs.scandir/out/types/index.js new file mode 100644 index 000000000..c8ad2e549 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/types/index.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/utils/fs.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/utils/fs.d.ts new file mode 100644 index 000000000..bb863f157 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/utils/fs.d.ts @@ -0,0 +1,2 @@ +import type { Dirent, Stats } from '../types'; +export declare function createDirentFromStats(name: string, stats: Stats): Dirent; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/utils/fs.js b/libs/events/node_modules/@nodelib/fs.scandir/out/utils/fs.js new file mode 100644 index 000000000..ace7c74d6 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/utils/fs.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createDirentFromStats = void 0; +class DirentFromStats { + constructor(name, stats) { + this.name = name; + this.isBlockDevice = stats.isBlockDevice.bind(stats); + this.isCharacterDevice = stats.isCharacterDevice.bind(stats); + this.isDirectory = stats.isDirectory.bind(stats); + this.isFIFO = stats.isFIFO.bind(stats); + this.isFile = stats.isFile.bind(stats); + this.isSocket = stats.isSocket.bind(stats); + this.isSymbolicLink = stats.isSymbolicLink.bind(stats); + } +} +function createDirentFromStats(name, stats) { + return new DirentFromStats(name, stats); +} +exports.createDirentFromStats = createDirentFromStats; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/utils/index.d.ts b/libs/events/node_modules/@nodelib/fs.scandir/out/utils/index.d.ts new file mode 100644 index 000000000..1b41954e7 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/utils/index.d.ts @@ -0,0 +1,2 @@ +import * as fs from './fs'; +export { fs }; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/out/utils/index.js b/libs/events/node_modules/@nodelib/fs.scandir/out/utils/index.js new file mode 100644 index 000000000..f5de129f4 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/out/utils/index.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.fs = void 0; +const fs = require("./fs"); +exports.fs = fs; diff --git a/libs/events/node_modules/@nodelib/fs.scandir/package.json b/libs/events/node_modules/@nodelib/fs.scandir/package.json new file mode 100644 index 000000000..d3a89241b --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.scandir/package.json @@ -0,0 +1,44 @@ +{ + "name": "@nodelib/fs.scandir", + "version": "2.1.5", + "description": "List files and directories inside the specified directory", + "license": "MIT", + "repository": "https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.scandir", + "keywords": [ + "NodeLib", + "fs", + "FileSystem", + "file system", + "scandir", + "readdir", + "dirent" + ], + "engines": { + "node": ">= 8" + }, + "files": [ + "out/**", + "!out/**/*.map", + "!out/**/*.spec.*" + ], + "main": "out/index.js", + "typings": "out/index.d.ts", + "scripts": { + "clean": "rimraf {tsconfig.tsbuildinfo,out}", + "lint": "eslint \"src/**/*.ts\" --cache", + "compile": "tsc -b .", + "compile:watch": "tsc -p . --watch --sourceMap", + "test": "mocha \"out/**/*.spec.js\" -s 0", + "build": "npm run clean && npm run compile && npm run lint && npm test", + "watch": "npm run clean && npm run compile:watch" + }, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "devDependencies": { + "@nodelib/fs.macchiato": "1.0.4", + "@types/run-parallel": "^1.1.0" + }, + "gitHead": "d6a7960d5281d3dd5f8e2efba49bb552d090f562" +} diff --git a/libs/events/node_modules/@nodelib/fs.stat/LICENSE b/libs/events/node_modules/@nodelib/fs.stat/LICENSE new file mode 100644 index 000000000..65a999460 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Denis Malinochkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/@nodelib/fs.stat/README.md b/libs/events/node_modules/@nodelib/fs.stat/README.md new file mode 100644 index 000000000..686f0471d --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/README.md @@ -0,0 +1,126 @@ +# @nodelib/fs.stat + +> Get the status of a file with some features. + +## :bulb: Highlights + +Wrapper around standard method `fs.lstat` and `fs.stat` with some features. + +* :beginner: Normally follows symbolic link. +* :gear: Can safely work with broken symbolic link. + +## Install + +```console +npm install @nodelib/fs.stat +``` + +## Usage + +```ts +import * as fsStat from '@nodelib/fs.stat'; + +fsStat.stat('path', (error, stats) => { /* … */ }); +``` + +## API + +### .stat(path, [optionsOrSettings], callback) + +Returns an instance of `fs.Stats` class for provided path with standard callback-style. + +```ts +fsStat.stat('path', (error, stats) => { /* … */ }); +fsStat.stat('path', {}, (error, stats) => { /* … */ }); +fsStat.stat('path', new fsStat.Settings(), (error, stats) => { /* … */ }); +``` + +### .statSync(path, [optionsOrSettings]) + +Returns an instance of `fs.Stats` class for provided path. + +```ts +const stats = fsStat.stat('path'); +const stats = fsStat.stat('path', {}); +const stats = fsStat.stat('path', new fsStat.Settings()); +``` + +#### path + +* Required: `true` +* Type: `string | Buffer | URL` + +A path to a file. If a URL is provided, it must use the `file:` protocol. + +#### optionsOrSettings + +* Required: `false` +* Type: `Options | Settings` +* Default: An instance of `Settings` class + +An [`Options`](#options) object or an instance of [`Settings`](#settings) class. + +> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class. + +### Settings([options]) + +A class of full settings of the package. + +```ts +const settings = new fsStat.Settings({ followSymbolicLink: false }); + +const stats = fsStat.stat('path', settings); +``` + +## Options + +### `followSymbolicLink` + +* Type: `boolean` +* Default: `true` + +Follow symbolic link or not. Call `fs.stat` on symbolic link if `true`. + +### `markSymbolicLink` + +* Type: `boolean` +* Default: `false` + +Mark symbolic link by setting the return value of `isSymbolicLink` function to always `true` (even after `fs.stat`). + +> :book: Can be used if you want to know what is hidden behind a symbolic link, but still continue to know that it is a symbolic link. + +### `throwErrorOnBrokenSymbolicLink` + +* Type: `boolean` +* Default: `true` + +Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`. + +### `fs` + +* Type: [`FileSystemAdapter`](./src/adapters/fs.ts) +* Default: A default FS methods + +By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own. + +```ts +interface FileSystemAdapter { + lstat?: typeof fs.lstat; + stat?: typeof fs.stat; + lstatSync?: typeof fs.lstatSync; + statSync?: typeof fs.statSync; +} + +const settings = new fsStat.Settings({ + fs: { lstat: fakeLstat } +}); +``` + +## Changelog + +See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version. + +## License + +This software is released under the terms of the MIT license. diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/adapters/fs.d.ts b/libs/events/node_modules/@nodelib/fs.stat/out/adapters/fs.d.ts new file mode 100644 index 000000000..3af759c95 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/adapters/fs.d.ts @@ -0,0 +1,13 @@ +/// +import * as fs from 'fs'; +import type { ErrnoException } from '../types'; +export declare type StatAsynchronousMethod = (path: string, callback: (error: ErrnoException | null, stats: fs.Stats) => void) => void; +export declare type StatSynchronousMethod = (path: string) => fs.Stats; +export interface FileSystemAdapter { + lstat: StatAsynchronousMethod; + stat: StatAsynchronousMethod; + lstatSync: StatSynchronousMethod; + statSync: StatSynchronousMethod; +} +export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter; +export declare function createFileSystemAdapter(fsMethods?: Partial): FileSystemAdapter; diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/adapters/fs.js b/libs/events/node_modules/@nodelib/fs.stat/out/adapters/fs.js new file mode 100644 index 000000000..8dc08c8ca --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/adapters/fs.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0; +const fs = require("fs"); +exports.FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + stat: fs.stat, + lstatSync: fs.lstatSync, + statSync: fs.statSync +}; +function createFileSystemAdapter(fsMethods) { + if (fsMethods === undefined) { + return exports.FILE_SYSTEM_ADAPTER; + } + return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); +} +exports.createFileSystemAdapter = createFileSystemAdapter; diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/index.d.ts b/libs/events/node_modules/@nodelib/fs.stat/out/index.d.ts new file mode 100644 index 000000000..f95db995c --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/index.d.ts @@ -0,0 +1,12 @@ +import type { FileSystemAdapter, StatAsynchronousMethod, StatSynchronousMethod } from './adapters/fs'; +import * as async from './providers/async'; +import Settings, { Options } from './settings'; +import type { Stats } from './types'; +declare type AsyncCallback = async.AsyncCallback; +declare function stat(path: string, callback: AsyncCallback): void; +declare function stat(path: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void; +declare namespace stat { + function __promisify__(path: string, optionsOrSettings?: Options | Settings): Promise; +} +declare function statSync(path: string, optionsOrSettings?: Options | Settings): Stats; +export { Settings, stat, statSync, AsyncCallback, FileSystemAdapter, StatAsynchronousMethod, StatSynchronousMethod, Options, Stats }; diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/index.js b/libs/events/node_modules/@nodelib/fs.stat/out/index.js new file mode 100644 index 000000000..b23f7510d --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/index.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.statSync = exports.stat = exports.Settings = void 0; +const async = require("./providers/async"); +const sync = require("./providers/sync"); +const settings_1 = require("./settings"); +exports.Settings = settings_1.default; +function stat(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + async.read(path, getSettings(), optionsOrSettingsOrCallback); + return; + } + async.read(path, getSettings(optionsOrSettingsOrCallback), callback); +} +exports.stat = stat; +function statSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync.read(path, settings); +} +exports.statSync = statSync; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/providers/async.d.ts b/libs/events/node_modules/@nodelib/fs.stat/out/providers/async.d.ts new file mode 100644 index 000000000..85423ce11 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/providers/async.d.ts @@ -0,0 +1,4 @@ +import type Settings from '../settings'; +import type { ErrnoException, Stats } from '../types'; +export declare type AsyncCallback = (error: ErrnoException, stats: Stats) => void; +export declare function read(path: string, settings: Settings, callback: AsyncCallback): void; diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/providers/async.js b/libs/events/node_modules/@nodelib/fs.stat/out/providers/async.js new file mode 100644 index 000000000..983ff0e6c --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/providers/async.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.read = void 0; +function read(path, settings, callback) { + settings.fs.lstat(path, (lstatError, lstat) => { + if (lstatError !== null) { + callFailureCallback(callback, lstatError); + return; + } + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + callSuccessCallback(callback, lstat); + return; + } + settings.fs.stat(path, (statError, stat) => { + if (statError !== null) { + if (settings.throwErrorOnBrokenSymbolicLink) { + callFailureCallback(callback, statError); + return; + } + callSuccessCallback(callback, lstat); + return; + } + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; + } + callSuccessCallback(callback, stat); + }); + }); +} +exports.read = read; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, result) { + callback(null, result); +} diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/providers/sync.d.ts b/libs/events/node_modules/@nodelib/fs.stat/out/providers/sync.d.ts new file mode 100644 index 000000000..428c3d792 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/providers/sync.d.ts @@ -0,0 +1,3 @@ +import type Settings from '../settings'; +import type { Stats } from '../types'; +export declare function read(path: string, settings: Settings): Stats; diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/providers/sync.js b/libs/events/node_modules/@nodelib/fs.stat/out/providers/sync.js new file mode 100644 index 000000000..1521c3616 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/providers/sync.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.read = void 0; +function read(path, settings) { + const lstat = settings.fs.lstatSync(path); + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + return lstat; + } + try { + const stat = settings.fs.statSync(path); + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; + } + return stat; + } + catch (error) { + if (!settings.throwErrorOnBrokenSymbolicLink) { + return lstat; + } + throw error; + } +} +exports.read = read; diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/settings.d.ts b/libs/events/node_modules/@nodelib/fs.stat/out/settings.d.ts new file mode 100644 index 000000000..f4b3d4443 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/settings.d.ts @@ -0,0 +1,16 @@ +import * as fs from './adapters/fs'; +export interface Options { + followSymbolicLink?: boolean; + fs?: Partial; + markSymbolicLink?: boolean; + throwErrorOnBrokenSymbolicLink?: boolean; +} +export default class Settings { + private readonly _options; + readonly followSymbolicLink: boolean; + readonly fs: fs.FileSystemAdapter; + readonly markSymbolicLink: boolean; + readonly throwErrorOnBrokenSymbolicLink: boolean; + constructor(_options?: Options); + private _getValue; +} diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/settings.js b/libs/events/node_modules/@nodelib/fs.stat/out/settings.js new file mode 100644 index 000000000..111ec09ca --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/settings.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = require("./adapters/fs"); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); + this.fs = fs.createFileSystemAdapter(this._options.fs); + this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + } + _getValue(option, value) { + return option !== null && option !== void 0 ? option : value; + } +} +exports.default = Settings; diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/types/index.d.ts b/libs/events/node_modules/@nodelib/fs.stat/out/types/index.d.ts new file mode 100644 index 000000000..74c08ed2f --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/types/index.d.ts @@ -0,0 +1,4 @@ +/// +import type * as fs from 'fs'; +export declare type Stats = fs.Stats; +export declare type ErrnoException = NodeJS.ErrnoException; diff --git a/libs/events/node_modules/@nodelib/fs.stat/out/types/index.js b/libs/events/node_modules/@nodelib/fs.stat/out/types/index.js new file mode 100644 index 000000000..c8ad2e549 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/out/types/index.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/libs/events/node_modules/@nodelib/fs.stat/package.json b/libs/events/node_modules/@nodelib/fs.stat/package.json new file mode 100644 index 000000000..f2540c289 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.stat/package.json @@ -0,0 +1,37 @@ +{ + "name": "@nodelib/fs.stat", + "version": "2.0.5", + "description": "Get the status of a file with some features", + "license": "MIT", + "repository": "https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.stat", + "keywords": [ + "NodeLib", + "fs", + "FileSystem", + "file system", + "stat" + ], + "engines": { + "node": ">= 8" + }, + "files": [ + "out/**", + "!out/**/*.map", + "!out/**/*.spec.*" + ], + "main": "out/index.js", + "typings": "out/index.d.ts", + "scripts": { + "clean": "rimraf {tsconfig.tsbuildinfo,out}", + "lint": "eslint \"src/**/*.ts\" --cache", + "compile": "tsc -b .", + "compile:watch": "tsc -p . --watch --sourceMap", + "test": "mocha \"out/**/*.spec.js\" -s 0", + "build": "npm run clean && npm run compile && npm run lint && npm test", + "watch": "npm run clean && npm run compile:watch" + }, + "devDependencies": { + "@nodelib/fs.macchiato": "1.0.4" + }, + "gitHead": "d6a7960d5281d3dd5f8e2efba49bb552d090f562" +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/LICENSE b/libs/events/node_modules/@nodelib/fs.walk/LICENSE new file mode 100644 index 000000000..65a999460 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Denis Malinochkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/@nodelib/fs.walk/README.md b/libs/events/node_modules/@nodelib/fs.walk/README.md new file mode 100644 index 000000000..6ccc08db4 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/README.md @@ -0,0 +1,215 @@ +# @nodelib/fs.walk + +> A library for efficiently walking a directory recursively. + +## :bulb: Highlights + +* :moneybag: Returns useful information: `name`, `path`, `dirent` and `stats` (optional). +* :rocket: On Node.js 10.10+ uses the mechanism without additional calls to determine the entry type for performance reasons. See [`old` and `modern` mode](https://github.com/nodelib/nodelib/blob/master/packages/fs/fs.scandir/README.md#old-and-modern-mode). +* :gear: Built-in directories/files and error filtering system. +* :link: Can safely work with broken symbolic links. + +## Install + +```console +npm install @nodelib/fs.walk +``` + +## Usage + +```ts +import * as fsWalk from '@nodelib/fs.walk'; + +fsWalk.walk('path', (error, entries) => { /* … */ }); +``` + +## API + +### .walk(path, [optionsOrSettings], callback) + +Reads the directory recursively and asynchronously. Requires a callback function. + +> :book: If you want to use the Promise API, use `util.promisify`. + +```ts +fsWalk.walk('path', (error, entries) => { /* … */ }); +fsWalk.walk('path', {}, (error, entries) => { /* … */ }); +fsWalk.walk('path', new fsWalk.Settings(), (error, entries) => { /* … */ }); +``` + +### .walkStream(path, [optionsOrSettings]) + +Reads the directory recursively and asynchronously. [Readable Stream](https://nodejs.org/dist/latest-v12.x/docs/api/stream.html#stream_readable_streams) is used as a provider. + +```ts +const stream = fsWalk.walkStream('path'); +const stream = fsWalk.walkStream('path', {}); +const stream = fsWalk.walkStream('path', new fsWalk.Settings()); +``` + +### .walkSync(path, [optionsOrSettings]) + +Reads the directory recursively and synchronously. Returns an array of entries. + +```ts +const entries = fsWalk.walkSync('path'); +const entries = fsWalk.walkSync('path', {}); +const entries = fsWalk.walkSync('path', new fsWalk.Settings()); +``` + +#### path + +* Required: `true` +* Type: `string | Buffer | URL` + +A path to a file. If a URL is provided, it must use the `file:` protocol. + +#### optionsOrSettings + +* Required: `false` +* Type: `Options | Settings` +* Default: An instance of `Settings` class + +An [`Options`](#options) object or an instance of [`Settings`](#settings) class. + +> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class. + +### Settings([options]) + +A class of full settings of the package. + +```ts +const settings = new fsWalk.Settings({ followSymbolicLinks: true }); + +const entries = fsWalk.walkSync('path', settings); +``` + +## Entry + +* `name` — The name of the entry (`unknown.txt`). +* `path` — The path of the entry relative to call directory (`root/unknown.txt`). +* `dirent` — An instance of [`fs.Dirent`](./src/types/index.ts) class. +* [`stats`] — An instance of `fs.Stats` class. + +## Options + +### basePath + +* Type: `string` +* Default: `undefined` + +By default, all paths are built relative to the root path. You can use this option to set custom root path. + +In the example below we read the files from the `root` directory, but in the results the root path will be `custom`. + +```ts +fsWalk.walkSync('root'); // → ['root/file.txt'] +fsWalk.walkSync('root', { basePath: 'custom' }); // → ['custom/file.txt'] +``` + +### concurrency + +* Type: `number` +* Default: `Infinity` + +The maximum number of concurrent calls to `fs.readdir`. + +> :book: The higher the number, the higher performance and the load on the File System. If you want to read in quiet mode, set the value to `4 * os.cpus().length` (4 is default size of [thread pool work scheduling](http://docs.libuv.org/en/v1.x/threadpool.html#thread-pool-work-scheduling)). + +### deepFilter + +* Type: [`DeepFilterFunction`](./src/settings.ts) +* Default: `undefined` + +A function that indicates whether the directory will be read deep or not. + +```ts +// Skip all directories that starts with `node_modules` +const filter: DeepFilterFunction = (entry) => !entry.path.startsWith('node_modules'); +``` + +### entryFilter + +* Type: [`EntryFilterFunction`](./src/settings.ts) +* Default: `undefined` + +A function that indicates whether the entry will be included to results or not. + +```ts +// Exclude all `.js` files from results +const filter: EntryFilterFunction = (entry) => !entry.name.endsWith('.js'); +``` + +### errorFilter + +* Type: [`ErrorFilterFunction`](./src/settings.ts) +* Default: `undefined` + +A function that allows you to skip errors that occur when reading directories. + +For example, you can skip `ENOENT` errors if required: + +```ts +// Skip all ENOENT errors +const filter: ErrorFilterFunction = (error) => error.code == 'ENOENT'; +``` + +### stats + +* Type: `boolean` +* Default: `false` + +Adds an instance of `fs.Stats` class to the [`Entry`](#entry). + +> :book: Always use `fs.readdir` with additional `fs.lstat/fs.stat` calls to determine the entry type. + +### followSymbolicLinks + +* Type: `boolean` +* Default: `false` + +Follow symbolic links or not. Call `fs.stat` on symbolic link if `true`. + +### `throwErrorOnBrokenSymbolicLink` + +* Type: `boolean` +* Default: `true` + +Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`. + +### `pathSegmentSeparator` + +* Type: `string` +* Default: `path.sep` + +By default, this package uses the correct path separator for your OS (`\` on Windows, `/` on Unix-like systems). But you can set this option to any separator character(s) that you want to use instead. + +### `fs` + +* Type: `FileSystemAdapter` +* Default: A default FS methods + +By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own. + +```ts +interface FileSystemAdapter { + lstat: typeof fs.lstat; + stat: typeof fs.stat; + lstatSync: typeof fs.lstatSync; + statSync: typeof fs.statSync; + readdir: typeof fs.readdir; + readdirSync: typeof fs.readdirSync; +} + +const settings = new fsWalk.Settings({ + fs: { lstat: fakeLstat } +}); +``` + +## Changelog + +See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version. + +## License + +This software is released under the terms of the MIT license. diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/index.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/index.d.ts new file mode 100644 index 000000000..8864c7bff --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/index.d.ts @@ -0,0 +1,14 @@ +/// +import type { Readable } from 'stream'; +import type { Dirent, FileSystemAdapter } from '@nodelib/fs.scandir'; +import { AsyncCallback } from './providers/async'; +import Settings, { DeepFilterFunction, EntryFilterFunction, ErrorFilterFunction, Options } from './settings'; +import type { Entry } from './types'; +declare function walk(directory: string, callback: AsyncCallback): void; +declare function walk(directory: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void; +declare namespace walk { + function __promisify__(directory: string, optionsOrSettings?: Options | Settings): Promise; +} +declare function walkSync(directory: string, optionsOrSettings?: Options | Settings): Entry[]; +declare function walkStream(directory: string, optionsOrSettings?: Options | Settings): Readable; +export { walk, walkSync, walkStream, Settings, AsyncCallback, Dirent, Entry, FileSystemAdapter, Options, DeepFilterFunction, EntryFilterFunction, ErrorFilterFunction }; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/index.js b/libs/events/node_modules/@nodelib/fs.walk/out/index.js new file mode 100644 index 000000000..15207874a --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/index.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Settings = exports.walkStream = exports.walkSync = exports.walk = void 0; +const async_1 = require("./providers/async"); +const stream_1 = require("./providers/stream"); +const sync_1 = require("./providers/sync"); +const settings_1 = require("./settings"); +exports.Settings = settings_1.default; +function walk(directory, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + new async_1.default(directory, getSettings()).read(optionsOrSettingsOrCallback); + return; + } + new async_1.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback); +} +exports.walk = walk; +function walkSync(directory, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new sync_1.default(directory, settings); + return provider.read(); +} +exports.walkSync = walkSync; +function walkStream(directory, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new stream_1.default(directory, settings); + return provider.read(); +} +exports.walkStream = walkStream; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/providers/async.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/providers/async.d.ts new file mode 100644 index 000000000..0f6717d78 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/providers/async.d.ts @@ -0,0 +1,12 @@ +import AsyncReader from '../readers/async'; +import type Settings from '../settings'; +import type { Entry, Errno } from '../types'; +export declare type AsyncCallback = (error: Errno, entries: Entry[]) => void; +export default class AsyncProvider { + private readonly _root; + private readonly _settings; + protected readonly _reader: AsyncReader; + private readonly _storage; + constructor(_root: string, _settings: Settings); + read(callback: AsyncCallback): void; +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/providers/async.js b/libs/events/node_modules/@nodelib/fs.walk/out/providers/async.js new file mode 100644 index 000000000..51d3be51a --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/providers/async.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const async_1 = require("../readers/async"); +class AsyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async_1.default(this._root, this._settings); + this._storage = []; + } + read(callback) { + this._reader.onError((error) => { + callFailureCallback(callback, error); + }); + this._reader.onEntry((entry) => { + this._storage.push(entry); + }); + this._reader.onEnd(() => { + callSuccessCallback(callback, this._storage); + }); + this._reader.read(); + } +} +exports.default = AsyncProvider; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, entries) { + callback(null, entries); +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/providers/index.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/providers/index.d.ts new file mode 100644 index 000000000..874f60c5a --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/providers/index.d.ts @@ -0,0 +1,4 @@ +import AsyncProvider from './async'; +import StreamProvider from './stream'; +import SyncProvider from './sync'; +export { AsyncProvider, StreamProvider, SyncProvider }; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/providers/index.js b/libs/events/node_modules/@nodelib/fs.walk/out/providers/index.js new file mode 100644 index 000000000..4c2529ce8 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/providers/index.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SyncProvider = exports.StreamProvider = exports.AsyncProvider = void 0; +const async_1 = require("./async"); +exports.AsyncProvider = async_1.default; +const stream_1 = require("./stream"); +exports.StreamProvider = stream_1.default; +const sync_1 = require("./sync"); +exports.SyncProvider = sync_1.default; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/providers/stream.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/providers/stream.d.ts new file mode 100644 index 000000000..294185f85 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/providers/stream.d.ts @@ -0,0 +1,12 @@ +/// +import { Readable } from 'stream'; +import AsyncReader from '../readers/async'; +import type Settings from '../settings'; +export default class StreamProvider { + private readonly _root; + private readonly _settings; + protected readonly _reader: AsyncReader; + protected readonly _stream: Readable; + constructor(_root: string, _settings: Settings); + read(): Readable; +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/providers/stream.js b/libs/events/node_modules/@nodelib/fs.walk/out/providers/stream.js new file mode 100644 index 000000000..51298b0f5 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/providers/stream.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = require("stream"); +const async_1 = require("../readers/async"); +class StreamProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async_1.default(this._root, this._settings); + this._stream = new stream_1.Readable({ + objectMode: true, + read: () => { }, + destroy: () => { + if (!this._reader.isDestroyed) { + this._reader.destroy(); + } + } + }); + } + read() { + this._reader.onError((error) => { + this._stream.emit('error', error); + }); + this._reader.onEntry((entry) => { + this._stream.push(entry); + }); + this._reader.onEnd(() => { + this._stream.push(null); + }); + this._reader.read(); + return this._stream; + } +} +exports.default = StreamProvider; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/providers/sync.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/providers/sync.d.ts new file mode 100644 index 000000000..551c42e41 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/providers/sync.d.ts @@ -0,0 +1,10 @@ +import SyncReader from '../readers/sync'; +import type Settings from '../settings'; +import type { Entry } from '../types'; +export default class SyncProvider { + private readonly _root; + private readonly _settings; + protected readonly _reader: SyncReader; + constructor(_root: string, _settings: Settings); + read(): Entry[]; +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/providers/sync.js b/libs/events/node_modules/@nodelib/fs.walk/out/providers/sync.js new file mode 100644 index 000000000..faab6ca2a --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/providers/sync.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const sync_1 = require("../readers/sync"); +class SyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new sync_1.default(this._root, this._settings); + } + read() { + return this._reader.read(); + } +} +exports.default = SyncProvider; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/readers/async.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/readers/async.d.ts new file mode 100644 index 000000000..9acf4e6c2 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/readers/async.d.ts @@ -0,0 +1,30 @@ +/// +import { EventEmitter } from 'events'; +import * as fsScandir from '@nodelib/fs.scandir'; +import type Settings from '../settings'; +import type { Entry, Errno } from '../types'; +import Reader from './reader'; +declare type EntryEventCallback = (entry: Entry) => void; +declare type ErrorEventCallback = (error: Errno) => void; +declare type EndEventCallback = () => void; +export default class AsyncReader extends Reader { + protected readonly _settings: Settings; + protected readonly _scandir: typeof fsScandir.scandir; + protected readonly _emitter: EventEmitter; + private readonly _queue; + private _isFatalError; + private _isDestroyed; + constructor(_root: string, _settings: Settings); + read(): EventEmitter; + get isDestroyed(): boolean; + destroy(): void; + onEntry(callback: EntryEventCallback): void; + onError(callback: ErrorEventCallback): void; + onEnd(callback: EndEventCallback): void; + private _pushToQueue; + private _worker; + private _handleError; + private _handleEntry; + private _emitEntry; +} +export {}; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/readers/async.js b/libs/events/node_modules/@nodelib/fs.walk/out/readers/async.js new file mode 100644 index 000000000..ebe8dd573 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/readers/async.js @@ -0,0 +1,97 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = require("events"); +const fsScandir = require("@nodelib/fs.scandir"); +const fastq = require("fastq"); +const common = require("./common"); +const reader_1 = require("./reader"); +class AsyncReader extends reader_1.default { + constructor(_root, _settings) { + super(_root, _settings); + this._settings = _settings; + this._scandir = fsScandir.scandir; + this._emitter = new events_1.EventEmitter(); + this._queue = fastq(this._worker.bind(this), this._settings.concurrency); + this._isFatalError = false; + this._isDestroyed = false; + this._queue.drain = () => { + if (!this._isFatalError) { + this._emitter.emit('end'); + } + }; + } + read() { + this._isFatalError = false; + this._isDestroyed = false; + setImmediate(() => { + this._pushToQueue(this._root, this._settings.basePath); + }); + return this._emitter; + } + get isDestroyed() { + return this._isDestroyed; + } + destroy() { + if (this._isDestroyed) { + throw new Error('The reader is already destroyed'); + } + this._isDestroyed = true; + this._queue.killAndDrain(); + } + onEntry(callback) { + this._emitter.on('entry', callback); + } + onError(callback) { + this._emitter.once('error', callback); + } + onEnd(callback) { + this._emitter.once('end', callback); + } + _pushToQueue(directory, base) { + const queueItem = { directory, base }; + this._queue.push(queueItem, (error) => { + if (error !== null) { + this._handleError(error); + } + }); + } + _worker(item, done) { + this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => { + if (error !== null) { + done(error, undefined); + return; + } + for (const entry of entries) { + this._handleEntry(entry, item.base); + } + done(null, undefined); + }); + } + _handleError(error) { + if (this._isDestroyed || !common.isFatalError(this._settings, error)) { + return; + } + this._isFatalError = true; + this._isDestroyed = true; + this._emitter.emit('error', error); + } + _handleEntry(entry, base) { + if (this._isDestroyed || this._isFatalError) { + return; + } + const fullpath = entry.path; + if (base !== undefined) { + entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } + if (common.isAppliedFilter(this._settings.entryFilter, entry)) { + this._emitEntry(entry); + } + if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, base === undefined ? undefined : entry.path); + } + } + _emitEntry(entry) { + this._emitter.emit('entry', entry); + } +} +exports.default = AsyncReader; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/readers/common.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/readers/common.d.ts new file mode 100644 index 000000000..5985f97c4 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/readers/common.d.ts @@ -0,0 +1,7 @@ +import type { FilterFunction } from '../settings'; +import type Settings from '../settings'; +import type { Errno } from '../types'; +export declare function isFatalError(settings: Settings, error: Errno): boolean; +export declare function isAppliedFilter(filter: FilterFunction | null, value: T): boolean; +export declare function replacePathSegmentSeparator(filepath: string, separator: string): string; +export declare function joinPathSegments(a: string, b: string, separator: string): string; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/readers/common.js b/libs/events/node_modules/@nodelib/fs.walk/out/readers/common.js new file mode 100644 index 000000000..a93572f48 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/readers/common.js @@ -0,0 +1,31 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.joinPathSegments = exports.replacePathSegmentSeparator = exports.isAppliedFilter = exports.isFatalError = void 0; +function isFatalError(settings, error) { + if (settings.errorFilter === null) { + return true; + } + return !settings.errorFilter(error); +} +exports.isFatalError = isFatalError; +function isAppliedFilter(filter, value) { + return filter === null || filter(value); +} +exports.isAppliedFilter = isAppliedFilter; +function replacePathSegmentSeparator(filepath, separator) { + return filepath.split(/[/\\]/).join(separator); +} +exports.replacePathSegmentSeparator = replacePathSegmentSeparator; +function joinPathSegments(a, b, separator) { + if (a === '') { + return b; + } + /** + * The correct handling of cases when the first segment is a root (`/`, `C:/`) or UNC path (`//?/C:/`). + */ + if (a.endsWith(separator)) { + return a + b; + } + return a + separator + b; +} +exports.joinPathSegments = joinPathSegments; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/readers/reader.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/readers/reader.d.ts new file mode 100644 index 000000000..e1f383b25 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/readers/reader.d.ts @@ -0,0 +1,6 @@ +import type Settings from '../settings'; +export default class Reader { + protected readonly _root: string; + protected readonly _settings: Settings; + constructor(_root: string, _settings: Settings); +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/readers/reader.js b/libs/events/node_modules/@nodelib/fs.walk/out/readers/reader.js new file mode 100644 index 000000000..782f07cbf --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/readers/reader.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const common = require("./common"); +class Reader { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._root = common.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); + } +} +exports.default = Reader; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/readers/sync.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/readers/sync.d.ts new file mode 100644 index 000000000..af4103353 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/readers/sync.d.ts @@ -0,0 +1,15 @@ +import * as fsScandir from '@nodelib/fs.scandir'; +import type { Entry } from '../types'; +import Reader from './reader'; +export default class SyncReader extends Reader { + protected readonly _scandir: typeof fsScandir.scandirSync; + private readonly _storage; + private readonly _queue; + read(): Entry[]; + private _pushToQueue; + private _handleQueue; + private _handleDirectory; + private _handleError; + private _handleEntry; + private _pushToStorage; +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/readers/sync.js b/libs/events/node_modules/@nodelib/fs.walk/out/readers/sync.js new file mode 100644 index 000000000..9a8d5a6f1 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/readers/sync.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const fsScandir = require("@nodelib/fs.scandir"); +const common = require("./common"); +const reader_1 = require("./reader"); +class SyncReader extends reader_1.default { + constructor() { + super(...arguments); + this._scandir = fsScandir.scandirSync; + this._storage = []; + this._queue = new Set(); + } + read() { + this._pushToQueue(this._root, this._settings.basePath); + this._handleQueue(); + return this._storage; + } + _pushToQueue(directory, base) { + this._queue.add({ directory, base }); + } + _handleQueue() { + for (const item of this._queue.values()) { + this._handleDirectory(item.directory, item.base); + } + } + _handleDirectory(directory, base) { + try { + const entries = this._scandir(directory, this._settings.fsScandirSettings); + for (const entry of entries) { + this._handleEntry(entry, base); + } + } + catch (error) { + this._handleError(error); + } + } + _handleError(error) { + if (!common.isFatalError(this._settings, error)) { + return; + } + throw error; + } + _handleEntry(entry, base) { + const fullpath = entry.path; + if (base !== undefined) { + entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } + if (common.isAppliedFilter(this._settings.entryFilter, entry)) { + this._pushToStorage(entry); + } + if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, base === undefined ? undefined : entry.path); + } + } + _pushToStorage(entry) { + this._storage.push(entry); + } +} +exports.default = SyncReader; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/settings.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/settings.d.ts new file mode 100644 index 000000000..d1c4b45f6 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/settings.d.ts @@ -0,0 +1,30 @@ +import * as fsScandir from '@nodelib/fs.scandir'; +import type { Entry, Errno } from './types'; +export declare type FilterFunction = (value: T) => boolean; +export declare type DeepFilterFunction = FilterFunction; +export declare type EntryFilterFunction = FilterFunction; +export declare type ErrorFilterFunction = FilterFunction; +export interface Options { + basePath?: string; + concurrency?: number; + deepFilter?: DeepFilterFunction; + entryFilter?: EntryFilterFunction; + errorFilter?: ErrorFilterFunction; + followSymbolicLinks?: boolean; + fs?: Partial; + pathSegmentSeparator?: string; + stats?: boolean; + throwErrorOnBrokenSymbolicLink?: boolean; +} +export default class Settings { + private readonly _options; + readonly basePath?: string; + readonly concurrency: number; + readonly deepFilter: DeepFilterFunction | null; + readonly entryFilter: EntryFilterFunction | null; + readonly errorFilter: ErrorFilterFunction | null; + readonly pathSegmentSeparator: string; + readonly fsScandirSettings: fsScandir.Settings; + constructor(_options?: Options); + private _getValue; +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/settings.js b/libs/events/node_modules/@nodelib/fs.walk/out/settings.js new file mode 100644 index 000000000..d7a85c81e --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/settings.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); +const fsScandir = require("@nodelib/fs.scandir"); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.basePath = this._getValue(this._options.basePath, undefined); + this.concurrency = this._getValue(this._options.concurrency, Number.POSITIVE_INFINITY); + this.deepFilter = this._getValue(this._options.deepFilter, null); + this.entryFilter = this._getValue(this._options.entryFilter, null); + this.errorFilter = this._getValue(this._options.errorFilter, null); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); + this.fsScandirSettings = new fsScandir.Settings({ + followSymbolicLinks: this._options.followSymbolicLinks, + fs: this._options.fs, + pathSegmentSeparator: this._options.pathSegmentSeparator, + stats: this._options.stats, + throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink + }); + } + _getValue(option, value) { + return option !== null && option !== void 0 ? option : value; + } +} +exports.default = Settings; diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/types/index.d.ts b/libs/events/node_modules/@nodelib/fs.walk/out/types/index.d.ts new file mode 100644 index 000000000..6ee9bd3f9 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/types/index.d.ts @@ -0,0 +1,8 @@ +/// +import type * as scandir from '@nodelib/fs.scandir'; +export declare type Entry = scandir.Entry; +export declare type Errno = NodeJS.ErrnoException; +export interface QueueItem { + directory: string; + base?: string; +} diff --git a/libs/events/node_modules/@nodelib/fs.walk/out/types/index.js b/libs/events/node_modules/@nodelib/fs.walk/out/types/index.js new file mode 100644 index 000000000..c8ad2e549 --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/out/types/index.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/libs/events/node_modules/@nodelib/fs.walk/package.json b/libs/events/node_modules/@nodelib/fs.walk/package.json new file mode 100644 index 000000000..86bfce48b --- /dev/null +++ b/libs/events/node_modules/@nodelib/fs.walk/package.json @@ -0,0 +1,44 @@ +{ + "name": "@nodelib/fs.walk", + "version": "1.2.8", + "description": "A library for efficiently walking a directory recursively", + "license": "MIT", + "repository": "https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.walk", + "keywords": [ + "NodeLib", + "fs", + "FileSystem", + "file system", + "walk", + "scanner", + "crawler" + ], + "engines": { + "node": ">= 8" + }, + "files": [ + "out/**", + "!out/**/*.map", + "!out/**/*.spec.*", + "!out/**/tests/**" + ], + "main": "out/index.js", + "typings": "out/index.d.ts", + "scripts": { + "clean": "rimraf {tsconfig.tsbuildinfo,out}", + "lint": "eslint \"src/**/*.ts\" --cache", + "compile": "tsc -b .", + "compile:watch": "tsc -p . --watch --sourceMap", + "test": "mocha \"out/**/*.spec.js\" -s 0", + "build": "npm run clean && npm run compile && npm run lint && npm test", + "watch": "npm run clean && npm run compile:watch" + }, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "devDependencies": { + "@nodelib/fs.macchiato": "1.0.4" + }, + "gitHead": "1e5bad48565da2b06b8600e744324ea240bf49d8" +} diff --git a/libs/events/node_modules/@types/json-schema/LICENSE b/libs/events/node_modules/@types/json-schema/LICENSE new file mode 100644 index 000000000..9e841e7a2 --- /dev/null +++ b/libs/events/node_modules/@types/json-schema/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/libs/events/node_modules/@types/json-schema/README.md b/libs/events/node_modules/@types/json-schema/README.md new file mode 100644 index 000000000..8c2380e89 --- /dev/null +++ b/libs/events/node_modules/@types/json-schema/README.md @@ -0,0 +1,16 @@ +# Installation +> `npm install --save @types/json-schema` + +# Summary +This package contains type definitions for json-schema 4.0, 6.0 and (https://github.com/kriszyp/json-schema). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/json-schema. + +### Additional Details + * Last updated: Fri, 15 Sep 2023 20:36:37 GMT + * Dependencies: none + * Global values: none + +# Credits +These definitions were written by [Boris Cherny](https://github.com/bcherny), [Lucian Buzzo](https://github.com/lucianbuzzo), [Roland Groza](https://github.com/rolandjitsu), and [Jason Kwok](https://github.com/JasonHK). diff --git a/libs/events/node_modules/@types/json-schema/index.d.ts b/libs/events/node_modules/@types/json-schema/index.d.ts new file mode 100644 index 000000000..a6d8f5db2 --- /dev/null +++ b/libs/events/node_modules/@types/json-schema/index.d.ts @@ -0,0 +1,758 @@ +// Type definitions for json-schema 4.0, 6.0 and 7.0 +// Project: https://github.com/kriszyp/json-schema +// Definitions by: Boris Cherny +// Lucian Buzzo +// Roland Groza +// Jason Kwok +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.2 + +// ================================================================================================== +// JSON Schema Draft 04 +// ================================================================================================== + +/** + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1 + */ +export type JSONSchema4TypeName = + | "string" // + | "number" + | "integer" + | "boolean" + | "object" + | "array" + | "null" + | "any"; + +/** + * @see https://tools.ietf.org/html/draft-zyp-json-schema-04#section-3.5 + */ +export type JSONSchema4Type = + | string // + | number + | boolean + | JSONSchema4Object + | JSONSchema4Array + | null; + +// Workaround for infinite type recursion +export interface JSONSchema4Object { + [key: string]: JSONSchema4Type; +} + +// Workaround for infinite type recursion +// https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540 +export interface JSONSchema4Array extends Array {} + +/** + * Meta schema + * + * Recommended values: + * - 'http://json-schema.org/schema#' + * - 'http://json-schema.org/hyper-schema#' + * - 'http://json-schema.org/draft-04/schema#' + * - 'http://json-schema.org/draft-04/hyper-schema#' + * - 'http://json-schema.org/draft-03/schema#' + * - 'http://json-schema.org/draft-03/hyper-schema#' + * + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-5 + */ +export type JSONSchema4Version = string; + +/** + * JSON Schema V4 + * @see https://tools.ietf.org/html/draft-zyp-json-schema-04 + */ +export interface JSONSchema4 { + id?: string | undefined; + $ref?: string | undefined; + $schema?: JSONSchema4Version | undefined; + + /** + * This attribute is a string that provides a short description of the + * instance property. + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.21 + */ + title?: string | undefined; + + /** + * This attribute is a string that provides a full description of the of + * purpose the instance property. + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.22 + */ + description?: string | undefined; + + default?: JSONSchema4Type | undefined; + multipleOf?: number | undefined; + maximum?: number | undefined; + exclusiveMaximum?: boolean | undefined; + minimum?: number | undefined; + exclusiveMinimum?: boolean | undefined; + maxLength?: number | undefined; + minLength?: number | undefined; + pattern?: string | undefined; + + /** + * May only be defined when "items" is defined, and is a tuple of JSONSchemas. + * + * This provides a definition for additional items in an array instance + * when tuple definitions of the items is provided. This can be false + * to indicate additional items in the array are not allowed, or it can + * be a schema that defines the schema of the additional items. + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.6 + */ + additionalItems?: boolean | JSONSchema4 | undefined; + + /** + * This attribute defines the allowed items in an instance array, and + * MUST be a schema or an array of schemas. The default value is an + * empty schema which allows any value for items in the instance array. + * + * When this attribute value is a schema and the instance value is an + * array, then all the items in the array MUST be valid according to the + * schema. + * + * When this attribute value is an array of schemas and the instance + * value is an array, each position in the instance array MUST conform + * to the schema in the corresponding position for this array. This + * called tuple typing. When tuple typing is used, additional items are + * allowed, disallowed, or constrained by the "additionalItems" + * (Section 5.6) attribute using the same rules as + * "additionalProperties" (Section 5.4) for objects. + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.5 + */ + items?: JSONSchema4 | JSONSchema4[] | undefined; + + maxItems?: number | undefined; + minItems?: number | undefined; + uniqueItems?: boolean | undefined; + maxProperties?: number | undefined; + minProperties?: number | undefined; + + /** + * This attribute indicates if the instance must have a value, and not + * be undefined. This is false by default, making the instance + * optional. + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.7 + */ + required?: boolean | string[] | undefined; + + /** + * This attribute defines a schema for all properties that are not + * explicitly defined in an object type definition. If specified, the + * value MUST be a schema or a boolean. If false is provided, no + * additional properties are allowed beyond the properties defined in + * the schema. The default value is an empty schema which allows any + * value for additional properties. + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.4 + */ + additionalProperties?: boolean | JSONSchema4 | undefined; + + definitions?: { + [k: string]: JSONSchema4; + } | undefined; + + /** + * This attribute is an object with property definitions that define the + * valid values of instance object property values. When the instance + * value is an object, the property values of the instance object MUST + * conform to the property definitions in this object. In this object, + * each property definition's value MUST be a schema, and the property's + * name MUST be the name of the instance property that it defines. The + * instance property value MUST be valid according to the schema from + * the property definition. Properties are considered unordered, the + * order of the instance properties MAY be in any order. + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.2 + */ + properties?: { + [k: string]: JSONSchema4; + } | undefined; + + /** + * This attribute is an object that defines the schema for a set of + * property names of an object instance. The name of each property of + * this attribute's object is a regular expression pattern in the ECMA + * 262/Perl 5 format, while the value is a schema. If the pattern + * matches the name of a property on the instance object, the value of + * the instance's property MUST be valid against the pattern name's + * schema value. + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.3 + */ + patternProperties?: { + [k: string]: JSONSchema4; + } | undefined; + dependencies?: { + [k: string]: JSONSchema4 | string[]; + } | undefined; + + /** + * This provides an enumeration of all possible values that are valid + * for the instance property. This MUST be an array, and each item in + * the array represents a possible value for the instance value. If + * this attribute is defined, the instance value MUST be one of the + * values in the array in order for the schema to be valid. + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.19 + */ + enum?: JSONSchema4Type[] | undefined; + + /** + * A single type, or a union of simple types + */ + type?: JSONSchema4TypeName | JSONSchema4TypeName[] | undefined; + + allOf?: JSONSchema4[] | undefined; + anyOf?: JSONSchema4[] | undefined; + oneOf?: JSONSchema4[] | undefined; + not?: JSONSchema4 | undefined; + + /** + * The value of this property MUST be another schema which will provide + * a base schema which the current schema will inherit from. The + * inheritance rules are such that any instance that is valid according + * to the current schema MUST be valid according to the referenced + * schema. This MAY also be an array, in which case, the instance MUST + * be valid for all the schemas in the array. A schema that extends + * another schema MAY define additional attributes, constrain existing + * attributes, or add other constraints. + * + * Conceptually, the behavior of extends can be seen as validating an + * instance against all constraints in the extending schema as well as + * the extended schema(s). + * + * @see https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.26 + */ + extends?: string | string[] | undefined; + + /** + * @see https://tools.ietf.org/html/draft-zyp-json-schema-04#section-5.6 + */ + [k: string]: any; + + format?: string | undefined; +} + +// ================================================================================================== +// JSON Schema Draft 06 +// ================================================================================================== + +export type JSONSchema6TypeName = + | "string" // + | "number" + | "integer" + | "boolean" + | "object" + | "array" + | "null" + | "any"; + +export type JSONSchema6Type = + | string // + | number + | boolean + | JSONSchema6Object + | JSONSchema6Array + | null; + +// Workaround for infinite type recursion +export interface JSONSchema6Object { + [key: string]: JSONSchema6Type; +} + +// Workaround for infinite type recursion +// https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540 +export interface JSONSchema6Array extends Array {} + +/** + * Meta schema + * + * Recommended values: + * - 'http://json-schema.org/schema#' + * - 'http://json-schema.org/hyper-schema#' + * - 'http://json-schema.org/draft-06/schema#' + * - 'http://json-schema.org/draft-06/hyper-schema#' + * + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-5 + */ +export type JSONSchema6Version = string; + +/** + * JSON Schema V6 + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01 + */ +export type JSONSchema6Definition = JSONSchema6 | boolean; +export interface JSONSchema6 { + $id?: string | undefined; + $ref?: string | undefined; + $schema?: JSONSchema6Version | undefined; + + /** + * Must be strictly greater than 0. + * A numeric instance is valid only if division by this keyword's value results in an integer. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.1 + */ + multipleOf?: number | undefined; + + /** + * Representing an inclusive upper limit for a numeric instance. + * This keyword validates only if the instance is less than or exactly equal to "maximum". + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.2 + */ + maximum?: number | undefined; + + /** + * Representing an exclusive upper limit for a numeric instance. + * This keyword validates only if the instance is strictly less than (not equal to) to "exclusiveMaximum". + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.3 + */ + exclusiveMaximum?: number | undefined; + + /** + * Representing an inclusive lower limit for a numeric instance. + * This keyword validates only if the instance is greater than or exactly equal to "minimum". + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.4 + */ + minimum?: number | undefined; + + /** + * Representing an exclusive lower limit for a numeric instance. + * This keyword validates only if the instance is strictly greater than (not equal to) to "exclusiveMinimum". + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.5 + */ + exclusiveMinimum?: number | undefined; + + /** + * Must be a non-negative integer. + * A string instance is valid against this keyword if its length is less than, or equal to, the value of this keyword. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.6 + */ + maxLength?: number | undefined; + + /** + * Must be a non-negative integer. + * A string instance is valid against this keyword if its length is greater than, or equal to, the value of this keyword. + * Omitting this keyword has the same behavior as a value of 0. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.7 + */ + minLength?: number | undefined; + + /** + * Should be a valid regular expression, according to the ECMA 262 regular expression dialect. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.8 + */ + pattern?: string | undefined; + + /** + * This keyword determines how child instances validate for arrays, and does not directly validate the immediate instance itself. + * Omitting this keyword has the same behavior as an empty schema. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.9 + */ + items?: JSONSchema6Definition | JSONSchema6Definition[] | undefined; + + /** + * This keyword determines how child instances validate for arrays, and does not directly validate the immediate instance itself. + * If "items" is an array of schemas, validation succeeds if every instance element + * at a position greater than the size of "items" validates against "additionalItems". + * Otherwise, "additionalItems" MUST be ignored, as the "items" schema + * (possibly the default value of an empty schema) is applied to all elements. + * Omitting this keyword has the same behavior as an empty schema. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.10 + */ + additionalItems?: JSONSchema6Definition | undefined; + + /** + * Must be a non-negative integer. + * An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.11 + */ + maxItems?: number | undefined; + + /** + * Must be a non-negative integer. + * An array instance is valid against "maxItems" if its size is greater than, or equal to, the value of this keyword. + * Omitting this keyword has the same behavior as a value of 0. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.12 + */ + minItems?: number | undefined; + + /** + * If this keyword has boolean value false, the instance validates successfully. + * If it has boolean value true, the instance validates successfully if all of its elements are unique. + * Omitting this keyword has the same behavior as a value of false. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.13 + */ + uniqueItems?: boolean | undefined; + + /** + * An array instance is valid against "contains" if at least one of its elements is valid against the given schema. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.14 + */ + contains?: JSONSchema6Definition | undefined; + + /** + * Must be a non-negative integer. + * An object instance is valid against "maxProperties" if its number of properties is less than, or equal to, the value of this keyword. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.15 + */ + maxProperties?: number | undefined; + + /** + * Must be a non-negative integer. + * An object instance is valid against "maxProperties" if its number of properties is greater than, + * or equal to, the value of this keyword. + * Omitting this keyword has the same behavior as a value of 0. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.16 + */ + minProperties?: number | undefined; + + /** + * Elements of this array must be unique. + * An object instance is valid against this keyword if every item in the array is the name of a property in the instance. + * Omitting this keyword has the same behavior as an empty array. + * + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.17 + */ + required?: string[] | undefined; + + /** + * This keyword determines how child instances validate for objects, and does not directly validate the immediate instance itself. + * Validation succeeds if, for each name that appears in both the instance and as a name within this keyword's value, + * the child instance for that name successfully validates against the corresponding schema. + * Omitting this keyword has the same behavior as an empty object. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.18 + */ + properties?: { + [k: string]: JSONSchema6Definition; + } | undefined; + + /** + * This attribute is an object that defines the schema for a set of property names of an object instance. + * The name of each property of this attribute's object is a regular expression pattern in the ECMA 262, while the value is a schema. + * If the pattern matches the name of a property on the instance object, the value of the instance's property + * MUST be valid against the pattern name's schema value. + * Omitting this keyword has the same behavior as an empty object. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.19 + */ + patternProperties?: { + [k: string]: JSONSchema6Definition; + } | undefined; + + /** + * This attribute defines a schema for all properties that are not explicitly defined in an object type definition. + * If specified, the value MUST be a schema or a boolean. + * If false is provided, no additional properties are allowed beyond the properties defined in the schema. + * The default value is an empty schema which allows any value for additional properties. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.20 + */ + additionalProperties?: JSONSchema6Definition | undefined; + + /** + * This keyword specifies rules that are evaluated if the instance is an object and contains a certain property. + * Each property specifies a dependency. + * If the dependency value is an array, each element in the array must be unique. + * Omitting this keyword has the same behavior as an empty object. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.21 + */ + dependencies?: { + [k: string]: JSONSchema6Definition | string[]; + } | undefined; + + /** + * Takes a schema which validates the names of all properties rather than their values. + * Note the property name that the schema is testing will always be a string. + * Omitting this keyword has the same behavior as an empty schema. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.22 + */ + propertyNames?: JSONSchema6Definition | undefined; + + /** + * This provides an enumeration of all possible values that are valid + * for the instance property. This MUST be an array, and each item in + * the array represents a possible value for the instance value. If + * this attribute is defined, the instance value MUST be one of the + * values in the array in order for the schema to be valid. + * + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.23 + */ + enum?: JSONSchema6Type[] | undefined; + + /** + * More readable form of a one-element "enum" + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.24 + */ + const?: JSONSchema6Type | undefined; + + /** + * A single type, or a union of simple types + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.25 + */ + type?: JSONSchema6TypeName | JSONSchema6TypeName[] | undefined; + + /** + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.26 + */ + allOf?: JSONSchema6Definition[] | undefined; + + /** + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.27 + */ + anyOf?: JSONSchema6Definition[] | undefined; + + /** + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.28 + */ + oneOf?: JSONSchema6Definition[] | undefined; + + /** + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.29 + */ + not?: JSONSchema6Definition | undefined; + + /** + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-7.1 + */ + definitions?: { + [k: string]: JSONSchema6Definition; + } | undefined; + + /** + * This attribute is a string that provides a short description of the instance property. + * + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-7.2 + */ + title?: string | undefined; + + /** + * This attribute is a string that provides a full description of the of purpose the instance property. + * + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-7.2 + */ + description?: string | undefined; + + /** + * This keyword can be used to supply a default JSON value associated with a particular schema. + * It is RECOMMENDED that a default value be valid against the associated schema. + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-7.3 + */ + default?: JSONSchema6Type | undefined; + + /** + * Array of examples with no validation effect the value of "default" is usable as an example without repeating it under this keyword + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-7.4 + */ + examples?: JSONSchema6Type[] | undefined; + + /** + * @see https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-8 + */ + format?: string | undefined; +} + +// ================================================================================================== +// JSON Schema Draft 07 +// ================================================================================================== +// https://tools.ietf.org/html/draft-handrews-json-schema-validation-01 +// -------------------------------------------------------------------------------------------------- + +/** + * Primitive type + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.1.1 + */ +export type JSONSchema7TypeName = + | "string" // + | "number" + | "integer" + | "boolean" + | "object" + | "array" + | "null"; + +/** + * Primitive type + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.1.1 + */ +export type JSONSchema7Type = + | string // + | number + | boolean + | JSONSchema7Object + | JSONSchema7Array + | null; + +// Workaround for infinite type recursion +export interface JSONSchema7Object { + [key: string]: JSONSchema7Type; +} + +// Workaround for infinite type recursion +// https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540 +export interface JSONSchema7Array extends Array {} + +/** + * Meta schema + * + * Recommended values: + * - 'http://json-schema.org/schema#' + * - 'http://json-schema.org/hyper-schema#' + * - 'http://json-schema.org/draft-07/schema#' + * - 'http://json-schema.org/draft-07/hyper-schema#' + * + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-5 + */ +export type JSONSchema7Version = string; + +/** + * JSON Schema v7 + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01 + */ +export type JSONSchema7Definition = JSONSchema7 | boolean; +export interface JSONSchema7 { + $id?: string | undefined; + $ref?: string | undefined; + $schema?: JSONSchema7Version | undefined; + $comment?: string | undefined; + + /** + * @see https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-8.2.4 + * @see https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#appendix-A + */ + $defs?: { + [key: string]: JSONSchema7Definition; + } | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.1 + */ + type?: JSONSchema7TypeName | JSONSchema7TypeName[] | undefined; + enum?: JSONSchema7Type[] | undefined; + const?: JSONSchema7Type | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.2 + */ + multipleOf?: number | undefined; + maximum?: number | undefined; + exclusiveMaximum?: number | undefined; + minimum?: number | undefined; + exclusiveMinimum?: number | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.3 + */ + maxLength?: number | undefined; + minLength?: number | undefined; + pattern?: string | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.4 + */ + items?: JSONSchema7Definition | JSONSchema7Definition[] | undefined; + additionalItems?: JSONSchema7Definition | undefined; + maxItems?: number | undefined; + minItems?: number | undefined; + uniqueItems?: boolean | undefined; + contains?: JSONSchema7Definition | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.5 + */ + maxProperties?: number | undefined; + minProperties?: number | undefined; + required?: string[] | undefined; + properties?: { + [key: string]: JSONSchema7Definition; + } | undefined; + patternProperties?: { + [key: string]: JSONSchema7Definition; + } | undefined; + additionalProperties?: JSONSchema7Definition | undefined; + dependencies?: { + [key: string]: JSONSchema7Definition | string[]; + } | undefined; + propertyNames?: JSONSchema7Definition | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.6 + */ + if?: JSONSchema7Definition | undefined; + then?: JSONSchema7Definition | undefined; + else?: JSONSchema7Definition | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.7 + */ + allOf?: JSONSchema7Definition[] | undefined; + anyOf?: JSONSchema7Definition[] | undefined; + oneOf?: JSONSchema7Definition[] | undefined; + not?: JSONSchema7Definition | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-7 + */ + format?: string | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-8 + */ + contentMediaType?: string | undefined; + contentEncoding?: string | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-9 + */ + definitions?: { + [key: string]: JSONSchema7Definition; + } | undefined; + + /** + * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-10 + */ + title?: string | undefined; + description?: string | undefined; + default?: JSONSchema7Type | undefined; + readOnly?: boolean | undefined; + writeOnly?: boolean | undefined; + examples?: JSONSchema7Type | undefined; +} + +export interface ValidationResult { + valid: boolean; + errors: ValidationError[]; +} + +export interface ValidationError { + property: string; + message: string; +} + +/** + * To use the validator call JSONSchema.validate with an instance object and an optional schema object. + * If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), + * that schema will be used to validate and the schema parameter is not necessary (if both exist, + * both validations will occur). + */ +export function validate(instance: {}, schema: JSONSchema4 | JSONSchema6 | JSONSchema7): ValidationResult; + +/** + * The checkPropertyChange method will check to see if an value can legally be in property with the given schema + * This is slightly different than the validate method in that it will fail if the schema is readonly and it will + * not check for self-validation, it is assumed that the passed in value is already internally valid. + */ +export function checkPropertyChange( + value: any, + schema: JSONSchema4 | JSONSchema6 | JSONSchema7, + property: string, +): ValidationResult; + +/** + * This checks to ensure that the result is valid and will throw an appropriate error message if it is not. + */ +export function mustBeValid(result: ValidationResult): void; diff --git a/libs/events/node_modules/@types/json-schema/package.json b/libs/events/node_modules/@types/json-schema/package.json new file mode 100644 index 000000000..f30a8ca18 --- /dev/null +++ b/libs/events/node_modules/@types/json-schema/package.json @@ -0,0 +1,40 @@ +{ + "name": "@types/json-schema", + "version": "7.0.13", + "description": "TypeScript definitions for json-schema 4.0, 6.0 and", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/json-schema", + "license": "MIT", + "contributors": [ + { + "name": "Boris Cherny", + "url": "https://github.com/bcherny", + "githubUsername": "bcherny" + }, + { + "name": "Lucian Buzzo", + "url": "https://github.com/lucianbuzzo", + "githubUsername": "lucianbuzzo" + }, + { + "name": "Roland Groza", + "url": "https://github.com/rolandjitsu", + "githubUsername": "rolandjitsu" + }, + { + "name": "Jason Kwok", + "url": "https://github.com/JasonHK", + "githubUsername": "JasonHK" + } + ], + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/json-schema" + }, + "scripts": {}, + "dependencies": {}, + "typesPublisherContentHash": "85f3277dfcda7a00b7ff8c2ad838d5d9dc8ecaccbaee5f6d53252195d6818981", + "typeScriptVersion": "4.5" +} \ No newline at end of file diff --git a/libs/events/node_modules/@types/lodash.clonedeep/LICENSE b/libs/events/node_modules/@types/lodash.clonedeep/LICENSE new file mode 100755 index 000000000..9e841e7a2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash.clonedeep/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/libs/events/node_modules/@types/lodash.clonedeep/README.md b/libs/events/node_modules/@types/lodash.clonedeep/README.md new file mode 100755 index 000000000..52fddb9dd --- /dev/null +++ b/libs/events/node_modules/@types/lodash.clonedeep/README.md @@ -0,0 +1,31 @@ +# Installation +> `npm install --save @types/lodash.clonedeep` + +# Summary +This package contains type definitions for lodash.cloneDeep (https://lodash.com). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/lodash.clonedeep. +## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/lodash.clonedeep/index.d.ts) +````ts +// Type definitions for lodash.cloneDeep 4.5 +// Project: https://lodash.com +// Definitions by: Brian Zengel +// Ilya Mochalov +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 + +// Generated from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/lodash/scripts/generate-modules.ts + +import { cloneDeep } from "lodash"; +export = cloneDeep; + +```` + +### Additional Details + * Last updated: Mon, 18 Apr 2022 23:03:13 GMT + * Dependencies: [@types/lodash](https://npmjs.com/package/@types/lodash) + * Global values: none + +# Credits +These definitions were written by [Brian Zengel](https://github.com/bczengel), and [Ilya Mochalov](https://github.com/chrootsu). diff --git a/libs/events/node_modules/@types/lodash.clonedeep/index.d.ts b/libs/events/node_modules/@types/lodash.clonedeep/index.d.ts new file mode 100755 index 000000000..4883e0c59 --- /dev/null +++ b/libs/events/node_modules/@types/lodash.clonedeep/index.d.ts @@ -0,0 +1,11 @@ +// Type definitions for lodash.cloneDeep 4.5 +// Project: https://lodash.com +// Definitions by: Brian Zengel +// Ilya Mochalov +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 + +// Generated from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/lodash/scripts/generate-modules.ts + +import { cloneDeep } from "lodash"; +export = cloneDeep; diff --git a/libs/events/node_modules/@types/lodash.clonedeep/package.json b/libs/events/node_modules/@types/lodash.clonedeep/package.json new file mode 100755 index 000000000..4529a6895 --- /dev/null +++ b/libs/events/node_modules/@types/lodash.clonedeep/package.json @@ -0,0 +1,32 @@ +{ + "name": "@types/lodash.clonedeep", + "version": "4.5.7", + "description": "TypeScript definitions for lodash.cloneDeep", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/lodash.clonedeep", + "license": "MIT", + "contributors": [ + { + "name": "Brian Zengel", + "url": "https://github.com/bczengel", + "githubUsername": "bczengel" + }, + { + "name": "Ilya Mochalov", + "url": "https://github.com/chrootsu", + "githubUsername": "chrootsu" + } + ], + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/lodash.clonedeep" + }, + "scripts": {}, + "dependencies": { + "@types/lodash": "*" + }, + "typesPublisherContentHash": "15ba0625a8b54f7e2dac53c8fafa2e413210915f841087c42acad29bc460e760", + "typeScriptVersion": "3.9" +} \ No newline at end of file diff --git a/libs/events/node_modules/@types/lodash/LICENSE b/libs/events/node_modules/@types/lodash/LICENSE new file mode 100755 index 000000000..9e841e7a2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/libs/events/node_modules/@types/lodash/README.md b/libs/events/node_modules/@types/lodash/README.md new file mode 100755 index 000000000..7c5c6e0b8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/README.md @@ -0,0 +1,16 @@ +# Installation +> `npm install --save @types/lodash` + +# Summary +This package contains type definitions for Lo-Dash (https://lodash.com). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/lodash. + +### Additional Details + * Last updated: Tue, 05 Sep 2023 19:33:08 GMT + * Dependencies: none + * Global values: `_` + +# Credits +These definitions were written by [Brian Zengel](https://github.com/bczengel), [Ilya Mochalov](https://github.com/chrootsu), [AJ Richardson](https://github.com/aj-r), [e-cloud](https://github.com/e-cloud), [Georgii Dolzhykov](https://github.com/thorn0), [Jack Moore](https://github.com/jtmthf), [Dominique Rau](https://github.com/DomiR), and [William Chelman](https://github.com/WilliamChelman). diff --git a/libs/events/node_modules/@types/lodash/add.d.ts b/libs/events/node_modules/@types/lodash/add.d.ts new file mode 100755 index 000000000..4650a89c4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/add.d.ts @@ -0,0 +1,2 @@ +import { add } from "./index"; +export = add; diff --git a/libs/events/node_modules/@types/lodash/after.d.ts b/libs/events/node_modules/@types/lodash/after.d.ts new file mode 100755 index 000000000..277ae1ea5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/after.d.ts @@ -0,0 +1,2 @@ +import { after } from "./index"; +export = after; diff --git a/libs/events/node_modules/@types/lodash/ary.d.ts b/libs/events/node_modules/@types/lodash/ary.d.ts new file mode 100755 index 000000000..ac1c72e95 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/ary.d.ts @@ -0,0 +1,2 @@ +import { ary } from "./index"; +export = ary; diff --git a/libs/events/node_modules/@types/lodash/assign.d.ts b/libs/events/node_modules/@types/lodash/assign.d.ts new file mode 100755 index 000000000..5ffc1e34d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/assign.d.ts @@ -0,0 +1,2 @@ +import { assign } from "./index"; +export = assign; diff --git a/libs/events/node_modules/@types/lodash/assignIn.d.ts b/libs/events/node_modules/@types/lodash/assignIn.d.ts new file mode 100755 index 000000000..3cc54e817 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/assignIn.d.ts @@ -0,0 +1,2 @@ +import { assignIn } from "./index"; +export = assignIn; diff --git a/libs/events/node_modules/@types/lodash/assignInWith.d.ts b/libs/events/node_modules/@types/lodash/assignInWith.d.ts new file mode 100755 index 000000000..b4c4dfef2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/assignInWith.d.ts @@ -0,0 +1,2 @@ +import { assignInWith } from "./index"; +export = assignInWith; diff --git a/libs/events/node_modules/@types/lodash/assignWith.d.ts b/libs/events/node_modules/@types/lodash/assignWith.d.ts new file mode 100755 index 000000000..97da10ceb --- /dev/null +++ b/libs/events/node_modules/@types/lodash/assignWith.d.ts @@ -0,0 +1,2 @@ +import { assignWith } from "./index"; +export = assignWith; diff --git a/libs/events/node_modules/@types/lodash/at.d.ts b/libs/events/node_modules/@types/lodash/at.d.ts new file mode 100755 index 000000000..49e714778 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/at.d.ts @@ -0,0 +1,2 @@ +import { at } from "./index"; +export = at; diff --git a/libs/events/node_modules/@types/lodash/attempt.d.ts b/libs/events/node_modules/@types/lodash/attempt.d.ts new file mode 100755 index 000000000..d4b608900 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/attempt.d.ts @@ -0,0 +1,2 @@ +import { attempt } from "./index"; +export = attempt; diff --git a/libs/events/node_modules/@types/lodash/before.d.ts b/libs/events/node_modules/@types/lodash/before.d.ts new file mode 100755 index 000000000..03c45c803 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/before.d.ts @@ -0,0 +1,2 @@ +import { before } from "./index"; +export = before; diff --git a/libs/events/node_modules/@types/lodash/bind.d.ts b/libs/events/node_modules/@types/lodash/bind.d.ts new file mode 100755 index 000000000..6367da1e1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/bind.d.ts @@ -0,0 +1,2 @@ +import { bind } from "./index"; +export = bind; diff --git a/libs/events/node_modules/@types/lodash/bindAll.d.ts b/libs/events/node_modules/@types/lodash/bindAll.d.ts new file mode 100755 index 000000000..25d47e397 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/bindAll.d.ts @@ -0,0 +1,2 @@ +import { bindAll } from "./index"; +export = bindAll; diff --git a/libs/events/node_modules/@types/lodash/bindKey.d.ts b/libs/events/node_modules/@types/lodash/bindKey.d.ts new file mode 100755 index 000000000..128b065f3 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/bindKey.d.ts @@ -0,0 +1,2 @@ +import { bindKey } from "./index"; +export = bindKey; diff --git a/libs/events/node_modules/@types/lodash/camelCase.d.ts b/libs/events/node_modules/@types/lodash/camelCase.d.ts new file mode 100755 index 000000000..5c10659d9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/camelCase.d.ts @@ -0,0 +1,2 @@ +import { camelCase } from "./index"; +export = camelCase; diff --git a/libs/events/node_modules/@types/lodash/capitalize.d.ts b/libs/events/node_modules/@types/lodash/capitalize.d.ts new file mode 100755 index 000000000..416f5f598 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/capitalize.d.ts @@ -0,0 +1,2 @@ +import { capitalize } from "./index"; +export = capitalize; diff --git a/libs/events/node_modules/@types/lodash/castArray.d.ts b/libs/events/node_modules/@types/lodash/castArray.d.ts new file mode 100755 index 000000000..74ea7bd23 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/castArray.d.ts @@ -0,0 +1,2 @@ +import { castArray } from "./index"; +export = castArray; diff --git a/libs/events/node_modules/@types/lodash/ceil.d.ts b/libs/events/node_modules/@types/lodash/ceil.d.ts new file mode 100755 index 000000000..0c6f1fd1c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/ceil.d.ts @@ -0,0 +1,2 @@ +import { ceil } from "./index"; +export = ceil; diff --git a/libs/events/node_modules/@types/lodash/chain.d.ts b/libs/events/node_modules/@types/lodash/chain.d.ts new file mode 100755 index 000000000..d09d2bb08 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/chain.d.ts @@ -0,0 +1,2 @@ +import { chain } from "./index"; +export = chain; diff --git a/libs/events/node_modules/@types/lodash/chunk.d.ts b/libs/events/node_modules/@types/lodash/chunk.d.ts new file mode 100755 index 000000000..125c98f73 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/chunk.d.ts @@ -0,0 +1,2 @@ +import { chunk } from "./index"; +export = chunk; diff --git a/libs/events/node_modules/@types/lodash/clamp.d.ts b/libs/events/node_modules/@types/lodash/clamp.d.ts new file mode 100755 index 000000000..df1706691 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/clamp.d.ts @@ -0,0 +1,2 @@ +import { clamp } from "./index"; +export = clamp; diff --git a/libs/events/node_modules/@types/lodash/clone.d.ts b/libs/events/node_modules/@types/lodash/clone.d.ts new file mode 100755 index 000000000..c5884d700 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/clone.d.ts @@ -0,0 +1,2 @@ +import { clone } from "./index"; +export = clone; diff --git a/libs/events/node_modules/@types/lodash/cloneDeep.d.ts b/libs/events/node_modules/@types/lodash/cloneDeep.d.ts new file mode 100755 index 000000000..b7bd89327 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/cloneDeep.d.ts @@ -0,0 +1,2 @@ +import { cloneDeep } from "./index"; +export = cloneDeep; diff --git a/libs/events/node_modules/@types/lodash/cloneDeepWith.d.ts b/libs/events/node_modules/@types/lodash/cloneDeepWith.d.ts new file mode 100755 index 000000000..3eb368ba7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/cloneDeepWith.d.ts @@ -0,0 +1,2 @@ +import { cloneDeepWith } from "./index"; +export = cloneDeepWith; diff --git a/libs/events/node_modules/@types/lodash/cloneWith.d.ts b/libs/events/node_modules/@types/lodash/cloneWith.d.ts new file mode 100755 index 000000000..1e6bf7a80 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/cloneWith.d.ts @@ -0,0 +1,2 @@ +import { cloneWith } from "./index"; +export = cloneWith; diff --git a/libs/events/node_modules/@types/lodash/common/array.d.ts b/libs/events/node_modules/@types/lodash/common/array.d.ts new file mode 100755 index 000000000..ae96d714a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/array.d.ts @@ -0,0 +1,2127 @@ +import _ = require("../index"); +declare module "../index" { + interface LoDashStatic { + /** + * Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the + * final chunk will be the remaining elements. + * + * @param array The array to process. + * @param size The length of each chunk. + * @return Returns the new array containing chunks. + */ + chunk(array: List | null | undefined, size?: number): T[][]; + } + interface Collection { + /** + * @see _.chunk + */ + chunk(size?: number): Collection; + } + interface CollectionChain { + /** + * @see _.chunk + */ + chunk(size?: number): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array with all falsey values removed. The values false, null, 0, 0n, "", undefined, and NaN are + * falsey. + * + * @param array The array to compact. + * @return Returns the new array of filtered values. + */ + compact(array: List | null | undefined): T[]; + } + + type Falsey = null | undefined | false | "" | 0 | 0n; + type Truthy = T extends Falsey ? never : T; + interface Collection { + /** + * @see _.compact + */ + compact(): Collection>; + } + interface CollectionChain { + /** + * @see _.compact + */ + compact(): CollectionChain>; + } + interface LoDashStatic { + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @category Array + * @param [values] The array values to concatenate. + * @returns Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + concat(...values: Array>): T[]; + } + interface Primitive { + /** + * @see _.concat + */ + concat(...values: Array>): Collection; + } + interface Collection { + /** + * @see _.concat + */ + concat(...values: Array>): Collection; + } + interface Object { + /** + * @see _.concat + */ + concat(...values: Array>): Collection; + } + interface PrimitiveChain { + /** + * @see _.concat + */ + concat(...values: Array>): CollectionChain; + } + interface CollectionChain { + /** + * @see _.concat + */ + concat(...values: Array>): CollectionChain; + } + interface ObjectChain { + /** + * @see _.concat + */ + concat(...values: Array>): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of `array` values not included in the other provided arrays using SameValueZero for + * equality comparisons. The order and references of result values are determined by the first array. + * + * @param array The array to inspect. + * @param values The arrays of values to exclude. + * @return Returns the new array of filtered values. + */ + difference(array: List | null | undefined, ...values: Array>): T[]; + } + interface Collection { + /** + * @see _.difference + */ + difference(...values: Array>): Collection; + } + interface CollectionChain { + /** + * @see _.difference + */ + difference(...values: Array>): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like _.difference except that it accepts iteratee which is invoked for each element + * of array and values to generate the criterion by which they're compared. The order and references + * of result values are determined by the first array. The iteratee is invoked with one argument: (value). + * + * @param array The array to inspect. + * @param values The values to exclude. + * @param iteratee The iteratee invoked per element. + * @returns Returns the new array of filtered values. + */ + differenceBy(array: List | null | undefined, values: List, iteratee: ValueIteratee): T1[]; + /** + * @see _.differenceBy + */ + differenceBy(array: List | null | undefined, values1: List, values2: List, iteratee: ValueIteratee): T1[]; + /** + * @see _.differenceBy + */ + differenceBy(array: List | null | undefined, values1: List, values2: List, values3: List, iteratee: ValueIteratee): T1[]; + /** + * @see _.differenceBy + */ + differenceBy(array: List | null | undefined, values1: List, values2: List, values3: List, values4: List, iteratee: ValueIteratee): T1[]; + /** + * @see _.differenceBy + */ + differenceBy(array: List | null | undefined, values1: List, values2: List, values3: List, values4: List, values5: List, iteratee: ValueIteratee): T1[]; + /** + * @see _.differenceBy + */ + differenceBy(array: List | null | undefined, values1: List, values2: List, values3: List, values4: List, values5: List, ...values: Array | ValueIteratee>): T1[]; + /** + * @see _.differenceBy + */ + differenceBy(array: List | null | undefined, ...values: Array>): T[]; + } + interface Collection { + /** + * @see _.differenceBy + */ + differenceBy(values1: List, iteratee?: ValueIteratee): Collection; + /** + * @see _.differenceBy + */ + differenceBy(...values: Array | ValueIteratee>): Collection; + } + interface CollectionChain { + /** + * @see _.differenceBy + */ + differenceBy(values1: List, iteratee?: ValueIteratee): CollectionChain; + /** + * @see _.differenceBy + */ + differenceBy(...values: Array | ValueIteratee>): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like _.difference except that it accepts comparator which is invoked to compare elements + * of array to values. The order and references of result values are determined by the first array. The + * comparator is invoked with two arguments: (arrVal, othVal). + * + * @category Array + * @param [values] The arrays to inspect. + * @param [comparator] The comparator invoked per element. + * @returns Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ + differenceWith(array: List | null | undefined, values: List, comparator: Comparator2): T1[]; + /** + * @see _.differenceWith + */ + differenceWith(array: List | null | undefined, values1: List, values2: List, comparator: Comparator2): T1[]; + /** + * @see _.differenceWith + */ + differenceWith(array: List | null | undefined, values1: List, values2: List, ...values: Array | Comparator2>): T1[]; + /** + * @see _.differenceWith + */ + differenceWith(array: List | null | undefined, ...values: Array>): T[]; + } + interface Collection { + /** + * @see _.differenceWith + */ + differenceWith(values: List, comparator: Comparator2): Collection; + /** + * @see _.differenceWith + */ + differenceWith(...values: Array | Comparator2>): Collection; + } + interface CollectionChain { + /** + * @see _.differenceWith + */ + differenceWith< T2>(values: List, comparator: Comparator2): CollectionChain; + /** + * @see _.differenceWith + */ + differenceWith< T2, T3, T4>(...values: Array | Comparator2>): CollectionChain; + } + interface LoDashStatic { + /** + * Creates a slice of array with n elements dropped from the beginning. + * + * @param array The array to query. + * @param n The number of elements to drop. + * @return Returns the slice of array. + */ + drop(array: List | null | undefined, n?: number): T[]; + } + interface Collection { + /** + * @see _.drop + */ + drop(n?: number): Collection; + } + interface CollectionChain { + /** + * @see _.drop + */ + drop(n?: number): CollectionChain; + } + interface LoDashStatic { + /** + * Creates a slice of array with n elements dropped from the end. + * + * @param array The array to query. + * @param n The number of elements to drop. + * @return Returns the slice of array. + */ + dropRight(array: List | null | undefined, n?: number): T[]; + } + interface Collection { + /** + * @see _.dropRight + */ + dropRight(n?: number): Collection; + } + interface CollectionChain { + /** + * @see _.dropRight + */ + dropRight(n?: number): CollectionChain; + } + interface LoDashStatic { + /** + * Creates a slice of array excluding elements dropped from the end. Elements are dropped until predicate + * returns falsey. The predicate is invoked with three arguments: (value, index, array). + * + * @param array The array to query. + * @param predicate The function invoked per iteration. + * @return Returns the slice of array. + */ + dropRightWhile(array: List | null | undefined, predicate?: ListIteratee): T[]; + } + interface Collection { + /** + * @see _.dropRightWhile + */ + dropRightWhile(predicate?: ListIteratee): Collection; + } + interface CollectionChain { + /** + * @see _.dropRightWhile + */ + dropRightWhile(predicate?: ListIteratee): CollectionChain; + } + interface LoDashStatic { + /** + * Creates a slice of array excluding elements dropped from the beginning. Elements are dropped until predicate + * returns falsey. The predicate is invoked with three arguments: (value, index, array). + * + * @param array The array to query. + * @param predicate The function invoked per iteration. + * @return Returns the slice of array. + */ + dropWhile(array: List | null | undefined, predicate?: ListIteratee): T[]; + } + interface Collection { + /** + * @see _.dropWhile + */ + dropWhile(predicate?: ListIteratee): Collection; + } + interface CollectionChain { + /** + * @see _.dropWhile + */ + dropWhile(predicate?: ListIteratee): CollectionChain; + } + interface LoDashStatic { + /** + * Fills elements of array with value from start up to, but not including, end. + * + * Note: This method mutates array. + * + * @param array The array to fill. + * @param value The value to fill array with. + * @param start The start position. + * @param end The end position. + * @return Returns array. + */ + fill(array: any[] | null | undefined, value: T): T[]; + /** + * @see _.fill + */ + fill(array: List | null | undefined, value: T): List; + /** + * @see _.fill + */ + fill(array: U[] | null | undefined, value: T, start?: number, end?: number): Array; + /** + * @see _.fill + */ + fill(array: List | null | undefined, value: T, start?: number, end?: number): List; + } + interface Collection { + /** + * @see _.fill + */ + fill(value: U, start?: number, end?: number): Collection; + } + interface CollectionChain { + /** + * @see _.fill + */ + fill(value: U, start?: number, end?: number): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like _.find except that it returns the index of the first element predicate returns truthy + * for instead of the element itself. + * + * @param array The array to search. + * @param predicate The function invoked per iteration. + * @param fromIndex The index to search from. + * @return Returns the index of the found element, else -1. + */ + findIndex(array: List | null | undefined, predicate?: ListIterateeCustom, fromIndex?: number): number; + } + interface Collection { + /** + * @see _.findIndex + */ + findIndex(predicate?: ListIterateeCustom, fromIndex?: number): number; + } + interface CollectionChain { + /** + * @see _.findIndex + */ + findIndex(predicate?: ListIterateeCustom, fromIndex?: number): PrimitiveChain; + } + interface LoDashStatic { + /** + * This method is like _.findIndex except that it iterates over elements of collection from right to left. + * + * @param array The array to search. + * @param predicate The function invoked per iteration. + * @param fromIndex The index to search from. + * @return Returns the index of the found element, else -1. + */ + findLastIndex(array: List | null | undefined, predicate?: ListIterateeCustom, fromIndex?: number): number; + } + interface Collection { + /** + * @see _.findLastIndex + */ + findLastIndex(predicate?: ListIterateeCustom, fromIndex?: number): number; + } + interface CollectionChain { + /** + * @see _.findLastIndex + */ + findLastIndex(predicate?: ListIterateeCustom, fromIndex?: number): PrimitiveChain; + } + interface LoDashStatic { + /** + * @see _.head + */ + first: LoDashStatic["head"]; + } + interface String { + /** + * @see _.first + */ + first(): string | undefined; + } + interface StringChain { + /** + * @see _.first + */ + first(): StringNullableChain; + } + interface StringNullableChain { + /** + * @see _.first + */ + first(): StringNullableChain; + } + interface Collection { + /** + * @see _.first + */ + first(): T | undefined; + } + interface CollectionChain { + /** + * @see _.first + */ + first(): ExpChain; + } + interface RecursiveArray extends Array> {} + interface ListOfRecursiveArraysOrValues extends List> {} + interface LoDashStatic { + /** + * Flattens `array` a single level deep. + * + * @param array The array to flatten. + * @return Returns the new flattened array. + */ + flatten(array: List> | null | undefined): T[]; + } + interface String { + /** + * @see _.flatten + */ + flatten(): Collection; + } + interface StringChain { + /** + * @see _.flatten + */ + flatten(): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.flatten + */ + flatten(): CollectionChain; + } + interface Collection { + /** + * @see _.flatten + */ + flatten(): T extends Many ? Collection : Collection; + } + interface CollectionChain { + /** + * @see _.flatten + */ + flatten(): T extends Many ? CollectionChain : CollectionChain; + } + + type Flat = T extends string ? T : (T extends List ? never : T); + + interface LoDashStatic { + /** + * Recursively flattens a nested array. + * + * @param array The array to recursively flatten. + * @return Returns the new flattened array. + */ + flattenDeep(array: ListOfRecursiveArraysOrValues | null | undefined): Array>; + } + interface Collection { + /** + * @see _.flattenDeep + */ + flattenDeep(): T extends ListOfRecursiveArraysOrValues ? Collection> : Collection; + } + interface CollectionChain { + /** + * @see _.flattenDeep + */ + flattenDeep(): T extends ListOfRecursiveArraysOrValues ? CollectionChain> : CollectionChain; + } + interface LoDashStatic { + /** + * Recursively flatten array up to depth times. + * + * @param array The array to recursively flatten. + * @param number The maximum recursion depth. + * @return Returns the new flattened array. + */ + flattenDepth(array: ListOfRecursiveArraysOrValues | null | undefined, depth?: number): T[]; + } + interface Collection { + /** + * @see _.flattenDepth + */ + flattenDepth(depth?: number): Collection; + } + interface CollectionChain { + /** + * @see _.flattenDepth + */ + flattenDepth(depth?: number): CollectionChain; + } + interface LoDashStatic { + /** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @category Array + * @param pairs The key-value pairs. + * @returns Returns the new object. + * @example + * + * _.fromPairs([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + */ + fromPairs(pairs: List<[PropertyName, T]> | null | undefined): Dictionary; + /** + * @see _.fromPairs + */ + fromPairs(pairs: List | null | undefined): Dictionary; + } + interface Collection { + /** + * @see _.fromPairs + */ + fromPairs(): Object>; + } + interface CollectionChain { + /** + * @see _.fromPairs + */ + fromPairs(): ObjectChain>; + } + interface LoDashStatic { + /** + * Gets the first element of array. + * + * @alias _.first + * + * @param array The array to query. + * @return Returns the first element of array. + */ + head(array: List | null | undefined): T | undefined; + } + interface String { + /** + * @see _.head + */ + head(): string | undefined; + } + interface StringChain { + /** + * @see _.head + */ + head(): StringNullableChain; + } + interface StringNullableChain { + /** + * @see _.head + */ + head(): StringNullableChain; + } + interface Collection { + /** + * @see _.head + */ + head(): T | undefined; + } + interface CollectionChain { + /** + * @see _.head + */ + head(): ExpChain; + } + interface LoDashStatic { + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. + * + * @category Array + * @param array The array to search. + * @param value The value to search for. + * @param [fromIndex=0] The index to search from. + * @returns Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + indexOf(array: List | null | undefined, value: T, fromIndex?: number): number; + } + interface Collection { + /** + * @see _.indexOf + */ + indexOf(value: T, fromIndex?: number): number; + } + interface CollectionChain { + /** + * @see _.indexOf + */ + indexOf(value: T, fromIndex?: number): PrimitiveChain; + } + interface LoDashStatic { + /** + * Gets all but the last element of array. + * + * @param array The array to query. + * @return Returns the slice of array. + */ + initial(array: List | null | undefined): T[]; + } + interface Collection { + /** + * @see _.initial + */ + initial(): Collection; + } + interface CollectionChain { + /** + * @see _.initial + */ + initial(): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of unique values that are included in all of the provided arrays using SameValueZero for + * equality comparisons. + * + * @param arrays The arrays to inspect. + * @return Returns the new array of shared values. + */ + intersection(...arrays: Array | null | undefined>): T[]; + } + interface Collection { + /** + * @see _.intersection + */ + intersection(...arrays: Array | null | undefined>): Collection; + } + interface CollectionChain { + /** + * @see _.intersection + */ + intersection(...arrays: Array | null | undefined>): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @category Array + * @param [arrays] The arrays to inspect. + * @param [iteratee=_.identity] The iteratee invoked per element. + * @returns Returns the new array of shared values. + * @example + * + * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [2.1] + * + * // using the `_.property` iteratee shorthand + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ + intersectionBy(array: List | null, values: List, iteratee: ValueIteratee): T1[]; + /** + * @see _.intersectionBy + */ + intersectionBy(array: List | null, values1: List, values2: List, iteratee: ValueIteratee): T1[]; + /** + * @see _.intersectionBy + */ + intersectionBy(array: List | null | undefined, values1: List, values2: List, ...values: Array | ValueIteratee>): T1[]; + /** + * @see _.intersectionBy + */ + intersectionBy(array?: List | null, ...values: Array>): T[]; + /** + * @see _.intersectionBy + */ + intersectionBy(...values: Array | ValueIteratee>): T[]; + } + interface Collection { + /** + * @see _.intersectionBy + */ + intersectionBy(values: List, iteratee: ValueIteratee): Collection; + /** + * @see _.intersectionBy + */ + intersectionBy(...values: Array | ValueIteratee>): Collection; + } + interface CollectionChain { + /** + * @see _.intersectionBy + */ + intersectionBy(values: List, iteratee: ValueIteratee): CollectionChain; + /** + * @see _.intersectionBy + */ + intersectionBy(...values: Array | ValueIteratee>): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of unique `array` values not included in the other + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @category Array + * @param [values] The arrays to inspect. + * @param [comparator] The comparator invoked per element. + * @returns Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ + intersectionWith(array: List | null | undefined, values: List, comparator: Comparator2): T1[]; + /** + * @see _.intersectionWith + */ + intersectionWith(array: List | null | undefined, values1: List, values2: List, comparator: Comparator2): T1[]; + /** + * @see _.intersectionWith + */ + intersectionWith(array: List | null | undefined, values1: List, values2: List, ...values: Array | Comparator2>): T1[]; + /** + * @see _.intersectionWith + */ + intersectionWith(array?: List | null, ...values: Array | Comparator2>): T[]; + } + interface Collection { + /** + * @see _.intersectionWith + */ + intersectionWith(values: List, comparator: Comparator2): Collection; + /** + * @see _.intersectionWith + */ + intersectionWith(...values: Array | Comparator2>): Collection; + } + interface CollectionChain { + /** + * @see _.intersectionWith + */ + intersectionWith(values: List, comparator: Comparator2): CollectionChain; + /** + * @see _.intersectionWith + */ + intersectionWith(...values: Array | Comparator2>): CollectionChain; + } + interface LoDashStatic { + /** + * Converts all elements in `array` into a string separated by `separator`. + * + * @param array The array to convert. + * @param separator The element separator. + * @returns Returns the joined string. + */ + join(array: List | null | undefined, separator?: string): string; + } + interface String { + /** + * @see _.join + */ + join(separator?: string): string; + } + interface StringChain { + /** + * @see _.join + */ + join(separator?: string): StringChain; + } + interface StringNullableChain { + /** + * @see _.join + */ + join(separator?: string): StringChain; + } + interface Collection { + /** + * @see _.join + */ + join(separator?: string): string; + } + interface CollectionChain { + /** + * @see _.join + */ + join(separator?: string): StringChain; + } + interface LoDashStatic { + /** + * Gets the last element of array. + * + * @param array The array to query. + * @return Returns the last element of array. + */ + last(array: List | null | undefined): T | undefined; + } + interface Collection { + /** + * @see _.last + */ + last(): T | undefined; + } + interface CollectionChain { + /** + * @see _.last + */ + last(): ExpChain; + } + interface String { + /** + * @see _.last + */ + last(): string | undefined; + } + interface StringChain { + /** + * @see _.last + */ + last(): StringNullableChain; + } + interface StringNullableChain { + /** + * @see _.last + */ + last(): StringNullableChain; + } + interface LoDashStatic { + /** + * This method is like _.indexOf except that it iterates over elements of array from right to left. + * + * @param array The array to search. + * @param value The value to search for. + * @param fromIndex The index to search from or true to perform a binary search on a sorted array. + * @return Returns the index of the matched value, else -1. + */ + lastIndexOf(array: List | null | undefined, value: T, fromIndex?: true|number): number; + } + interface Collection { + /** + * @see _.lastIndexOf + */ + lastIndexOf(value: T, fromIndex?: true|number): number; + } + interface CollectionChain { + /** + * @see _.lastIndexOf + */ + lastIndexOf(value: T, fromIndex?: true|number): PrimitiveChain; + } + interface LoDashStatic { + /** + * Gets the element at index `n` of `array`. If `n` is negative, the nth element from the end is returned. + * + * @param array array The array to query. + * @param value The index of the element to return. + * @return Returns the nth element of `array`. + */ + nth(array: List | null | undefined, n?: number): T | undefined; + } + interface Collection { + /** + * @see _.nth + */ + nth(n?: number): T | undefined; + } + interface CollectionChain { + /** + * @see _.nth + */ + nth(n?: number): ExpChain; + } + interface LoDashStatic { + /** + * Removes all provided values from array using SameValueZero for equality comparisons. + * + * Note: Unlike _.without, this method mutates array. + * + * @param array The array to modify. + * @param values The values to remove. + * @return Returns array. + */ + pull(array: T[], ...values: T[]): T[]; + /** + * @see _.pull + */ + pull(array: List, ...values: T[]): List; + } + interface Collection { + /** + * @see _.pull + */ + pull(...values: T[]): Collection; + } + interface CollectionChain { + /** + * @see _.pull + */ + pull(...values: T[]): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.pull` except that it accepts an array of values to remove. + * + * **Note:** Unlike `_.difference`, this method mutates `array`. + * + * @category Array + * @param array The array to modify. + * @param values The values to remove. + * @returns Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, [2, 3]); + * console.log(array); + * // => [1, 1] + */ + pullAll(array: T[], values?: List): T[]; + /** + * @see _.pullAll + */ + pullAll(array: List, values?: List): List; + } + interface Collection { + /** + * @see _.pullAll + */ + pullAll(values?: List): Collection; + } + interface CollectionChain { + /** + * @see _.pullAll + */ + pullAll(values?: List): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.pullAll` except that it accepts `iteratee` which is + * invoked for each element of `array` and `values` to to generate the criterion + * by which uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * **Note:** Unlike `_.differenceBy`, this method mutates `array`. + * + * @category Array + * @param array The array to modify. + * @param values The values to remove. + * @param [iteratee=_.identity] The iteratee invoked per element. + * @returns Returns `array`. + * @example + * + * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; + * + * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); + * console.log(array); + * // => [{ 'x': 2 }] + */ + pullAllBy(array: T[], values?: List, iteratee?: ValueIteratee): T[]; + /** + * @see _.pullAllBy + */ + pullAllBy(array: List, values?: List, iteratee?: ValueIteratee): List; + /** + * @see _.pullAllBy + */ + pullAllBy(array: T1[], values: List, iteratee: ValueIteratee): T1[]; + /** + * @see _.pullAllBy + */ + pullAllBy(array: List, values: List, iteratee: ValueIteratee): List; + } + interface Collection { + /** + * @see _.pullAllBy + */ + pullAllBy(values?: List, iteratee?: ValueIteratee): Collection; + } + interface CollectionChain { + /** + * @see _.pullAllBy + */ + pullAllBy(values?: List, iteratee?: ValueIteratee): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.pullAll` except that it accepts `comparator` which is + * invoked to compare elements of array to values. The comparator is invoked with + * two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.differenceWith`, this method mutates `array`. + * + * @category Array + * @param array The array to modify. + * @param values The values to remove. + * @param [iteratee=_.identity] The iteratee invoked per element. + * @returns Returns `array`. + * @example + * + * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; + * + * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); + * console.log(array); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] + */ + pullAllWith(array: T[], values?: List, comparator?: Comparator): T[]; + /** + * @see _.pullAllWith + */ + pullAllWith(array: List, values?: List, comparator?: Comparator): List; + /** + * @see _.pullAllWith + */ + pullAllWith(array: T1[], values: List, comparator: Comparator2): T1[]; + /** + * @see _.pullAllWith + */ + pullAllWith(array: List, values: List, comparator: Comparator2): List; + } + interface Collection { + /** + * @see _.pullAllWith + */ + pullAllWith(values?: List, comparator?: Comparator2): Collection; + } + interface CollectionChain { + /** + * @see _.pullAllWith + */ + pullAllWith(values?: List, comparator?: Comparator2): CollectionChain; + } + interface LoDashStatic { + /** + * Removes elements from array corresponding to the given indexes and returns an array of the removed elements. + * Indexes may be specified as an array of indexes or as individual arguments. + * + * Note: Unlike _.at, this method mutates array. + * + * @param array The array to modify. + * @param indexes The indexes of elements to remove, specified as individual indexes or arrays of indexes. + * @return Returns the new array of removed elements. + */ + pullAt(array: T[], ...indexes: Array>): T[]; + /** + * @see _.pullAt + */ + pullAt(array: List, ...indexes: Array>): List; + } + interface Collection { + /** + * @see _.pullAt + */ + pullAt(...indexes: Array>): Collection; + } + interface CollectionChain { + /** + * @see _.pullAt + */ + pullAt(...indexes: Array>): CollectionChain; + } + interface LoDashStatic { + /** + * Removes all elements from array that predicate returns truthy for and returns an array of the removed + * elements. The predicate is invoked with three arguments: (value, index, array). + * + * Note: Unlike _.filter, this method mutates array. + * + * @param array The array to modify. + * @param predicate The function invoked per iteration. + * @return Returns the new array of removed elements. + */ + remove(array: List, predicate?: ListIteratee): T[]; + } + interface Collection { + /** + * @see _.remove + */ + remove(predicate?: ListIteratee): Collection; + } + interface CollectionChain { + /** + * @see _.remove + */ + remove(predicate?: ListIteratee): CollectionChain; + } + interface LoDashStatic { + /** + * Reverses `array` so that the first element becomes the last, the second + * element becomes the second to last, and so on. + * + * **Note:** This method mutates `array` and is based on + * [`Array#reverse`](https://mdn.io/Array/reverse). + * + * @category Array + * @returns Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.reverse(array); + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + reverse>(array: TList): TList; + } + interface LoDashStatic { + /** + * Creates a slice of array from start up to, but not including, end. + * + * @param array The array to slice. + * @param start The start position. + * @param end The end position. + * @return Returns the slice of array. + */ + slice(array: List | null | undefined, start?: number, end?: number): T[]; + } + interface Collection { + /** + * @see _.slice + */ + slice(start?: number, end?: number): Collection; + } + interface CollectionChain { + /** + * @see _.slice + */ + slice(start?: number, end?: number): CollectionChain; + } + interface LoDashStatic { + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. + * + * @category Array + * @param array The sorted array to inspect. + * @param value The value to evaluate. + * @returns Returns the index at which `value` should be inserted into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 5], 4); + * // => 0 + */ + sortedIndex(array: List | null | undefined, value: T): number; + } + interface Collection { + /** + * @see _.sortedIndex + */ + sortedIndex(value: T): number; + } + interface CollectionChain { + /** + * @see _.sortedIndex + */ + sortedIndex(value: T): PrimitiveChain; + } + interface LoDashStatic { + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. + * + * @category Array + * @param array The sorted array to inspect. + * @param value The value to evaluate. + * @returns Returns the index at which `value` should be inserted into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 5], 4); + * // => 0 + */ + sortedIndex(array: List | null | undefined, value: T): number; + } + interface Collection { + /** + * @see _.sortedIndex + */ + sortedIndex(value: T): number; + } + interface CollectionChain { + /** + * @see _.sortedIndex + */ + sortedIndex(value: T): PrimitiveChain; + } + interface LoDashStatic { + /** + * This method is like `_.sortedIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @category Array + * @param array The sorted array to inspect. + * @param value The value to evaluate. + * @param [iteratee=_.identity] The iteratee invoked per element. + * @returns Returns the index at which `value` should be inserted into `array`. + * @example + * + * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 }; + * + * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict)); + * // => 1 + * + * // using the `_.property` iteratee shorthand + * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * // => 0 + */ + sortedIndexBy(array: List | null | undefined, value: T, iteratee?: ValueIteratee): number; + } + interface Collection { + /** + * @see _.sortedIndexBy + */ + sortedIndexBy(value: T, iteratee?: ValueIteratee): number; + } + interface CollectionChain { + /** + * @see _.sortedIndexBy + */ + sortedIndexBy(value: T, iteratee?: ValueIteratee): PrimitiveChain; + } + interface LoDashStatic { + /** + * This method is like `_.indexOf` except that it performs a binary + * search on a sorted `array`. + * + * @category Array + * @param array The array to search. + * @param value The value to search for. + * @returns Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedIndexOf([1, 1, 2, 2], 2); + * // => 2 + */ + sortedIndexOf(array: List | null | undefined, value: T): number; + } + interface Collection { + /** + * @see _.sortedIndexOf + */ + sortedIndexOf(value: T): number; + } + interface CollectionChain { + /** + * @see _.sortedIndexOf + */ + sortedIndexOf(value: T): PrimitiveChain; + } + interface LoDashStatic { + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @category Array + * @param array The sorted array to inspect. + * @param value The value to evaluate. + * @returns Returns the index at which `value` should be inserted into `array`. + * @example + * + * _.sortedLastIndex([4, 5], 4); + * // => 1 + */ + sortedLastIndex(array: List | null | undefined, value: T): number; + } + interface Collection { + /** + * @see _.sortedLastIndex + */ + sortedLastIndex(value: T): number; + } + interface CollectionChain { + /** + * @see _.sortedLastIndex + */ + sortedLastIndex(value: T): PrimitiveChain; + } + interface LoDashStatic { + /** + * This method is like `_.sortedLastIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @category Array + * @param array The sorted array to inspect. + * @param value The value to evaluate. + * @param [iteratee=_.identity] The iteratee invoked per element. + * @returns Returns the index at which `value` should be inserted into `array`. + * @example + * + * // using the `_.property` iteratee shorthand + * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * // => 1 + */ + sortedLastIndexBy(array: List | null | undefined, value: T, iteratee: ValueIteratee): number; + } + interface Collection { + /** + * @see _.sortedLastIndexBy + */ + sortedLastIndexBy(value: T, iteratee: ValueIteratee): number; + } + interface CollectionChain { + /** + * @see _.sortedLastIndexBy + */ + sortedLastIndexBy(value: T, iteratee: ValueIteratee): PrimitiveChain; + } + interface LoDashStatic { + /** + * This method is like `_.lastIndexOf` except that it performs a binary + * search on a sorted `array`. + * + * @category Array + * @param array The array to search. + * @param value The value to search for. + * @returns Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedLastIndexOf([1, 1, 2, 2], 2); + * // => 3 + */ + sortedLastIndexOf(array: List | null | undefined, value: T): number; + } + interface Collection { + /** + * @see _.sortedLastIndexOf + */ + sortedLastIndexOf(value: T): number; + } + interface CollectionChain { + /** + * @see _.sortedLastIndexOf + */ + sortedLastIndexOf(value: T): PrimitiveChain; + } + interface LoDashStatic { + /** + * This method is like `_.uniq` except that it's designed and optimized + * for sorted arrays. + * + * @category Array + * @param array The array to inspect. + * @returns Returns the new duplicate free array. + * @example + * + * _.sortedUniq([1, 1, 2]); + * // => [1, 2] + */ + sortedUniq(array: List | null | undefined): T[]; + } + interface Collection { + /** + * @see _.sortedUniq + */ + sortedUniq(): Collection; + } + interface CollectionChain { + /** + * @see _.sortedUniq + */ + sortedUniq(): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.uniqBy` except that it's designed and optimized + * for sorted arrays. + * + * @category Array + * @param array The array to inspect. + * @param [iteratee] The iteratee invoked per element. + * @returns Returns the new duplicate free array. + * @example + * + * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); + * // => [1.1, 2.3] + */ + sortedUniqBy(array: List | null | undefined, iteratee: ValueIteratee): T[]; + } + interface Collection { + /** + * @see _.sortedUniqBy + */ + sortedUniqBy(iteratee: ValueIteratee): Collection; + } + interface CollectionChain { + /** + * @see _.sortedUniqBy + */ + sortedUniqBy(iteratee: ValueIteratee): CollectionChain; + } + interface LoDashStatic { + /** + * Gets all but the first element of array. + * + * @param array The array to query. + * @return Returns the slice of array. + */ + tail(array: List | null | undefined): T[]; + } + interface Collection { + /** + * @see _.tail + */ + tail(): Collection; + } + interface CollectionChain { + /** + * @see _.tail + */ + tail(): CollectionChain; + } + interface LoDashStatic { + /** + * Creates a slice of array with n elements taken from the beginning. + * + * @param array The array to query. + * @param n The number of elements to take. + * @return Returns the slice of array. + */ + take(array: List | null | undefined, n?: number): T[]; + } + interface Collection { + /** + * @see _.take + */ + take(n?: number): Collection; + } + interface CollectionChain { + /** + * @see _.take + */ + take(n?: number): CollectionChain; + } + interface LoDashStatic { + /** + * Creates a slice of array with n elements taken from the end. + * + * @param array The array to query. + * @param n The number of elements to take. + * @return Returns the slice of array. + */ + takeRight(array: List | null | undefined, n?: number): T[]; + } + interface Collection { + /** + * @see _.takeRight + */ + takeRight(n?: number): Collection; + } + interface CollectionChain { + /** + * @see _.takeRight + */ + takeRight(n?: number): CollectionChain; + } + interface LoDashStatic { + /** + * Creates a slice of array with elements taken from the end. Elements are taken until predicate returns + * falsey. The predicate is invoked with three arguments: (value, index, array). + * + * @param array The array to query. + * @param predicate The function invoked per iteration. + * @return Returns the slice of array. + */ + takeRightWhile(array: List | null | undefined, predicate?: ListIteratee): T[]; + } + interface Collection { + /** + * @see _.takeRightWhile + */ + takeRightWhile(predicate?: ListIteratee): Collection; + } + interface CollectionChain { + /** + * @see _.takeRightWhile + */ + takeRightWhile(predicate?: ListIteratee): CollectionChain; + } + interface LoDashStatic { + /** + * Creates a slice of array with elements taken from the beginning. Elements are taken until predicate returns + * falsey. The predicate is invoked with three arguments: (value, index, array). + * + * @param array The array to query. + * @param predicate The function invoked per iteration. + * @return Returns the slice of array. + */ + takeWhile(array: List | null | undefined, predicate?: ListIteratee): T[]; + } + interface Collection { + /** + * @see _.takeWhile + */ + takeWhile(predicate?: ListIteratee): Collection; + } + interface CollectionChain { + /** + * @see _.takeWhile + */ + takeWhile(predicate?: ListIteratee): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of unique values, in order, from all of the provided arrays using SameValueZero for + * equality comparisons. + * + * @param arrays The arrays to inspect. + * @return Returns the new array of combined values. + */ + union(...arrays: Array | null | undefined>): T[]; + } + interface Collection { + /** + * @see _.union + */ + union(...arrays: Array | null | undefined>): Collection; + } + interface CollectionChain { + /** + * @see _.union + */ + union(...arrays: Array | null | undefined>): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.union` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @param arrays The arrays to inspect. + * @param iteratee The iteratee invoked per element. + * @return Returns the new array of combined values. + */ + unionBy(arrays: List | null | undefined, iteratee?: ValueIteratee): T[]; + /** + * @see _.unionBy + */ + unionBy(arrays1: List | null | undefined, arrays2: List | null | undefined, iteratee?: ValueIteratee): T[]; + /** + * @see _.unionBy + */ + unionBy(arrays1: List | null | undefined, arrays2: List | null | undefined, arrays3: List | null | undefined, iteratee?: ValueIteratee): T[]; + /** + * @see _.unionBy + */ + unionBy(arrays1: List | null | undefined, arrays2: List | null | undefined, arrays3: List | null | undefined, arrays4: List | null | undefined, iteratee?: ValueIteratee): T[]; + /** + * @see _.unionBy + */ + unionBy(arrays1: List | null | undefined, arrays2: List | null | undefined, arrays3: List | null | undefined, arrays4: List | null | undefined, arrays5: List | null | undefined, ...iteratee: Array | List | null | undefined>): T[]; + } + interface Collection { + /** + * @see _.unionBy + */ + unionBy(arrays2: List | null | undefined, iteratee?: ValueIteratee): Collection; + /** + * @see _.unionBy + */ + unionBy(...iteratee: Array | List | null | undefined>): Collection; + } + interface CollectionChain { + /** + * @see _.unionBy + */ + unionBy(arrays2: List | null | undefined, iteratee?: ValueIteratee): CollectionChain; + /** + * @see _.unionBy + */ + unionBy(...iteratee: Array | List | null | undefined>): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.union` except that it accepts `comparator` which + * is invoked to compare elements of `arrays`. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @category Array + * @param [arrays] The arrays to inspect. + * @param [comparator] The comparator invoked per element. + * @returns Returns the new array of combined values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.unionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + unionWith(arrays: List | null | undefined, comparator?: Comparator): T[]; + /** + * @see _.unionWith + */ + unionWith(arrays: List | null | undefined, arrays2: List | null | undefined, comparator?: Comparator): T[]; + /** + * @see _.unionWith + */ + unionWith(arrays: List | null | undefined, arrays2: List | null | undefined, arrays3: List | null | undefined, ...comparator: Array | List | null | undefined>): T[]; + } + interface Collection { + /** + * @see _.unionWith + */ + unionWith(arrays2: List | null | undefined, comparator?: Comparator): Collection; + /** + * @see _.unionWith + */ + unionWith(...comparator: Array | List | null | undefined>): Collection; + } + interface CollectionChain { + /** + * @see _.unionWith + */ + unionWith(arrays2: List | null | undefined, comparator?: Comparator): CollectionChain; + /** + * @see _.unionWith + */ + unionWith(...comparator: Array | List | null | undefined>): CollectionChain; + } + interface LoDashStatic { + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. + * + * @category Array + * @param array The array to inspect. + * @returns Returns the new duplicate free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + */ + uniq(array: List | null | undefined): T[]; + } + interface Collection { + /** + * @see _.uniq + */ + uniq(): Collection; + } + interface CollectionChain { + /** + * @see _.uniq + */ + uniq(): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @category Array + * @param array The array to inspect. + * @param [iteratee=_.identity] The iteratee invoked per element. + * @returns Returns the new duplicate free array. + * @example + * + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // using the `_.property` iteratee shorthand + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + uniqBy(array: List | null | undefined, iteratee: ValueIteratee): T[]; + } + interface Collection { + /** + * @see _.uniqBy + */ + uniqBy(iteratee: ValueIteratee): Collection; + } + interface CollectionChain { + /** + * @see _.uniqBy + */ + uniqBy(iteratee: ValueIteratee): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The comparator is invoked with + * two arguments: (arrVal, othVal). + * + * @category Array + * @param array The array to inspect. + * @param [comparator] The comparator invoked per element. + * @returns Returns the new duplicate free array. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.uniqWith(objects, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] + */ + uniqWith(array: List | null | undefined, comparator?: Comparator): T[]; + } + interface Collection { + /** + * @see _.uniqWith + */ + uniqWith(comparator?: Comparator): Collection; + } + interface CollectionChain { + /** + * @see _.uniqWith + */ + uniqWith(comparator?: Comparator): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like _.zip except that it accepts an array of grouped elements and creates an array + * regrouping the elements to their pre-zip configuration. + * + * @param array The array of grouped elements to process. + * @return Returns the new array of regrouped elements. + */ + unzip(array: T[][] | List> | null | undefined): T[][]; + } + interface Collection { + /** + * @see _.unzip + */ + unzip(): T extends List ? Collection : unknown; + } + interface CollectionChain { + /** + * @see _.unzip + */ + unzip(): T extends List ? CollectionChain : unknown; + } + interface LoDashStatic { + /** + * This method is like _.unzip except that it accepts an iteratee to specify how regrouped values should be + * combined. The iteratee is invoked with four arguments: (accumulator, value, index, group). + * + * @param array The array of grouped elements to process. + * @param iteratee The function to combine regrouped values. + * @return Returns the new array of regrouped elements. + */ + unzipWith(array: List> | null | undefined, iteratee: (...values: T[]) => TResult): TResult[]; + /** + * @see _.unzipWith + */ + unzipWith(array: List> | null | undefined): T[][]; + } + interface Collection { + /** + * @see _.unzipWith + */ + unzipWith(iteratee: (...values: Array ? U : unknown>) => TResult): Collection; + /** + * @see _.unzipWith + */ + unzipWith(): T extends List ? Collection : unknown; + } + interface CollectionChain { + /** + * @see _.unzipWith + */ + unzipWith(iteratee: (...values: Array ? U : unknown>) => TResult): CollectionChain; + /** + * @see _.unzipWith + */ + unzipWith(): T extends List ? CollectionChain : unknown; + } + interface LoDashStatic { + /** + * Creates an array excluding all provided values using SameValueZero for equality comparisons. + * + * @param array The array to filter. + * @param values The values to exclude. + * @return Returns the new array of filtered values. + */ + without(array: List | null | undefined, ...values: T[]): T[]; + } + interface Collection { + /** + * @see _.without + */ + without(...values: T[]): Collection; + } + interface CollectionChain { + /** + * @see _.without + */ + without(...values: T[]): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of unique values that is the symmetric difference of the provided arrays. + * + * @param arrays The arrays to inspect. + * @return Returns the new array of values. + */ + xor(...arrays: Array | null | undefined>): T[]; + } + interface Collection { + /** + * @see _.xor + */ + xor(...arrays: Array | null | undefined>): Collection; + } + interface CollectionChain { + /** + * @see _.xor + */ + xor(...arrays: Array | null | undefined>): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.xor` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @category Array + * @param [arrays] The arrays to inspect. + * @param [iteratee=_.identity] The iteratee invoked per element. + * @returns Returns the new array of values. + * @example + * + * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [1.2, 4.3] + * + * // using the `_.property` iteratee shorthand + * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + xorBy(arrays: List | null | undefined, iteratee?: ValueIteratee): T[]; + /** + * @see _.xorBy + */ + xorBy(arrays: List | null | undefined, arrays2: List | null | undefined, iteratee?: ValueIteratee): T[]; + /** + * @see _.xorBy + */ + xorBy(arrays: List | null | undefined, arrays2: List | null | undefined, arrays3: List | null | undefined, ...iteratee: Array | List | null | undefined>): T[]; + } + interface Collection { + /** + * @see _.xorBy + */ + xorBy(arrays2: List | null | undefined, iteratee?: ValueIteratee): Collection; + /** + * @see _.xorBy + */ + xorBy(...iteratee: Array | List | null | undefined>): Collection; + } + interface CollectionChain { + /** + * @see _.xorBy + */ + xorBy(arrays2: List | null | undefined, iteratee?: ValueIteratee): CollectionChain; + /** + * @see _.xorBy + */ + xorBy(...iteratee: Array | List | null | undefined>): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.xor` except that it accepts `comparator` which is + * invoked to compare elements of `arrays`. The comparator is invoked with + * two arguments: (arrVal, othVal). + * + * @category Array + * @param [arrays] The arrays to inspect. + * @param [comparator] The comparator invoked per element. + * @returns Returns the new array of values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.xorWith(objects, others, _.isEqual); + * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + xorWith(arrays: List | null | undefined, comparator?: Comparator): T[]; + /** + * @see _.xorWith + */ + xorWith(arrays: List | null | undefined, arrays2: List | null | undefined, comparator?: Comparator): T[]; + /** + * @see _.xorWith + */ + xorWith(arrays: List | null | undefined, arrays2: List | null | undefined, arrays3: List | null | undefined, ...comparator: Array | List | null | undefined>): T[]; + } + interface Collection { + /** + * @see _.xorWith + */ + xorWith(arrays2: List | null | undefined, comparator?: Comparator): Collection; + /** + * @see _.xorWith + */ + xorWith(...comparator: Array | List | null | undefined>): Collection; + } + interface CollectionChain { + /** + * @see _.xorWith + */ + xorWith(arrays2: List | null | undefined, comparator?: Comparator): CollectionChain; + /** + * @see _.xorWith + */ + xorWith(...comparator: Array | List | null | undefined>): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of grouped elements, the first of which contains the first elements of the given arrays, + * the second of which contains the second elements of the given arrays, and so on. + * + * @param arrays The arrays to process. + * @return Returns the new array of grouped elements. + */ + zip(arrays1: List, arrays2: List): Array<[T1 | undefined, T2 | undefined]>; + /** + * @see _.zip + */ + zip(arrays1: List, arrays2: List, arrays3: List): Array<[T1 | undefined, T2 | undefined, T3 | undefined]>; + /** + * @see _.zip + */ + zip(arrays1: List, arrays2: List, arrays3: List, arrays4: List): Array<[T1 | undefined, T2 | undefined, T3 | undefined, T4 | undefined]>; + /** + * @see _.zip + */ + zip(arrays1: List, arrays2: List, arrays3: List, arrays4: List, arrays5: List): Array<[T1 | undefined, T2 | undefined, T3 | undefined, T4 | undefined, T5 | undefined]>; + /** + * @see _.zip + */ + zip(...arrays: Array | null | undefined>): Array>; + } + interface Collection { + /** + * @see _.zip + */ + zip(arrays2: List): Collection<[T | undefined, T2 | undefined]>; + /** + * @see _.zip + */ + zip(...arrays: Array | null | undefined>): Collection>; + } + interface CollectionChain { + /** + * @see _.zip + */ + zip(arrays2: List): CollectionChain<[T | undefined, T2 | undefined]>; + /** + * @see _.zip + */ + zip(...arrays: Array | null | undefined>): CollectionChain>; + } + interface LoDashStatic { + /** + * This method is like _.fromPairs except that it accepts two arrays, one of property + * identifiers and one of corresponding values. + * + * @param props The property names. + * @param values The property values. + * @return Returns the new object. + */ + zipObject(props: List, values: List): Dictionary; + /** + * @see _.zipObject + */ + zipObject(props?: List): Dictionary; + } + interface Collection { + /** + * @see _.zipObject + */ + zipObject(values: List): Object>; + /** + * @see _.zipObject + */ + zipObject(): Object>; + } + interface CollectionChain { + /** + * @see _.zipObject + */ + zipObject(values: List): ObjectChain>; + /** + * @see _.zipObject + */ + zipObject(): ObjectChain>; + } + interface LoDashStatic { + /** + * This method is like _.zipObject except that it supports property paths. + * + * @param paths The property names. + * @param values The property values. + * @return Returns the new object. + */ + zipObjectDeep(paths?: List, values?: List): object; + } + interface Collection { + /** + * @see _.zipObjectDeep + */ + zipObjectDeep(values?: List): Object; + } + interface CollectionChain { + /** + * @see _.zipObjectDeep + */ + zipObjectDeep(values?: List): ObjectChain; + } + interface LoDashStatic { + /** + * This method is like _.zip except that it accepts an iteratee to specify how grouped values should be + * combined. The iteratee is invoked with four arguments: (accumulator, value, index, + * group). + * @param arrays The arrays to process. + * @param iteratee The function to combine grouped values. + * @return Returns the new array of grouped elements. + */ + zipWith(arrays: List, iteratee: (value1: T) => TResult): TResult[]; + /** + * @see _.zipWith + */ + zipWith(arrays1: List, arrays2: List, iteratee: (value1: T1, value2: T2) => TResult): TResult[]; + /** + * @see _.zipWith + */ + zipWith(arrays1: List, arrays2: List, arrays3: List, iteratee: (value1: T1, value2: T2, value3: T3) => TResult): TResult[]; + /** + * @see _.zipWith + */ + zipWith(arrays1: List, arrays2: List, arrays3: List, arrays4: List, iteratee: (value1: T1, value2: T2, value3: T3, value4: T4) => TResult): TResult[]; + /** + * @see _.zipWith + */ + zipWith(arrays1: List, arrays2: List, arrays3: List, arrays4: List, arrays5: List, iteratee: (value1: T1, value2: T2, value3: T3, value4: T4, value5: T5) => TResult): TResult[]; + /** + * @see _.zipWith + */ + zipWith(...iteratee: Array<((...group: T[]) => TResult) | List | null | undefined>): TResult[]; + } + interface Collection { + /** + * @see _.zipWith + */ + zipWith(arrays2: List, iteratee: (value1: T, value2: T2) => TResult): Collection; + /** + * @see _.zipWith + */ + zipWith(arrays2: List, arrays3: List, iteratee: (value1: T, value2: T2, value3: T3) => TResult): Collection; + /** + * @see _.zipWith + */ + zipWith(...iteratee: Array<((...group: T[]) => TResult) | List | null | undefined>): Collection; + } + interface CollectionChain { + /** + * @see _.zipWith + */ + zipWith(arrays2: List, iteratee: (value1: T, value2: T2) => TResult): CollectionChain; + /** + * @see _.zipWith + */ + zipWith(arrays2: List, arrays3: List, iteratee: (value1: T, value2: T2, value3: T3) => TResult): CollectionChain; + /** + * @see _.zipWith + */ + zipWith(...iteratee: Array<((...group: T[]) => TResult) | List | null | undefined>): CollectionChain; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/collection.d.ts b/libs/events/node_modules/@types/lodash/common/collection.d.ts new file mode 100755 index 000000000..1a2ab5cb4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/collection.d.ts @@ -0,0 +1,1934 @@ +import _ = require("../index"); +declare module "../index" { + interface LoDashStatic { + /** + * Creates an object composed of keys generated from the results of running each element of collection through + * iteratee. The corresponding value of each key is the number of times the key was returned by iteratee. The + * iteratee is invoked with one argument: (value). + * + * @param collection The collection to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns the composed aggregate object. + */ + countBy(collection: List | null | undefined, iteratee?: ValueIteratee): Dictionary; + /** + * @see _.countBy + */ + countBy(collection: T | null | undefined, iteratee?: ValueIteratee): Dictionary; + } + interface Object { + /** + * @see _.countBy + */ + countBy(iteratee?: ValueIteratee): Object>; + } + interface String { + /** + * @see _.countBy + */ + countBy(iteratee?: ValueIteratee): Object>; + } + interface Collection { + /** + * @see _.countBy + */ + countBy(iteratee?: ValueIteratee): Object>; + } + interface ObjectChain { + /** + * @see _.countBy + */ + countBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface StringChain { + /** + * @see _.countBy + */ + countBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface StringNullableChain { + /** + * @see _.countBy + */ + countBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface CollectionChain { + /** + * @see _.countBy + */ + countBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface LoDashStatic { + /** + * @see _.forEach + */ + each: LoDashStatic['forEach']; + } + interface String { + /** + * @see _.each + */ + each: String['forEach']; + } + interface Collection { + /** + * @see _.each + */ + each: Collection['forEach']; + } + interface Object { + /** + * @see _.each + */ + each: Object['forEach']; + } + interface StringChain { + /** + * @see _.each + */ + each: StringChain['forEach']; + } + interface StringNullableChain { + /** + * @see _.each + */ + each: StringNullableChain['forEach']; + } + interface CollectionChain { + /** + * @see _.each + */ + each: CollectionChain['forEach']; + } + interface ObjectChain { + /** + * @see _.each + */ + each: ObjectChain['forEach']; + } + interface LoDashStatic { + /** + * @see _.forEachRight + */ + eachRight: LoDashStatic["forEachRight"]; + } + interface String { + /** + * @see _.eachRight + */ + eachRight: String['forEachRight']; + } + interface Collection { + /** + * @see _.eachRight + */ + eachRight: Collection['forEachRight']; + } + interface Object { + /** + * @see _.eachRight + */ + eachRight: Object['forEachRight']; + } + interface StringChain { + /** + * @see _.eachRight + */ + eachRight: StringChain['forEachRight']; + } + interface StringNullableChain { + /** + * @see _.eachRight + */ + eachRight: StringNullableChain['forEachRight']; + } + interface CollectionChain { + /** + * @see _.eachRight + */ + eachRight: CollectionChain['forEachRight']; + } + interface ObjectChain { + /** + * @see _.eachRight + */ + eachRight: ObjectChain['forEachRight']; + } + interface LoDashStatic { + /** + * Checks if predicate returns truthy for all elements of collection. Iteration is stopped once predicate + * returns falsey. The predicate is invoked with three arguments: (value, index|key, collection). + * + * @param collection The collection to iterate over. + * @param predicate The function invoked per iteration. + * @return Returns true if all elements pass the predicate check, else false. + */ + every(collection: List | null | undefined, predicate?: ListIterateeCustom): boolean; + /** + * @see _.every + */ + every(collection: T | null | undefined, predicate?: ObjectIterateeCustom): boolean; + } + interface Collection { + /** + * @see _.every + */ + every(predicate?: ListIterateeCustom): boolean; + } + interface Object { + /** + * @see _.every + */ + every(predicate?: ObjectIterateeCustom): boolean; + } + interface CollectionChain { + /** + * @see _.every + */ + every(predicate?: ListIterateeCustom): PrimitiveChain; + } + interface ObjectChain { + /** + * @see _.every + */ + every(predicate?: ObjectIterateeCustom): PrimitiveChain; + } + interface LoDashStatic { + /** + * Iterates over elements of collection, returning an array of all elements predicate returns truthy for. The + * predicate is invoked with three arguments: (value, index|key, collection). + * + * @param collection The collection to iterate over. + * @param predicate The function invoked per iteration. + * @return Returns the new filtered array. + */ + filter(collection: string | null | undefined, predicate?: StringIterator): string[]; + /** + * @see _.filter + */ + filter(collection: List | null | undefined, predicate: ListIteratorTypeGuard): S[]; + /** + * @see _.filter + */ + filter(collection: List | null | undefined, predicate?: ListIterateeCustom): T[]; + /** + * @see _.filter + */ + filter(collection: T | null | undefined, predicate: ObjectIteratorTypeGuard): S[]; + /** + * @see _.filter + */ + filter(collection: T | null | undefined, predicate?: ObjectIterateeCustom): Array; + } + interface String { + /** + * @see _.filter + */ + filter(predicate?: StringIterator): Collection; + } + interface Collection { + /** + * @see _.filter + */ + filter(predicate: ListIteratorTypeGuard): Collection; + /** + * @see _.filter + */ + filter(predicate?: ListIterateeCustom): Collection; + } + interface Object { + /** + * @see _.filter + */ + filter(predicate: ObjectIteratorTypeGuard): Collection; + /** + * @see _.filter + */ + filter(predicate?: ObjectIterateeCustom): Collection; + } + interface StringChain { + /** + * @see _.filter + */ + filter(predicate?: StringIterator): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.filter + */ + filter(predicate?: StringIterator): CollectionChain; + } + interface CollectionChain { + /** + * @see _.filter + */ + filter(predicate: ListIteratorTypeGuard): CollectionChain; + /** + * @see _.filter + */ + filter(predicate?: ListIterateeCustom): CollectionChain; + } + interface ObjectChain { + /** + * @see _.filter + */ + filter(predicate: ObjectIteratorTypeGuard): CollectionChain; + /** + * @see _.filter + */ + filter(predicate?: ObjectIterateeCustom): CollectionChain; + } + interface LoDashStatic { + /** + * Iterates over elements of collection, returning the first element predicate returns truthy for. + * The predicate is invoked with three arguments: (value, index|key, collection). + * + * @param collection The collection to search. + * @param predicate The function invoked per iteration. + * @param fromIndex The index to search from. + * @return Returns the matched element, else undefined. + */ + find(collection: List | null | undefined, predicate: ListIteratorTypeGuard, fromIndex?: number): S|undefined; + /** + * @see _.find + */ + find(collection: List | null | undefined, predicate?: ListIterateeCustom, fromIndex?: number): T|undefined; + /** + * @see _.find + */ + find(collection: T | null | undefined, predicate: ObjectIteratorTypeGuard, fromIndex?: number): S|undefined; + /** + * @see _.find + */ + find(collection: T | null | undefined, predicate?: ObjectIterateeCustom, fromIndex?: number): T[keyof T]|undefined; + } + interface Collection { + /** + * @see _.find + */ + find(predicate: ListIteratorTypeGuard, fromIndex?: number): S|undefined; + /** + * @see _.find + */ + find(predicate?: ListIterateeCustom, fromIndex?: number): T|undefined; + } + interface Object { + /** + * @see _.find + */ + find< S extends T[keyof T]>(predicate: ObjectIteratorTypeGuard, fromIndex?: number): S|undefined; + /** + * @see _.find + */ + find(predicate?: ObjectIterateeCustom, fromIndex?: number): T[keyof T]|undefined; + } + interface CollectionChain { + /** + * @see _.find + */ + find< S extends T>(predicate: ListIteratorTypeGuard, fromIndex?: number): ExpChain; + /** + * @see _.find + */ + find(predicate?: ListIterateeCustom, fromIndex?: number): ExpChain; + } + interface ObjectChain { + /** + * @see _.find + */ + find< S extends T[keyof T]>(predicate: ObjectIteratorTypeGuard, fromIndex?: number): ExpChain; + /** + * @see _.find + */ + find(predicate?: ObjectIterateeCustom, fromIndex?: number): ExpChain; + } + interface LoDashStatic { + /** + * This method is like _.find except that it iterates over elements of a collection from + * right to left. + * @param collection Searches for a value in this list. + * @param predicate The function called per iteration. + * @param fromIndex The index to search from. + * @return The found element, else undefined. + */ + findLast(collection: List | null | undefined, predicate: ListIteratorTypeGuard, fromIndex?: number): S|undefined; + /** + * @see _.findLast + */ + findLast(collection: List | null | undefined, predicate?: ListIterateeCustom, fromIndex?: number): T|undefined; + /** + * @see _.findLast + */ + findLast(collection: T | null | undefined, predicate: ObjectIteratorTypeGuard, fromIndex?: number): S|undefined; + /** + * @see _.findLast + */ + findLast(collection: T | null | undefined, predicate?: ObjectIterateeCustom, fromIndex?: number): T[keyof T]|undefined; + } + interface Collection { + /** + * @see _.findLast + */ + findLast(predicate: ListIteratorTypeGuard, fromIndex?: number): S|undefined; + /** + * @see _.findLast + */ + findLast(predicate?: ListIterateeCustom, fromIndex?: number): T|undefined; + } + interface Object { + /** + * @see _.findLast + */ + findLast< S extends T[keyof T]>(predicate: ObjectIteratorTypeGuard, fromIndex?: number): S|undefined; + /** + * @see _.findLast + */ + findLast(predicate?: ObjectIterateeCustom, fromIndex?: number): T[keyof T]|undefined; + } + interface CollectionChain { + /** + * @see _.findLast + */ + findLast< S extends T>(predicate: ListIteratorTypeGuard, fromIndex?: number): ExpChain; + /** + * @see _.findLast + */ + findLast(predicate?: ListIterateeCustom, fromIndex?: number): ExpChain; + } + interface ObjectChain { + /** + * @see _.findLast + */ + findLast< S extends T[keyof T]>(predicate: ObjectIteratorTypeGuard, fromIndex?: number): ExpChain; + /** + * @see _.findLast + */ + findLast(predicate?: ObjectIterateeCustom, fromIndex?: number): ExpChain; + } + interface LoDashStatic { + /** + * Creates an array of flattened values by running each element in collection through iteratee + * and concating its result to the other mapped values. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * @param collection The collection to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns the new flattened array. + */ + flatMap(collection: Dictionary> | NumericDictionary> | null | undefined): T[]; + /** + * @see _.flatMap + */ + flatMap(collection: object | null | undefined): any[]; + /** + * @see _.flatMap + */ + flatMap(collection: List | null | undefined, iteratee: ListIterator>): TResult[]; + /** + * @see _.flatMap + */ + flatMap(collection: T | null | undefined, iteratee: ObjectIterator>): TResult[]; + /** + * @see _.flatMap + */ + flatMap(collection: object | null | undefined, iteratee: string): any[]; + /** + * @see _.flatMap + */ + flatMap(collection: object | null | undefined, iteratee: object): boolean[]; + } + interface String { + /** + * @see _.flatMap + */ + flatMap(iteratee: StringIterator>): Collection; + /** + * @see _.flatMap + */ + flatMap(): Collection; + } + interface Collection { + /** + * @see _.flatMap + */ + flatMap(iteratee: ListIterator> | PropertyName): Collection; + /** + * @see _.flatMap + */ + flatMap(iteratee: [PropertyName, any] | object): Collection; + /** + * @see _.flatMap + */ + flatMap(): T extends Many ? Collection : Collection; + } + interface Object { + /** + * @see _.flatMap + */ + flatMap(iteratee: ObjectIterator> | PropertyName): Collection; + /** + * @see _.flatMap + */ + flatMap(iteratee: [PropertyName, any] | object): Collection; + /** + * @see _.flatMap + */ + flatMap(): Collection; + } + interface StringChain { + /** + * @see _.flatMap + */ + flatMap(iteratee: StringIterator>): CollectionChain; + /** + * @see _.flatMap + */ + flatMap(): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.flatMap + */ + flatMap(iteratee: StringIterator>): CollectionChain; + /** + * @see _.flatMap + */ + flatMap(): CollectionChain; + } + interface CollectionChain { + /** + * @see _.flatMap + */ + flatMap(iteratee: ListIterator> | PropertyName): CollectionChain; + /** + * @see _.flatMap + */ + flatMap(iteratee: [PropertyName, any] | object): CollectionChain; + /** + * @see _.flatMap + */ + flatMap(): T extends Many ? CollectionChain : CollectionChain; + } + interface ObjectChain { + /** + * @see _.flatMap + */ + flatMap(iteratee: ObjectIterator> | PropertyName): CollectionChain; + /** + * @see _.flatMap + */ + flatMap(iteratee: [PropertyName, any] | object): CollectionChain; + /** + * @see _.flatMap + */ + flatMap(): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results. + * + * @since 4.7.0 + * @category Collection + * @param collection The collection to iterate over. + * @param [iteratee=_.identity] The function invoked per iteration. + * @returns Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDeep([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ + flatMapDeep(collection: Dictionary | T> | NumericDictionary | T> | null | undefined): T[]; + /** + * @see _.flatMapDeep + */ + flatMapDeep(collection: List | null | undefined, iteratee: ListIterator | TResult>): TResult[]; + /** + * @see _.flatMapDeep + */ + flatMapDeep(collection: T | null | undefined, iteratee: ObjectIterator | TResult>): TResult[]; + /** + * @see _.flatMapDeep + */ + flatMapDeep(collection: object | null | undefined, iteratee: string): any[]; + /** + * @see _.flatMapDeep + */ + flatMapDeep(collection: object | null | undefined, iteratee: object): boolean[]; + } + interface String { + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: StringIterator | TResult>): Collection; + /** + * @see _.flatMapDeep + */ + flatMapDeep(): Collection; + } + interface Collection { + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: ListIterator | TResult> | PropertyName): Collection; + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: [PropertyName, any] | object): Collection; + /** + * @see _.flatMapDeep + */ + flatMapDeep(): Collection; + } + interface Object { + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: ObjectIterator | TResult> | PropertyName): Collection; + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: [PropertyName, any] | object): Collection; + /** + * @see _.flatMapDeep + */ + flatMapDeep(): Collection; + } + interface StringChain { + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: StringIterator | TResult>): CollectionChain; + /** + * @see _.flatMapDeep + */ + flatMapDeep(): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: StringIterator | TResult>): CollectionChain; + /** + * @see _.flatMapDeep + */ + flatMapDeep(): CollectionChain; + } + interface CollectionChain { + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: ListIterator | TResult> | PropertyName): CollectionChain; + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: [PropertyName, any] | object): CollectionChain; + /** + * @see _.flatMapDeep + */ + flatMapDeep(): CollectionChain; + } + interface ObjectChain { + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: ObjectIterator | TResult> | PropertyName): CollectionChain; + /** + * @see _.flatMapDeep + */ + flatMapDeep(iteratee: [PropertyName, any] | object): CollectionChain; + /** + * @see _.flatMapDeep + */ + flatMapDeep(): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results up to `depth` times. + * + * @since 4.7.0 + * @category Collection + * @param collection The collection to iterate over. + * @param [iteratee=_.identity] The function invoked per iteration. + * @param [depth=1] The maximum recursion depth. + * @returns Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDepth([1, 2], duplicate, 2); + * // => [[1, 1], [2, 2]] + */ + flatMapDepth(collection: Dictionary | T> | NumericDictionary | T> | null | undefined): T[]; + /** + * @see _.flatMapDepth + */ + flatMapDepth(collection: List | null | undefined, iteratee: ListIterator | TResult>, depth?: number): TResult[]; + /** + * @see _.flatMapDepth + */ + flatMapDepth(collection: T | null | undefined, iteratee: ObjectIterator | TResult>, depth?: number): TResult[]; + /** + * @see _.flatMapDepth + */ + flatMapDepth(collection: object | null | undefined, iteratee: string, depth?: number): any[]; + /** + * @see _.flatMapDepth + */ + flatMapDepth(collection: object | null | undefined, iteratee: object, depth?: number): boolean[]; + } + interface String { + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: StringIterator | TResult>, depth?: number): Collection; + /** + * @see _.flatMapDepth + */ + flatMapDepth(depth?: number): Collection; + } + interface Collection { + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: ListIterator | TResult> | PropertyName, depth?: number): Collection; + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: [PropertyName, any] | object, depth?: number): Collection; + /** + * @see _.flatMapDepth + */ + flatMapDepth(depth?: number): Collection; + } + interface Object { + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: ObjectIterator | TResult> | PropertyName, depth?: number): Collection; + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: [PropertyName, any] | object, depth?: number): Collection; + /** + * @see _.flatMapDepth + */ + flatMapDepth(depth?: number): Collection; + } + interface StringChain { + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: StringIterator | TResult>, depth?: number): CollectionChain; + /** + * @see _.flatMapDepth + */ + flatMapDepth(depth?: number): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: StringIterator | TResult>, depth?: number): CollectionChain; + /** + * @see _.flatMapDepth + */ + flatMapDepth(depth?: number): CollectionChain; + } + interface CollectionChain { + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: ListIterator | TResult> | PropertyName, depth?: number): CollectionChain; + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: [PropertyName, any] | object, depth?: number): CollectionChain; + /** + * @see _.flatMapDepth + */ + flatMapDepth(depth?: number): CollectionChain; + } + interface ObjectChain { + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: ObjectIterator | TResult> | PropertyName, depth?: number): CollectionChain; + /** + * @see _.flatMapDepth + */ + flatMapDepth(iteratee: [PropertyName, any] | object, depth?: number): CollectionChain; + /** + * @see _.flatMapDepth + */ + flatMapDepth(depth?: number): CollectionChain; + } + interface LoDashStatic { + /** + * Iterates over elements of collection invoking iteratee for each element. The iteratee is invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early by explicitly returning false. + * + * Note: As with other "Collections" methods, objects with a "length" property are iterated like arrays. To + * avoid this behavior _.forIn or _.forOwn may be used for object iteration. + * + * @alias _.each + * + * @param collection The collection to iterate over. + * @param iteratee The function invoked per iteration. + */ + forEach(collection: T[], iteratee?: ArrayIterator): T[]; + /** + * @see _.forEach + */ + forEach(collection: string, iteratee?: StringIterator): string; + /** + * @see _.forEach + */ + forEach(collection: List, iteratee?: ListIterator): List; + /** + * @see _.forEach + */ + forEach(collection: T, iteratee?: ObjectIterator): T; + /** + * @see _.forEach + */ + forEach(collection: TArray & (T[] | null | undefined), iteratee?: ArrayIterator): TArray; + /** + * @see _.forEach + */ + forEach(collection: TString, iteratee?: StringIterator): TString; + /** + * @see _.forEach + */ + forEach | null | undefined>(collection: TList & (List | null | undefined), iteratee?: ListIterator): TList; + /** + * @see _.forEach + */ + forEach(collection: T | null | undefined, iteratee?: ObjectIterator): T | null | undefined; + } + interface String { + /** + * @see _.forEach + */ + forEach(iteratee?: StringIterator): String; + } + interface Object { + /** + * @see _.forEach + */ + forEach(iteratee?: ObjectIterator): Object; + } + interface Collection { + /** + * @see _.forEach + */ + forEach(iteratee?: ListIterator): Collection; + } + interface StringChain { + /** + * @see _.forEach + */ + forEach(iteratee?: StringIterator): StringChain; + } + interface StringNullableChain { + /** + * @see _.forEach + */ + forEach(iteratee?: StringIterator): StringNullableChain; + } + interface ObjectChain { + /** + * @see _.forEach + */ + forEach(iteratee?: ObjectIterator): ObjectChain; + } + interface CollectionChain { + /** + * @see _.forEach + */ + forEach(iteratee?: ListIterator): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like _.forEach except that it iterates over elements of collection from right to left. + * + * @alias _.eachRight + * + * @param collection The collection to iterate over. + * @param iteratee The function called per iteration. + */ + forEachRight(collection: T[], iteratee?: ArrayIterator): T[]; + /** + * @see _.forEachRight + */ + forEachRight(collection: string, iteratee?: StringIterator): string; + /** + * @see _.forEachRight + */ + forEachRight(collection: List, iteratee?: ListIterator): List; + /** + * @see _.forEachRight + */ + forEachRight(collection: T, iteratee?: ObjectIterator): T; + /** + * @see _.forEachRight + */ + forEachRight(collection: TArray & (T[] | null | undefined), iteratee?: ArrayIterator): TArray; + /** + * @see _.forEachRight + */ + forEachRight(collection: TString, iteratee?: StringIterator): TString; + /** + * @see _.forEachRight + */ + forEachRight | null | undefined>(collection: TList & (List | null | undefined), iteratee?: ListIterator): TList; + /** + * @see _.forEachRight + */ + forEachRight(collection: T | null | undefined, iteratee?: ObjectIterator): T | null | undefined; + } + interface String { + /** + * @see _.forEachRight + */ + forEachRight(iteratee?: StringIterator): String; + } + interface Object { + /** + * @see _.forEachRight + */ + forEachRight(iteratee?: ObjectIterator): Object; + } + interface Collection { + /** + * @see _.forEachRight + */ + forEachRight(iteratee?: ListIterator): Collection; + } + interface StringChain { + /** + * @see _.forEachRight + */ + forEachRight(iteratee?: StringIterator): StringChain; + } + interface StringNullableChain { + /** + * @see _.forEachRight + */ + forEachRight(iteratee?: StringIterator): StringNullableChain; + } + interface ObjectChain { + /** + * @see _.forEachRight + */ + forEachRight(iteratee?: ObjectIterator): ObjectChain; + } + interface CollectionChain { + /** + * @see _.forEachRight + */ + forEachRight(iteratee?: ListIterator): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an object composed of keys generated from the results of running each element of collection through + * iteratee. The corresponding value of each key is an array of the elements responsible for generating the + * key. The iteratee is invoked with one argument: (value). + * + * @param collection The collection to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns the composed aggregate object. + */ + groupBy(collection: List | null | undefined, iteratee?: ValueIteratee): Dictionary; + /** + * @see _.groupBy + */ + groupBy(collection: T | null | undefined, iteratee?: ValueIteratee): Dictionary>; + } + interface String { + /** + * @see _.groupBy + */ + groupBy(iteratee?: ValueIteratee): Object>; + } + interface Collection { + /** + * @see _.groupBy + */ + groupBy(iteratee?: ValueIteratee): Object>; + } + interface Object { + /** + * @see _.groupBy + */ + groupBy(iteratee?: ValueIteratee): Object>>; + } + interface StringChain { + /** + * @see _.groupBy + */ + groupBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface StringNullableChain { + /** + * @see _.groupBy + */ + groupBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface CollectionChain { + /** + * @see _.groupBy + */ + groupBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface ObjectChain { + /** + * @see _.groupBy + */ + groupBy(iteratee?: ValueIteratee): ObjectChain>>; + } + interface LoDashStatic { + /** + * Checks if target is in collection using SameValueZero for equality comparisons. If fromIndex is negative, + * it’s used as the offset from the end of collection. + * + * @param collection The collection to search. + * @param target The value to search for. + * @param fromIndex The index to search from. + * @return True if the target element is found, else false. + */ + includes(collection: Dictionary | NumericDictionary | null | undefined, target: T, fromIndex?: number): boolean; + } + interface Object { + /** + * @see _.includes + */ + includes(target: T[keyof T], fromIndex?: number): boolean; + } + interface Collection { + /** + * @see _.includes + */ + includes(target: T, fromIndex?: number): boolean; + } + interface String { + /** + * @see _.includes + */ + includes(target: string, fromIndex?: number): boolean; + } + interface ObjectChain { + /** + * @see _.includes + */ + includes(target: T[keyof T], fromIndex?: number): PrimitiveChain; + } + interface CollectionChain { + /** + * @see _.includes + */ + includes(target: T, fromIndex?: number): PrimitiveChain; + } + interface StringChain { + /** + * @see _.includes + */ + includes(target: string, fromIndex?: number): PrimitiveChain; + } + interface LoDashStatic { + /** + * Invokes the method named by methodName on each element in the collection returning + * an array of the results of each invoked method. Additional arguments will be provided + * to each invoked method. If methodName is a function it will be invoked for, and this + * bound to, each element in the collection. + * @param collection The collection to iterate over. + * @param methodName The name of the method to invoke. + * @param args Arguments to invoke the method with. + */ + invokeMap(collection: object | null | undefined, methodName: string, ...args: any[]): any[]; + /** + * @see _.invokeMap + */ + invokeMap(collection: object | null | undefined, method: (...args: any[]) => TResult, ...args: any[]): TResult[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.invokeMap + */ + invokeMap(methodName: string, ...args: any[]): Collection; + /** + * @see _.invokeMap + */ + invokeMap(method: (...args: any[]) => TResult, ...args: any[]): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.invokeMap + */ + invokeMap(methodName: string, ...args: any[]): CollectionChain; + /** + * @see _.invokeMap + */ + invokeMap(method: (...args: any[]) => TResult, ...args: any[]): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an object composed of keys generated from the results of running each element of collection through + * iteratee. The corresponding value of each key is the last element responsible for generating the key. The + * iteratee function is invoked with one argument: (value). + * + * @param collection The collection to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns the composed aggregate object. + */ + keyBy(collection: List | null | undefined, iteratee?: ValueIterateeCustom): Dictionary; + /** + * @see _.keyBy + */ + keyBy(collection: T | null | undefined, iteratee?: ValueIterateeCustom): Dictionary; + } + interface String { + /** + * @see _.keyBy + */ + keyBy(iteratee?: ValueIterateeCustom): Object>; + } + interface Collection { + /** + * @see _.keyBy + */ + keyBy(iteratee?: ValueIterateeCustom): Object>; + } + interface Object { + /** + * @see _.keyBy + */ + keyBy(iteratee?: ValueIterateeCustom): Object>; + } + interface StringChain { + /** + * @see _.keyBy + */ + keyBy(iteratee?: ValueIterateeCustom): ObjectChain>; + } + interface StringNullableChain { + /** + * @see _.keyBy + */ + keyBy(iteratee?: ValueIterateeCustom): ObjectChain>; + } + interface CollectionChain { + /** + * @see _.keyBy + */ + keyBy(iteratee?: ValueIterateeCustom): ObjectChain>; + } + interface ObjectChain { + /** + * @see _.keyBy + */ + keyBy(iteratee?: ValueIterateeCustom): ObjectChain>; + } + interface LoDashStatic { + /** + * Creates an array of values by running each element in collection through iteratee. The iteratee is + * invoked with three arguments: (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like _.every, _.filter, _.map, _.mapValues, + * _.reject, and _.some. + * + * The guarded methods are: + * ary, callback, chunk, clone, create, curry, curryRight, drop, dropRight, every, fill, flatten, invert, max, + * min, parseInt, slice, sortBy, take, takeRight, template, trim, trimLeft, trimRight, trunc, random, range, + * sample, some, sum, uniq, and words + * + * @param collection The collection to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns the new mapped array. + */ + map(collection: T[] | null | undefined, iteratee: ArrayIterator): TResult[]; + /** + * @see _.map + */ + map(collection: List | null | undefined, iteratee: ListIterator): TResult[]; + /** + * @see _.map + */ + map(collection: Dictionary | NumericDictionary | null | undefined): T[]; + /** + * @see _.map + */ + map(collection: T | null | undefined, iteratee: ObjectIterator): TResult[]; + /** + * @see _.map + */ + map(collection: Dictionary | NumericDictionary | null | undefined, iteratee: K): Array; + /** + * @see _.map + */ + map(collection: Dictionary | NumericDictionary | null | undefined, iteratee?: string): any[]; + /** + * @see _.map + */ + map(collection: Dictionary | NumericDictionary | null | undefined, iteratee?: object): boolean[]; + } + + interface String { + /** + * @see _.map + */ + map(iteratee: StringIterator): Collection; + /** + * @see _.map + */ + map(): Collection; + } + interface Collection { + /** + * @see _.map + */ + map(key: K): Collection; + /** + * @see _.map + */ + map(iteratee: ListIterator): Collection; + /** + * @see _.map + */ + map(iteratee: PropertyName): Collection; + /** + * @see _.map + */ + map(iteratee: [PropertyName, any] | object): Collection; + /** + * @see _.map + */ + map(): Collection; + } + interface Object { + /** + * @see _.map + */ + map(key: K): Collection; + /** + * @see _.map + */ + map(iteratee: ObjectIterator): Collection; + /** + * @see _.map + */ + map(iteratee: PropertyName): Collection; + /** + * @see _.map + */ + map(iteratee: [PropertyName, any] | object): Collection; + /** + * @see _.map + */ + map(): Collection; + } + interface StringChain { + /** + * @see _.map + */ + map(iteratee: StringIterator): CollectionChain; + /** + * @see _.map + */ + map(): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.map + */ + map(iteratee: StringIterator): CollectionChain; + /** + * @see _.map + */ + map(): CollectionChain; + } + interface CollectionChain { + /** + * @see _.map + */ + map(key: K): CollectionChain; + /** + * @see _.map + */ + map(iteratee: ListIterator): CollectionChain; + /** + * @see _.map + */ + map(iteratee: PropertyName): CollectionChain; + /** + * @see _.map + */ + map(iteratee: [PropertyName, any] | object): CollectionChain; + /** + * @see _.map + */ + map(): CollectionChain; + } + interface ObjectChain { + /** + * @see _.map + */ + map(key: K): CollectionChain; + /** + * @see _.map + */ + map(iteratee: ObjectIterator): CollectionChain; + /** + * @see _.map + */ + map(iteratee: PropertyName): CollectionChain; + /** + * @see _.map + */ + map(iteratee: [PropertyName, any] | object): CollectionChain; + /** + * @see _.map + */ + map(): CollectionChain; + } + interface LoDashStatic { + /** + * This method is like `_.sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. + * + * @category Collection + * @param collection The collection to iterate over. + * @param [iteratees=[_.identity]] The iteratees to sort by. + * @param [orders] The sort orders of `iteratees`. + * @param [guard] Enables use as an iteratee for functions like `_.reduce`. + * @returns Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + orderBy(collection: List | null | undefined, iteratees?: Many>, orders?: Many): T[]; + /** + * @see _.orderBy + */ + orderBy(collection: List | null | undefined, iteratees?: Many>, orders?: Many): T[]; + /** + * @see _.orderBy + */ + orderBy(collection: T | null | undefined, iteratees?: Many>, orders?: Many): Array; + /** + * @see _.orderBy + */ + orderBy(collection: T | null | undefined, iteratees?: Many>, orders?: Many): Array; + } + interface Collection { + /** + * @see _.orderBy + */ + orderBy(iteratees?: Many | PropertyName | PartialShallow>, orders?: Many): Collection; + } + interface Object { + /** + * @see _.orderBy + */ + orderBy(iteratees?: Many>, orders?: Many): Collection; + } + interface CollectionChain { + /** + * @see _.orderBy + */ + orderBy(iteratees?: Many | PropertyName | PartialShallow>, orders?: Many): CollectionChain; + } + interface ObjectChain { + /** + * @see _.orderBy + */ + orderBy(iteratees?: Many>, orders?: Many): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of elements split into two groups, the first of which contains elements predicate returns truthy for, + * while the second of which contains elements predicate returns falsey for. + * The predicate is invoked with three arguments: (value, index|key, collection). + * + * @param collection The collection to iterate over. + * @param callback The function called per iteration. + * @return Returns the array of grouped elements. + */ + partition(collection: List | null | undefined, callback: ValueIteratorTypeGuard): [U[], Array>]; + /** + * @see _.partition + */ + partition(collection: List | null | undefined, callback: ValueIteratee): [T[], T[]]; + /** + * @see _.partition + */ + partition(collection: T | null | undefined, callback: ValueIteratee): [Array, Array]; + } + interface String { + /** + * @see _.partition + */ + partition(callback: StringIterator): LoDashImplicitWrapper<[string[], string[]]>; + } + interface Collection { + /** + * @see _.partition + */ + partition(callback: ValueIteratorTypeGuard): LoDashImplicitWrapper<[U[], Array>]>; + /** + * @see _.partition + */ + partition(callback: ValueIteratee): LoDashImplicitWrapper<[T[], T[]]>; + } + interface Object { + /** + * @see _.partition + */ + partition(callback: ValueIteratee): LoDashImplicitWrapper<[Array, Array]>; + } + interface StringChain { + /** + * @see _.partition + */ + partition(callback: StringIterator): LoDashExplicitWrapper<[string[], string[]]>; + } + interface StringNullableChain { + /** + * @see _.partition + */ + partition(callback: StringIterator): LoDashExplicitWrapper<[string[], string[]]>; + } + interface CollectionChain { + /** + * @see _.partition + */ + partition(callback: ValueIteratorTypeGuard): LoDashExplicitWrapper<[U[], Array>]>; + /** + * @see _.partition + */ + partition(callback: ValueIteratee): LoDashExplicitWrapper<[T[], T[]]>; + } + interface ObjectChain { + /** + * @see _.partition + */ + partition(callback: ValueIteratee): LoDashExplicitWrapper<[Array, Array]>; + } + interface LoDashStatic { + /** + * Reduces a collection to a value which is the accumulated result of running each + * element in the collection through the callback, where each successive callback execution + * consumes the return value of the previous execution. If accumulator is not provided the + * first element of the collection will be used as the initial accumulator value. The callback + * is invoked with four arguments: (accumulator, value, index|key, collection). + * @param collection The collection to iterate over. + * @param callback The function called per iteration. + * @param accumulator Initial value of the accumulator. + * @return Returns the accumulated value. + */ + reduce(collection: T[] | null | undefined, callback: MemoListIterator, accumulator: TResult): TResult; + /** + * @see _.reduce + */ + reduce(collection: List | null | undefined, callback: MemoListIterator>, accumulator: TResult): TResult; + /** + * @see _.reduce + */ + reduce(collection: T | null | undefined, callback: MemoObjectIterator, accumulator: TResult): TResult; + /** + * @see _.reduce + */ + reduce(collection: T[] | null | undefined, callback: MemoListIterator): T | undefined; + /** + * @see _.reduce + */ + reduce(collection: List | null | undefined, callback: MemoListIterator>): T | undefined; + /** + * @see _.reduce + */ + reduce(collection: T | null | undefined, callback: MemoObjectIterator): T[keyof T] | undefined; + } + interface Collection { + /** + * @see _.reduce + */ + reduce(callback: MemoListIterator>, accumulator: TResult): TResult; + /** + * @see _.reduce + */ + reduce(callback: MemoListIterator>): T | undefined; + } + interface Object { + /** + * @see _.reduce + */ + reduce(callback: MemoObjectIterator, accumulator: TResult): TResult; + /** + * @see _.reduce + */ + reduce(callback: MemoObjectIterator): T[keyof T] | undefined; + } + interface CollectionChain { + /** + * @see _.reduce + */ + reduce(callback: MemoListIterator>, accumulator: TResult): ExpChain; + /** + * @see _.reduce + */ + reduce(callback: MemoListIterator>): ExpChain; + } + interface ObjectChain { + /** + * @see _.reduce + */ + reduce(callback: MemoObjectIterator, accumulator: TResult): ExpChain; + /** + * @see _.reduce + */ + reduce(callback: MemoObjectIterator): ExpChain; + } + interface LoDashStatic { + /** + * This method is like _.reduce except that it iterates over elements of a collection from + * right to left. + * @param collection The collection to iterate over. + * @param callback The function called per iteration. + * @param accumulator Initial value of the accumulator. + * @return The accumulated value. + */ + reduceRight(collection: T[] | null | undefined, callback: MemoListIterator, accumulator: TResult): TResult; + /** + * @see _.reduceRight + */ + reduceRight(collection: List | null | undefined, callback: MemoListIterator>, accumulator: TResult): TResult; + /** + * @see _.reduceRight + */ + reduceRight(collection: T | null | undefined, callback: MemoObjectIterator, accumulator: TResult): TResult; + /** + * @see _.reduceRight + */ + reduceRight(collection: T[] | null | undefined, callback: MemoListIterator): T | undefined; + /** + * @see _.reduceRight + */ + reduceRight(collection: List | null | undefined, callback: MemoListIterator>): T | undefined; + /** + * @see _.reduceRight + */ + reduceRight(collection: T | null | undefined, callback: MemoObjectIterator): T[keyof T] | undefined; + } + interface Collection { + /** + * @see _.reduceRight + */ + reduceRight(callback: MemoListIterator>, accumulator: TResult): TResult; + /** + * @see _.reduceRight + */ + reduceRight(callback: MemoListIterator>): T | undefined; + } + interface Object { + /** + * @see _.reduceRight + */ + reduceRight(callback: MemoObjectIterator, accumulator: TResult): TResult; + /** + * @see _.reduceRight + */ + reduceRight(callback: MemoObjectIterator): T[keyof T] | undefined; + } + interface CollectionChain { + /** + * @see _.reduceRight + */ + reduceRight(callback: MemoListIterator>, accumulator: TResult): ExpChain; + /** + * @see _.reduceRight + */ + reduceRight(callback: MemoListIterator>): ExpChain; + } + interface ObjectChain { + /** + * @see _.reduceRight + */ + reduceRight(callback: MemoObjectIterator, accumulator: TResult): ExpChain; + /** + * @see _.reduceRight + */ + reduceRight(callback: MemoObjectIterator): ExpChain; + } + interface LoDashStatic { + /** + * The opposite of _.filter; this method returns the elements of collection that predicate does not return + * truthy for. + * + * @param collection The collection to iterate over. + * @param predicate The function invoked per iteration. + * @return Returns the new filtered array. + */ + reject(collection: string | null | undefined, predicate?: StringIterator): string[]; + /** + * @see _.reject + */ + reject(collection: List | null | undefined, predicate?: ListIterateeCustom): T[]; + /** + * @see _.reject + */ + reject(collection: T | null | undefined, predicate?: ObjectIterateeCustom): Array; + } + interface String { + /** + * @see _.reject + */ + reject(predicate?: StringIterator): Collection; + } + interface Collection { + /** + * @see _.reject + */ + reject(predicate?: ListIterateeCustom): Collection; + } + interface Object { + /** + * @see _.reject + */ + reject(predicate?: ObjectIterateeCustom): Collection; + } + interface StringChain { + /** + * @see _.reject + */ + reject(predicate?: StringIterator): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.reject + */ + reject(predicate?: StringIterator): CollectionChain; + } + interface CollectionChain { + /** + * @see _.reject + */ + reject(predicate?: ListIterateeCustom): CollectionChain; + } + interface ObjectChain { + /** + * @see _.reject + */ + reject(predicate?: ObjectIterateeCustom): CollectionChain; + } + interface LoDashStatic { + /** + * Gets a random element from collection. + * + * @param collection The collection to sample. + * @return Returns the random element. + */ + sample(collection: readonly [T, ...T[]]): T; + /** + * @see _.sample + */ + sample(collection: Dictionary | NumericDictionary | null | undefined): T | undefined; + /** + * @see _.sample + */ + sample(collection: T | null | undefined): T[keyof T] | undefined; + } + interface String { + /** + * @see _.sample + */ + sample(): string | undefined; + } + interface Collection { + /** + * @see _.sample + */ + sample(): T | undefined; + } + interface Object { + /** + * @see _.sample + */ + sample(): T[keyof T] | undefined; + } + interface StringChain { + /** + * @see _.sample + */ + sample(): StringNullableChain; + } + interface StringNullableChain { + /** + * @see _.sample + */ + sample(): StringNullableChain; + } + interface CollectionChain { + /** + * @see _.sample + */ + sample(): ExpChain; + } + interface ObjectChain { + /** + * @see _.sample + */ + sample(): ExpChain; + } + interface LoDashStatic { + /** + * Gets n random elements at unique keys from collection up to the size of collection. + * + * @param collection The collection to sample. + * @param n The number of elements to sample. + * @return Returns the random elements. + */ + sampleSize(collection: Dictionary | NumericDictionary | null | undefined, n?: number): T[]; + /** + * @see _.sampleSize + */ + sampleSize(collection: T | null | undefined, n?: number): Array; + } + interface String { + /** + * @see _.sampleSize + */ + sampleSize(n?: number): Collection; + } + interface Collection { + /** + * @see _.sampleSize + */ + sampleSize(n?: number): Collection; + } + interface Object { + /** + * @see _.sampleSize + */ + sampleSize(n?: number): Collection; + } + interface StringChain { + /** + * @see _.sampleSize + */ + sampleSize(n?: number): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.sampleSize + */ + sampleSize(n?: number): CollectionChain; + } + interface CollectionChain { + /** + * @see _.sampleSize + */ + sampleSize(n?: number): CollectionChain; + } + interface ObjectChain { + /** + * @see _.sampleSize + */ + sampleSize(n?: number): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates shuffle. + * + * @param collection The collection to shuffle. + * @return Returns the new shuffled array. + */ + shuffle(collection: List | null | undefined): T[]; + /** + * @see _.shuffle + */ + shuffle(collection: T | null | undefined): Array; + } + interface String { + /** + * @see _.shuffle + */ + shuffle(): Collection; + } + interface Collection { + /** + * @see _.shuffle + */ + shuffle(): Collection; + } + interface Object { + /** + * @see _.shuffle + */ + shuffle(): Collection; + } + interface StringChain { + /** + * @see _.shuffle + */ + shuffle(): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.shuffle + */ + shuffle(): CollectionChain; + } + interface CollectionChain { + /** + * @see _.shuffle + */ + shuffle(): CollectionChain; + } + interface ObjectChain { + /** + * @see _.shuffle + */ + shuffle(): CollectionChain; + } + interface LoDashStatic { + /** + * Gets the size of collection by returning its length for array-like values or the number of own enumerable + * properties for objects. + * + * @param collection The collection to inspect. + * @return Returns the size of collection. + */ + size(collection: object | string | null | undefined): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.size + */ + size(): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.size + */ + size(): PrimitiveChain; + } + interface LoDashStatic { + /** + * Checks if predicate returns truthy for any element of collection. Iteration is stopped once predicate + * returns truthy. The predicate is invoked with three arguments: (value, index|key, collection). + * + * @param collection The collection to iterate over. + * @param predicate The function invoked per iteration. + * @return Returns true if any element passes the predicate check, else false. + */ + some(collection: List | null | undefined, predicate?: ListIterateeCustom): boolean; + /** + * @see _.some + */ + some(collection: T | null | undefined, predicate?: ObjectIterateeCustom): boolean; + } + interface Collection { + /** + * @see _.some + */ + some(predicate?: ListIterateeCustom): boolean; + } + interface Object { + /** + * @see _.some + */ + some(predicate?: ObjectIterateeCustom): boolean; + } + interface CollectionChain { + /** + * @see _.some + */ + some(predicate?: ListIterateeCustom): PrimitiveChain; + } + interface ObjectChain { + /** + * @see _.some + */ + some(predicate?: ObjectIterateeCustom): PrimitiveChain; + } + interface LoDashStatic { + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @category Collection + * @param collection The collection to iterate over. + * @param [iteratees=[_.identity]] + * The iteratees to sort by, specified individually or in arrays. + * @returns Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, function(o) { return o.user; }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.sortBy(users, 'user', function(o) { + * return Math.floor(o.age / 10); + * }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + sortBy(collection: List | null | undefined, ...iteratees: Array>>): T[]; + /** + * @see _.sortBy + */ + sortBy(collection: T | null | undefined, ...iteratees: Array>>): Array; + } + interface Collection { + /** + * @see _.sortBy + */ + sortBy(...iteratees: Array>>): Collection; + } + interface Object { + /** + * @see _.sortBy + */ + sortBy(...iteratees: Array>>): Collection; + } + interface CollectionChain { + /** + * @see _.sortBy + */ + sortBy(...iteratees: Array>>): CollectionChain; + } + interface ObjectChain { + /** + * @see _.sortBy + */ + sortBy(...iteratees: Array>>): CollectionChain; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/common.d.ts b/libs/events/node_modules/@types/lodash/common/common.d.ts new file mode 100755 index 000000000..376b70626 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/common.d.ts @@ -0,0 +1,280 @@ +import _ = require("../index"); +// tslint:disable-next-line:strict-export-declare-modifiers +type GlobalPartial = Partial; +declare module "../index" { + type Omit = Pick>; + type PartialObject = GlobalPartial; + type Many = T | ReadonlyArray; + type ImpChain = + T extends { __trapAny: any } ? Collection & Function & Object & Primitive & String : + T extends null | undefined ? never : + T extends string | null | undefined ? String : + T extends (...args: any) => any ? Function : + T extends List | null | undefined ? Collection : + T extends object | null | undefined ? Object : + Primitive; + type ExpChain = + T extends { __trapAny: any } ? CollectionChain & FunctionChain & ObjectChain & PrimitiveChain & StringChain : + T extends null | undefined ? never : + T extends string ? StringChain : + T extends string | null | undefined ? StringNullableChain : + T extends (...args: any) => any ? FunctionChain : + T extends List | null | undefined ? CollectionChain : + T extends object | null | undefined ? ObjectChain : + PrimitiveChain; + interface LoDashStatic { + /** + * Creates a lodash object which wraps value to enable implicit method chain sequences. + * Methods that operate on and return arrays, collections, and functions can be chained together. + * Methods that retrieve a single value or may return a primitive value will automatically end the + * chain sequence and return the unwrapped value. Otherwise, the value must be unwrapped with value(). + * + * Explicit chain sequences, which must be unwrapped with value(), may be enabled using _.chain. + * + * The execution of chained methods is lazy, that is, it's deferred until value() is + * implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut fusion + * is an optimization to merge iteratee calls; this avoids the creation of intermediate + * arrays and can greatly reduce the number of iteratee executions. Sections of a chain + * sequence qualify for shortcut fusion if the section is applied to an array and iteratees + * accept only one argument. The heuristic for whether a section qualifies for shortcut + * fusion is subject to change. + * + * Chaining is supported in custom builds as long as the value() method is directly or + * indirectly included in the build. + * + * In addition to lodash methods, wrappers have Array and String methods. + * The wrapper Array methods are: + * concat, join, pop, push, shift, sort, splice, and unshift. + * The wrapper String methods are: + * replace and split. + * + * The wrapper methods that support shortcut fusion are: + * at, compact, drop, dropRight, dropWhile, filter, find, findLast, head, initial, last, + * map, reject, reverse, slice, tail, take, takeRight, takeRightWhile, takeWhile, and toArray + * + * The chainable wrapper methods are: + * after, ary, assign, assignIn, assignInWith, assignWith, at, before, bind, bindAll, bindKey, + * castArray, chain, chunk, commit, compact, concat, conforms, constant, countBy, create, + * curry, debounce, defaults, defaultsDeep, defer, delay, difference, differenceBy, differenceWith, + * drop, dropRight, dropRightWhile, dropWhile, extend, extendWith, fill, filter, flatMap, + * flatMapDeep, flatMapDepth, flatten, flattenDeep, flattenDepth, flip, flow, flowRight, + * fromPairs, functions, functionsIn, groupBy, initial, intersection, intersectionBy, intersectionWith, + * invert, invertBy, invokeMap, iteratee, keyBy, keys, keysIn, map, mapKeys, mapValues, + * matches, matchesProperty, memoize, merge, mergeWith, method, methodOf, mixin, negate, + * nthArg, omit, omitBy, once, orderBy, over, overArgs, overEvery, overSome, partial, partialRight, + * partition, pick, pickBy, plant, property, propertyOf, pull, pullAll, pullAllBy, pullAllWith, pullAt, + * push, range, rangeRight, rearg, reject, remove, rest, reverse, sampleSize, set, setWith, + * shuffle, slice, sort, sortBy, sortedUniq, sortedUniqBy, splice, spread, tail, take, + * takeRight, takeRightWhile, takeWhile, tap, throttle, thru, toArray, toPairs, toPairsIn, + * toPath, toPlainObject, transform, unary, union, unionBy, unionWith, uniq, uniqBy, uniqWith, + * unset, unshift, unzip, unzipWith, update, updateWith, values, valuesIn, without, wrap, + * xor, xorBy, xorWith, zip, zipObject, zipObjectDeep, and zipWith. + * + * The wrapper methods that are not chainable by default are: + * add, attempt, camelCase, capitalize, ceil, clamp, clone, cloneDeep, cloneDeepWith, cloneWith, + * conformsTo, deburr, defaultTo, divide, each, eachRight, endsWith, eq, escape, escapeRegExp, + * every, find, findIndex, findKey, findLast, findLastIndex, findLastKey, first, floor, forEach, + * forEachRight, forIn, forInRight, forOwn, forOwnRight, get, gt, gte, has, hasIn, head, + * identity, includes, indexOf, inRange, invoke, isArguments, isArray, isArrayBuffer, + * isArrayLike, isArrayLikeObject, isBoolean, isBuffer, isDate, isElement, isEmpty, isEqual, isEqualWith, + * isError, isFinite, isFunction, isInteger, isLength, isMap, isMatch, isMatchWith, isNaN, + * isNative, isNil, isNull, isNumber, isObject, isObjectLike, isPlainObject, isRegExp, + * isSafeInteger, isSet, isString, isUndefined, isTypedArray, isWeakMap, isWeakSet, join, + * kebabCase, last, lastIndexOf, lowerCase, lowerFirst, lt, lte, max, maxBy, mean, meanBy, + * min, minBy, multiply, noConflict, noop, now, nth, pad, padEnd, padStart, parseInt, pop, + * random, reduce, reduceRight, repeat, result, round, runInContext, sample, shift, size, + * snakeCase, some, sortedIndex, sortedIndexBy, sortedLastIndex, sortedLastIndexBy, startCase, + * startsWith, stubArray, stubFalse, stubObject, stubString, stubTrue, subtract, sum, sumBy, + * template, times, toFinite, toInteger, toJSON, toLength, toLower, toNumber, toSafeInteger, + * toString, toUpper, trim, trimEnd, trimStart, truncate, unescape, uniqueId, upperCase, + * upperFirst, value, and words. + **/ + (value: TrapAny): Collection & Function & Object & Primitive & String; + (value: T): Primitive; + (value: string | null | undefined): String; + any>(value: T): Function; + (value: List | null | undefined): Collection; + (value: T | null | undefined): Object; + (value: T): Primitive; + /** + * The semantic version number. + **/ + VERSION: string; + /** + * By default, the template delimiters used by Lo-Dash are similar to those in embedded Ruby + * (ERB). Change the following template settings to use alternative delimiters. + **/ + templateSettings: TemplateSettings; + } + /** + * By default, the template delimiters used by Lo-Dash are similar to those in embedded Ruby + * (ERB). Change the following template settings to use alternative delimiters. + **/ + interface TemplateSettings { + /** + * The "escape" delimiter. + **/ + escape?: RegExp | undefined; + /** + * The "evaluate" delimiter. + **/ + evaluate?: RegExp | undefined; + /** + * An object to import into the template as local variables. + */ + imports?: Dictionary | undefined; + /** + * The "interpolate" delimiter. + */ + interpolate?: RegExp | undefined; + /** + * Used to reference the data object in the template text. + */ + variable?: string | undefined; + } + /** + * Creates a cache object to store key/value pairs. + */ + interface MapCache { + /** + * Removes `key` and its value from the cache. + * @param key The key of the value to remove. + * @return Returns `true` if the entry was removed successfully, else `false`. + */ + delete(key: any): boolean; + /** + * Gets the cached value for `key`. + * @param key The key of the value to get. + * @return Returns the cached value. + */ + get(key: any): any; + /** + * Checks if a cached value for `key` exists. + * @param key The key of the entry to check. + * @return Returns `true` if an entry for `key` exists, else `false`. + */ + has(key: any): boolean; + /** + * Sets `value` to `key` of the cache. + * @param key The key of the value to cache. + * @param value The value to cache. + * @return Returns the cache object. + */ + set(key: any, value: any): this; + /** + * Removes all key-value entries from the map. + */ + clear?: (() => void) | undefined; + } + interface MapCacheConstructor { + new (): MapCache; + } + interface Collection { + pop(): T | undefined; + push(...items: T[]): this; + shift(): T | undefined; + sort(compareFn?: (a: T, b: T) => number): this; + splice(start: number, deleteCount?: number, ...items: T[]): this; + unshift(...items: T[]): this; + } + interface CollectionChain { + pop(): ExpChain; + push(...items: T[]): this; + shift(): ExpChain; + sort(compareFn?: (a: T, b: T) => number): this; + splice(start: number, deleteCount?: number, ...items: T[]): this; + unshift(...items: T[]): this; + } + interface Function any> extends LoDashImplicitWrapper { + } + interface String extends LoDashImplicitWrapper { + } + interface Object extends LoDashImplicitWrapper { + } + interface Collection extends LoDashImplicitWrapper { + } + interface Primitive extends LoDashImplicitWrapper { + } + interface FunctionChain any> extends LoDashExplicitWrapper { + } + interface StringChain extends LoDashExplicitWrapper { + } + interface StringNullableChain extends LoDashExplicitWrapper { + } + interface ObjectChain extends LoDashExplicitWrapper { + } + interface CollectionChain extends LoDashExplicitWrapper { + } + interface PrimitiveChain extends LoDashExplicitWrapper { + } + type NotVoid = unknown; + type IterateeShorthand = PropertyName | [PropertyName, any] | PartialShallow; + type ArrayIterator = (value: T, index: number, collection: T[]) => TResult; + type ListIterator = (value: T, index: number, collection: List) => TResult; + type ListIteratee = ListIterator | IterateeShorthand; + type ListIterateeCustom = ListIterator | IterateeShorthand; + type ListIteratorTypeGuard = (value: T, index: number, collection: List) => value is S; + // Note: key should be string, not keyof T, because the actual object may contain extra properties that were not specified in the type. + type ObjectIterator = (value: TObject[keyof TObject], key: string, collection: TObject) => TResult; + type ObjectIteratee = ObjectIterator | IterateeShorthand; + type ObjectIterateeCustom = ObjectIterator | IterateeShorthand; + type ObjectIteratorTypeGuard = (value: TObject[keyof TObject], key: string, collection: TObject) => value is S; + type StringIterator = (char: string, index: number, string: string) => TResult; + /** @deprecated Use MemoVoidArrayIterator or MemoVoidDictionaryIterator instead. */ + type MemoVoidIterator = (prev: TResult, curr: T, indexOrKey: any, list: T[]) => void; + /** @deprecated Use MemoListIterator or MemoObjectIterator instead. */ + type MemoIterator = (prev: TResult, curr: T, indexOrKey: any, list: T[]) => TResult; + type MemoListIterator = (prev: TResult, curr: T, index: number, list: TList) => TResult; + type MemoObjectIterator = (prev: TResult, curr: T, key: string, list: TList) => TResult; + type MemoIteratorCapped = (prev: TResult, curr: T) => TResult; + type MemoIteratorCappedRight = (curr: T, prev: TResult) => TResult; + type MemoVoidArrayIterator = (acc: TResult, curr: T, index: number, arr: T[]) => void; + type MemoVoidDictionaryIterator = (acc: TResult, curr: T, key: K, dict: Record) => void; + type MemoVoidIteratorCapped = (acc: TResult, curr: T) => void; + type ValueIteratee = ((value: T) => NotVoid) | IterateeShorthand; + type ValueIterateeCustom = ((value: T) => TResult) | IterateeShorthand; + type ValueIteratorTypeGuard = (value: T) => value is S; + type ValueKeyIteratee = ((value: T, key: string) => NotVoid) | IterateeShorthand; + type ValueKeyIterateeTypeGuard = (value: T, key: string) => value is S; + type Comparator = (a: T, b: T) => boolean; + type Comparator2 = (a: T1, b: T2) => boolean; + type PropertyName = string | number | symbol; + type PropertyPath = Many; + /** Common interface between Arrays and jQuery objects */ + type List = ArrayLike; + interface Dictionary { + [index: string]: T; + } + interface NumericDictionary { + [index: number]: T; + } + // Crazy typedef needed get _.omit to work properly with Dictionary and NumericDictionary + type AnyKindOfDictionary = + | Dictionary + | NumericDictionary; + type PartialShallow = { + [P in keyof T]?: T[P] extends object ? object : T[P] + }; + // For backwards compatibility + type LoDashImplicitArrayWrapper = LoDashImplicitWrapper; + type LoDashImplicitNillableArrayWrapper = LoDashImplicitWrapper; + type LoDashImplicitObjectWrapper = LoDashImplicitWrapper; + type LoDashImplicitNillableObjectWrapper = LoDashImplicitWrapper; + type LoDashImplicitNumberArrayWrapper = LoDashImplicitWrapper; + type LoDashImplicitStringWrapper = LoDashImplicitWrapper; + type LoDashExplicitArrayWrapper = LoDashExplicitWrapper; + type LoDashExplicitNillableArrayWrapper = LoDashExplicitWrapper; + type LoDashExplicitObjectWrapper = LoDashExplicitWrapper; + type LoDashExplicitNillableObjectWrapper = LoDashExplicitWrapper; + type LoDashExplicitNumberArrayWrapper = LoDashExplicitWrapper; + type LoDashExplicitStringWrapper = LoDashExplicitWrapper; + type DictionaryIterator = ObjectIterator, TResult>; + type DictionaryIteratee = ObjectIteratee>; + type DictionaryIteratorTypeGuard = ObjectIteratorTypeGuard, S>; + // NOTE: keys of objects at run time are always strings, even when a NumericDictionary is being iterated. + type NumericDictionaryIterator = (value: T, key: string, collection: NumericDictionary) => TResult; + type NumericDictionaryIteratee = NumericDictionaryIterator | IterateeShorthand; + type NumericDictionaryIterateeCustom = NumericDictionaryIterator | IterateeShorthand; +} diff --git a/libs/events/node_modules/@types/lodash/common/date.d.ts b/libs/events/node_modules/@types/lodash/common/date.d.ts new file mode 100755 index 000000000..cc652ae6c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/date.d.ts @@ -0,0 +1,23 @@ +import _ = require("../index"); +declare module "../index" { + interface LoDashStatic { + /* + * Gets the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @return The number of milliseconds. + */ + now(): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.now + */ + now(): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.now + */ + now(): PrimitiveChain; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/function.d.ts b/libs/events/node_modules/@types/lodash/common/function.d.ts new file mode 100755 index 000000000..762827846 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/function.d.ts @@ -0,0 +1,1446 @@ +import _ = require("../index"); +declare module "../index" { + interface LoDashStatic { + /** + * The opposite of _.before; this method creates a function that invokes func once it’s called n or more times. + * + * @param n The number of calls before func is invoked. + * @param func The function to restrict. + * @return Returns the new restricted function. + */ + after any>(n: number, func: TFunc): TFunc; + } + interface Primitive { + /** + * @see _.after + */ + after any>(func: TFunc): Function; + } + interface PrimitiveChain { + /** + * @see _.after + */ + after any>(func: TFunc): FunctionChain; + } + interface LoDashStatic { + /** + * Creates a function that accepts up to n arguments ignoring any additional arguments. + * + * @param func The function to cap arguments for. + * @param n The arity cap. + * @returns Returns the new function. + */ + ary(func: (...args: any[]) => any, n?: number): (...args: any[]) => any; + } + interface Function any> { + /** + * @see _.ary + */ + ary(n?: number): Function<(...args: any[]) => any>; + } + interface FunctionChain any> { + /** + * @see _.ary + */ + ary(n?: number): FunctionChain<(...args: any[]) => any>; + } + interface LoDashStatic { + /** + * Creates a function that invokes func, with the this binding and arguments of the created function, while + * it’s called less than n times. Subsequent calls to the created function return the result of the last func + * invocation. + * + * @param n The number of calls at which func is no longer invoked. + * @param func The function to restrict. + * @return Returns the new restricted function. + */ + before any>(n: number, func: TFunc): TFunc; + } + interface Primitive { + /** + * @see _.before + */ + before any>(func: TFunc): Function; + } + interface PrimitiveChain { + /** + * @see _.before + */ + before any>(func: TFunc): FunctionChain; + } + interface FunctionBind { + /** + * @see _.placeholder + */ + placeholder: __; + (func: (...args: any[]) => any, thisArg: any, ...partials: any[]): (...args: any[]) => any; + } + interface LoDashStatic { + /** + * Creates a function that invokes func with the this binding of thisArg and prepends any additional _.bind + * arguments to those provided to the bound function. + * + * The _.bind.placeholder value, which defaults to _ in monolithic builds, may be used as a placeholder for + * partially applied arguments. + * + * Note: Unlike native Function#bind this method does not set the "length" property of bound functions. + * + * @param func The function to bind. + * @param thisArg The this binding of func. + * @param partials The arguments to be partially applied. + * @return Returns the new bound function. + */ + bind: FunctionBind; + } + interface LoDashImplicitWrapper { + /** + * @see _.bind + */ + bind(thisArg: any, ...partials: any[]): Function<(...args: any[]) => any>; + } + interface LoDashExplicitWrapper { + /** + * @see _.bind + */ + bind(thisArg: any, ...partials: any[]): FunctionChain<(...args: any[]) => any>; + } + interface FunctionBindKey { + placeholder: __; + (object: object, key: string, ...partials: any[]): (...args: any[]) => any; + } + interface LoDashStatic { + /** + * Creates a function that invokes the method at object[key] and prepends any additional _.bindKey arguments + * to those provided to the bound function. + * + * This method differs from _.bind by allowing bound functions to reference methods that may be redefined + * or don’t yet exist. See Peter Michaux’s article for more details. + * + * The _.bindKey.placeholder value, which defaults to _ in monolithic builds, may be used as a placeholder + * for partially applied arguments. + * + * @param object The object the method belongs to. + * @param key The key of the method. + * @param partials The arguments to be partially applied. + * @return Returns the new bound function. + */ + bindKey: FunctionBindKey; + } + interface LoDashImplicitWrapper { + /** + * @see _.bindKey + */ + bindKey(key: string, ...partials: any[]): Function<(...args: any[]) => any>; + } + interface LoDashExplicitWrapper { + /** + * @see _.bindKey + */ + bindKey(key: string, ...partials: any[]): FunctionChain<(...args: any[]) => any>; + } + interface Curry { + (func: (t1: T1) => R, arity?: number): CurriedFunction1; + (func: (t1: T1, t2: T2) => R, arity?: number): CurriedFunction2; + (func: (t1: T1, t2: T2, t3: T3) => R, arity?: number): CurriedFunction3; + (func: (t1: T1, t2: T2, t3: T3, t4: T4) => R, arity?: number): CurriedFunction4; + (func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R, arity?: number): CurriedFunction5; + (func: (...args: any[]) => any, arity?: number): (...args: any[]) => any; + placeholder: __; + } + interface LoDashStatic { + curry: Curry; + } + interface CurriedFunction1 { + (): CurriedFunction1; + (t1: T1): R; + } + interface CurriedFunction2 { + (): CurriedFunction2; + (t1: T1): CurriedFunction1; + (t1: __, t2: T2): CurriedFunction1; + (t1: T1, t2: T2): R; + } + interface CurriedFunction3 { + (): CurriedFunction3; + (t1: T1): CurriedFunction2; + (t1: __, t2: T2): CurriedFunction2; + (t1: T1, t2: T2): CurriedFunction1; + (t1: __, t2: __, t3: T3): CurriedFunction2; + (t1: T1, t2: __, t3: T3): CurriedFunction1; + (t1: __, t2: T2, t3: T3): CurriedFunction1; + (t1: T1, t2: T2, t3: T3): R; + } + interface CurriedFunction4 { + (): CurriedFunction4; + (t1: T1): CurriedFunction3; + (t1: __, t2: T2): CurriedFunction3; + (t1: T1, t2: T2): CurriedFunction2; + (t1: __, t2: __, t3: T3): CurriedFunction3; + (t1: __, t2: __, t3: T3): CurriedFunction2; + (t1: __, t2: T2, t3: T3): CurriedFunction2; + (t1: T1, t2: T2, t3: T3): CurriedFunction1; + (t1: __, t2: __, t3: __, t4: T4): CurriedFunction3; + (t1: T1, t2: __, t3: __, t4: T4): CurriedFunction2; + (t1: __, t2: T2, t3: __, t4: T4): CurriedFunction2; + (t1: __, t2: __, t3: T3, t4: T4): CurriedFunction2; + (t1: T1, t2: T2, t3: __, t4: T4): CurriedFunction1; + (t1: T1, t2: __, t3: T3, t4: T4): CurriedFunction1; + (t1: __, t2: T2, t3: T3, t4: T4): CurriedFunction1; + (t1: T1, t2: T2, t3: T3, t4: T4): R; + } + interface CurriedFunction5 { + (): CurriedFunction5; + (t1: T1): CurriedFunction4; + (t1: __, t2: T2): CurriedFunction4; + (t1: T1, t2: T2): CurriedFunction3; + (t1: __, t2: __, t3: T3): CurriedFunction4; + (t1: T1, t2: __, t3: T3): CurriedFunction3; + (t1: __, t2: T2, t3: T3): CurriedFunction3; + (t1: T1, t2: T2, t3: T3): CurriedFunction2; + (t1: __, t2: __, t3: __, t4: T4): CurriedFunction4; + (t1: T1, t2: __, t3: __, t4: T4): CurriedFunction3; + (t1: __, t2: T2, t3: __, t4: T4): CurriedFunction3; + (t1: __, t2: __, t3: T3, t4: T4): CurriedFunction3; + (t1: T1, t2: T2, t3: __, t4: T4): CurriedFunction2; + (t1: T1, t2: __, t3: T3, t4: T4): CurriedFunction2; + (t1: __, t2: T2, t3: T3, t4: T4): CurriedFunction2; + (t1: T1, t2: T2, t3: T3, t4: T4): CurriedFunction1; + (t1: __, t2: __, t3: __, t4: __, t5: T5): CurriedFunction4; + (t1: T1, t2: __, t3: __, t4: __, t5: T5): CurriedFunction3; + (t1: __, t2: T2, t3: __, t4: __, t5: T5): CurriedFunction3; + (t1: __, t2: __, t3: T3, t4: __, t5: T5): CurriedFunction3; + (t1: __, t2: __, t3: __, t4: T4, t5: T5): CurriedFunction3; + (t1: T1, t2: T2, t3: __, t4: __, t5: T5): CurriedFunction2; + (t1: T1, t2: __, t3: T3, t4: __, t5: T5): CurriedFunction2; + (t1: T1, t2: __, t3: __, t4: T4, t5: T5): CurriedFunction2; + (t1: __, t2: T2, t3: T3, t4: __, t5: T5): CurriedFunction2; + (t1: __, t2: T2, t3: __, t4: T4, t5: T5): CurriedFunction2; + (t1: __, t2: __, t3: T3, t4: T4, t5: T5): CurriedFunction2; + (t1: T1, t2: T2, t3: T3, t4: __, t5: T5): CurriedFunction1; + (t1: T1, t2: T2, t3: __, t4: T4, t5: T5): CurriedFunction1; + (t1: T1, t2: __, t3: T3, t4: T4, t5: T5): CurriedFunction1; + (t1: __, t2: T2, t3: T3, t4: T4, t5: T5): CurriedFunction1; + (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5): R; + } + interface RightCurriedFunction1 { + (): RightCurriedFunction1; + (t1: T1): R; + } + interface RightCurriedFunction2 { + (): RightCurriedFunction2; + (t2: T2): RightCurriedFunction1; + (t1: T1, t2: __): RightCurriedFunction1; + (t1: T1, t2: T2): R; + } + interface RightCurriedFunction3 { + (): RightCurriedFunction3; + (t3: T3): RightCurriedFunction2; + (t2: T2, t3: __): RightCurriedFunction2; + (t2: T2, t3: T3): RightCurriedFunction1; + (t1: T1, t2: __, t3: __): RightCurriedFunction2; + (t1: T1, t2: T2, t3: __): RightCurriedFunction1; + (t1: T1, t2: __, t3: T3): RightCurriedFunction1; + (t1: T1, t2: T2, t3: T3): R; + } + interface RightCurriedFunction4 { + (): RightCurriedFunction4; + (t4: T4): RightCurriedFunction3; + (t3: T3, t4: __): RightCurriedFunction3; + (t3: T3, t4: T4): RightCurriedFunction2; + (t2: T2, t3: __, t4: __): RightCurriedFunction3; + (t2: T2, t3: T3, t4: __): RightCurriedFunction2; + (t2: T2, t3: __, t4: T4): RightCurriedFunction2; + (t2: T2, t3: T3, t4: T4): RightCurriedFunction1; + (t1: T1, t2: __, t3: __, t4: __): RightCurriedFunction3; + (t1: T1, t2: T2, t3: __, t4: __): RightCurriedFunction2; + (t1: T1, t2: __, t3: T3, t4: __): RightCurriedFunction2; + (t1: T1, t2: __, t3: __, t4: T4): RightCurriedFunction2; + (t1: T1, t2: T2, t3: T3, t4: __): RightCurriedFunction1; + (t1: T1, t2: T2, t3: __, t4: T4): RightCurriedFunction1; + (t1: T1, t2: __, t3: T3, t4: T4): RightCurriedFunction1; + (t1: T1, t2: T2, t3: T3, t4: T4): R; + } + interface RightCurriedFunction5 { + (): RightCurriedFunction5; + (t5: T5): RightCurriedFunction4; + (t4: T4, t5: __): RightCurriedFunction4; + (t4: T4, t5: T5): RightCurriedFunction3; + (t3: T3, t4: __, t5: __): RightCurriedFunction4; + (t3: T3, t4: T4, t5: __): RightCurriedFunction3; + (t3: T3, t4: __, t5: T5): RightCurriedFunction3; + (t3: T3, t4: T4, t5: T5): RightCurriedFunction2; + (t2: T2, t3: __, t4: __, t5: __): RightCurriedFunction4; + (t2: T2, t3: T3, t4: __, t5: __): RightCurriedFunction3; + (t2: T2, t3: __, t4: T4, t5: __): RightCurriedFunction3; + (t2: T2, t3: __, t4: __, t5: T5): RightCurriedFunction3; + (t2: T2, t3: T3, t4: T4, t5: __): RightCurriedFunction2; + (t2: T2, t3: T3, t4: __, t5: T5): RightCurriedFunction2; + (t2: T2, t3: __, t4: T4, t5: T5): RightCurriedFunction2; + (t2: T2, t3: T3, t4: T4, t5: T5): RightCurriedFunction1; + (t1: T1, t2: __, t3: __, t4: __, t5: __): RightCurriedFunction4; + (t1: T1, t2: T2, t3: __, t4: __, t5: __): RightCurriedFunction3; + (t1: T1, t2: __, t3: T3, t4: __, t5: __): RightCurriedFunction3; + (t1: T1, t2: __, t3: __, t4: T4, t5: __): RightCurriedFunction3; + (t1: T1, t2: __, t3: __, t4: __, t5: T5): RightCurriedFunction3; + (t1: T1, t2: T2, t3: T3, t4: __, t5: __): RightCurriedFunction2; + (t1: T1, t2: T2, t3: __, t4: T4, t5: __): RightCurriedFunction2; + (t1: T1, t2: T2, t3: __, t4: __, t5: T5): RightCurriedFunction2; + (t1: T1, t2: __, t3: T3, t4: T4, t5: __): RightCurriedFunction2; + (t1: T1, t2: __, t3: T3, t4: __, t5: T5): RightCurriedFunction2; + (t1: T1, t2: __, t3: __, t4: T4, t5: T5): RightCurriedFunction2; + (t1: T1, t2: T2, t3: T3, t4: T4, t5: __): RightCurriedFunction1; + (t1: T1, t2: T2, t3: T3, t4: __, t5: T5): RightCurriedFunction1; + (t1: T1, t2: T2, t3: __, t4: T4, t5: T5): RightCurriedFunction1; + (t1: T1, t2: __, t3: T3, t4: T4, t5: T5): RightCurriedFunction1; + (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5): R; + } + interface Function any> { + /** + * @see _.curry + */ + curry(arity?: number): + T extends (arg1: infer T1) => infer R ? Function> : + T extends (arg1: infer T1, arg2: infer T2) => infer R ? Function> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3) => infer R ? Function> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3, arg4: infer T4) => infer R ? Function> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3, arg4: infer T4, arg5: infer T5) => infer R ? Function> : + Function<(...args: any[]) => any>; + } + interface FunctionChain any> { + /** + * @see _.curry + */ + curry(arity?: number): + T extends (arg1: infer T1) => infer R ? FunctionChain> : + T extends (arg1: infer T1, arg2: infer T2) => infer R ? FunctionChain> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3) => infer R ? FunctionChain> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3, arg4: infer T4) => infer R ? FunctionChain> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3, arg4: infer T4, arg5: infer T5) => infer R ? FunctionChain> : + FunctionChain<(...args: any[]) => any>; + } + interface CurryRight { + (func: (t1: T1) => R, arity?: number): RightCurriedFunction1; + (func: (t1: T1, t2: T2) => R, arity?: number): RightCurriedFunction2; + (func: (t1: T1, t2: T2, t3: T3) => R, arity?: number): RightCurriedFunction3; + (func: (t1: T1, t2: T2, t3: T3, t4: T4) => R, arity?: number): RightCurriedFunction4; + (func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R, arity?: number): RightCurriedFunction5; + (func: (...args: any[]) => any, arity?: number): (...args: any[]) => any; + placeholder: __; + } + interface LoDashStatic { + curryRight: CurryRight; + } + interface Function any> { + /** + * @see _.curryRight + */ + curryRight(arity?: number): + T extends (arg1: infer T1) => infer R ? Function> : + T extends (arg1: infer T1, arg2: infer T2) => infer R ? Function> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3) => infer R ? Function> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3, arg4: infer T4) => infer R ? Function> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3, arg4: infer T4, arg5: infer T5) => infer R ? Function> : + Function<(...args: any[]) => any>; + } + interface FunctionChain any> { + /** + * @see _.curryRight + */ + curryRight(arity?: number): + T extends (arg1: infer T1) => infer R ? FunctionChain> : + T extends (arg1: infer T1, arg2: infer T2) => infer R ? FunctionChain> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3) => infer R ? FunctionChain> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3, arg4: infer T4) => infer R ? FunctionChain> : + T extends (arg1: infer T1, arg2: infer T2, arg3: infer T3, arg4: infer T4, arg5: infer T5) => infer R ? FunctionChain> : + FunctionChain<(...args: any[]) => any>; + } + interface DebounceSettings { + /** + * @see _.leading + */ + leading?: boolean | undefined; + /** + * @see _.maxWait + */ + maxWait?: number | undefined; + /** + * @see _.trailing + */ + trailing?: boolean | undefined; + } + interface DebounceSettingsLeading extends DebounceSettings { + leading: true; + } + interface DebouncedFunc any> { + /** + * Call the original function, but applying the debounce rules. + * + * If the debounced function can be run immediately, this calls it and returns its return + * value. + * + * Otherwise, it returns the return value of the last invocation, or undefined if the debounced + * function was not invoked yet. + */ + (...args: Parameters): ReturnType | undefined; + + /** + * Throw away any pending invocation of the debounced function. + */ + cancel(): void; + + /** + * If there is a pending invocation of the debounced function, invoke it immediately and return + * its return value. + * + * Otherwise, return the value from the last invocation, or undefined if the debounced function + * was never invoked. + */ + flush(): ReturnType | undefined; + } + interface DebouncedFuncLeading any> extends DebouncedFunc { + (...args: Parameters): ReturnType; + flush(): ReturnType; + } + interface LoDashStatic { + /** + * Creates a debounced function that delays invoking func until after wait milliseconds have elapsed since + * the last time the debounced function was invoked. The debounced function comes with a cancel method to + * cancel delayed invocations and a flush method to immediately invoke them. Provide an options object to + * indicate that func should be invoked on the leading and/or trailing edge of the wait timeout. Subsequent + * calls to the debounced function return the result of the last func invocation. + * + * Note: If leading and trailing options are true, func is invoked on the trailing edge of the timeout only + * if the the debounced function is invoked more than once during the wait timeout. + * + * See David Corbacho’s article for details over the differences between _.debounce and _.throttle. + * + * @param func The function to debounce. + * @param wait The number of milliseconds to delay. + * @param options The options object. + * @param options.leading Specify invoking on the leading edge of the timeout. + * @param options.maxWait The maximum time func is allowed to be delayed before it’s invoked. + * @param options.trailing Specify invoking on the trailing edge of the timeout. + * @return Returns the new debounced function. + */ + debounce any>(func: T, wait: number | undefined, options: DebounceSettingsLeading): DebouncedFuncLeading; + debounce any>(func: T, wait?: number, options?: DebounceSettings): DebouncedFunc; + } + interface Function any> { + /** + * @see _.debounce + */ + debounce( + wait: number | undefined, + options: DebounceSettingsLeading + ): T extends (...args: any[]) => any ? Function> : never; + debounce( + wait?: number, + options?: DebounceSettings + ): T extends (...args: any[]) => any ? Function> : never; + } + interface FunctionChain any> { + /** + * @see _.debounce + */ + debounce( + wait: number | undefined, + options: DebounceSettingsLeading + ): T extends (...args: any[]) => any ? FunctionChain> : never; + debounce( + wait?: number, + options?: DebounceSettings + ): T extends (...args: any[]) => any ? FunctionChain> : never; + } + interface LoDashStatic { + /** + * Defers invoking the func until the current call stack has cleared. Any additional arguments are provided to + * func when it’s invoked. + * + * @param func The function to defer. + * @param args The arguments to invoke the function with. + * @return Returns the timer id. + */ + defer(func: (...args: any[]) => any, ...args: any[]): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.defer + */ + defer(...args: any[]): Primitive; + } + interface LoDashExplicitWrapper { + /** + * @see _.defer + */ + defer(...args: any[]): PrimitiveChain; + } + interface LoDashStatic { + /** + * Invokes func after wait milliseconds. Any additional arguments are provided to func when it’s invoked. + * + * @param func The function to delay. + * @param wait The number of milliseconds to delay invocation. + * @param args The arguments to invoke the function with. + * @return Returns the timer id. + */ + delay(func: (...args: any[]) => any, wait: number, ...args: any[]): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.delay + */ + delay(wait: number, ...args: any[]): Primitive; + } + interface LoDashExplicitWrapper { + /** + * @see _.delay + */ + delay(wait: number, ...args: any[]): PrimitiveChain; + } + interface LoDashStatic { + /** + * Creates a function that invokes `func` with arguments reversed. + * + * @category Function + * @param func The function to flip arguments for. + * @returns Returns the new function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ + flip any>(func: T): T; + } + interface Function any> { + /** + * @see _.flip + */ + flip(): this; + } + interface FunctionChain any> { + /** + * @see _.flip + */ + flip(): this; + } + interface MemoizedFunction { + /** + * @see _.cache + */ + cache: MapCache; + } + interface LoDashStatic { + /** + * Creates a function that memoizes the result of func. If resolver is provided it determines the cache key for + * storing the result based on the arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the cache key. The func is invoked with + * the this binding of the memoized function. + * + * @param func The function to have its output memoized. + * @param resolver The function to resolve the cache key. + * @return Returns the new memoizing function. + */ + memoize: { + any>(func: T, resolver?: (...args: Parameters) => any): T & MemoizedFunction; + Cache: MapCacheConstructor; + }; + } + interface Function any> { + /** + * @see _.memoize + */ + memoize(resolver?: (...args: any[]) => any): Function; + } + interface FunctionChain any> { + /** + * @see _.memoize + */ + memoize(resolver?: (...args: any[]) => any): FunctionChain; + } + interface LoDashStatic { + /** + * Creates a function that negates the result of the predicate func. The func predicate is invoked with + * the this binding and arguments of the created function. + * + * @param predicate The predicate to negate. + * @return Returns the new function. + */ + negate(predicate: (...args: T) => boolean): (...args: T) => boolean; + } + interface Function any> { + /** + * @see _.negate + */ + negate(): Function<(...args: Parameters) => boolean>; + } + interface FunctionChain any> { + /** + * @see _.negate + */ + negate(): FunctionChain<(...args: Parameters) => boolean>; + } + interface LoDashStatic { + /** + * Creates a function that is restricted to invoking func once. Repeat calls to the function return the value + * of the first call. The func is invoked with the this binding and arguments of the created function. + * + * @param func The function to restrict. + * @return Returns the new restricted function. + */ + once any>(func: T): T; + } + interface Function any> { + /** + * @see _.once + */ + once(): Function; + } + interface FunctionChain any> { + /** + * @see _.once + */ + once(): FunctionChain; + } + interface LoDashStatic { + /** + * Creates a function that runs each argument through a corresponding transform function. + * + * @param func The function to wrap. + * @param transforms The functions to transform arguments, specified as individual functions or arrays + * of functions. + * @return Returns the new function. + */ + overArgs(func: (...args: any[]) => any, ...transforms: Array any>>): (...args: any[]) => any; + } + interface Function any> { + /** + * @see _.overArgs + */ + overArgs(...transforms: Array any>>): Function<(...args: any[]) => any>; + } + interface FunctionChain any> { + /** + * @see _.overArgs + */ + overArgs(...transforms: Array any>>): FunctionChain<(...args: any[]) => any>; + } + interface LoDashStatic { + /** + * Creates a function that, when called, invokes func with any additional partial arguments + * prepended to those provided to the new function. This method is similar to _.bind except + * it does not alter the this binding. + * @param func The function to partially apply arguments to. + * @param args Arguments to be partially applied. + * @return The new partially applied function. + */ + partial: Partial; + } + type __ = LoDashStatic; + type Function0 = () => R; + type Function1 = (t1: T1) => R; + type Function2 = (t1: T1, t2: T2) => R; + type Function3 = (t1: T1, t2: T2, t3: T3) => R; + type Function4 = (t1: T1, t2: T2, t3: T3, t4: T4) => R; + interface Partial { + (func: Function2, plc1: __, arg2: T2): Function1; + (func: Function3, plc1: __, arg2: T2): Function2; + (func: Function3, plc1: __, plc2: __, arg3: T3): Function2; + (func: Function3, arg1: T1, plc2: __, arg3: T3): Function1; + (func: Function3, plc1: __, arg2: T2, arg3: T3): Function1; + (func: Function4, plc1: __, arg2: T2): Function3; + (func: Function4, plc1: __, plc2: __, arg3: T3): Function3; + (func: Function4, arg1: T1, plc2: __, arg3: T3): Function2; + (func: Function4, plc1: __, arg2: T2, arg3: T3): Function2; + (func: Function4, arg1: T1, arg2: T2, arg3: T3): Function1; + (func: Function4, plc1: __, plc2: __, plc3: __, arg4: T4): Function3; + (func: Function4, arg1: T1, plc2: __, plc3: __, arg4: T4): Function2; + (func: Function4, plc1: __, arg2: T2, plc3: __, arg4: T4): Function2; + (func: Function4, arg1: T1, arg2: T2, plc3: __, arg4: T4): Function1; + (func: Function4, plc1: __, plc2: __, arg3: T3, arg4: T4): Function2; + (func: Function4, arg1: T1, plc2: __, arg3: T3, arg4: T4): Function1; + (func: Function4, plc1: __, arg2: T2, arg3: T3, arg4: T4): Function1; + (func: (...ts: TS) => R): (...ts: TS) => R; + (func: (t1: T1, ...ts: TS) => R, arg1: T1): (...ts: TS) => R; + (func: (t1: T1, t2: T2, ...ts: TS) => R, t1: T1, t2: T2): (...ts: TS) => R; + (func: (t1: T1, t2: T2, t3: T3, ...ts: TS) => R, t1: T1, t2: T2, t3: T3): (...ts: TS) => R; + (func: (t1: T1, t2: T2, t3: T3, t4: T4, ...ts: TS) => R, t1: T1, t2: T2, t3: T3, t4: T4): (...ts: TS) => R; + placeholder: __; + } + interface Function any> { + /** + * @see _.partial + */ + partial(plc1: __, arg2: T2): Function< + T extends Function2 ? Function1 : + T extends Function3 ? Function2 : + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, plc2: __, arg3: T3): Function< + T extends Function3 ? Function2 : + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, plc2: __, arg3: T3): Function< + T extends Function3 ? Function1 : + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, arg2: T2, arg3: T3): Function< + T extends Function3 ? Function1 : + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, plc2: __, arg3: T3): Function< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, plc2: __, plc3: __, arg4: T4): Function< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, arg2: T2, plc3: __, arg4: T4): Function< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, arg2: T2, plc3: __, arg4: T4): Function< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, plc2: __, arg3: T3, arg4: T4): Function< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, plc2: __, arg3: T3, arg4: T4): Function< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, arg2: T2, arg3: T3, arg4: T4): Function< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, arg2: T2, arg3: T3, arg4: T4): Function< + T extends (t1: T1, t2: T2, t3: T3, t4: T4, ...ts: infer TS) => infer R ? (...ts: TS) => R : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, arg2: T2, arg3: T3): Function< + T extends (t1: T1, t2: T2, t3: T3, ...ts: infer TS) => infer R ? (...ts: TS) => R : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, arg2: T2): Function< + T extends (t1: T1, t2: T2, ...ts: infer TS) => infer R ? (...ts: TS) => R : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1): Function< + T extends (t1: T1, ...ts: infer TS) => infer R ? (...ts: TS) => R : + any + >; + /** + * @see _.partial + */ + partial(): Function any ? T : any>; + } + interface FunctionChain any> { + /** + * @see _.partial + */ + partial(plc1: __, arg2: T2): FunctionChain< + T extends Function2 ? Function1 : + T extends Function3 ? Function2 : + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, plc2: __, arg3: T3): FunctionChain< + T extends Function3 ? Function2 : + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, plc2: __, arg3: T3): FunctionChain< + T extends Function3 ? Function1 : + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, arg2: T2, arg3: T3): FunctionChain< + T extends Function3 ? Function1 : + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, plc2: __, arg3: T3): FunctionChain< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, plc2: __, plc3: __, arg4: T4): FunctionChain< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, arg2: T2, plc3: __, arg4: T4): FunctionChain< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, arg2: T2, plc3: __, arg4: T4): FunctionChain< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, plc2: __, arg3: T3, arg4: T4): FunctionChain< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, plc2: __, arg3: T3, arg4: T4): FunctionChain< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partial + */ + partial(plc1: __, arg2: T2, arg3: T3, arg4: T4): FunctionChain< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, arg2: T2, arg3: T3, arg4: T4): FunctionChain< + T extends (t1: T1, t2: T2, t3: T3, t4: T4, ...ts: infer TS) => infer R ? (...ts: TS) => R : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, arg2: T2, arg3: T3): FunctionChain< + T extends (t1: T1, t2: T2, t3: T3, ...ts: infer TS) => infer R ? (...ts: TS) => R : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1, arg2: T2): FunctionChain< + T extends (t1: T1, t2: T2, ...ts: infer TS) => infer R ? (...ts: TS) => R : + any + >; + /** + * @see _.partial + */ + partial(arg1: T1): FunctionChain< + T extends (t1: T1, ...ts: infer TS) => infer R ? (...ts: TS) => R : + any + >; + /** + * @see _.partial + */ + partial(): FunctionChain any ? T : any>; + } + interface LoDashStatic { + /** + * This method is like _.partial except that partial arguments are appended to those provided + * to the new function. + * @param func The function to partially apply arguments to. + * @param args Arguments to be partially applied. + * @return The new partially applied function. + */ + partialRight: PartialRight; + } + interface PartialRight { + (func: Function0): Function0; + (func: Function1): Function1; + (func: Function1, arg1: T1): Function0; + (func: Function2): Function2; + (func: Function2, arg1: T1, plc2: __): Function1; + (func: Function2, arg2: T2): Function1; + (func: Function2, arg1: T1, arg2: T2): Function0; + (func: Function3): Function3; + (func: Function3, arg1: T1, plc2: __, plc3: __): Function2; + (func: Function3, arg2: T2, plc3: __): Function2; + (func: Function3, arg1: T1, arg2: T2, plc3: __): Function1; + (func: Function3, arg3: T3): Function2; + (func: Function3, arg1: T1, plc2: __, arg3: T3): Function1; + (func: Function3, arg2: T2, arg3: T3): Function1; + (func: Function3, arg1: T1, arg2: T2, arg3: T3): Function0; + (func: Function4): Function4; + (func: Function4, arg1: T1, plc2: __, plc3: __, plc4: __): Function3; + (func: Function4, arg2: T2, plc3: __, plc4: __): Function3; + (func: Function4, arg1: T1, arg2: T2, plc3: __, plc4: __): Function2; + (func: Function4, arg3: T3, plc4: __): Function3; + (func: Function4, arg1: T1, plc2: __, arg3: T3, plc4: __): Function2; + (func: Function4, arg2: T2, arg3: T3, plc4: __): Function2; + (func: Function4, arg1: T1, arg2: T2, arg3: T3, plc4: __): Function1; + (func: Function4, arg4: T4): Function3; + (func: Function4, arg1: T1, plc2: __, plc3: __, arg4: T4): Function2; + (func: Function4, arg2: T2, plc3: __, arg4: T4): Function2; + (func: Function4, arg1: T1, arg2: T2, plc3: __, arg4: T4): Function1; + (func: Function4, arg3: T3, arg4: T4): Function2; + (func: Function4, arg1: T1, plc2: __, arg3: T3, arg4: T4): Function1; + (func: Function4, arg2: T2, arg3: T3, arg4: T4): Function1; + (func: Function4, arg1: T1, arg2: T2, arg3: T3, arg4: T4): Function0; + (func: (...args: any[]) => any, ...args: any[]): (...args: any[]) => any; + placeholder: __; + } + interface Function any> { + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __): Function< + T extends Function2 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2): Function< + T extends Function2 ? Function1 : any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, plc3: __): Function< + T extends Function3 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, plc3: __): Function< + T extends Function3 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, arg2: T2, plc3: __): Function< + T extends Function3 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg3: T3): Function< + T extends Function3 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, arg3: T3): Function< + T extends Function3 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, arg3: T3): Function< + T extends Function3 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, plc3: __, plc4: __): Function< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, plc3: __, plc4: __): Function< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, arg2: T2, plc3: __, plc4: __): Function< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg3: T3, plc4: __): Function< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, arg3: T3, plc4: __): Function< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, arg3: T3, plc4: __): Function< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, arg2: T2, arg3: T3, plc4: __): Function< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg4: T4): Function< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, plc3: __, arg4: T4): Function< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, plc3: __, arg4: T4): Function< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, arg2: T2, plc3: __, arg4: T4): Function< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg3: T3, arg4: T4): Function< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, arg3: T3, arg4: T4): Function< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, arg3: T3, arg4: T4): Function< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(...ts: TS): Function infer R ? () => R : any>; + /** + * @see _.partialRight + */ + partialRight(): Function any ? T : any>; + } + interface FunctionChain any> { + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __): FunctionChain< + T extends Function2 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2): FunctionChain< + T extends Function2 ? Function1 : any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, plc3: __): FunctionChain< + T extends Function3 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, plc3: __): FunctionChain< + T extends Function3 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, arg2: T2, plc3: __): FunctionChain< + T extends Function3 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg3: T3): FunctionChain< + T extends Function3 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, arg3: T3): FunctionChain< + T extends Function3 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, arg3: T3): FunctionChain< + T extends Function3 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, plc3: __, plc4: __): FunctionChain< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, plc3: __, plc4: __): FunctionChain< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, arg2: T2, plc3: __, plc4: __): FunctionChain< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg3: T3, plc4: __): FunctionChain< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, arg3: T3, plc4: __): FunctionChain< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, arg3: T3, plc4: __): FunctionChain< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, arg2: T2, arg3: T3, plc4: __): FunctionChain< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg4: T4): FunctionChain< + T extends Function4 ? Function3 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, plc3: __, arg4: T4): FunctionChain< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, plc3: __, arg4: T4): FunctionChain< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, arg2: T2, plc3: __, arg4: T4): FunctionChain< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg3: T3, arg4: T4): FunctionChain< + T extends Function4 ? Function2 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg1: T1, plc2: __, arg3: T3, arg4: T4): FunctionChain< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(arg2: T2, arg3: T3, arg4: T4): FunctionChain< + T extends Function4 ? Function1 : + any + >; + /** + * @see _.partialRight + */ + partialRight(...ts: TS): FunctionChain infer R ? () => R : any>; + /** + * @see _.partialRight + */ + partialRight(): FunctionChain any ? T : any>; + } + interface LoDashStatic { + /** + * Creates a function that invokes func with arguments arranged according to the specified indexes where the + * argument value at the first index is provided as the first argument, the argument value at the second index + * is provided as the second argument, and so on. + * @param func The function to rearrange arguments for. + * @param indexes The arranged argument indexes, specified as individual indexes or arrays of indexes. + * @return Returns the new function. + */ + rearg(func: (...args: any[]) => any, ...indexes: Array>): (...args: any[]) => any; + } + interface Function any> { + /** + * @see _.rearg + */ + rearg(...indexes: Array>): Function<(...args: any[]) => any>; + } + interface FunctionChain any> { + /** + * @see _.rearg + */ + rearg(...indexes: Array>): FunctionChain<(...args: any[]) => any>; + } + interface LoDashStatic { + /** + * Creates a function that invokes func with the this binding of the created function and arguments from start + * and beyond provided as an array. + * + * Note: This method is based on the rest parameter. + * + * @param func The function to apply a rest parameter to. + * @param start The start position of the rest parameter. + * @return Returns the new function. + */ + rest(func: (...args: any[]) => any, start?: number): (...args: any[]) => any; + } + interface Function any> { + /** + * @see _.rest + */ + rest(start?: number): Function<(...args: any[]) => any>; + } + interface FunctionChain any> { + /** + * @see _.rest + */ + rest(start?: number): FunctionChain<(...args: any[]) => any>; + } + interface LoDashStatic { + /** + * Creates a function that invokes func with the this binding of the created function and an array of arguments + * much like Function#apply. + * + * Note: This method is based on the spread operator. + * + * @param func The function to spread arguments over. + * @return Returns the new function. + */ + spread(func: (...args: any[]) => TResult, start?: number): (...args: any[]) => TResult; + } + interface Function any> { + /** + * @see _.spread + */ + spread(start?: number): Function<(...args: any[]) => ReturnType>; + } + interface FunctionChain any> { + /** + * @see _.spread + */ + spread(start?: number): FunctionChain<(...args: any[]) => ReturnType>; + } + interface ThrottleSettings { + /** + * @see _.leading + */ + leading?: boolean | undefined; + /** + * @see _.trailing + */ + trailing?: boolean | undefined; + } + interface LoDashStatic { + /** + * Creates a throttled function that only invokes func at most once per every wait milliseconds. The throttled + * function comes with a cancel method to cancel delayed invocations and a flush method to immediately invoke + * them. Provide an options object to indicate that func should be invoked on the leading and/or trailing edge + * of the wait timeout. Subsequent calls to the throttled function return the result of the last func call. + * + * Note: If leading and trailing options are true, func is invoked on the trailing edge of the timeout only if + * the the throttled function is invoked more than once during the wait timeout. + * + * @param func The function to throttle. + * @param wait The number of milliseconds to throttle invocations to. + * @param options The options object. + * @param options.leading Specify invoking on the leading edge of the timeout. + * @param options.trailing Specify invoking on the trailing edge of the timeout. + * @return Returns the new throttled function. + */ + throttle any>(func: T, wait?: number, options?: ThrottleSettings): DebouncedFunc; + } + interface Function any> { + /** + * @see _.throttle + */ + throttle( + wait?: number, + options?: ThrottleSettings + ): T extends (...args: any[]) => any ? Function> : never; + } + interface FunctionChain any> { + /** + * @see _.throttle + */ + throttle( + wait?: number, + options?: ThrottleSettings + ): T extends (...args: any[]) => any ? FunctionChain> : never; + } + interface LoDashStatic { + /** + * Creates a function that accepts up to one argument, ignoring any + * additional arguments. + * + * @category Function + * @param func The function to cap arguments for. + * @returns Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.unary(parseInt)); + * // => [6, 8, 10] + */ + unary(func: (arg1: T, ...args: any[]) => TResult): (arg1: T) => TResult; + } + interface Function any> { + /** + * @see _.unary + */ + unary(): Function<(arg1: Parameters['0']) => ReturnType>; + } + interface FunctionChain any> { + /** + * @see _.unary + */ + unary(): FunctionChain<(arg1: Parameters['0']) => ReturnType>; + } + interface LoDashStatic { + /** + * Creates a function that provides value to the wrapper function as its first argument. Any additional + * arguments provided to the function are appended to those provided to the wrapper function. The wrapper is + * invoked with the this binding of the created function. + * + * @param value The value to wrap. + * @param wrapper The wrapper function. + * @return Returns the new function. + */ + wrap(value: T, wrapper: (value: T, ...args: TArgs[]) => TResult): (...args: TArgs[]) => TResult; + } + interface LoDashImplicitWrapper { + /** + * @see _.wrap + */ + wrap(wrapper: (value: TValue, ...args: TArgs[]) => TResult): Function<(...args: TArgs[]) => TResult>; + } + interface LoDashExplicitWrapper { + /** + * @see _.wrap + */ + wrap(wrapper: (value: TValue, ...args: TArgs[]) => TResult): FunctionChain<(...args: TArgs[]) => TResult>; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/lang.d.ts b/libs/events/node_modules/@types/lodash/common/lang.d.ts new file mode 100755 index 000000000..6a1d5fd43 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/lang.d.ts @@ -0,0 +1,1700 @@ +import _ = require("../index"); +// tslint:disable-next-line:strict-export-declare-modifiers +type GlobalFunction = Function; +declare module "../index" { + type FunctionBase = GlobalFunction; + interface LoDashStatic { + /** + * Casts value as an array if it’s not one. + * + * @param value The value to inspect. + * @return Returns the cast array. + */ + castArray(value?: Many): T[]; + } + interface Collection { + /** + * @see _.castArray + */ + castArray(): Collection; + } + interface String { + /** + * @see _.castArray + */ + castArray(): Collection; + } + interface Object { + /** + * @see _.castArray + */ + castArray(): Collection; + } + interface Function any> { + /** + * @see _.castArray + */ + castArray(): Collection; + } + interface Primitive { + /** + * @see _.castArray + */ + castArray(): Collection; + } + interface CollectionChain { + /** + * @see _.castArray + */ + castArray(): CollectionChain; + } + interface StringChain { + /** + * @see _.castArray + */ + castArray(): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.castArray + */ + castArray(): CollectionChain; + } + interface ObjectChain { + /** + * @see _.castArray + */ + castArray(): CollectionChain; + } + interface FunctionChain any> { + /** + * @see _.castArray + */ + castArray(): CollectionChain; + } + interface PrimitiveChain { + /** + * @see _.castArray + */ + castArray(): CollectionChain; + } + + interface LoDashStatic { + /** + * Creates a shallow clone of value. + * + * Note: This method is loosely based on the structured clone algorithm and supports cloning arrays, + * array buffers, booleans, date objects, maps, numbers, Object objects, regexes, sets, strings, symbols, + * and typed arrays. The own enumerable properties of arguments objects are cloned as plain objects. An empty + * object is returned for uncloneable values such as error objects, functions, DOM nodes, and WeakMaps. + * + * @param value The value to clone. + * @return Returns the cloned value. + */ + clone(value: T): T; + } + + interface LoDashImplicitWrapper { + /** + * @see _.clone + */ + clone(): TValue; + /** + * @see _.cloneDeep + */ + cloneDeep(): TValue; + /** + * @see _.cloneDeepWith + */ + cloneDeepWith(customizer: CloneDeepWithCustomizer): any; + /** + * @see _.cloneDeepWith + */ + cloneDeepWith(): TValue; + /** + * @see _.cloneWith + */ + cloneWith(customizer: CloneWithCustomizer): TResult; + /** + * @see _.cloneWith + */ + cloneWith(customizer: CloneWithCustomizer): TResult | TValue; + /** + * @see _.cloneWith + */ + cloneWith(): TValue; + } + interface LoDashExplicitWrapper { + /** + * @see _.clone + */ + clone(): this; + /** + * @see _.cloneDeep + */ + cloneDeep(): this; + /** + * @see _.cloneDeepWith + */ + cloneDeepWith(customizer: CloneDeepWithCustomizer): LoDashExplicitWrapper; + /** + * @see _.cloneDeepWith + */ + cloneDeepWith(): this; + /** + * @see _.cloneWith + */ + cloneWith(customizer: CloneWithCustomizer): ExpChain; + /** + * @see _.cloneWith + */ + cloneWith(customizer: CloneWithCustomizer): ExpChain; + /** + * @see _.cloneWith + */ + cloneWith(): this; + } + + interface LoDashStatic { + /** + * This method is like _.clone except that it recursively clones value. + * + * @param value The value to recursively clone. + * @return Returns the deep cloned value. + */ + cloneDeep(value: T): T; + } + type CloneDeepWithCustomizer = (value: any, key: number | string | undefined, object: TObject | undefined, stack: any) => any; + interface LoDashStatic { + /** + * This method is like _.cloneWith except that it recursively clones value. + * + * @param value The value to recursively clone. + * @param customizer The function to customize cloning. + * @return Returns the deep cloned value. + */ + cloneDeepWith(value: T, customizer: CloneDeepWithCustomizer): any; + /** + * @see _.cloneDeepWith + */ + cloneDeepWith(value: T): T; + } + type CloneWithCustomizer = (value: TValue, key: number | string | undefined, object: any, stack: any) => TResult; + interface LoDashStatic { + /** + * This method is like _.clone except that it accepts customizer which is invoked to produce the cloned value. + * If customizer returns undefined cloning is handled by the method instead. + * + * @param value The value to clone. + * @param customizer The function to customize cloning. + * @return Returns the cloned value. + */ + cloneWith(value: T, customizer: CloneWithCustomizer): TResult; + /** + * @see _.cloneWith + */ + cloneWith(value: T, customizer: CloneWithCustomizer): TResult | T; + /** + * @see _.cloneWith + */ + cloneWith(value: T): T; + } + interface LoDashStatic { + /** + * Checks if object conforms to source by invoking the predicate properties of source with the + * corresponding property values of object. + * + * Note: This method is equivalent to _.conforms when source is partially applied. + */ + conformsTo(object: T, source: ConformsPredicateObject): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.conformsTo + */ + conformsTo(source: ConformsPredicateObject): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.conformsTo + */ + conformsTo(source: ConformsPredicateObject): PrimitiveChain; + } + type CondPairNullary = [() => boolean, () => R]; + type CondPairUnary = [(val: T) => boolean, (val: T) => R]; + interface LoDashStatic { + /** + * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @category Lang + * @param value The value to compare. + * @param other The other value to compare. + * @returns Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + eq(value: any, other: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.eq + */ + eq(other: any): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.eq + */ + eq(other: any): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is greater than other. + * + * @param value The value to compare. + * @param other The other value to compare. + * @return Returns true if value is greater than other, else false. + */ + gt(value: any, other: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.gt + */ + gt(other: any): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.gt + */ + gt(other: any): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is greater than or equal to other. + * + * @param value The value to compare. + * @param other The other value to compare. + * @return Returns true if value is greater than or equal to other, else false. + */ + gte(value: any, other: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.gte + */ + gte(other: any): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.gte + */ + gte(other: any): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as an arguments object. + * + * @param value The value to check. + * @return Returns true if value is correctly classified, else false. + */ + isArguments(value?: any): value is IArguments; + } + interface LoDashImplicitWrapper { + /** + * @see _.isArguments + */ + isArguments(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isArguments + */ + isArguments(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as an Array object. + * @param value The value to check. + * + * @return Returns true if value is correctly classified, else false. + */ + isArray(value?: any): value is any[]; + /** + * @see _.isArray + */ + isArray(value?: any): value is any[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.isArray + */ + isArray(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isArray + */ + isArray(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as an ArrayBuffer object. + * + * @param value The value to check. + * @return Returns true if value is correctly classified, else false. + */ + isArrayBuffer(value?: any): value is ArrayBuffer; + } + interface LoDashImplicitWrapper { + /** + * @see _.isArrayBuffer + */ + isArrayBuffer(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isArrayBuffer + */ + isArrayBuffer(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @category Lang + * @param value The value to check. + * @returns Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + isArrayLike(t: T): boolean; + /** + * @see _.isArrayLike + */ + isArrayLike(value: ((...args: any[]) => any) | null | undefined): value is never; + /** + * @see _.isArrayLike + */ + isArrayLike(value: any): value is { length: number }; + } + interface LoDashImplicitWrapper { + /** + * @see _.isArrayLike + */ + isArrayLike(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isArrayLike + */ + isArrayLike(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @category Lang + * @param value The value to check. + * @returns Returns `true` if `value` is an array-like object, else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + isArrayLikeObject(value: T): boolean; + /** + * @see _.isArrayLikeObject + */ + isArrayLikeObject(value: ((...args: any[]) => any) | FunctionBase | string | boolean | number | null | undefined): value is never; + /** + * @see _.isArrayLikeObject + */ + isArrayLikeObject(value: any): value is object & { length: number }; + } + interface LoDashImplicitWrapper { + /** + * @see _.isArrayLikeObject + */ + isArrayLikeObject(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isArrayLikeObject + */ + isArrayLikeObject(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a boolean primitive or object. + * + * @param value The value to check. + * @return Returns true if value is correctly classified, else false. + */ + isBoolean(value?: any): value is boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isBoolean + */ + isBoolean(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isBoolean + */ + isBoolean(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is a buffer. + * + * @param value The value to check. + * @return Returns true if value is a buffer, else false. + */ + isBuffer(value?: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isBuffer + */ + isBuffer(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isBuffer + */ + isBuffer(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a Date object. + * @param value The value to check. + * + * @return Returns true if value is correctly classified, else false. + */ + isDate(value?: any): value is Date; + } + interface LoDashImplicitWrapper { + /** + * @see _.isDate + */ + isDate(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isDate + */ + isDate(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is a DOM element. + * + * @param value The value to check. + * @return Returns true if value is a DOM element, else false. + */ + isElement(value?: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isElement + */ + isElement(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isElement + */ + isElement(): PrimitiveChain; + } + + type EmptyObject = { [K in keyof T]?: never }; + type EmptyObjectOf = EmptyObject extends T ? EmptyObject : never; + interface LoDashStatic { + /** + * Checks if value is empty. A value is considered empty unless it’s an arguments object, array, string, or + * jQuery-like collection with a length greater than 0 or an object with own enumerable properties. + * + * @param value The value to inspect. + * @return Returns true if value is empty, else false. + */ + isEmpty(value?: T): boolean; + isEmpty(value: string): value is ''; + isEmpty(value: Map | Set | List | null | undefined): boolean; + isEmpty(value: object): boolean; + isEmpty(value: T | null | undefined): value is EmptyObjectOf | null | undefined; + isEmpty(value?: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isEmpty + */ + isEmpty(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isEmpty + */ + isEmpty(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are **not** supported. + * + * @category Lang + * @param value The value to compare. + * @param other The other value to compare. + * @returns Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + isEqual(value: any, other: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isEqual + */ + isEqual(other: any): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isEqual + */ + isEqual(other: any): PrimitiveChain; + } + + type IsEqualCustomizer = (value: any, other: any, indexOrKey: PropertyName | undefined, parent: any, otherParent: any, stack: any) => boolean | undefined; + interface LoDashStatic { + /** + * This method is like `_.isEqual` except that it accepts `customizer` which is + * invoked to compare values. If `customizer` returns `undefined` comparisons are + * handled by the method instead. The `customizer` is invoked with up to seven arguments: + * (objValue, othValue [, index|key, object, other, stack]). + * + * @category Lang + * @param value The value to compare. + * @param other The other value to compare. + * @param [customizer] The function to customize comparisons. + * @returns Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ + isEqualWith(value: any, other: any, customizer?: IsEqualCustomizer): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isEqualWith + */ + isEqualWith(other: any, customizer?: IsEqualCustomizer): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isEqualWith + */ + isEqualWith(other: any, customizer?: IsEqualCustomizer): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is an Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, or URIError + * object. + * + * @param value The value to check. + * @return Returns true if value is an error object, else false. + */ + isError(value: any): value is Error; + } + interface LoDashImplicitWrapper { + /** + * @see _.isError + */ + isError(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isError + */ + isError(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is a finite primitive number. + * + * Note: This method is based on Number.isFinite. + * + * @param value The value to check. + * @return Returns true if value is a finite number, else false. + */ + isFinite(value?: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isFinite + */ + isFinite(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isFinite + */ + isFinite(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is a callable function. + * + * @param value The value to check. + * @return Returns true if value is correctly classified, else false. + */ + isFunction(value: any): value is (...args: any[]) => any; + } + interface LoDashImplicitWrapper { + /** + * @see _.isFunction + */ + isFunction(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isFunction + */ + isFunction(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @category Lang + * @param value The value to check. + * @returns Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ + isInteger(value?: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isInteger + */ + isInteger(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isInteger + */ + isInteger(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @category Lang + * @param value The value to check. + * @returns Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + isLength(value?: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isLength + */ + isLength(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isLength + */ + isLength(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a Map object. + * + * @param value The value to check. + * @returns Returns true if value is correctly classified, else false. + */ + isMap(value?: any): value is Map; + } + interface LoDashImplicitWrapper { + /** + * @see _.isMap + */ + isMap(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isMap + */ + isMap(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Performs a deep comparison between `object` and `source` to determine if + * `object` contains equivalent property values. + * + * **Note:** This method supports comparing the same values as `_.isEqual`. + * + * @category Lang + * @param object The object to inspect. + * @param source The object of property values to match. + * @returns Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + */ + isMatch(object: object, source: object): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isMatch + */ + isMatch(source: object): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isMatch + */ + isMatch(source: object): PrimitiveChain; + } + + type isMatchWithCustomizer = (value: any, other: any, indexOrKey: PropertyName, object: object, source: object) => boolean | undefined; + interface LoDashStatic { + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with three + * arguments: (objValue, srcValue, index|key, object, source). + * + * @category Lang + * @param object The object to inspect. + * @param source The object of property values to match. + * @param [customizer] The function to customize comparisons. + * @returns Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ + isMatchWith(object: object, source: object, customizer: isMatchWithCustomizer): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isMatchWith + */ + isMatchWith(source: object, customizer: isMatchWithCustomizer): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isMatchWith + */ + isMatchWith(source: object, customizer: isMatchWithCustomizer): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is NaN. + * + * Note: This method is not the same as isNaN which returns true for undefined and other non-numeric values. + * + * @param value The value to check. + * @return Returns true if value is NaN, else false. + */ + isNaN(value?: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isNaN + */ + isNaN(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isNaN + */ + isNaN(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is a native function. + * @param value The value to check. + * + * @return Returns true if value is a native function, else false. + */ + isNative(value: any): value is (...args: any[]) => any; + } + interface LoDashImplicitWrapper { + /** + * @see _.isNative + */ + isNative(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isNative + */ + isNative(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if `value` is `null` or `undefined`. + * + * @category Lang + * @param value The value to check. + * @returns Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ + isNil(value: any): value is null | undefined; + } + interface LoDashImplicitWrapper { + /** + * @see _.isNil + */ + isNil(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isNil + */ + isNil(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is null. + * + * @param value The value to check. + * @return Returns true if value is null, else false. + */ + isNull(value: any): value is null; + } + interface LoDashImplicitWrapper { + /** + * @see _.isNull + */ + isNull(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isNull + */ + isNull(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a Number primitive or object. + * + * Note: To exclude Infinity, -Infinity, and NaN, which are classified as numbers, use the _.isFinite method. + * + * @param value The value to check. + * @return Returns true if value is correctly classified, else false. + */ + isNumber(value?: any): value is number; + } + interface LoDashImplicitWrapper { + /** + * @see _.isNumber + */ + isNumber(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isNumber + */ + isNumber(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is the language type of Object. (e.g. arrays, functions, objects, regexes, new Number(0), + * and new String('')) + * + * @param value The value to check. + * @return Returns true if value is an object, else false. + */ + isObject(value?: any): value is object; + } + interface LoDashImplicitWrapper { + /** + * @see _.isObject + */ + isObject(): this is LoDashImplicitWrapper; + } + interface LoDashExplicitWrapper { + /** + * @see _.isObject + */ + isObject(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @category Lang + * @param value The value to check. + * @returns Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + isObjectLike(value?: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isObjectLike + */ + isObjectLike(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isObjectLike + */ + isObjectLike(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is a plain object, that is, an object created by the Object constructor or one with a + * [[Prototype]] of null. + * + * Note: This method assumes objects created by the Object constructor have no inherited enumerable properties. + * + * @param value The value to check. + * @return Returns true if value is a plain object, else false. + */ + isPlainObject(value?: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isPlainObject + */ + isPlainObject(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isPlainObject + */ + isPlainObject(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a RegExp object. + * @param value The value to check. + * + * @return Returns true if value is correctly classified, else false. + */ + isRegExp(value?: any): value is RegExp; + } + interface LoDashImplicitWrapper { + /** + * @see _.isRegExp + */ + isRegExp(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isRegExp + */ + isRegExp(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @category Lang + * @param value The value to check. + * @returns Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ + isSafeInteger(value: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isSafeInteger + */ + isSafeInteger(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isSafeInteger + */ + isSafeInteger(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a Set object. + * + * @param value The value to check. + * @returns Returns true if value is correctly classified, else false. + */ + isSet(value?: any): value is Set; + } + interface LoDashImplicitWrapper { + /** + * @see _.isSet + */ + isSet(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isSet + */ + isSet(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a String primitive or object. + * + * @param value The value to check. + * @return Returns true if value is correctly classified, else false. + */ + isString(value?: any): value is string; + } + interface LoDashImplicitWrapper { + /** + * @see _.isString + */ + isString(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isString + */ + isString(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @category Lang + * @param value The value to check. + * @returns Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + isSymbol(value: any): value is symbol; + } + interface LoDashImplicitWrapper { + /** + * @see _.isSymbol + */ + isSymbol(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isSymbol + */ + isSymbol(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a typed array. + * + * @param value The value to check. + * @return Returns true if value is correctly classified, else false. + */ + isTypedArray(value: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.isTypedArray + */ + isTypedArray(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isTypedArray + */ + isTypedArray(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is undefined. + * + * @param value The value to check. + * @return Returns true if value is undefined, else false. + */ + isUndefined(value: any): value is undefined; + } + interface LoDashImplicitWrapper { + /** + * @see _.isUndefined + */ + isUndefined(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isUndefined + */ + isUndefined(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a WeakMap object. + * + * @param value The value to check. + * @returns Returns true if value is correctly classified, else false. + */ + isWeakMap(value?: any): value is WeakMap; + } + interface LoDashImplicitWrapper { + /** + * @see _.isWeakMap + */ + isWeakMap(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isWeakMap + */ + isWeakMap(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is classified as a WeakSet object. + * + * @param value The value to check. + * @returns Returns true if value is correctly classified, else false. + */ + isWeakSet(value?: any): value is WeakSet; + } + interface LoDashImplicitWrapper { + /** + * @see _.isWeakSet + */ + isWeakSet(): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.isWeakSet + */ + isWeakSet(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is less than other. + * + * @param value The value to compare. + * @param other The other value to compare. + * @return Returns true if value is less than other, else false. + */ + lt(value: any, other: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.lt + */ + lt(other: any): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.lt + */ + lt(other: any): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Checks if value is less than or equal to other. + * + * @param value The value to compare. + * @param other The other value to compare. + * @return Returns true if value is less than or equal to other, else false. + */ + lte(value: any, other: any): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.lte + */ + lte(other: any): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.lte + */ + lte(other: any): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Converts value to an array. + * + * @param value The value to convert. + * @return Returns the converted array. + */ + toArray(value: Dictionary | NumericDictionary | null | undefined): T[]; + /** + * @see _.toArray + */ + toArray(value: T): Array; + /** + * @see _.toArray + */ + toArray(): any[]; + } + interface String { + /** + * @see _.toArray + */ + toArray(): Collection; + } + interface Collection { + /** + * @see _.toArray + */ + toArray(): Collection; + } + interface Object { + /** + * @see _.toArray + */ + toArray(): Collection; + } + interface StringChain { + /** + * @see _.toArray + */ + toArray(): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.toArray + */ + toArray(): CollectionChain; + } + interface CollectionChain { + /** + * @see _.toArray + */ + toArray(): CollectionChain; + } + interface ObjectChain { + /** + * @see _.toArray + */ + toArray(): CollectionChain; + } + + interface LoDashStatic { + /** + * Converts `value` to a finite number. + * + * @since 4.12.0 + * @category Lang + * @param value The value to convert. + * @returns Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + toFinite(value: any): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.toFinite + */ + toFinite(): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.toFinite + */ + toFinite(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Converts `value` to an integer. + * + * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). + * + * @category Lang + * @param value The value to convert. + * @returns Returns the converted integer. + * @example + * + * _.toInteger(3); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3'); + * // => 3 + */ + toInteger(value: any): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.toInteger + */ + toInteger(): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.toInteger + */ + toInteger(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @category Lang + * @param value The value to convert. + * @return Returns the converted integer. + * @example + * + * _.toLength(3); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3'); + * // => 3 + */ + toLength(value: any): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.toLength + */ + toLength(): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.toLength + */ + toLength(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Converts `value` to a number. + * + * @category Lang + * @param value The value to process. + * @returns Returns the number. + * @example + * + * _.toNumber(3); + * // => 3 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3'); + * // => 3 + */ + toNumber(value: any): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.toNumber + */ + toNumber(): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.toNumber + */ + toNumber(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Converts value to a plain object flattening inherited enumerable properties of value to own properties + * of the plain object. + * + * @param value The value to convert. + * @return Returns the converted plain object. + */ + toPlainObject(value?: any): any; + } + interface LoDashImplicitWrapper { + /** + * @see _.toPlainObject + */ + toPlainObject(): Object; + } + interface LoDashExplicitWrapper { + /** + * @see _.toPlainObject + */ + toPlainObject(): ObjectChain; + } + + interface LoDashStatic { + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @category Lang + * @param value The value to convert. + * @returns Returns the converted integer. + * @example + * + * _.toSafeInteger(3); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3'); + * // => 3 + */ + toSafeInteger(value: any): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.toSafeInteger + */ + toSafeInteger(): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.toSafeInteger + */ + toSafeInteger(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` and `undefined` values. The sign of `-0` is preserved. + * + * @category Lang + * @param value The value to process. + * @returns Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + toString(value: any): string; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/math.d.ts b/libs/events/node_modules/@types/lodash/common/math.d.ts new file mode 100755 index 000000000..656cd97f8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/math.d.ts @@ -0,0 +1,405 @@ +import _ = require("../index"); +declare module "../index" { + interface LoDashStatic { + /** + * Adds two numbers. + * + * @param augend The first number to add. + * @param addend The second number to add. + * @return Returns the sum. + */ + add(augend: number, addend: number): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.add + */ + add(addend: number): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.add + */ + add(addend: number): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Calculates n rounded up to precision. + * + * @param n The number to round up. + * @param precision The precision to round up to. + * @return Returns the rounded up number. + */ + ceil(n: number, precision?: number): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.ceil + */ + ceil(precision?: number): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.ceil + */ + ceil(precision?: number): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Divide two numbers. + * + * @param dividend The first number in a division. + * @param divisor The second number in a division. + * @returns Returns the quotient. + */ + divide(dividend: number, divisor: number): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.divide + */ + divide(divisor: number): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.divide + */ + divide(divisor: number): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Calculates n rounded down to precision. + * + * @param n The number to round down. + * @param precision The precision to round down to. + * @return Returns the rounded down number. + */ + floor(n: number, precision?: number): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.floor + */ + floor(precision?: number): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.floor + */ + floor(precision?: number): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Computes the maximum value of `array`. If `array` is empty or falsey + * `undefined` is returned. + * + * @category Math + * @param array The array to iterate over. + * @returns Returns the maximum value. + */ + max(collection: List | null | undefined): T | undefined; + } + interface Collection { + /** + * @see _.max + */ + max(): T | undefined; + } + interface CollectionChain { + /** + * @see _.max + */ + max(): ExpChain; + } + + interface LoDashStatic { + /** + * This method is like `_.max` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @category Math + * @param array The array to iterate over. + * @param iteratee The iteratee invoked per element. + * @returns Returns the maximum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.maxBy(objects, function(o) { return o.n; }); + * // => { 'n': 2 } + * + * // using the `_.property` iteratee shorthand + * _.maxBy(objects, 'n'); + * // => { 'n': 2 } + */ + maxBy(collection: List | null | undefined, iteratee?: ValueIteratee): T | undefined; + } + interface Collection { + /** + * @see _.maxBy + */ + maxBy(iteratee?: ValueIteratee): T | undefined; + } + interface CollectionChain { + /** + * @see _.maxBy + */ + maxBy(iteratee?: ValueIteratee): ExpChain; + } + + interface LoDashStatic { + /** + * Computes the mean of the values in `array`. + * + * @category Math + * @param array The array to iterate over. + * @returns Returns the mean. + * @example + * + * _.mean([4, 2, 8, 6]); + * // => 5 + */ + mean(collection: List | null | undefined): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.mean + */ + mean(): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.mean + */ + mean(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Computes the mean of the provided properties of the objects in the `array` + * + * @category Math + * @param array The array to iterate over. + * @param iteratee The iteratee invoked per element. + * @returns Returns the mean. + * @example + * + * _.mean([{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }], 'n'); + * // => 5 + */ + meanBy(collection: List | null | undefined, iteratee?: ValueIteratee): number; + } + interface Collection { + /** + * @see _.meanBy + */ + meanBy(iteratee?: ValueIteratee): number; + } + interface CollectionChain { + /** + * @see _.meanBy + */ + meanBy(iteratee?: ValueIteratee): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Computes the minimum value of `array`. If `array` is empty or falsey + * `undefined` is returned. + * + * @category Math + * @param array The array to iterate over. + * @returns Returns the minimum value. + */ + min(collection: List | null | undefined): T | undefined; + } + interface Collection { + /** + * @see _.min + */ + min(): T | undefined; + } + interface CollectionChain { + /** + * @see _.min + */ + min(): ExpChain; + } + + interface LoDashStatic { + /** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @category Math + * @param array The array to iterate over. + * @param iteratee The iteratee invoked per element. + * @returns Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.a; }); + * // => { 'n': 1 } + * + * // using the `_.property` iteratee shorthand + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ + minBy(collection: List | null | undefined, iteratee?: ValueIteratee): T | undefined; + } + interface Collection { + /** + * @see _.minBy + */ + minBy(iteratee?: ValueIteratee): T | undefined; + } + interface CollectionChain { + /** + * @see _.minBy + */ + minBy(iteratee?: ValueIteratee): ExpChain; + } + + interface LoDashStatic { + /** + * Multiply two numbers. + * @param multiplier The first number in a multiplication. + * @param multiplicand The second number in a multiplication. + * @returns Returns the product. + */ + multiply(multiplier: number, multiplicand: number): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.multiply + */ + multiply(multiplicand: number): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.multiply + */ + multiply(multiplicand: number): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Calculates n rounded to precision. + * + * @param n The number to round. + * @param precision The precision to round to. + * @return Returns the rounded number. + */ + round(n: number, precision?: number): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.round + */ + round(precision?: number): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.round + */ + round(precision?: number): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Subtract two numbers. + * + * @category Math + * @param minuend The first number in a subtraction. + * @param subtrahend The second number in a subtraction. + * @returns Returns the difference. + * @example + * + * _.subtract(6, 4); + * // => 2 + */ + subtract(minuend: number, subtrahend: number): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.subtract + */ + subtract(subtrahend: number): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.subtract + */ + subtract(subtrahend: number): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Computes the sum of the values in `array`. + * + * @category Math + * @param array The array to iterate over. + * @returns Returns the sum. + * @example + * + * _.sum([4, 2, 8, 6]); + * // => 20 + */ + sum(collection: List | null | undefined): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.sum + */ + sum(): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.sum + */ + sum(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * This method is like `_.sum` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the value to be summed. + * The iteratee is invoked with one argument: (value). + * + * @category Math + * @param array The array to iterate over. + * @param [iteratee=_.identity] The iteratee invoked per element. + * @returns Returns the sum. + * @example + * + * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }]; + * + * _.sumBy(objects, function(o) { return o.n; }); + * // => 20 + * + * // using the `_.property` iteratee shorthand + * _.sumBy(objects, 'n'); + * // => 20 + */ + sumBy(collection: List | null | undefined, iteratee?: ((value: T) => number) | string): number; + } + interface Collection { + /** + * @see _.sumBy + */ + sumBy(iteratee?: ((value: T) => number) | string): number; + } + interface CollectionChain { + /** + * @see _.sumBy + */ + sumBy(iteratee?: ((value: T) => number) | string): PrimitiveChain; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/number.d.ts b/libs/events/node_modules/@types/lodash/common/number.d.ts new file mode 100755 index 000000000..ad9ce72ac --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/number.d.ts @@ -0,0 +1,131 @@ +import _ = require("../index"); +declare module "../index" { + // clamp + interface LoDashStatic { + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @category Number + * @param number The number to clamp. + * @param [lower] The lower bound. + * @param upper The upper bound. + * @returns Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @category Number + * @param number The number to clamp. + * @param [lower] The lower bound. + * @param upper The upper bound. + * @returns Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + */ + clamp(number: number, lower: number, upper: number): number; + /** + * @see _.clamp + */ + clamp(number: number, upper: number): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.clamp + */ + clamp(lower: number, upper: number): number; + /** + * @see _.clamp + */ + clamp(upper: number): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.clamp + */ + clamp(lower: number, upper: number): PrimitiveChain; + /** + * @see _.clamp + */ + clamp(upper: number): PrimitiveChain; + } + // inRange + interface LoDashStatic { + /** + * Checks if n is between start and up to but not including, end. If end is not specified it’s set to start + * with start then set to 0. + * + * @param n The number to check. + * @param start The start of the range. + * @param end The end of the range. + * @return Returns true if n is in the range, else false. + */ + inRange(n: number, start: number, end?: number): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.inRange + */ + inRange(start: number, end?: number): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.inRange + */ + inRange(start: number, end?: number): PrimitiveChain; + } + // random + interface LoDashStatic { + /** + * Produces a random number between min and max (inclusive). If only one argument is provided a number between + * 0 and the given number is returned. If floating is true, or either min or max are floats, a floating-point + * number is returned instead of an integer. + * + * @param min The minimum possible value. + * @param max The maximum possible value. + * @param floating Specify returning a floating-point number. + * @return Returns the random number. + */ + random(floating?: boolean): number; + /** + * @see _.random + */ + random(max: number, floating?: boolean): number; + /** + * @see _.random + */ + random(min: number, max: number, floating?: boolean): number; + /** + * @see _.random + */ + random(min: number, index: string | number, guard: object): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.random + */ + random(floating?: boolean): number; + /** + * @see _.random + */ + random(max: number, floating?: boolean): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.random + */ + random(floating?: boolean): PrimitiveChain; + /** + * @see _.random + */ + random(max: number, floating?: boolean): PrimitiveChain; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/object.d.ts b/libs/events/node_modules/@types/lodash/common/object.d.ts new file mode 100755 index 000000000..66cce8662 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/object.d.ts @@ -0,0 +1,2580 @@ +import _ = require("../index"); +declare module "../index" { + interface LoDashStatic { + /** + * Assigns own enumerable properties of source objects to the destination + * object. Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @category Object + * @param object The destination object. + * @param [sources] The source objects. + * @returns Returns `object`. + * @example + * + * function Foo() { + * this.c = 3; + * } + * + * function Bar() { + * this.e = 5; + * } + * + * Foo.prototype.d = 4; + * Bar.prototype.f = 6; + * + * _.assign({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3, 'e': 5 } + */ + assign(object: TObject, source: TSource): TObject & TSource; + /** + * @see _.assign + */ + assign(object: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2; + /** + * @see _.assign + */ + assign(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3): TObject & TSource1 & TSource2 & TSource3; + /** + * @see _.assign + */ + assign(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): TObject & TSource1 & TSource2 & TSource3 & TSource4; + /** + * @see _.assign + */ + assign(object: TObject): TObject; + /** + * @see _.assign + */ + assign(object: any, ...otherArgs: any[]): any; + } + interface Object { + /** + * @see _.assign + */ + assign(source: TSource): Object; + /** + * @see _.assign + */ + assign(source1: TSource1, source2: TSource2): Object; + /** + * @see _.assign + */ + assign(source1: TSource1, source2: TSource2, source3: TSource3): Object; + /** + * @see _.assign + */ + assign(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): Object; + /** + * @see _.assign + */ + assign(): Object; + /** + * @see _.assign + */ + assign(...otherArgs: any[]): Object; + } + interface ObjectChain { + /** + * @see _.assign + */ + assign(source: TSource): ObjectChain; + /** + * @see _.assign + */ + assign(source1: TSource1, source2: TSource2): ObjectChain; + /** + * @see _.assign + */ + assign(source1: TSource1, source2: TSource2, source3: TSource3): ObjectChain; + /** + * @see _.assign + */ + assign(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): ObjectChain; + /** + * @see _.assign + */ + assign(): ObjectChain; + /** + * @see _.assign + */ + assign(...otherArgs: any[]): ObjectChain; + } + interface LoDashStatic { + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @alias extend + * @category Object + * @param object The destination object. + * @param [sources] The source objects. + * @returns Returns `object`. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * function Bar() { + * this.d = 4; + * } + * + * Foo.prototype.c = 3; + * Bar.prototype.e = 5; + * + * _.assignIn({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } + */ + assignIn(object: TObject, source: TSource): TObject & TSource; + /** + * @see _.assignIn + */ + assignIn(object: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2; + /** + * @see _.assignIn + */ + assignIn(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3): TObject & TSource1 & TSource2 & TSource3; + /** + * @see _.assignIn + */ + assignIn(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): TObject & TSource1 & TSource2 & TSource3 & TSource4; + /** + * @see _.assignIn + */ + assignIn(object: TObject): TObject; + /** + * @see _.assignIn + */ + assignIn(object: any, ...otherArgs: any[]): TResult; + } + interface Object { + /** + * @see _.assignIn + */ + assignIn(source: TSource): Object; + /** + * @see _.assignIn + */ + assignIn(source1: TSource1, source2: TSource2): Object; + /** + * @see _.assignIn + */ + assignIn(source1: TSource1, source2: TSource2, source3: TSource3): Object; + /** + * @see _.assignIn + */ + assignIn(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): Object; + /** + * @see _.assignIn + */ + assignIn(): Object; + /** + * @see _.assignIn + */ + assignIn(...otherArgs: any[]): Object; + } + interface ObjectChain { + /** + * @see _.assignIn + */ + assignIn(source: TSource): ObjectChain; + /** + * @see _.assignIn + */ + assignIn(source1: TSource1, source2: TSource2): ObjectChain; + /** + * @see _.assignIn + */ + assignIn(source1: TSource1, source2: TSource2, source3: TSource3): ObjectChain; + /** + * @see _.assignIn + */ + assignIn(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): ObjectChain; + /** + * @see _.assignIn + */ + assignIn(): ObjectChain; + /** + * @see _.assignIn + */ + assignIn(...otherArgs: any[]): ObjectChain; + } + type AssignCustomizer = (objectValue: any, sourceValue: any, key?: string, object?: {}, source?: {}) => any; + interface LoDashStatic { + /** + * This method is like `_.assignIn` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @alias extendWith + * @category Object + * @param object The destination object. + * @param sources The source objects. + * @param [customizer] The function to customize assigned values. + * @returns Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + assignInWith(object: TObject, source: TSource, customizer: AssignCustomizer): TObject & TSource; + /** + * @see _.assignInWith + */ + assignInWith(object: TObject, source1: TSource1, source2: TSource2, customizer: AssignCustomizer): TObject & TSource1 & TSource2; + /** + * @see _.assignInWith + */ + assignInWith(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, customizer: AssignCustomizer): TObject & TSource1 & TSource2 & TSource3; + /** + * @see _.assignInWith + */ + assignInWith(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: AssignCustomizer): TObject & TSource1 & TSource2 & TSource3 & TSource4; + /** + * @see _.assignInWith + */ + assignInWith(object: TObject): TObject; + /** + * @see _.assignInWith + */ + assignInWith(object: any, ...otherArgs: any[]): TResult; + } + interface Object { + /** + * @see _.assignInWith + */ + assignInWith(source: TSource, customizer: AssignCustomizer): Object; + /** + * @see _.assignInWith + */ + assignInWith(source1: TSource1, source2: TSource2, customizer: AssignCustomizer): Object; + /** + * @see _.assignInWith + */ + assignInWith(source1: TSource1, source2: TSource2, source3: TSource3, customizer: AssignCustomizer): Object; + /** + * @see _.assignInWith + */ + assignInWith(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: AssignCustomizer): Object; + /** + * @see _.assignInWith + */ + assignInWith(): Object; + /** + * @see _.assignInWith + */ + assignInWith(...otherArgs: any[]): Object; + } + interface ObjectChain { + /** + * @see _.assignInWith + */ + assignInWith(source: TSource, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.assignInWith + */ + assignInWith(source1: TSource1, source2: TSource2, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.assignInWith + */ + assignInWith(source1: TSource1, source2: TSource2, source3: TSource3, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.assignInWith + */ + assignInWith(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.assignInWith + */ + assignInWith(): ObjectChain; + /** + * @see _.assignInWith + */ + assignInWith(...otherArgs: any[]): ObjectChain; + } + interface LoDashStatic { + /** + * This method is like `_.assign` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @category Object + * @param object The destination object. + * @param sources The source objects. + * @param [customizer] The function to customize assigned values. + * @returns Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + assignWith(object: TObject, source: TSource, customizer: AssignCustomizer): TObject & TSource; + /** + * @see _.assignWith + */ + assignWith(object: TObject, source1: TSource1, source2: TSource2, customizer: AssignCustomizer): TObject & TSource1 & TSource2; + /** + * @see _.assignWith + */ + assignWith(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, customizer: AssignCustomizer): TObject & TSource1 & TSource2 & TSource3; + /** + * @see _.assignWith + */ + assignWith(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: AssignCustomizer): TObject & TSource1 & TSource2 & TSource3 & TSource4; + /** + * @see _.assignWith + */ + assignWith(object: TObject): TObject; + /** + * @see _.assignWith + */ + assignWith(object: any, ...otherArgs: any[]): TResult; + } + interface Object { + /** + * @see _.assignWith + */ + assignWith(source: TSource, customizer: AssignCustomizer): Object; + /** + * @see _.assignWith + */ + assignWith(source1: TSource1, source2: TSource2, customizer: AssignCustomizer): Object; + /** + * @see _.assignWith + */ + assignWith(source1: TSource1, source2: TSource2, source3: TSource3, customizer: AssignCustomizer): Object; + /** + * @see _.assignWith + */ + assignWith(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: AssignCustomizer): Object; + /** + * @see _.assignWith + */ + assignWith(): Object; + /** + * @see _.assignWith + */ + assignWith(...otherArgs: any[]): Object; + } + interface ObjectChain { + /** + * @see _.assignWith + */ + assignWith(source: TSource, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.assignWith + */ + assignWith(source1: TSource1, source2: TSource2, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.assignWith + */ + assignWith(source1: TSource1, source2: TSource2, source3: TSource3, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.assignWith + */ + assignWith(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.assignWith + */ + assignWith(): ObjectChain; + /** + * @see _.assignWith + */ + assignWith(...otherArgs: any[]): ObjectChain; + } + interface LoDashStatic { + /** + * Creates an array of elements corresponding to the given keys, or indexes, of collection. Keys may be + * specified as individual arguments or as arrays of keys. + * + * @param object The object to iterate over. + * @param props The property names or indexes of elements to pick, specified individually or in arrays. + * @return Returns the new array of picked elements. + */ + at(object: Dictionary | NumericDictionary | null | undefined, ...props: PropertyPath[]): T[]; + /** + * @see _.at + */ + at(object: T | null | undefined, ...props: Array>): Array; + } + interface Object { + /** + * @see _.at + */ + at(...props: Array>): Collection; + } + interface Collection { + /** + * @see _.at + */ + at(...props: PropertyPath[]): Collection; + } + interface ObjectChain { + /** + * @see _.at + */ + at(...props: Array>): CollectionChain; + } + interface CollectionChain { + /** + * @see _.at + */ + at(...props: PropertyPath[]): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an object that inherits from the given prototype object. If a properties object is provided its own + * enumerable properties are assigned to the created object. + * + * @param prototype The object to inherit from. + * @param properties The properties to assign to the object. + * @return Returns the new object. + */ + create(prototype: T, properties?: U): T & U; + } + interface Object { + /** + * @see _.create + */ + create(properties?: U): Object; + } + interface ObjectChain { + /** + * @see _.create + */ + create(properties?: U): ObjectChain; + } + interface LoDashStatic { + /** + * Assigns own enumerable properties of source object(s) to the destination object for all destination + * properties that resolve to undefined. Once a property is set, additional values of the same property are + * ignored. + * + * Note: This method mutates object. + * + * @param object The destination object. + * @param sources The source objects. + * @return The destination object. + */ + defaults(object: TObject, source: TSource): NonNullable; + /** + * @see _.defaults + */ + defaults(object: TObject, source1: TSource1, source2: TSource2): NonNullable; + /** + * @see _.defaults + */ + defaults(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3): NonNullable; + /** + * @see _.defaults + */ + defaults(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): NonNullable; + /** + * @see _.defaults + */ + defaults(object: TObject): NonNullable; + /** + * @see _.defaults + */ + defaults(object: any, ...sources: any[]): any; + } + interface Object { + /** + * @see _.defaults + */ + defaults(source: TSource): Object>; + /** + * @see _.defaults + */ + defaults(source1: TSource1, source2: TSource2): Object>; + /** + * @see _.defaults + */ + defaults(source1: TSource1, source2: TSource2, source3: TSource3): Object>; + /** + * @see _.defaults + */ + defaults(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): Object>; + /** + * @see _.defaults + */ + defaults(): Object>; + /** + * @see _.defaults + */ + defaults(...sources: any[]): Object; + } + interface ObjectChain { + /** + * @see _.defaults + */ + defaults(source: TSource): ObjectChain>; + /** + * @see _.defaults + */ + defaults(source1: TSource1, source2: TSource2): ObjectChain>; + /** + * @see _.defaults + */ + defaults(source1: TSource1, source2: TSource2, source3: TSource3): ObjectChain>; + /** + * @see _.defaults + */ + defaults(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): ObjectChain>; + /** + * @see _.defaults + */ + defaults(): ObjectChain>; + /** + * @see _.defaults + */ + defaults(...sources: any[]): ObjectChain; + } + interface LoDashStatic { + /** + * This method is like _.defaults except that it recursively assigns default properties. + * @param object The destination object. + * @param sources The source objects. + * @return Returns object. + */ + defaultsDeep(object: any, ...sources: any[]): any; + } + interface Object { + /** + * @see _.defaultsDeep + */ + defaultsDeep(...sources: any[]): Object; + } + interface ObjectChain { + /** + * @see _.defaultsDeep + */ + defaultsDeep(...sources: any[]): ObjectChain; + } + interface LoDashStatic { + /** + * @see _.toPairs + */ + entries(object?: Dictionary | NumericDictionary): Array<[string, T]>; + /** + * @see _.entries + */ + entries(object?: object): Array<[string, any]>; + } + interface Object { + /** + * @see _.entries + */ + entries(): Collection<[string, T[keyof T]]>; + } + interface LoDashImplicitWrapper { + /** + * @see _.entries + */ + entries(): Collection<[string, any]>; + } + interface ObjectChain { + /** + * @see _.entries + */ + entries(): CollectionChain<[string, T[keyof T]]>; + } + interface LoDashExplicitWrapper { + /** + * @see _.entries + */ + entries(): CollectionChain<[string, any]>; + } + interface LoDashStatic { + /** + * @see _.entriesIn + */ + entriesIn(object?: Dictionary | NumericDictionary): Array<[string, T]>; + /** + * @see _.entriesIn + */ + entriesIn(object?: object): Array<[string, any]>; + } + interface Object { + /** + * @see _.entriesIn + */ + entriesIn(): Collection<[string, T[keyof T]]>; + } + interface LoDashImplicitWrapper { + /** + * @see _.entriesIn + */ + entriesIn(): Collection<[string, any]>; + } + interface ObjectChain { + /** + * @see _.entriesIn + */ + entriesIn(): CollectionChain<[string, T[keyof T]]>; + } + interface LoDashExplicitWrapper { + /** + * @see _.entriesIn + */ + entriesIn(): CollectionChain<[string, any]>; + } + interface LoDashStatic { + /** + * @see _.extend + */ + extend(object: TObject, source: TSource): TObject & TSource; + /** + * @see _.extend + */ + extend(object: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2; + /** + * @see _.extend + */ + extend(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3): TObject & TSource1 & TSource2 & TSource3; + /** + * @see _.extend + */ + extend(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): TObject & TSource1 & TSource2 & TSource3 & TSource4; + /** + * @see _.extend + */ + extend(object: TObject): TObject; + /** + * @see _.extend + */ + extend(object: any, ...otherArgs: any[]): TResult; + } + interface Object { + /** + * @see _.extend + */ + extend(source: TSource): Object; + /** + * @see _.extend + */ + extend(source1: TSource1, source2: TSource2): Object; + /** + * @see _.extend + */ + extend(source1: TSource1, source2: TSource2, source3: TSource3): Object; + /** + * @see _.extend + */ + extend(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): Object; + /** + * @see _.extend + */ + extend(): Object; + /** + * @see _.extend + */ + extend(...otherArgs: any[]): Object; + } + interface ObjectChain { + /** + * @see _.extend + */ + extend(source: TSource): ObjectChain; + /** + * @see _.extend + */ + extend(source1: TSource1, source2: TSource2): ObjectChain; + /** + * @see _.extend + */ + extend(source1: TSource1, source2: TSource2, source3: TSource3): ObjectChain; + /** + * @see _.extend + */ + extend(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): ObjectChain; + /** + * @see _.extend + */ + extend(): ObjectChain; + /** + * @see _.extend + */ + extend(...otherArgs: any[]): ObjectChain; + } + interface LoDashStatic { + /** + * @see _.extendWith + */ + extendWith(object: TObject, source: TSource, customizer: AssignCustomizer): TObject & TSource; + /** + * @see _.extendWith + */ + extendWith(object: TObject, source1: TSource1, source2: TSource2, customizer: AssignCustomizer): TObject & TSource1 & TSource2; + /** + * @see _.extendWith + */ + extendWith(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, customizer: AssignCustomizer): TObject & TSource1 & TSource2 & TSource3; + /** + * @see _.extendWith + */ + extendWith(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: AssignCustomizer): TObject & TSource1 & TSource2 & TSource3 & TSource4; + /** + * @see _.extendWith + */ + extendWith(object: TObject): TObject; + /** + * @see _.extendWith + */ + extendWith(object: any, ...otherArgs: any[]): TResult; + } + interface Object { + /** + * @see _.extendWith + */ + extendWith(source: TSource, customizer: AssignCustomizer): Object; + /** + * @see _.extendWith + */ + extendWith(source1: TSource1, source2: TSource2, customizer: AssignCustomizer): Object; + /** + * @see _.extendWith + */ + extendWith(source1: TSource1, source2: TSource2, source3: TSource3, customizer: AssignCustomizer): Object; + /** + * @see _.extendWith + */ + extendWith(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: AssignCustomizer): Object; + /** + * @see _.extendWith + */ + extendWith(): Object; + /** + * @see _.extendWith + */ + extendWith(...otherArgs: any[]): Object; + } + interface ObjectChain { + /** + * @see _.extendWith + */ + extendWith(source: TSource, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.extendWith + */ + extendWith(source1: TSource1, source2: TSource2, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.extendWith + */ + extendWith(source1: TSource1, source2: TSource2, source3: TSource3, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.extendWith + */ + extendWith(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: AssignCustomizer): ObjectChain; + /** + * @see _.extendWith + */ + extendWith(): ObjectChain; + /** + * @see _.extendWith + */ + extendWith(...otherArgs: any[]): ObjectChain; + } + interface LoDashStatic { + /** + * This method is like _.find except that it returns the key of the first element predicate returns truthy for + * instead of the element itself. + * + * @param object The object to search. + * @param predicate The function invoked per iteration. + * @return Returns the key of the matched element, else undefined. + */ + findKey(object: T | null | undefined, predicate?: ObjectIteratee): string | undefined; + } + interface LoDashImplicitWrapper { + /** + * @see _.findKey + */ + findKey(predicate?: ObjectIteratee): string | undefined; + } + interface LoDashExplicitWrapper { + /** + * @see _.findKey + */ + findKey(predicate?: ObjectIteratee): StringNullableChain; + } + interface LoDashStatic { + /** + * This method is like _.findKey except that it iterates over elements of a collection in the opposite order. + * + * @param object The object to search. + * @param predicate The function invoked per iteration. + * @return Returns the key of the matched element, else undefined. + */ + findLastKey(object: T | null | undefined, predicate?: ObjectIteratee): string | undefined; + } + interface LoDashImplicitWrapper { + /** + * @see _.findLastKey + */ + findLastKey(predicate?: ObjectIteratee): string | undefined; + } + interface LoDashExplicitWrapper { + /** + * @see _.findLastKey + */ + findLastKey(predicate?: ObjectIteratee): StringNullableChain; + } + interface LoDashStatic { + /** + * Iterates over own and inherited enumerable properties of an object invoking iteratee for each property. The + * iteratee is invoked with three arguments: (value, key, object). Iteratee functions may + * exit iteration early by explicitly returning false. + * + * @param object The object to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns object. + */ + forIn(object: T, iteratee?: ObjectIterator): T; + /** + * @see _.forIn + */ + forIn(object: T | null | undefined, iteratee?: ObjectIterator): T | null | undefined; + } + interface LoDashImplicitWrapper { + /** + * @see _.forIn + */ + forIn(iteratee?: ObjectIterator): this; + } + interface LoDashExplicitWrapper { + /** + * @see _.forIn + */ + forIn(iteratee?: ObjectIterator): this; + } + interface LoDashStatic { + /** + * This method is like _.forIn except that it iterates over properties of object in the opposite order. + * + * @param object The object to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns object. + */ + forInRight(object: T, iteratee?: ObjectIterator): T; + /** + * @see _.forInRight + */ + forInRight(object: T | null | undefined, iteratee?: ObjectIterator): T | null | undefined; + } + interface LoDashImplicitWrapper { + /** + * @see _.forInRight + */ + forInRight(iteratee?: ObjectIterator): this; + } + interface LoDashExplicitWrapper { + /** + * @see _.forInRight + */ + forInRight(iteratee?: ObjectIterator): this; + } + interface LoDashStatic { + /** + * Iterates over own enumerable properties of an object invoking iteratee for each property. The iteratee is + * invoked with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning false. + * + * @param object The object to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns object. + */ + forOwn(object: T, iteratee?: ObjectIterator): T; + /** + * @see _.forOwn + */ + forOwn(object: T | null | undefined, iteratee?: ObjectIterator): T | null | undefined; + } + interface LoDashImplicitWrapper { + /** + * @see _.forOwn + */ + forOwn(iteratee?: ObjectIterator): this; + } + interface LoDashExplicitWrapper { + /** + * @see _.forOwn + */ + forOwn(iteratee?: ObjectIterator): this; + } + interface LoDashStatic { + /** + * This method is like _.forOwn except that it iterates over properties of object in the opposite order. + * + * @param object The object to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns object. + */ + forOwnRight(object: T, iteratee?: ObjectIterator): T; + /** + * @see _.forOwnRight + */ + forOwnRight(object: T | null | undefined, iteratee?: ObjectIterator): T | null | undefined; + } + interface LoDashImplicitWrapper { + /** + * @see _.forOwnRight + */ + forOwnRight(iteratee?: ObjectIterator): this; + } + interface LoDashExplicitWrapper { + /** + * @see _.forOwnRight + */ + forOwnRight(iteratee?: ObjectIterator): this; + } + interface LoDashStatic { + /** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @category Object + * @param object The object to inspect. + * @returns Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ + functions(object: any): string[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.functions + */ + functions(): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.functions + */ + functions(): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @category Object + * @param object The object to inspect. + * @returns Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ + functionsIn(object: any): string[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.functionsIn + */ + functionsIn(): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.functionsIn + */ + functionsIn(): CollectionChain; + } + + type GetIndexedField = K extends keyof T + ? T[K] + : K extends `${number}` + ? 'length' extends keyof T + ? number extends T['length'] + ? number extends keyof T + ? T[number] + : undefined + : undefined + : undefined + : undefined; + + type FieldWithPossiblyUndefined = + | GetFieldType, Key> + | Extract; + + type IndexedFieldWithPossiblyUndefined = + | GetIndexedField, Key> + | Extract; + + type GetFieldType = P extends `${infer Left}.${infer Right}` + ? Left extends keyof Exclude + ? FieldWithPossiblyUndefined[Left], Right> | Extract + : Left extends `${infer FieldKey}[${infer IndexKey}]` + ? FieldKey extends keyof T + ? FieldWithPossiblyUndefined, Right> + : undefined + : undefined + : P extends keyof T + ? T[P] + : P extends `${infer FieldKey}[${infer IndexKey}]` + ? FieldKey extends keyof T + ? IndexedFieldWithPossiblyUndefined + : undefined + : IndexedFieldWithPossiblyUndefined; + + interface LoDashStatic { + /** + * Gets the property value at path of object. If the resolved value is undefined the defaultValue is used + * in its place. + * + * @param object The object to query. + * @param path The path of the property to get. + * @param defaultValue The value returned if the resolved value is undefined. + * @return Returns the resolved value. + */ + get(object: TObject, path: TKey | [TKey]): TObject[TKey]; + /** + * @see _.get + */ + get(object: TObject | null | undefined, path: TKey | [TKey]): TObject[TKey] | undefined; + /** + * @see _.get + */ + get(object: TObject | null | undefined, path: TKey | [TKey], defaultValue: TDefault): Exclude | TDefault; + /** + * @see _.get + */ + get(object: TObject, path: [TKey1, TKey2]): TObject[TKey1][TKey2]; + /** + * @see _.get + */ + get(object: TObject | null | undefined, path: [TKey1, TKey2]): TObject[TKey1][TKey2] | undefined; + /** + * @see _.get + */ + get(object: TObject | null | undefined, path: [TKey1, TKey2], defaultValue: TDefault): Exclude | TDefault; + /** + * @see _.get + */ + get(object: TObject, path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3]; + /** + * @see _.get + */ + get(object: TObject | null | undefined, path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3] | undefined; + /** + * @see _.get + */ + get(object: TObject | null | undefined, path: [TKey1, TKey2, TKey3], defaultValue: TDefault): Exclude | TDefault; + /** + * @see _.get + */ + get(object: TObject, path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4]; + /** + * @see _.get + */ + get(object: TObject | null | undefined, path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + /** + * @see _.get + */ + get(object: TObject | null | undefined, path: [TKey1, TKey2, TKey3, TKey4], defaultValue: TDefault): Exclude | TDefault; + /** + * @see _.get + */ + get(object: NumericDictionary, path: number): T; + /** + * @see _.get + */ + get(object: NumericDictionary | null | undefined, path: number): T | undefined; + /** + * @see _.get + */ + get(object: NumericDictionary | null | undefined, path: number, defaultValue: TDefault): T | TDefault; + /** + * @see _.get + */ + get(object: null | undefined, path: PropertyPath, defaultValue: TDefault): TDefault; + /** + * @see _.get + */ + get(object: null | undefined, path: PropertyPath): undefined; + /** + * @see _.get + */ + get(data: TObject, path: TPath): string extends TPath ? any : GetFieldType; + /** + * @see _.get + */ + get>(data: TObject, path: TPath, defaultValue: TDefault): Exclude, null | undefined> | TDefault; + /** + * @see _.get + */ + get(object: any, path: PropertyPath, defaultValue?: any): any; + } + interface String { + /** + * @see _.get + */ + get(path: number | number[]): string; + /** + * @see _.get + */ + get(path: number | number[], defaultValue: string): string; + } + interface Object { + /** + * @see _.get + */ + get(path: TKey | [TKey]): T[TKey]; + /** + * @see _.get + */ + get(path: TKey | [TKey], defaultValue: TDefault): Exclude | TDefault; + /** + * @see _.get + */ + get(path: [TKey1, TKey2]): T[TKey1][TKey2]; + /** + * @see _.get + */ + get(path: [TKey1, TKey2], defaultValue: TDefault): Exclude | TDefault; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3]): T[TKey1][TKey2][TKey3]; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3], defaultValue: TDefault): Exclude | TDefault; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3, TKey4]): T[TKey1][TKey2][TKey3][TKey4]; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3, TKey4], defaultValue: TDefault): Exclude | TDefault; + /** + * @see _.get + */ + get(path: TPath): string extends TPath ? any : GetFieldType; + /** + * @see _.get + */ + get>(path: TPath, defaultValue: TDefault): Exclude, null | undefined> | TDefault; + /** + * @see _.get + */ + get(path: PropertyPath, defaultValue?: any): any; + } + interface Collection { + /** + * @see _.get + */ + get(path: number): T; + /** + * @see _.get + */ + get(path: number, defaultValue: TDefault): T | TDefault; + } + interface StringChain { + /** + * @see _.get + */ + get(path: number | number[]): StringChain; + /** + * @see _.get + */ + get(path: number | number[], defaultValue: string): StringChain; + } + interface StringNullableChain { + /** + * @see _.get + */ + get(path: number | number[]): StringNullableChain; + /** + * @see _.get + */ + get(path: number | number[], defaultValue: string): StringChain; + } + interface ObjectChain { + /** + * @see _.get + */ + get(path: TKey | [TKey]): ExpChain; + /** + * @see _.get + */ + get(path: TKey | [TKey], defaultValue: never[]): T[TKey] extends any[] ? ExpChain> : ExpChain | never[]>; + /** + * @see _.get + */ + get(path: TKey | [TKey], defaultValue: TDefault): ExpChain | TDefault>; + /** + * @see _.get + */ + get(path: [TKey1, TKey2]): ExpChain; + /** + * @see _.get + */ + get(path: [TKey1, TKey2], defaultValue: never[]): T[TKey1][TKey2] extends any[] ? ExpChain> : ExpChain | never[]>; + /** + * @see _.get + */ + get(path: [TKey1, TKey2], defaultValue: TDefault): ExpChain | TDefault>; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3]): ExpChain; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3], defaultValue: never[]): T[TKey1][TKey2][TKey3] extends any[] ? ExpChain> : ExpChain | never[]>; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3], defaultValue: TDefault): ExpChain | TDefault>; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3, TKey4]): ExpChain; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3, TKey4], defaultValue: never[]): T[TKey1][TKey2][TKey3][TKey4] extends any[] ? ExpChain> : ExpChain | never[]>; + /** + * @see _.get + */ + get(path: [TKey1, TKey2, TKey3, TKey4], defaultValue: TDefault): ExpChain | TDefault>; + /** + * @see _.get + */ + get(path: TPath): string extends TPath ? LoDashExplicitWrapper : ExpChain>; + /** + * @see _.get + */ + get>(path: TPath, defaultValue: TDefault): ExpChain, null | undefined> | TDefault>; + /** + * @see _.get + */ + get(path: PropertyPath, defaultValue?: any): LoDashExplicitWrapper; + } + interface CollectionChain { + /** + * @see _.get + */ + get(path: number): ExpChain; + /** + * @see _.get + */ + get(path: number, defaultValue: TDefault): ExpChain; + } + interface LoDashStatic { + /** + * Checks if `path` is a direct property of `object`. + * + * @category Object + * @param object The object to query. + * @param path The path to check. + * @returns Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + has(object: T, path: PropertyPath): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.has + */ + has(path: PropertyPath): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.has + */ + has(path: PropertyPath): PrimitiveChain; + } + interface LoDashStatic { + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @category Object + * @param object The object to query. + * @param path The path to check. + * @returns Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b.c'); + * // => true + * + * _.hasIn(object, ['a', 'b', 'c']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + hasIn(object: T, path: PropertyPath): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.hasIn + */ + hasIn(path: PropertyPath): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.hasIn + */ + hasIn(path: PropertyPath): PrimitiveChain; + } + interface LoDashStatic { + /** + * Creates an object composed of the inverted keys and values of object. If object contains duplicate values, + * subsequent values overwrite property assignments of previous values unless multiValue is true. + * + * @param object The object to invert. + * @param multiValue Allow multiple values per key. + * @return Returns the new inverted object. + */ + invert(object: object): Dictionary; + } + interface LoDashImplicitWrapper { + /** + * @see _.invert + */ + invert(): Object>; + } + interface LoDashExplicitWrapper { + /** + * @see _.invert + */ + invert(): ObjectChain>; + } + interface LoDashStatic { + /** + * This method is like _.invert except that the inverted object is generated from the results of running each + * element of object through iteratee. The corresponding inverted value of each inverted key is an array of + * keys responsible for generating the inverted value. The iteratee is invoked with one argument: (value). + * + * @param object The object to invert. + * @param interatee The iteratee invoked per element. + * @return Returns the new inverted object. + */ + invertBy(object: Dictionary | NumericDictionary | null | undefined, interatee?: ValueIteratee): Dictionary; + /** + * @see _.invertBy + */ + invertBy(object: T | null | undefined, interatee?: ValueIteratee): Dictionary; + } + interface String { + /** + * @see _.invertBy + */ + invertBy(iteratee?: ValueIteratee): Object>; + } + interface Collection { + /** + * @see _.invertBy + */ + invertBy(iteratee?: ValueIteratee): Object>; + } + interface Object { + /** + * @see _.invertBy + */ + invertBy(iteratee?: ValueIteratee): Object>; + } + interface StringChain { + /** + * @see _.invertBy + */ + invertBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface StringNullableChain { + /** + * @see _.invertBy + */ + invertBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface CollectionChain { + /** + * @see _.invertBy + */ + invertBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface ObjectChain { + /** + * @see _.invertBy + */ + invertBy(iteratee?: ValueIteratee): ObjectChain>; + } + interface LoDashStatic { + /** + * Invokes the method at path of object. + * @param object The object to query. + * @param path The path of the method to invoke. + * @param args The arguments to invoke the method with. + */ + invoke(object: any, path: PropertyPath, ...args: any[]): any; + } + interface LoDashImplicitWrapper { + /** + * @see _.invoke + */ + invoke(path: PropertyPath, ...args: any[]): any; + } + interface LoDashExplicitWrapper { + /** + * @see _.invoke + */ + invoke(path: PropertyPath, ...args: any[]): LoDashExplicitWrapper; + } + interface LoDashStatic { + /** + * Creates an array of the own enumerable property names of object. + * + * Note: Non-object values are coerced to objects. See the ES spec for more details. + * + * @param object The object to query. + * @return Returns the array of property names. + */ + keys(object?: any): string[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.keys + */ + keys(): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.keys + */ + keys(): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of the own and inherited enumerable property names of object. + * + * Note: Non-object values are coerced to objects. + * + * @param object The object to query. + * @return An array of property names. + */ + keysIn(object?: any): string[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.keysIn + */ + keysIn(): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.keysIn + */ + keysIn(): CollectionChain; + } + interface LoDashStatic { + /** + * The opposite of _.mapValues; this method creates an object with the same values as object and keys generated + * by running each own enumerable property of object through iteratee. + * + * @param object The object to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns the new mapped object. + */ + mapKeys(object: List | null | undefined, iteratee?: ListIteratee): Dictionary; + /** + * @see _.mapKeys + */ + mapKeys(object: T | null | undefined, iteratee?: ObjectIteratee): Dictionary; + } + interface Collection { + /** + * @see _.mapKeys + */ + mapKeys(iteratee?: ListIteratee): Object>; + } + interface Object { + /** + * @see _.mapKeys + */ + mapKeys(iteratee?: ObjectIteratee): Object>; + } + interface CollectionChain { + /** + * @see _.mapKeys + */ + mapKeys(iteratee?: ListIteratee): ObjectChain>; + } + interface ObjectChain { + /** + * @see _.mapKeys + */ + mapKeys(iteratee?: ObjectIteratee): ObjectChain>; + } + interface LoDashStatic { + /** + * Creates an object with the same keys as object and values generated by running each own + * enumerable property of object through iteratee. The iteratee function is + * invoked with three arguments: (value, key, object). + * + * @param object The object to iterate over. + * @param iteratee The function invoked per iteration. + * @return Returns the new mapped object. + */ + mapValues(obj: string | null | undefined, callback: StringIterator): NumericDictionary; + /** + * @see _.mapValues + */ + mapValues(obj: T | null | undefined, callback: ObjectIterator): { [P in keyof T]: TResult }; + /** + * @see _.mapValues + */ + mapValues(obj: Dictionary | NumericDictionary | null | undefined, iteratee: object): Dictionary; + /** + * @see _.mapValues + */ + mapValues(obj: T | null | undefined, iteratee: object): { [P in keyof T]: boolean }; + /** + * @see _.mapValues + */ + mapValues(obj: Dictionary | NumericDictionary | null | undefined, iteratee: TKey): Dictionary; + /** + * @see _.mapValues + */ + mapValues(obj: Dictionary | NumericDictionary | null | undefined, iteratee: string): Dictionary; + /** + * @see _.mapValues + */ + mapValues(obj: T | null | undefined, iteratee: string): { [P in keyof T]: any }; + /** + * @see _.mapValues + */ + mapValues(obj: string | null | undefined): NumericDictionary; + /** + * @see _.mapValues + */ + mapValues(obj: Dictionary | NumericDictionary | null | undefined): Dictionary; + /** + * @see _.mapValues + */ + mapValues(obj: T): T; + /** + * @see _.mapValues + */ + mapValues(obj: T | null | undefined): PartialObject; + } + interface String { + /** + * @see _.mapValues + */ + mapValues(callback: StringIterator): Object>; + /** + * @see _.mapValues + */ + mapValues(): Object>; + } + interface Collection { + /** + * @see _.mapValues + */ + mapValues(callback: DictionaryIterator): Object>; + /** + * @see _.mapValues + */ + mapValues(iteratee: TKey): Object>; + /** + * @see _.mapValues + */ + mapValues(iteratee: object): Object>; + /** + * @see _.mapValues + */ + mapValues(iteratee: string): Object>; + /** + * @see _.mapValues + */ + mapValues(): Object>; + } + interface Object { + /** + * @see _.mapValues + */ + mapValues(callback: ObjectIterator): Object<{ [P in keyof T]: TResult }>; + /** + * @see _.mapValues + */ + mapValues(callback: DictionaryIterator): Object>; + /** + * @see _.mapValues + */ + mapValues(iteratee: object): Object<{ [P in keyof T]: boolean }>; + /** + * @see _.mapValues + */ + mapValues(iteratee: TKey): Object>; + /** + * @see _.mapValues + */ + mapValues(iteratee: string): Object<{ [P in keyof T]: any }>; + /** + * @see _.mapValues + */ + mapValues(): Object; + } + interface StringChain { + /** + * @see _.mapValues + */ + mapValues(callback: StringIterator): ObjectChain>; + /** + * @see _.mapValues + */ + mapValues(): ObjectChain>; + } + interface StringNullableChain { + /** + * @see _.mapValues + */ + mapValues(callback: StringIterator): ObjectChain>; + /** + * @see _.mapValues + */ + mapValues(): ObjectChain>; + } + interface CollectionChain { + /** + * @see _.mapValues + */ + mapValues(callback: DictionaryIterator): ObjectChain>; + /** + * @see _.mapValues + */ + mapValues(iteratee: TKey): ObjectChain>; + /** + * @see _.mapValues + */ + mapValues(iteratee: object): ObjectChain>; + /** + * @see _.mapValues + */ + mapValues(iteratee: string): ObjectChain>; + /** + * @see _.mapValues + */ + mapValues(): ObjectChain>; + } + interface ObjectChain { + /** + * @see _.mapValues + */ + mapValues(callback: ObjectIterator): ObjectChain<{ [P in keyof T]: TResult }>; + /** + * @see _.mapValues + */ + mapValues(callback: DictionaryIterator): ObjectChain>; + /** + * @see _.mapValues + */ + mapValues(iteratee: object): ObjectChain<{ [P in keyof T]: boolean }>; + /** + * @see _.mapValues + */ + mapValues(iteratee: TKey): ObjectChain>; + /** + * @see _.mapValues + */ + mapValues(iteratee: string): ObjectChain<{ [P in keyof T]: any }>; + /** + * @see _.mapValues + */ + mapValues(): ObjectChain; + } + interface LoDashStatic { + /** + * Recursively merges own and inherited enumerable properties of source + * objects into the destination object, skipping source properties that resolve + * to `undefined`. Array and plain object properties are merged recursively. + * Other objects and value types are overridden by assignment. Source objects + * are applied from left to right. Subsequent sources overwrite property + * assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @category Object + * @param object The destination object. + * @param [sources] The source objects. + * @returns Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + */ + merge(object: TObject, source: TSource): TObject & TSource; + /** + * @see _.merge + */ + merge(object: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2; + /** + * @see _.merge + */ + merge(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3): TObject & TSource1 & TSource2 & TSource3; + /** + * @see _.merge + */ + merge(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): TObject & TSource1 & TSource2 & TSource3 & TSource4; + /** + * @see _.merge + */ + merge(object: any, ...otherArgs: any[]): any; + } + interface Object { + /** + * @see _.merge + */ + merge(source: TSource): Object; + /** + * @see _.merge + */ + merge(source1: TSource1, source2: TSource2): Object; + /** + * @see _.merge + */ + merge(source1: TSource1, source2: TSource2, source3: TSource3): Object; + /** + * @see _.merge + */ + merge(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): Object; + /** + * @see _.merge + */ + merge(...otherArgs: any[]): Object; + } + interface ObjectChain { + /** + * @see _.merge + */ + merge(source: TSource): ObjectChain; + /** + * @see _.merge + */ + merge(source1: TSource1, source2: TSource2): ObjectChain; + /** + * @see _.merge + */ + merge(source1: TSource1, source2: TSource2, source3: TSource3): ObjectChain; + /** + * @see _.merge + */ + merge(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): ObjectChain; + /** + * @see _.merge + */ + merge(...otherArgs: any[]): ObjectChain; + } + type MergeWithCustomizer = { bivariantHack(value: any, srcValue: any, key: string, object: any, source: any): any; }["bivariantHack"]; + // TODO: Probably should just put all these methods on Object and forget about it. + // oh, except for Collection I GUESS + interface LoDashStatic { + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined` merging is handled by the + * method instead. The `customizer` is invoked with seven arguments: + * (objValue, srcValue, key, object, source, stack). + * + * @category Object + * @param object The destination object. + * @param sources The source objects. + * @param customizer The function to customize assigned values. + * @returns Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.mergeWith(object, other, customizer); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + mergeWith(object: TObject, source: TSource, customizer: MergeWithCustomizer): TObject & TSource; + /** + * @see _.mergeWith + */ + mergeWith(object: TObject, source1: TSource1, source2: TSource2, customizer: MergeWithCustomizer): TObject & TSource1 & TSource2; + /** + * @see _.mergeWith + */ + mergeWith(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, customizer: MergeWithCustomizer): TObject & TSource1 & TSource2 & TSource3; + /** + * @see _.mergeWith + */ + mergeWith(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: MergeWithCustomizer): TObject & TSource1 & TSource2 & TSource3 & TSource4; + /** + * @see _.mergeWith + */ + mergeWith(object: any, ...otherArgs: any[]): any; + } + interface Object { + /** + * @see _.mergeWith + */ + mergeWith(source: TSource, customizer: MergeWithCustomizer): Object; + /** + * @see _.mergeWith + */ + mergeWith(source1: TSource1, source2: TSource2, customizer: MergeWithCustomizer): Object; + /** + * @see _.mergeWith + */ + mergeWith(source1: TSource1, source2: TSource2, source3: TSource3, customizer: MergeWithCustomizer): Object; + /** + * @see _.mergeWith + */ + mergeWith(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: MergeWithCustomizer): Object; + /** + * @see _.mergeWith + */ + mergeWith(...otherArgs: any[]): Object; + } + interface ObjectChain { + /** + * @see _.mergeWith + */ + mergeWith(source: TSource, customizer: MergeWithCustomizer): ObjectChain; + /** + * @see _.mergeWith + */ + mergeWith(source1: TSource1, source2: TSource2, customizer: MergeWithCustomizer): ObjectChain; + /** + * @see _.mergeWith + */ + mergeWith(source1: TSource1, source2: TSource2, source3: TSource3, customizer: MergeWithCustomizer): ObjectChain; + /** + * @see _.mergeWith + */ + mergeWith(source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4, customizer: MergeWithCustomizer): ObjectChain; + /** + * @see _.mergeWith + */ + mergeWith(...otherArgs: any[]): ObjectChain; + } + interface LoDashStatic { + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * + * @category Object + * @param object The source object. + * @param [paths] The property names to omit, specified + * individually or in arrays.. + * @returns Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ + omit( + object: T | null | undefined, + ...paths: K + ): Pick>; + /** + * @see _.omit + */ + omit(object: T | null | undefined, ...paths: Array>): Omit; + /** + * @see _.omit + */ + omit(object: T | null | undefined, ...paths: Array>): PartialObject; + } + interface Collection { + /** + * @see _.omit + */ + omit(...paths: Array>): Collection; + } + interface Object { + /** + * @see _.omit + */ + omit(...paths: Array>): Object>; + /** + * @see _.omit + */ + omit(...paths: Array>>): Object>; + } + interface CollectionChain { + /** + * @see _.omit + */ + omit(...paths: Array>): CollectionChain; + } + interface ObjectChain { + /** + * @see _.omit + */ + omit(...paths: Array>): ObjectChain>; + /** + * @see _.omit + */ + omit(...paths: Array>): ObjectChain>; + } + interface LoDashStatic { + /** + * The opposite of `_.pickBy`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that `predicate` + * doesn't return truthy for. + * + * @category Object + * @param object The source object. + * @param [predicate=_.identity] The function invoked per property. + * @returns Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + omitBy(object: Dictionary | null | undefined, predicate?: ValueKeyIteratee): Dictionary; + /** + * @see _.omitBy + */ + omitBy(object: NumericDictionary | null | undefined, predicate?: ValueKeyIteratee): NumericDictionary; + /** + * @see _.omitBy + */ + omitBy(object: T | null | undefined, predicate: ValueKeyIteratee): PartialObject; + } + interface Collection { + /** + * @see _.omitBy + */ + omitBy(predicate?: ValueKeyIteratee): Object>; + } + interface Object { + /** + * @see _.omitBy + */ + omitBy(predicate: ValueKeyIteratee): Object>; + } + interface CollectionChain { + /** + * @see _.omitBy + */ + omitBy(predicate?: ValueKeyIteratee): ObjectChain>; + } + interface ObjectChain { + /** + * @see _.omitBy + */ + omitBy(predicate: ValueKeyIteratee): ObjectChain>; + } + interface LoDashStatic { + /** + * Creates an object composed of the picked `object` properties. + * + * @category Object + * @param object The source object. + * @param [props] The property names to pick, specified + * individually or in arrays. + * @returns Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + pick(object: T, ...props: Array>): Pick; + /** + * @see _.pick + */ + pick(object: T | null | undefined, ...props: Array>): PartialObject; + } + interface Object { + /** + * @see _.pick + */ + pick(...props: Array>): Object>; + /** + * @see _.pick + */ + pick(...props: Array>): Object>; + } + interface ObjectChain { + /** + * @see _.pick + */ + pick(...props: Array>): ObjectChain>; + /** + * @see _.pick + */ + pick(...props: Array>): ObjectChain>; + } + interface LoDashStatic { + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @category Object + * @param object The source object. + * @param [predicate=_.identity] The function invoked per property. + * @returns Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + pickBy(object: Dictionary | null | undefined, predicate: ValueKeyIterateeTypeGuard): Dictionary; + /** + * @see _.pickBy + */ + pickBy(object: NumericDictionary | null | undefined, predicate: ValueKeyIterateeTypeGuard): NumericDictionary; + /** + * @see _.pickBy + */ + pickBy(object: Dictionary | null | undefined, predicate?: ValueKeyIteratee): Dictionary; + /** + * @see _.pickBy + */ + pickBy(object: NumericDictionary | null | undefined, predicate?: ValueKeyIteratee): NumericDictionary; + /** + * @see _.pickBy + */ + pickBy(object: T | null | undefined, predicate?: ValueKeyIteratee): PartialObject; + } + interface Collection { + /** + * @see _.pickBy + */ + pickBy(predicate: ValueKeyIterateeTypeGuard): Object>; + /** + * @see _.pickBy + */ + pickBy(predicate?: ValueKeyIteratee): Object>; + } + interface Object { + /** + * @see _.pickBy + */ + pickBy(predicate: ValueKeyIterateeTypeGuard): Object extends T ? NumericDictionary : Dictionary>; + /** + * @see _.pickBy + */ + pickBy(predicate?: ValueKeyIteratee): Object ? Dictionary : T extends NumericDictionary ? NumericDictionary : PartialObject>; + } + interface CollectionChain { + /** + * @see _.pickBy + */ + pickBy(predicate: ValueKeyIterateeTypeGuard): ObjectChain>; + /** + * @see _.pickBy + */ + pickBy(predicate?: ValueKeyIteratee): ObjectChain>; + } + interface ObjectChain { + /** + * @see _.pickBy + */ + pickBy(predicate: ValueKeyIterateeTypeGuard): ObjectChain extends T ? NumericDictionary : Dictionary>; + /** + * @see _.pickBy + */ + pickBy(predicate?: ValueKeyIteratee): ObjectChain ? Dictionary : T extends NumericDictionary ? NumericDictionary : PartialObject>; + } + interface LoDashStatic { + /** + * This method is like _.get except that if the resolved value is a function it’s invoked with the this binding + * of its parent object and its result is returned. + * + * @param object The object to query. + * @param path The path of the property to resolve. + * @param defaultValue The value returned if the resolved value is undefined. + * @return Returns the resolved value. + */ + result(object: any, path: PropertyPath, defaultValue?: TResult | ((...args: any[]) => TResult)): TResult; + } + interface LoDashImplicitWrapper { + /** + * @see _.result + */ + result(path: PropertyPath, defaultValue?: TResult | ((...args: any[]) => TResult)): TResult; + } + interface LoDashExplicitWrapper { + /** + * @see _.result + */ + result(path: PropertyPath, defaultValue?: TResult | ((...args: any[]) => TResult)): ExpChain; + } + interface LoDashStatic { + /** + * Sets the value at path of object. If a portion of path doesn’t exist it’s created. Arrays are created for + * missing index properties while objects are created for all other missing properties. Use _.setWith to + * customize path creation. + * + * @param object The object to modify. + * @param path The path of the property to set. + * @param value The value to set. + * @return Returns object. + */ + set(object: T, path: PropertyPath, value: any): T; + /** + * @see _.set + */ + set(object: object, path: PropertyPath, value: any): TResult; + } + interface LoDashImplicitWrapper { + /** + * @see _.set + */ + set(path: PropertyPath, value: any): this; + /** + * @see _.set + */ + set(path: PropertyPath, value: any): ImpChain; + } + interface LoDashExplicitWrapper { + /** + * @see _.set + */ + set(path: PropertyPath, value: any): this; + /** + * @see _.set + */ + set(path: PropertyPath, value: any): ExpChain; + } + type SetWithCustomizer = (nsValue: any, key: string, nsObject: T) => any; + interface LoDashStatic { + /** + * This method is like _.set except that it accepts customizer which is invoked to produce the objects of + * path. If customizer returns undefined path creation is handled by the method instead. The customizer is + * invoked with three arguments: (nsValue, key, nsObject). + * + * @param object The object to modify. + * @param path The path of the property to set. + * @param value The value to set. + * @param customizer The function to customize assigned values. + * @return Returns object. + */ + setWith(object: T, path: PropertyPath, value: any, customizer?: SetWithCustomizer): T; + /** + * @see _.setWith + */ + setWith(object: T, path: PropertyPath, value: any, customizer?: SetWithCustomizer): TResult; + } + interface LoDashImplicitWrapper { + /** + * @see _.setWith + */ + setWith(path: PropertyPath, value: any, customizer?: SetWithCustomizer): this; + /** + * @see _.setWith + */ + setWith(path: PropertyPath, value: any, customizer?: SetWithCustomizer): ImpChain; + } + interface LoDashExplicitWrapper { + /** + * @see _.setWith + */ + setWith(path: PropertyPath, value: any, customizer?: SetWithCustomizer): this; + /** + * @see _.setWith + */ + setWith(path: PropertyPath, value: any, customizer?: SetWithCustomizer): ExpChain; + } + interface LoDashStatic { + /** + * Creates an array of own enumerable key-value pairs for object. + * + * @param object The object to query. + * @return Returns the new array of key-value pairs. + */ + toPairs(object?: Dictionary | NumericDictionary): Array<[string, T]>; + /** + * @see _.toPairs + */ + toPairs(object?: object): Array<[string, any]>; + } + interface LoDashImplicitWrapper { + /** + * @see _.toPairs + */ + toPairs(): Collection<[string, TValue extends Dictionary ? U : TValue extends NumericDictionary ? V : any]>; + } + interface LoDashExplicitWrapper { + /** + * @see _.toPairs + */ + toPairs(): CollectionChain<[string, TValue extends Dictionary ? U : TValue extends NumericDictionary ? V : any]>; + } + interface LoDashStatic { + /** + * Creates an array of own and inherited enumerable key-value pairs for object. + * + * @param object The object to query. + * @return Returns the new array of key-value pairs. + */ + toPairsIn(object?: Dictionary | NumericDictionary): Array<[string, T]>; + /** + * @see _.toPairsIn + */ + toPairsIn(object?: object): Array<[string, any]>; + } + interface LoDashImplicitWrapper { + /** + * @see _.toPairsIn + */ + toPairsIn(): Collection<[string, TValue extends Dictionary ? U : TValue extends NumericDictionary ? V : any]>; + } + interface LoDashExplicitWrapper { + /** + * @see _.toPairsIn + */ + toPairsIn(): CollectionChain<[string, TValue extends Dictionary ? U : TValue extends NumericDictionary ? V : any]>; + } + interface LoDashStatic { + /** + * An alternative to _.reduce; this method transforms object to a new accumulator object which is the result of + * running each of its own enumerable properties through iteratee, with each invocation potentially mutating + * the accumulator object. The iteratee is invoked with four arguments: (accumulator, + * value, key, object). Iteratee functions may exit iteration early by explicitly returning false. + * + * @param object The object to iterate over. + * @param iteratee The function invoked per iteration. + * @param accumulator The custom accumulator value. + * @return Returns the accumulated value. + */ + transform(object: ReadonlyArray, iteratee: MemoVoidArrayIterator, accumulator?: TResult): TResult; + /** + * @see _.transform + */ + transform(object: Dictionary, iteratee: MemoVoidDictionaryIterator, accumulator?: TResult): TResult; + /** + * @see _.transform + */ + transform(object: T, iteratee: MemoVoidDictionaryIterator, accumulator?: TResult): TResult; + /** + * @see _.transform + */ + transform(object: any[]): any[]; + /** + * @see _.transform + */ + transform(object: object): Dictionary; + } + interface Collection { + /** + * @see _.transform + */ + transform(iteratee: MemoVoidArrayIterator, accumulator?: TResult): ImpChain; + /** + * @see _.transform + */ + transform(): Collection; + } + interface Object { + /** + * @see _.transform + */ + transform(iteratee: MemoVoidDictionaryIterator, accumulator?: TResult): ImpChain; + /** + * @see _.transform + */ + transform(iteratee: MemoVoidDictionaryIterator, accumulator?: TResult): ImpChain; + /** + * @see _.transform + */ + transform(): ImpChain ? Dictionary : T>; + } + interface CollectionChain { + /** + * @see _.transform + */ + transform(iteratee: MemoVoidArrayIterator, accumulator?: TResult): ExpChain; + /** + * @see _.transform + */ + transform(): CollectionChain; + } + interface ObjectChain { + /** + * @see _.transform + */ + transform(iteratee: MemoVoidDictionaryIterator, accumulator?: TResult): ExpChain; + /** + * @see _.transform + */ + transform(iteratee: MemoVoidDictionaryIterator, accumulator?: TResult): ExpChain; + /** + * @see _.transform + */ + transform(): ExpChain ? Dictionary : T>; + } + interface LoDashStatic { + /** + * Removes the property at path of object. + * + * Note: This method mutates object. + * + * @param object The object to modify. + * @param path The path of the property to unset. + * @return Returns true if the property is deleted, else false. + */ + unset(object: any, path: PropertyPath): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.unset + */ + unset(path: PropertyPath): Primitive; + } + interface LoDashExplicitWrapper { + /** + * @see _.unset + */ + unset(path: PropertyPath): PrimitiveChain; + } + interface LoDashStatic { + /** + * This method is like _.set except that accepts updater to produce the value to set. Use _.updateWith to + * customize path creation. The updater is invoked with one argument: (value). + * + * @param object The object to modify. + * @param path The path of the property to set. + * @param updater The function to produce the updated value. + * @return Returns object. + */ + update(object: object, path: PropertyPath, updater: (value: any) => any): any; + } + interface LoDashImplicitWrapper { + /** + * @see _.update + */ + update(path: PropertyPath, updater: (value: any) => any): Object; + } + interface LoDashExplicitWrapper { + /** + * @see _.update + */ + update(path: PropertyPath, updater: (value: any) => any): ObjectChain; + } + interface LoDashStatic { + /** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @since 4.6.0 + * @category Object + * @param object The object to modify. + * @param path The path of the property to set. + * @param updater The function to produce the updated value. + * @param [customizer] The function to customize assigned values. + * @returns Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ + updateWith(object: T, path: PropertyPath, updater: (oldValue: any) => any, customizer?: SetWithCustomizer): T; + /** + * @see _.updateWith + */ + updateWith(object: T, path: PropertyPath, updater: (oldValue: any) => any, customizer?: SetWithCustomizer): TResult; + } + interface Object { + /** + * @see _.updateWith + */ + updateWith(path: PropertyPath, updater: (oldValue: any) => any, customizer?: SetWithCustomizer): this; + /** + * @see _.updateWith + */ + updateWith(path: PropertyPath, updater: (oldValue: any) => any, customizer?: SetWithCustomizer): Object; + } + interface ObjectChain { + /** + * @see _.updateWith + */ + updateWith(path: PropertyPath, updater: (oldValue: any) => any, customizer?: SetWithCustomizer): this; + /** + * @see _.updateWith + */ + updateWith(path: PropertyPath, updater: (oldValue: any) => any, customizer?: SetWithCustomizer): ObjectChain; + } + interface LoDashStatic { + /** + * Creates an array of the own enumerable property values of object. + * + * @param object The object to query. + * @return Returns an array of property values. + */ + values(object: Dictionary | NumericDictionary | List | null | undefined): T[]; + /** + * @see _.values + */ + values(object: T | null | undefined): Array; + /** + * @see _.values + */ + values(object: any): any[]; + } + interface String { + /** + * @see _.values + */ + values(): Collection; + } + interface Object { + /** + * @see _.values + */ + values(): Collection; + } + interface ObjectChain { + /** + * @see _.values + */ + values(): CollectionChain; + } + interface StringChain { + /** + * @see _.values + */ + values(): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.values + */ + values(): CollectionChain; + } + interface LoDashStatic { + /** + * Creates an array of the own and inherited enumerable property values of object. + * + * @param object The object to query. + * @return Returns the array of property values. + */ + valuesIn(object: Dictionary | NumericDictionary | List | null | undefined): T[]; + /** + * @see _.valuesIn + */ + valuesIn(object: T | null | undefined): Array; + } + interface String { + /** + * @see _.valuesIn + */ + valuesIn(): Collection; + } + interface Object { + /** + * @see _.valuesIn + */ + valuesIn(): Collection; + } + interface StringChain { + /** + * @see _.valuesIn + */ + valuesIn(): CollectionChain; + } + interface StringNullableChain { + /** + * @see _.valuesIn + */ + valuesIn(): CollectionChain; + } + interface ObjectChain { + /** + * @see _.valuesIn + */ + valuesIn(): CollectionChain; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/seq.d.ts b/libs/events/node_modules/@types/lodash/common/seq.d.ts new file mode 100755 index 000000000..8a0ef1ce1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/seq.d.ts @@ -0,0 +1,210 @@ +import _ = require("../index"); +declare module "../index" { + // chain + interface LoDashStatic { + /** + * Creates a lodash object that wraps value with explicit method chaining enabled. + * + * @param value The value to wrap. + * @return Returns the new lodash wrapper instance. + */ + chain(value: TrapAny): CollectionChain & FunctionChain & ObjectChain & PrimitiveChain & StringChain; + /** + * @see _.chain + */ + chain(value: T): PrimitiveChain; + /** + * @see _.chain + */ + chain(value: string): StringChain; + /** + * @see _.chain + */ + chain(value: string | null | undefined): StringNullableChain; + /** + * @see _.chain + */ + chain any>(value: T): FunctionChain; + /** + * @see _.chain + */ + chain(value: List | null | undefined): CollectionChain; + /** + * @see _.chain + */ + chain(value: T | null | undefined): ObjectChain; + /** + * @see _.chain + */ + chain(value: T): PrimitiveChain; + } + interface Collection { + /** + * @see _.chain + */ + chain(): CollectionChain; + } + interface String { + /** + * @see _.chain + */ + chain(): StringChain; + } + interface Object { + /** + * @see _.chain + */ + chain(): ObjectChain; + } + interface Primitive { + /** + * @see _.chain + */ + chain(): PrimitiveChain; + } + interface Function any> { + /** + * @see _.chain + */ + chain(): FunctionChain; + } + interface LoDashExplicitWrapper { + /** + * @see _.chain + */ + chain(): this; + } + // prototype.commit + interface LoDashImplicitWrapper { + /** + * @see _.commit + */ + commit(): this; + } + interface LoDashExplicitWrapper { + /** + * @see _.commit + */ + commit(): this; + } + // prototype.plant + interface LoDashImplicitWrapper { + /** + * @see _.plant + */ + plant(value: unknown): this; + } + interface LoDashExplicitWrapper { + /** + * @see _.plant + */ + plant(value: unknown): this; + } + // prototype.reverse + interface LoDashImplicitWrapper { + /** + * @see _.reverse + */ + reverse(): this; + } + interface LoDashExplicitWrapper { + /** + * @see _.reverse + */ + reverse(): this; + } + // prototype.toJSON + interface LoDashImplicitWrapper { + /** + * @see _.toJSON + */ + toJSON(): TValue; + } + interface LoDashExplicitWrapper { + /** + * @see _.toJSON + */ + toJSON(): TValue; + } + // prototype.toString + interface LoDashWrapper { + /** + * @see _.toString + */ + toString(): string; + } + // prototype.value + interface LoDashImplicitWrapper { + /** + * @see _.value + */ + value(): TValue; + } + interface LoDashExplicitWrapper { + /** + * @see _.value + */ + value(): TValue; + } + // prototype.valueOf + interface LoDashImplicitWrapper { + /** + * @see _.valueOf + */ + valueOf(): TValue; + } + interface LoDashExplicitWrapper { + /** + * @see _.valueOf + */ + valueOf(): TValue; + } + // tap + interface LoDashStatic { + /** + * This method invokes interceptor and returns value. The interceptor is invoked with one + * argument; (value). The purpose of this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @param value The value to provide to interceptor. + * @param interceptor The function to invoke. + * @return Returns value. + */ + tap(value: T, interceptor: (value: T) => void): T; + } + interface LoDashImplicitWrapper { + /** + * @see _.tap + */ + tap(interceptor: (value: TValue) => void): this; + } + interface LoDashExplicitWrapper { + /** + * @see _.tap + */ + tap(interceptor: (value: TValue) => void): this; + } + // thru + interface LoDashStatic { + /** + * This method is like _.tap except that it returns the result of interceptor. + * + * @param value The value to provide to interceptor. + * @param interceptor The function to invoke. + * @return Returns the result of interceptor. + */ + thru(value: T, interceptor: (value: T) => TResult): TResult; + } + interface LoDashImplicitWrapper { + /** + * @see _.thru + */ + thru(interceptor: (value: TValue) => TResult): ImpChain; + } + interface LoDashExplicitWrapper { + /** + * @see _.thru + */ + thru(interceptor: (value: TValue) => TResult): ExpChain; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/string.d.ts b/libs/events/node_modules/@types/lodash/common/string.d.ts new file mode 100755 index 000000000..6a329684d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/string.d.ts @@ -0,0 +1,788 @@ +import _ = require("../index"); +declare module "../index" { + interface LoDashStatic { + /** + * Converts string to camel case. + * + * @param string The string to convert. + * @return Returns the camel cased string. + */ + camelCase(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.camelCase + */ + camelCase(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.camelCase + */ + camelCase(): StringChain; + } + + interface LoDashStatic { + /** + * Converts the first character of string to upper case and the remaining to lower case. + * + * @param string The string to capitalize. + * @return Returns the capitalized string. + */ + capitalize(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.capitalize + */ + capitalize(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.capitalize + */ + capitalize(): StringChain; + } + + interface LoDashStatic { + /** + * Deburrs string by converting latin-1 supplementary letters to basic latin letters and removing combining + * diacritical marks. + * + * @param string The string to deburr. + * @return Returns the deburred string. + */ + deburr(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.deburr + */ + deburr(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.deburr + */ + deburr(): StringChain; + } + + interface LoDashStatic { + /** + * Checks if string ends with the given target string. + * + * @param string The string to search. + * @param target The string to search for. + * @param position The position to search from. + * @return Returns true if string ends with target, else false. + */ + endsWith(string?: string, target?: string, position?: number): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.endsWith + */ + endsWith(target?: string, position?: number): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.endsWith + */ + endsWith(target?: string, position?: number): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Converts the characters "&", "<", ">", '"', "'", and "`" in string to their corresponding HTML entities. + * + * Note: No other characters are escaped. To escape additional characters use a third-party library like he. + * + * Though the ">" character is escaped for symmetry, characters like ">" and "/" don’t need escaping in HTML + * and have no special meaning unless they're part of a tag or unquoted attribute value. See Mathias Bynens’s + * article (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in IE < 9, they can break out of attribute values or HTML comments. See #59, + * #102, #108, and #133 of the HTML5 Security Cheatsheet for more details. + * + * When working with HTML you should always quote attribute values to reduce XSS vectors. + * + * @param string The string to escape. + * @return Returns the escaped string. + */ + escape(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.escape + */ + escape(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.escape + */ + escape(): StringChain; + } + + interface LoDashStatic { + /** + * Escapes the RegExp special characters "^", "$", "\", ".", "*", "+", "?", "(", ")", "[", "]", + * "{", "}", and "|" in string. + * + * @param string The string to escape. + * @return Returns the escaped string. + */ + escapeRegExp(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.escapeRegExp + */ + escapeRegExp(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.escapeRegExp + */ + escapeRegExp(): StringChain; + } + + interface LoDashStatic { + /** + * Converts string to kebab case. + * + * @param string The string to convert. + * @return Returns the kebab cased string. + */ + kebabCase(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.kebabCase + */ + kebabCase(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.kebabCase + */ + kebabCase(): StringChain; + } + + interface LoDashStatic { + /** + * Converts `string`, as space separated words, to lower case. + * + * @param string The string to convert. + * @return Returns the lower cased string. + */ + lowerCase(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.lowerCase + */ + lowerCase(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.lowerCase + */ + lowerCase(): StringChain; + } + + interface LoDashStatic { + /** + * Converts the first character of `string` to lower case. + * + * @param string The string to convert. + * @return Returns the converted string. + */ + lowerFirst(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.lowerFirst + */ + lowerFirst(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.lowerFirst + */ + lowerFirst(): StringChain; + } + + interface LoDashStatic { + /** + * Pads string on the left and right sides if it’s shorter than length. Padding characters are truncated if + * they can’t be evenly divided by length. + * + * @param string The string to pad. + * @param length The padding length. + * @param chars The string used as padding. + * @return Returns the padded string. + */ + pad(string?: string, length?: number, chars?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.pad + */ + pad(length?: number, chars?: string): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.pad + */ + pad(length?: number, chars?: string): StringChain; + } + + interface LoDashStatic { + /** + * Pads string on the right side if it’s shorter than length. Padding characters are truncated if they exceed + * length. + * + * @param string The string to pad. + * @param length The padding length. + * @param chars The string used as padding. + * @return Returns the padded string. + */ + padEnd(string?: string, length?: number, chars?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.padEnd + */ + padEnd(length?: number, chars?: string): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.padEnd + */ + padEnd(length?: number, chars?: string): StringChain; + } + + interface LoDashStatic { + /** + * Pads string on the left side if it’s shorter than length. Padding characters are truncated if they exceed + * length. + * + * @param string The string to pad. + * @param length The padding length. + * @param chars The string used as padding. + * @return Returns the padded string. + */ + padStart(string?: string, length?: number, chars?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.padStart + */ + padStart(length?: number, chars?: string): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.padStart + */ + padStart(length?: number, chars?: string): StringChain; + } + + interface LoDashStatic { + /** + * Converts string to an integer of the specified radix. If radix is undefined or 0, a radix of 10 is used + * unless value is a hexadecimal, in which case a radix of 16 is used. + * + * Note: This method aligns with the ES5 implementation of parseInt. + * + * @param string The string to convert. + * @param radix The radix to interpret value by. + * @return Returns the converted integer. + */ + parseInt(string: string, radix?: number): number; + } + interface LoDashImplicitWrapper { + /** + * @see _.parseInt + */ + parseInt(radix?: number): number; + } + interface LoDashExplicitWrapper { + /** + * @see _.parseInt + */ + parseInt(radix?: number): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Repeats the given string n times. + * + * @param string The string to repeat. + * @param n The number of times to repeat the string. + * @return Returns the repeated string. + */ + repeat(string?: string, n?: number): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.repeat + */ + repeat(n?: number): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.repeat + */ + repeat(n?: number): StringChain; + } + type ReplaceFunction = (match: string, ...args: any[]) => string; + + interface LoDashStatic { + /** + * Replaces matches for pattern in string with replacement. + * + * Note: This method is based on String#replace. + * + * @return Returns the modified string. + */ + replace(string: string, pattern: RegExp | string, replacement: ReplaceFunction | string): string; + /** + * @see _.replace + */ + replace(pattern: RegExp | string, replacement: ReplaceFunction | string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.replace + */ + replace(pattern: RegExp | string, replacement: ReplaceFunction | string): string; + /** + * @see _.replace + */ + replace(replacement: ReplaceFunction | string): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.replace + */ + replace(pattern: RegExp | string, replacement: ReplaceFunction | string): StringChain; + /** + * @see _.replace + */ + replace(replacement: ReplaceFunction | string): StringChain; + } + + interface LoDashStatic { + /** + * Converts string to snake case. + * + * @param string The string to convert. + * @return Returns the snake cased string. + */ + snakeCase(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.snakeCase + */ + snakeCase(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.snakeCase + */ + snakeCase(): StringChain; + } + + interface LoDashStatic { + /** + * Splits string by separator. + * + * Note: This method is based on String#split. + * + * @param string The string to split. + * @param separator The separator pattern to split by. + * @param limit The length to truncate results to. + * @return Returns the new array of string segments. + */ + split(string: string | null | undefined, separator?: RegExp | string, limit?: number): string[]; + /** + * @see _.split + */ + split(string: string | null | undefined, index: string | number, guard: object): string[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.split + */ + split(separator?: RegExp | string, limit?: number): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.split + */ + split(separator?: RegExp | string, limit?: number): CollectionChain; + } + + interface LoDashStatic { + /** + * Converts string to start case. + * + * @param string The string to convert. + * @return Returns the start cased string. + */ + startCase(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.startCase + */ + startCase(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.startCase + */ + startCase(): StringChain; + } + + interface LoDashStatic { + /** + * Checks if string starts with the given target string. + * + * @param string The string to search. + * @param target The string to search for. + * @param position The position to search from. + * @return Returns true if string starts with target, else false. + */ + startsWith(string?: string, target?: string, position?: number): boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.startsWith + */ + startsWith(target?: string, position?: number): boolean; + } + interface LoDashExplicitWrapper { + /** + * @see _.startsWith + */ + startsWith(target?: string, position?: number): PrimitiveChain; + } + + interface TemplateOptions extends TemplateSettings { + /** + * @see _.sourceURL + */ + sourceURL?: string | undefined; + } + interface TemplateExecutor { + (data?: object): string; + /** + * @see _.source + */ + source: string; + } + interface LoDashStatic { + /** + * Creates a compiled template function that can interpolate data properties in "interpolate" delimiters, + * HTML-escape interpolated data properties in "escape" delimiters, and execute JavaScript in "evaluate" + * delimiters. Data properties may be accessed as free variables in the template. If a setting object is + * provided it takes precedence over _.templateSettings values. + * + * Note: In the development build _.template utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier + * debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @param string The template string. + * @param options The options object. + * @param options.escape The HTML "escape" delimiter. + * @param options.evaluate The "evaluate" delimiter. + * @param options.imports An object to import into the template as free variables. + * @param options.interpolate The "interpolate" delimiter. + * @param options.sourceURL The sourceURL of the template's compiled source. + * @param options.variable The data object variable name. + * @return Returns the compiled template function. + */ + template(string?: string, options?: TemplateOptions): TemplateExecutor; + } + interface LoDashImplicitWrapper { + /** + * @see _.template + */ + template(options?: TemplateOptions): TemplateExecutor; + } + interface LoDashExplicitWrapper { + /** + * @see _.template + */ + template(options?: TemplateOptions): FunctionChain; + } + + interface LoDashStatic { + /** + * Converts `string`, as a whole, to lower case. + * + * @param string The string to convert. + * @return Returns the lower cased string. + */ + toLower(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.toLower + */ + toLower(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.toLower + */ + toLower(): StringChain; + } + + interface LoDashStatic { + /** + * Converts `string`, as a whole, to upper case. + * + * @param string The string to convert. + * @return Returns the upper cased string. + */ + toUpper(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.toUpper + */ + toUpper(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.toUpper + */ + toUpper(): StringChain; + } + + interface LoDashStatic { + /** + * Removes leading and trailing whitespace or specified characters from string. + * + * @param string The string to trim. + * @param chars The characters to trim. + * @return Returns the trimmed string. + */ + trim(string?: string, chars?: string): string; + /** + * @see _.trim + */ + trim(string: string, index: string | number, guard: object): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.trim + */ + trim(chars?: string): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.trim + */ + trim(chars?: string): StringChain; + } + + interface LoDashStatic { + /** + * Removes trailing whitespace or specified characters from string. + * + * @param string The string to trim. + * @param chars The characters to trim. + * @return Returns the trimmed string. + */ + trimEnd(string?: string, chars?: string): string; + /** + * @see _.trimEnd + */ + trimEnd(string: string, index: string | number, guard: object): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.trimEnd + */ + trimEnd(chars?: string): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.trimEnd + */ + trimEnd(chars?: string): StringChain; + } + + interface LoDashStatic { + /** + * Removes leading whitespace or specified characters from string. + * + * @param string The string to trim. + * @param chars The characters to trim. + * @return Returns the trimmed string. + */ + trimStart(string?: string, chars?: string): string; + /** + * @see _.trimStart + */ + trimStart(string: string, index: string | number, guard: object): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.trimStart + */ + trimStart(chars?: string): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.trimStart + */ + trimStart(chars?: string): StringChain; + } + + interface TruncateOptions { + /** + * @see _.length + */ + length?: number | undefined; + /** + * @see _.omission + */ + omission?: string | undefined; + /** + * @see _.separator + */ + separator?: string | RegExp | undefined; + } + interface LoDashStatic { + /** + * Truncates string if it’s longer than the given maximum string length. The last characters of the truncated + * string are replaced with the omission string which defaults to "…". + * + * @param string The string to truncate. + * @param options The options object or maximum string length. + * @return Returns the truncated string. + */ + truncate(string?: string, options?: TruncateOptions): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.truncate + */ + truncate(options?: TruncateOptions): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.truncate + */ + truncate(options?: TruncateOptions): StringChain; + } + + interface LoDashStatic { + /** + * The inverse of _.escape; this method converts the HTML entities &, <, >, ", ', and ` + * in string to their corresponding characters. + * + * Note: No other HTML entities are unescaped. To unescape additional HTML entities use a third-party library + * like he. + * + * @param string The string to unescape. + * @return Returns the unescaped string. + */ + unescape(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.unescape + */ + unescape(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.unescape + */ + unescape(): StringChain; + } + + interface LoDashStatic { + /** + * Converts `string`, as space separated words, to upper case. + * + * @param string The string to convert. + * @return Returns the upper cased string. + */ + upperCase(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.upperCase + */ + upperCase(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.upperCase + */ + upperCase(): StringChain; + } + + interface LoDashStatic { + /** + * Converts the first character of `string` to upper case. + * + * @param string The string to convert. + * @return Returns the converted string. + */ + upperFirst(string?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.upperFirst + */ + upperFirst(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.upperFirst + */ + upperFirst(): StringChain; + } + + interface LoDashStatic { + /** + * Splits `string` into an array of its words. + * + * @param string The string to inspect. + * @param pattern The pattern to match words. + * @return Returns the words of `string`. + */ + words(string?: string, pattern?: string | RegExp): string[]; + /** + * @see _.words + */ + words(string: string, index: string | number, guard: object): string[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.words + */ + words(pattern?: string | RegExp): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.words + */ + words(pattern?: string | RegExp): CollectionChain; + } +} diff --git a/libs/events/node_modules/@types/lodash/common/util.d.ts b/libs/events/node_modules/@types/lodash/common/util.d.ts new file mode 100755 index 000000000..caf2467fb --- /dev/null +++ b/libs/events/node_modules/@types/lodash/common/util.d.ts @@ -0,0 +1,1220 @@ +import _ = require("../index"); +declare module "../index" { + interface LoDashStatic { + /** + * Attempts to invoke func, returning either the result or the caught error object. Any additional arguments + * are provided to func when it’s invoked. + * + * @param func The function to attempt. + * @return Returns the func result or error object. + */ + attempt(func: (...args: any[]) => TResult, ...args: any[]): TResult | Error; + } + interface LoDashImplicitWrapper { + /** + * @see _.attempt + */ + attempt(...args: any[]): TResult | Error; + } + interface LoDashExplicitWrapper { + /** + * @see _.attempt + */ + attempt(...args: any[]): ExpChain; + } + + interface LoDashStatic { + /** + * Binds methods of an object to the object itself, overwriting the existing method. Method names may be + * specified as individual arguments or as arrays of method names. If no method names are provided all + * enumerable function properties, own and inherited, of object are bound. + * + * Note: This method does not set the "length" property of bound functions. + * + * @param object The object to bind and assign the bound methods to. + * @param methodNames The object method names to bind, specified as individual method names or arrays of + * method names. + * @return Returns object. + */ + bindAll(object: T, ...methodNames: Array>): T; + } + interface LoDashImplicitWrapper { + /** + * @see _.bindAll + */ + bindAll(...methodNames: Array>): this; + } + interface LoDashExplicitWrapper { + /** + * @see _.bindAll + */ + bindAll(...methodNames: Array>): this; + } + + interface LoDashStatic { + /** + * Creates a function that iterates over `pairs` and invokes the corresponding + * function of the first predicate to return truthy. The predicate-function + * pairs are invoked with the `this` binding and arguments of the created + * function. + * + * @since 4.0.0 + * @category Util + * @param pairs The predicate-function pairs. + * @returns Returns the new composite function. + * @example + * + * var func = _.cond([ + * [_.matches({ 'a': 1 }), _.constant('matches A')], + * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')], + * [_.stubTrue, _.constant('no match')] + * ]); + * + * func({ 'a': 1, 'b': 2 }); + * // => 'matches A' + * + * func({ 'a': 0, 'b': 1 }); + * // => 'matches B' + * + * func({ 'a': '1', 'b': '2' }); + * // => 'no match' + */ + cond(pairs: Array>): () => R; + cond(pairs: Array>): (Target: T) => R; + } + + type ConformsPredicateObject = { + [P in keyof T]: T[P] extends (arg: infer A) => any ? A : any + }; + interface LoDashStatic { + /** + * Creates a function that invokes the predicate properties of `source` with the corresponding + * property values of a given object, returning true if all predicates return truthy, else false. + */ + conforms(source: ConformsPredicateObject): (value: T) => boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.conforms + */ + conforms(): Function<(value: ConformsPredicateObject) => boolean>; + } + interface LoDashExplicitWrapper { + /** + * @see _.conforms + */ + conforms(): FunctionChain<(value: ConformsPredicateObject) => boolean>; + } + + interface LoDashStatic { + /** + * Creates a function that returns value. + * + * @param value The value to return from the new function. + * @return Returns the new function. + */ + constant(value: T): () => T; + } + interface LoDashImplicitWrapper { + /** + * @see _.constant + */ + constant(): Function<() => TValue>; + } + interface LoDashExplicitWrapper { + /** + * @see _.constant + */ + constant(): FunctionChain<() => TValue>; + } + + interface LoDashStatic { + /** + * Checks `value` to determine whether a default value should be returned in + * its place. The `defaultValue` is returned if `value` is `NaN`, `null`, + * or `undefined`. + * + * @param value The value to check. + * @param defaultValue The default value. + * @returns Returns the resolved value. + */ + defaultTo(value: T | null | undefined, defaultValue: T): T; + /** + * @see _.defaultTo + */ + defaultTo(value: T | null | undefined, defaultValue: TDefault): T | TDefault; + } + interface LoDashImplicitWrapper { + /** + * @see _.defaultTo + */ + defaultTo(defaultValue: TValue): TValue; + /** + * @see _.defaultTo + */ + defaultTo(defaultValue: TDefault): TValue extends null | undefined ? TDefault : TValue | TDefault; + } + interface LoDashExplicitWrapper { + /** + * @see _.defaultTo + */ + defaultTo(defaultValue: TValue): ExpChain; + /** + * @see _.defaultTo + */ + defaultTo(defaultValue: TDefault): ExpChain; + } + + interface LoDashStatic { + /** + * Creates a function that returns the result of invoking the provided functions with the this binding of the + * created function, where each successive invocation is supplied the return value of the previous. + * + * @param funcs Functions to invoke. + * @return Returns the new function. + */ + flow(f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6, f7: (a: R6) => R7): (...args: A) => R7; + /** + * @see _.flow + */ + flow(f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6, f7: (a: R6) => R7, ...func: Array any>>): (...args: A) => any; + /** + * @see _.flow + */ + flow(f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6): (...args: A) => R6; + /** + * @see _.flow + */ + flow(f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5): (...args: A) => R5; + /** + * @see _.flow + */ + flow(f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4): (...args: A) => R4; + /** + * @see _.flow + */ + flow(f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3): (...args: A) => R3; + /** + * @see _.flow + */ + flow(f1: (...args: A) => R1, f2: (a: R1) => R2): (...args: A) => R2; + /** + * @see _.flow + */ + flow(...func: Array any>>): (...args: any[]) => any; + } + interface Function any> { + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6, f7: (a: R6) => R7): Function<(...args: Parameters) => R7>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6, f7: (a: R6) => R7, ...func: Array any>>): Function<(...args: Parameters) => any>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6): Function<(...args: Parameters) => R6>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5): Function<(...args: Parameters) => R5>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4): Function<(...args: Parameters) => R4>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3): Function<(...args: Parameters) => R3>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2): Function<(...args: Parameters) => R2>; + /** + * @see _.flow + */ + flow(...func: Array any>>): Function<(...args: any[]) => any>; + } + interface FunctionChain { + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6, f7: (a: R6) => R7): FunctionChain<(...args: Parameters) => R7>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6, f7: (a: R6) => R7, ...func: Array any>>): FunctionChain<(...args: Parameters) => any>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6): FunctionChain<(...args: Parameters) => R6>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5): FunctionChain<(...args: Parameters) => R5>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4): FunctionChain<(...args: Parameters) => R4>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2, f3: (a: R2) => R3): FunctionChain<(...args: Parameters) => R3>; + /** + * @see _.flow + */ + flow(f2: (a: ReturnType) => R2): FunctionChain<(...args: Parameters) => R2>; + /** + * @see _.flow + */ + flow(...func: Array any>>): FunctionChain<(...args: any[]) => any>; + } + + interface LoDashStatic { + /** + * This method is like _.flow except that it creates a function that invokes the provided functions from right + * to left. + * + * @param funcs Functions to invoke. + * @return Returns the new function. + */ + flowRight(f7: (a: R6) => R7, f6: (a: R5) => R6, f5: (a: R4) => R5, f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R7; + /** + * @see _.flowRight + */ + flowRight(f6: (a: R5) => R6, f5: (a: R4) => R5, f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R6; + /** + * @see _.flowRight + */ + flowRight(f5: (a: R4) => R5, f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R5; + /** + * @see _.flowRight + */ + flowRight(f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R4; + /** + * @see _.flowRight + */ + flowRight(f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R3; + /** + * @see _.flowRight + */ + flowRight(f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R2; + /** + * @see _.flowRight + */ + flowRight(...func: Array any>>): (...args: any[]) => any; + } + interface Function { + /** + * @see _.flowRight + */ + flowRight(f6: (a: R5) => Parameters["0"], f5: (a: R4) => R5, f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): Function<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f5: (a: R4) => Parameters["0"], f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): Function<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f4: (a: R3) => Parameters["0"], f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): Function<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f3: (a: R2) => Parameters["0"], f2: (a: R1) => R2, f1: (...args: A) => R1): Function<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f2: (a: R1) => Parameters["0"], f1: (...args: A) => R1): Function<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f1: (...args: A) => Parameters["0"]): Function<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(...func: Array any>>): Function<(...args: any[]) => any>; + } + interface FunctionChain { + /** + * @see _.flowRight + */ + flowRight(f6: (a: R5) => Parameters["0"], f5: (a: R4) => R5, f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): FunctionChain<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f5: (a: R4) => Parameters["0"], f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): FunctionChain<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f4: (a: R3) => Parameters["0"], f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): FunctionChain<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f3: (a: R2) => Parameters["0"], f2: (a: R1) => R2, f1: (...args: A) => R1): FunctionChain<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f2: (a: R1) => Parameters["0"], f1: (...args: A) => R1): FunctionChain<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(f1: (...args: A) => Parameters["0"]): FunctionChain<(...args: A) => ReturnType>; + /** + * @see _.flowRight + */ + flowRight(...func: Array any>>): FunctionChain<(...args: any[]) => any>; + } + + interface LoDashStatic { + /** + * This method returns the first argument provided to it. + * + * @param value Any value. + * @return Returns value. + */ + identity(value: T): T; + /** + * @see _.identity + */ + identity(): undefined; + } + interface LoDashImplicitWrapper { + /** + * @see _.identity + */ + identity(): TValue; + } + interface LoDashExplicitWrapper { + /** + * @see _.identity + */ + identity(): this; + } + + interface LoDashStatic { + /** + * Creates a function that invokes `func` with the arguments of the created + * function. If `func` is a property name the created callback returns the + * property value for a given element. If `func` is an object the created + * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`. + * + * @category Util + * @param [func=_.identity] The value to convert to a callback. + * @returns Returns the callback. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // create custom iteratee shorthands + * _.iteratee = _.wrap(_.iteratee, function(callback, func) { + * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func); + * return !p ? callback(func) : function(object) { + * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]); + * }; + * }); + * + * _.filter(users, 'age > 36'); + * // => [{ 'user': 'fred', 'age': 40 }] + */ + iteratee any>(func: TFunction): TFunction; + /** + * @see _.iteratee + */ + iteratee(func: symbol | number | string | object): (...args: any[]) => any; + } + interface Function any> { + /** + * @see _.iteratee + */ + iteratee(): Function; + } + interface Collection { + /** + * @see _.iteratee + */ + iteratee(): Function<(o: object) => boolean>; + } + interface Object { + /** + * @see _.iteratee + */ + iteratee(): Function<(o: T) => boolean>; + } + interface String { + /** + * @see _.iteratee + */ + iteratee(): Function<(o: object) => any>; + } + interface FunctionChain any> { + /** + * @see _.iteratee + */ + iteratee(): FunctionChain; + } + interface CollectionChain { + /** + * @see _.iteratee + */ + iteratee(): FunctionChain<(o: object) => boolean>; + } + interface ObjectChain { + /** + * @see _.iteratee + */ + iteratee(): FunctionChain<(o: T) => boolean>; + } + interface StringChain { + /** + * @see _.iteratee + */ + iteratee(): FunctionChain<(o: object) => any>; + } + interface StringNullableChain { + /** + * @see _.iteratee + */ + iteratee(): FunctionChain<(o: object) => any>; + } + + interface LoDashStatic { + /** + * Creates a function that performs a deep comparison between a given object and source, returning true if the + * given object has equivalent property values, else false. + * + * Note: This method supports comparing arrays, booleans, Date objects, numbers, Object objects, regexes, and + * strings. Objects are compared by their own, not inherited, enumerable properties. For comparing a single own + * or inherited property value see _.matchesProperty. + * + * @param source The object of property values to match. + * @return Returns the new function. + */ + matches(source: T): (value: any) => boolean; + /** + * @see _.matches + */ + matches(source: T): (value: V) => boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.matches + */ + matches(): Function<(value: V) => boolean>; + } + interface LoDashExplicitWrapper { + /** + * @see _.matches + */ + matches(): FunctionChain<(value: V) => boolean>; + } + + interface LoDashStatic { + /** + * Creates a function that compares the property value of path on a given object to value. + * + * Note: This method supports comparing arrays, booleans, Date objects, numbers, Object objects, regexes, and + * strings. Objects are compared by their own, not inherited, enumerable properties. + * + * @param path The path of the property to get. + * @param srcValue The value to match. + * @return Returns the new function. + */ + matchesProperty(path: PropertyPath, srcValue: T): (value: any) => boolean; + /** + * @see _.matchesProperty + */ + matchesProperty(path: PropertyPath, srcValue: T): (value: V) => boolean; + } + interface LoDashImplicitWrapper { + /** + * @see _.matchesProperty + */ + matchesProperty(srcValue: SrcValue): Function<(value: any) => boolean>; + /** + * @see _.matchesProperty + */ + matchesProperty(srcValue: SrcValue): Function<(value: Value) => boolean>; + } + interface LoDashExplicitWrapper { + /** + * @see _.matchesProperty + */ + matchesProperty(srcValue: SrcValue): FunctionChain<(value: any) => boolean>; + /** + * @see _.matchesProperty + */ + matchesProperty(srcValue: SrcValue): FunctionChain<(value: Value) => boolean>; + } + + interface LoDashStatic { + /** + * Creates a function that invokes the method at path on a given object. Any additional arguments are provided + * to the invoked method. + * + * @param path The path of the method to invoke. + * @param args The arguments to invoke the method with. + * @return Returns the new function. + */ + method(path: PropertyPath, ...args: any[]): (object: any) => any; + } + interface LoDashImplicitWrapper { + /** + * @see _.method + */ + method(...args: any[]): Function<(object: any) => any>; + } + interface LoDashExplicitWrapper { + /** + * @see _.method + */ + method(...args: any[]): FunctionChain<(object: any) => any>; + } + + interface LoDashStatic { + /** + * The opposite of _.method; this method creates a function that invokes the method at a given path on object. + * Any additional arguments are provided to the invoked method. + * + * @param object The object to query. + * @param args The arguments to invoke the method with. + * @return Returns the new function. + */ + methodOf(object: object, ...args: any[]): (path: PropertyPath) => any; + } + interface LoDashImplicitWrapper { + /** + * @see _.methodOf + */ + methodOf(...args: any[]): LoDashImplicitWrapper<(path: PropertyPath) => any>; + } + interface LoDashExplicitWrapper { + /** + * @see _.methodOf + */ + methodOf(...args: any[]): LoDashExplicitWrapper<(path: PropertyPath) => any>; + } + + interface MixinOptions { + /** + * @see _.chain + */ + chain?: boolean | undefined; + } + interface LoDashStatic { + /** + * Adds all own enumerable function properties of a source object to the destination object. If object is a + * function then methods are added to its prototype as well. + * + * Note: Use _.runInContext to create a pristine lodash function to avoid conflicts caused by modifying + * the original. + * + * @param object The destination object. + * @param source The object of functions to add. + * @param options The options object. + * @param options.chain Specify whether the functions added are chainable. + * @return Returns object. + */ + mixin(object: TObject, source: Dictionary<(...args: any[]) => any>, options?: MixinOptions): TObject; + /** + * @see _.mixin + */ + mixin(source: Dictionary<(...args: any[]) => any>, options?: MixinOptions): LoDashStatic; + } + interface LoDashImplicitWrapper { + /** + * @see _.mixin + */ + mixin(source: Dictionary<(...args: any[]) => any>, options?: MixinOptions): this; + /** + * @see _.mixin + */ + mixin(options?: MixinOptions): LoDashImplicitWrapper; + } + interface LoDashExplicitWrapper { + /** + * @see _.mixin + */ + mixin(source: Dictionary<(...args: any[]) => any>, options?: MixinOptions): this; + /** + * @see _.mixin + */ + mixin(options?: MixinOptions): LoDashExplicitWrapper; + } + + interface LoDashStatic { + /** + * Reverts the _ variable to its previous value and returns a reference to the lodash function. + * + * @return Returns the lodash function. + */ + noConflict(): typeof _; + } + interface LoDashImplicitWrapper { + /** + * @see _.noConflict + */ + noConflict(): typeof _; + } + interface LoDashExplicitWrapper { + /** + * @see _.noConflict + */ + noConflict(): LoDashExplicitWrapper; + } + + interface LoDashStatic { + /** + * A no-operation function that returns undefined regardless of the arguments it receives. + * + * @return undefined + */ + noop(...args: any[]): void; + } + interface LoDashImplicitWrapper { + /** + * @see _.noop + */ + noop(...args: any[]): void; + } + interface LoDashExplicitWrapper { + /** + * @see _.noop + */ + noop(...args: any[]): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Creates a function that returns its nth argument. + * + * @param n The index of the argument to return. + * @return Returns the new function. + */ + nthArg(n?: number): (...args: any[]) => any; + } + interface LoDashImplicitWrapper { + /** + * @see _.nthArg + */ + nthArg(): Function<(...args: any[]) => any>; + } + interface LoDashExplicitWrapper { + /** + * @see _.nthArg + */ + nthArg(): FunctionChain<(...args: any[]) => any>; + } + + interface LoDashStatic { + /** + * Creates a function that invokes iteratees with the arguments provided to the created function and returns + * their results. + * + * @param iteratees The iteratees to invoke. + * @return Returns the new function. + */ + over(...iteratees: Array TResult>>): (...args: any[]) => TResult[]; + } + interface Collection { + /** + * @see _.over + */ + over(...iteratees: Array TResult>>): Function<(...args: any[]) => TResult[]>; + } + interface Function { + /** + * @see _.over + */ + over(...iteratees: Array TResult>>): Function<(...args: any[]) => Array | TResult>>; + } + interface CollectionChain { + /** + * @see _.over + */ + over(...iteratees: Array TResult>>): FunctionChain<(...args: any[]) => TResult[]>; + } + interface FunctionChain { + /** + * @see _.over + */ + over(...iteratees: Array TResult>>): FunctionChain<(...args: any[]) => Array | TResult>>; + } + + interface LoDashStatic { + /** + * Creates a function that checks if all of the predicates return truthy when invoked with the arguments + * provided to the created function. + * + * @param predicates The predicates to check. + * @return Returns the new function. + */ + overEvery(...predicates: [ + (arg: T) => arg is Result1, + (arg: T) => arg is Result2 + ]): (arg: T) => arg is Result1 & Result2; + overEvery(...predicates: Array boolean>>): (...args: T[]) => boolean; + } + interface Collection { + /** + * @see _.overEvery + */ + overEvery(...iteratees: Array boolean>>): Function<(...args: TArgs[]) => boolean>; + } + interface Function { + /** + * @see _.overEvery + */ + overEvery(...iteratees: Array boolean>>): Function<(...args: Parameters | TArgs[]) => boolean>; + } + interface CollectionChain { + /** + * @see _.overEvery + */ + overEvery(...iteratees: Array boolean>>): FunctionChain<(...args: TArgs[]) => boolean>; + } + interface FunctionChain { + /** + * @see _.overEvery + */ + overEvery(...iteratees: Array boolean>>): FunctionChain<(...args: Parameters | TArgs[]) => boolean>; + } + + interface LoDashStatic { + /** + * Creates a function that checks if any of the predicates return truthy when invoked with the arguments + * provided to the created function. + * + * @param predicates The predicates to check. + * @return Returns the new function. + */ + overSome(...predicates: [ + (arg: T) => arg is Result1, + (arg: T) => arg is Result2 + ]): (arg: T) => arg is Result1 | Result2; + overSome(...predicates: Array boolean>>): (...args: T[]) => boolean; + } + interface Collection { + /** + * @see _.overSome + */ + overSome(...iteratees: Array boolean>>): Function<(...args: TArgs[]) => boolean>; + } + interface Function { + /** + * @see _.overSome + */ + overSome(...iteratees: Array boolean>>): Function<(...args: Parameters | TArgs[]) => boolean>; + } + interface CollectionChain { + /** + * @see _.overSome + */ + overSome(...iteratees: Array boolean>>): FunctionChain<(...args: TArgs[]) => boolean>; + } + interface FunctionChain { + /** + * @see _.overSome + */ + overSome(...iteratees: Array boolean>>): FunctionChain<(...args: Parameters | TArgs[]) => boolean>; + } + + interface LoDashStatic { + /** + * Creates a function that returns the property value at path on a given object. + * + * @param path The path of the property to get. + * @return Returns the new function. + */ + property(path: PropertyPath): (obj: TObj) => TResult; + } + interface LoDashImplicitWrapper { + /** + * @see _.property + */ + property(): Function<(obj: TObj) => TResult>; + } + interface LoDashExplicitWrapper { + /** + * @see _.property + */ + property(): FunctionChain<(obj: TObj) => TResult>; + } + + interface LoDashStatic { + /** + * The opposite of _.property; this method creates a function that returns the property value at a given path + * on object. + * + * @param object The object to query. + * @return Returns the new function. + */ + propertyOf(object: T): (path: PropertyPath) => any; + } + interface LoDashImplicitWrapper { + /** + * @see _.propertyOf + */ + propertyOf(): LoDashImplicitWrapper<(path: PropertyPath) => any>; + } + interface LoDashExplicitWrapper { + /** + * @see _.propertyOf + */ + propertyOf(): LoDashExplicitWrapper<(path: PropertyPath) => any>; + } + + interface LoDashStatic { + /** + * Creates an array of numbers (positive and/or negative) progressing from start up to, but not including, end. + * If end is not specified it’s set to start with start then set to 0. If end is less than start a zero-length + * range is created unless a negative step is specified. + * + * @param start The start of the range. + * @param end The end of the range. + * @param step The value to increment or decrement by. + * @return Returns a new range array. + */ + range(start: number, end?: number, step?: number): number[]; + /** + * @see _.range + */ + range(end: number, index: string | number, guard: object): number[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.range + */ + range(end?: number, step?: number): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.range + */ + range(end?: number, step?: number): CollectionChain; + } + + interface LoDashStatic { + /** + * This method is like `_.range` except that it populates values in + * descending order. + * + * @category Util + * @param start The start of the range. + * @param end The end of the range. + * @param step The value to increment or decrement by. + * @returns Returns the new array of numbers. + * @example + * + * _.rangeRight(4); + * // => [3, 2, 1, 0] + * + * _.rangeRight(-4); + * // => [-3, -2, -1, 0] + * + * _.rangeRight(1, 5); + * // => [4, 3, 2, 1] + * + * _.rangeRight(0, 20, 5); + * // => [15, 10, 5, 0] + * + * _.rangeRight(0, -4, -1); + * // => [-3, -2, -1, 0] + * + * _.rangeRight(1, 4, 0); + * // => [1, 1, 1] + * + * _.rangeRight(0); + * // => [] + */ + rangeRight(start: number, end?: number, step?: number): number[]; + /** + * @see _.rangeRight + */ + rangeRight(end: number, index: string | number, guard: object): number[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.rangeRight + */ + rangeRight(end?: number, step?: number): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.rangeRight + */ + rangeRight(end?: number, step?: number): CollectionChain; + } + + interface LoDashStatic { + /** + * Create a new pristine lodash function using the given context object. + * + * @param context The context object. + * @return Returns a new lodash function. + */ + runInContext(context?: object): LoDashStatic; + } + interface LoDashImplicitWrapper { + /** + * @see _.runInContext + */ + runInContext(): LoDashStatic; + } + + interface LoDashStatic { + /** + * This method returns a new empty array. + * + * @returns Returns the new empty array. + */ + stubArray(): any[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.stubArray + */ + stubArray(): any[]; + } + interface LoDashExplicitWrapper { + /** + * @see _.stubArray + */ + stubArray(): CollectionChain; + } + + interface LoDashStatic { + /** + * This method returns `false`. + * + * @returns Returns `false`. + */ + stubFalse(): false; + } + interface LoDashImplicitWrapper { + /** + * @see _.stubFalse + */ + stubFalse(): false; + } + interface LoDashExplicitWrapper { + /** + * @see _.stubFalse + */ + stubFalse(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * This method returns a new empty object. + * + * @returns Returns the new empty object. + */ + stubObject(): any; + } + interface LoDashImplicitWrapper { + /** + * @see _.stubObject + */ + stubObject(): any; + } + interface LoDashExplicitWrapper { + /** + * @see _.stubObject + */ + stubObject(): LoDashExplicitWrapper; + } + + interface LoDashStatic { + /** + * This method returns an empty string. + * + * @returns Returns the empty string. + */ + stubString(): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.stubString + */ + stubString(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.stubString + */ + stubString(): StringChain; + } + + interface LoDashStatic { + /** + * This method returns `true`. + * + * @returns Returns `true`. + */ + stubTrue(): true; + } + interface LoDashImplicitWrapper { + /** + * @see _.stubTrue + */ + stubTrue(): true; + } + interface LoDashExplicitWrapper { + /** + * @see _.stubTrue + */ + stubTrue(): PrimitiveChain; + } + + interface LoDashStatic { + /** + * Invokes the iteratee function n times, returning an array of the results of each invocation. The iteratee + * is invoked with one argument; (index). + * + * @param n The number of times to invoke iteratee. + * @param iteratee The function invoked per iteration. + * @return Returns the array of results. + */ + times(n: number, iteratee: (num: number) => TResult): TResult[]; + /** + * @see _.times + */ + times(n: number): number[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.times + */ + times(iteratee: (num: number) => TResult): TResult[]; + /** + * @see _.times + */ + times(): number[]; + } + interface LoDashExplicitWrapper { + /** + * @see _.times + */ + times(iteratee: (num: number) => TResult): CollectionChain; + /** + * @see _.times + */ + times(): CollectionChain; + } + + interface LoDashStatic { + /** + * Converts `value` to a property path array. + * + * @category Util + * @param value The value to convert. + * @returns Returns the new property path array. + * @example + * + * _.toPath('a.b.c'); + * // => ['a', 'b', 'c'] + * + * _.toPath('a[0].b.c'); + * // => ['a', '0', 'b', 'c'] + * + * var path = ['a', 'b', 'c'], + * newPath = _.toPath(path); + * + * console.log(newPath); + * // => ['a', 'b', 'c'] + * + * console.log(path === newPath); + * // => false + */ + toPath(value: any): string[]; + } + interface LoDashImplicitWrapper { + /** + * @see _.toPath + */ + toPath(): Collection; + } + interface LoDashExplicitWrapper { + /** + * @see _.toPath + */ + toPath(): CollectionChain; + } + + interface LoDashStatic { + /** + * Generates a unique ID. If prefix is provided the ID is appended to it. + * + * @param prefix The value to prefix the ID with. + * @return Returns the unique ID. + */ + uniqueId(prefix?: string): string; + } + interface LoDashImplicitWrapper { + /** + * @see _.uniqueId + */ + uniqueId(): string; + } + interface LoDashExplicitWrapper { + /** + * @see _.uniqueId + */ + uniqueId(): StringChain; + } + + // stubTrue + + interface LoDashStatic { + /** + * This method returns true. + * + * @return Returns true. + */ + stubTrue(): true; + } + + interface LoDashImplicitWrapper { + /** + * @see _.stubTrue + */ + stubTrue(): true; + } + + interface LoDashExplicitWrapper { + /** + * @see _.stubTrue + */ + stubTrue(): LoDashExplicitWrapper; + } + + // stubFalse + + interface LoDashStatic { + /** + * This method returns false. + * + * @return Returns false. + */ + stubFalse(): false; + } + + interface LoDashImplicitWrapper { + /** + * @see _.stubFalse + */ + stubFalse(): false; + } + + interface LoDashExplicitWrapper { + /** + * @see _.stubFalse + */ + stubFalse(): LoDashExplicitWrapper; + } +} diff --git a/libs/events/node_modules/@types/lodash/compact.d.ts b/libs/events/node_modules/@types/lodash/compact.d.ts new file mode 100755 index 000000000..94a539778 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/compact.d.ts @@ -0,0 +1,2 @@ +import { compact } from "./index"; +export = compact; diff --git a/libs/events/node_modules/@types/lodash/concat.d.ts b/libs/events/node_modules/@types/lodash/concat.d.ts new file mode 100755 index 000000000..f8c26122c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/concat.d.ts @@ -0,0 +1,2 @@ +import { concat } from "./index"; +export = concat; diff --git a/libs/events/node_modules/@types/lodash/cond.d.ts b/libs/events/node_modules/@types/lodash/cond.d.ts new file mode 100755 index 000000000..a325bad4b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/cond.d.ts @@ -0,0 +1,2 @@ +import { cond } from "./index"; +export = cond; diff --git a/libs/events/node_modules/@types/lodash/conformsTo.d.ts b/libs/events/node_modules/@types/lodash/conformsTo.d.ts new file mode 100755 index 000000000..320b1806e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/conformsTo.d.ts @@ -0,0 +1,2 @@ +import { conformsTo } from "./index"; +export = conformsTo; diff --git a/libs/events/node_modules/@types/lodash/constant.d.ts b/libs/events/node_modules/@types/lodash/constant.d.ts new file mode 100755 index 000000000..ebab572c1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/constant.d.ts @@ -0,0 +1,2 @@ +import { constant } from "./index"; +export = constant; diff --git a/libs/events/node_modules/@types/lodash/countBy.d.ts b/libs/events/node_modules/@types/lodash/countBy.d.ts new file mode 100755 index 000000000..db56ff3c1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/countBy.d.ts @@ -0,0 +1,2 @@ +import { countBy } from "./index"; +export = countBy; diff --git a/libs/events/node_modules/@types/lodash/create.d.ts b/libs/events/node_modules/@types/lodash/create.d.ts new file mode 100755 index 000000000..5c7dc7a21 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/create.d.ts @@ -0,0 +1,2 @@ +import { create } from "./index"; +export = create; diff --git a/libs/events/node_modules/@types/lodash/curry.d.ts b/libs/events/node_modules/@types/lodash/curry.d.ts new file mode 100755 index 000000000..afbb8f47d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/curry.d.ts @@ -0,0 +1,2 @@ +import { curry } from "./index"; +export = curry; diff --git a/libs/events/node_modules/@types/lodash/curryRight.d.ts b/libs/events/node_modules/@types/lodash/curryRight.d.ts new file mode 100755 index 000000000..7d224c972 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/curryRight.d.ts @@ -0,0 +1,2 @@ +import { curryRight } from "./index"; +export = curryRight; diff --git a/libs/events/node_modules/@types/lodash/debounce.d.ts b/libs/events/node_modules/@types/lodash/debounce.d.ts new file mode 100755 index 000000000..983edd74c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/debounce.d.ts @@ -0,0 +1,2 @@ +import { debounce } from "./index"; +export = debounce; diff --git a/libs/events/node_modules/@types/lodash/deburr.d.ts b/libs/events/node_modules/@types/lodash/deburr.d.ts new file mode 100755 index 000000000..cf1fa376f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/deburr.d.ts @@ -0,0 +1,2 @@ +import { deburr } from "./index"; +export = deburr; diff --git a/libs/events/node_modules/@types/lodash/defaultTo.d.ts b/libs/events/node_modules/@types/lodash/defaultTo.d.ts new file mode 100755 index 000000000..89fb56505 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/defaultTo.d.ts @@ -0,0 +1,2 @@ +import { defaultTo } from "./index"; +export = defaultTo; diff --git a/libs/events/node_modules/@types/lodash/defaults.d.ts b/libs/events/node_modules/@types/lodash/defaults.d.ts new file mode 100755 index 000000000..e83508d12 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/defaults.d.ts @@ -0,0 +1,2 @@ +import { defaults } from "./index"; +export = defaults; diff --git a/libs/events/node_modules/@types/lodash/defaultsDeep.d.ts b/libs/events/node_modules/@types/lodash/defaultsDeep.d.ts new file mode 100755 index 000000000..19ff55129 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/defaultsDeep.d.ts @@ -0,0 +1,2 @@ +import { defaultsDeep } from "./index"; +export = defaultsDeep; diff --git a/libs/events/node_modules/@types/lodash/defer.d.ts b/libs/events/node_modules/@types/lodash/defer.d.ts new file mode 100755 index 000000000..144bf5b01 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/defer.d.ts @@ -0,0 +1,2 @@ +import { defer } from "./index"; +export = defer; diff --git a/libs/events/node_modules/@types/lodash/delay.d.ts b/libs/events/node_modules/@types/lodash/delay.d.ts new file mode 100755 index 000000000..ead89c100 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/delay.d.ts @@ -0,0 +1,2 @@ +import { delay } from "./index"; +export = delay; diff --git a/libs/events/node_modules/@types/lodash/difference.d.ts b/libs/events/node_modules/@types/lodash/difference.d.ts new file mode 100755 index 000000000..4a73c5659 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/difference.d.ts @@ -0,0 +1,2 @@ +import { difference } from "./index"; +export = difference; diff --git a/libs/events/node_modules/@types/lodash/differenceBy.d.ts b/libs/events/node_modules/@types/lodash/differenceBy.d.ts new file mode 100755 index 000000000..34558c4ef --- /dev/null +++ b/libs/events/node_modules/@types/lodash/differenceBy.d.ts @@ -0,0 +1,2 @@ +import { differenceBy } from "./index"; +export = differenceBy; diff --git a/libs/events/node_modules/@types/lodash/differenceWith.d.ts b/libs/events/node_modules/@types/lodash/differenceWith.d.ts new file mode 100755 index 000000000..86aebd889 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/differenceWith.d.ts @@ -0,0 +1,2 @@ +import { differenceWith } from "./index"; +export = differenceWith; diff --git a/libs/events/node_modules/@types/lodash/divide.d.ts b/libs/events/node_modules/@types/lodash/divide.d.ts new file mode 100755 index 000000000..3d8e39316 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/divide.d.ts @@ -0,0 +1,2 @@ +import { divide } from "./index"; +export = divide; diff --git a/libs/events/node_modules/@types/lodash/drop.d.ts b/libs/events/node_modules/@types/lodash/drop.d.ts new file mode 100755 index 000000000..1283f99a5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/drop.d.ts @@ -0,0 +1,2 @@ +import { drop } from "./index"; +export = drop; diff --git a/libs/events/node_modules/@types/lodash/dropRight.d.ts b/libs/events/node_modules/@types/lodash/dropRight.d.ts new file mode 100755 index 000000000..4133c9850 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/dropRight.d.ts @@ -0,0 +1,2 @@ +import { dropRight } from "./index"; +export = dropRight; diff --git a/libs/events/node_modules/@types/lodash/dropRightWhile.d.ts b/libs/events/node_modules/@types/lodash/dropRightWhile.d.ts new file mode 100755 index 000000000..0dda808d4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/dropRightWhile.d.ts @@ -0,0 +1,2 @@ +import { dropRightWhile } from "./index"; +export = dropRightWhile; diff --git a/libs/events/node_modules/@types/lodash/dropWhile.d.ts b/libs/events/node_modules/@types/lodash/dropWhile.d.ts new file mode 100755 index 000000000..894ebaa23 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/dropWhile.d.ts @@ -0,0 +1,2 @@ +import { dropWhile } from "./index"; +export = dropWhile; diff --git a/libs/events/node_modules/@types/lodash/each.d.ts b/libs/events/node_modules/@types/lodash/each.d.ts new file mode 100755 index 000000000..608f8a9b9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/each.d.ts @@ -0,0 +1,2 @@ +import { each } from "./index"; +export = each; diff --git a/libs/events/node_modules/@types/lodash/eachRight.d.ts b/libs/events/node_modules/@types/lodash/eachRight.d.ts new file mode 100755 index 000000000..ae0bb6f87 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/eachRight.d.ts @@ -0,0 +1,2 @@ +import { eachRight } from "./index"; +export = eachRight; diff --git a/libs/events/node_modules/@types/lodash/endsWith.d.ts b/libs/events/node_modules/@types/lodash/endsWith.d.ts new file mode 100755 index 000000000..d8475b13a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/endsWith.d.ts @@ -0,0 +1,2 @@ +import { endsWith } from "./index"; +export = endsWith; diff --git a/libs/events/node_modules/@types/lodash/entries.d.ts b/libs/events/node_modules/@types/lodash/entries.d.ts new file mode 100755 index 000000000..24b241751 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/entries.d.ts @@ -0,0 +1,2 @@ +import { entries } from "./index"; +export = entries; diff --git a/libs/events/node_modules/@types/lodash/entriesIn.d.ts b/libs/events/node_modules/@types/lodash/entriesIn.d.ts new file mode 100755 index 000000000..a68ab1e57 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/entriesIn.d.ts @@ -0,0 +1,2 @@ +import { entriesIn } from "./index"; +export = entriesIn; diff --git a/libs/events/node_modules/@types/lodash/eq.d.ts b/libs/events/node_modules/@types/lodash/eq.d.ts new file mode 100755 index 000000000..88ec88791 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/eq.d.ts @@ -0,0 +1,2 @@ +import { eq } from "./index"; +export = eq; diff --git a/libs/events/node_modules/@types/lodash/escape.d.ts b/libs/events/node_modules/@types/lodash/escape.d.ts new file mode 100755 index 000000000..9f628a3ba --- /dev/null +++ b/libs/events/node_modules/@types/lodash/escape.d.ts @@ -0,0 +1,2 @@ +import { escape } from "./index"; +export = escape; diff --git a/libs/events/node_modules/@types/lodash/escapeRegExp.d.ts b/libs/events/node_modules/@types/lodash/escapeRegExp.d.ts new file mode 100755 index 000000000..97519c10f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/escapeRegExp.d.ts @@ -0,0 +1,2 @@ +import { escapeRegExp } from "./index"; +export = escapeRegExp; diff --git a/libs/events/node_modules/@types/lodash/every.d.ts b/libs/events/node_modules/@types/lodash/every.d.ts new file mode 100755 index 000000000..d9717d4b1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/every.d.ts @@ -0,0 +1,2 @@ +import { every } from "./index"; +export = every; diff --git a/libs/events/node_modules/@types/lodash/extend.d.ts b/libs/events/node_modules/@types/lodash/extend.d.ts new file mode 100755 index 000000000..1b3107a00 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/extend.d.ts @@ -0,0 +1,2 @@ +import { extend } from "./index"; +export = extend; diff --git a/libs/events/node_modules/@types/lodash/extendWith.d.ts b/libs/events/node_modules/@types/lodash/extendWith.d.ts new file mode 100755 index 000000000..99ca5d04e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/extendWith.d.ts @@ -0,0 +1,2 @@ +import { extendWith } from "./index"; +export = extendWith; diff --git a/libs/events/node_modules/@types/lodash/fill.d.ts b/libs/events/node_modules/@types/lodash/fill.d.ts new file mode 100755 index 000000000..f595dfcd0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fill.d.ts @@ -0,0 +1,2 @@ +import { fill } from "./index"; +export = fill; diff --git a/libs/events/node_modules/@types/lodash/filter.d.ts b/libs/events/node_modules/@types/lodash/filter.d.ts new file mode 100755 index 000000000..a4496de6a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/filter.d.ts @@ -0,0 +1,2 @@ +import { filter } from "./index"; +export = filter; diff --git a/libs/events/node_modules/@types/lodash/find.d.ts b/libs/events/node_modules/@types/lodash/find.d.ts new file mode 100755 index 000000000..e8da4b4f5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/find.d.ts @@ -0,0 +1,2 @@ +import { find } from "./index"; +export = find; diff --git a/libs/events/node_modules/@types/lodash/findIndex.d.ts b/libs/events/node_modules/@types/lodash/findIndex.d.ts new file mode 100755 index 000000000..6b724446b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/findIndex.d.ts @@ -0,0 +1,2 @@ +import { findIndex } from "./index"; +export = findIndex; diff --git a/libs/events/node_modules/@types/lodash/findKey.d.ts b/libs/events/node_modules/@types/lodash/findKey.d.ts new file mode 100755 index 000000000..90230b437 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/findKey.d.ts @@ -0,0 +1,2 @@ +import { findKey } from "./index"; +export = findKey; diff --git a/libs/events/node_modules/@types/lodash/findLast.d.ts b/libs/events/node_modules/@types/lodash/findLast.d.ts new file mode 100755 index 000000000..c4f24fc17 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/findLast.d.ts @@ -0,0 +1,2 @@ +import { findLast } from "./index"; +export = findLast; diff --git a/libs/events/node_modules/@types/lodash/findLastIndex.d.ts b/libs/events/node_modules/@types/lodash/findLastIndex.d.ts new file mode 100755 index 000000000..21856e532 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/findLastIndex.d.ts @@ -0,0 +1,2 @@ +import { findLastIndex } from "./index"; +export = findLastIndex; diff --git a/libs/events/node_modules/@types/lodash/findLastKey.d.ts b/libs/events/node_modules/@types/lodash/findLastKey.d.ts new file mode 100755 index 000000000..ed7ff798d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/findLastKey.d.ts @@ -0,0 +1,2 @@ +import { findLastKey } from "./index"; +export = findLastKey; diff --git a/libs/events/node_modules/@types/lodash/first.d.ts b/libs/events/node_modules/@types/lodash/first.d.ts new file mode 100755 index 000000000..fd1cda7af --- /dev/null +++ b/libs/events/node_modules/@types/lodash/first.d.ts @@ -0,0 +1,2 @@ +import { first } from "./index"; +export = first; diff --git a/libs/events/node_modules/@types/lodash/flatMap.d.ts b/libs/events/node_modules/@types/lodash/flatMap.d.ts new file mode 100755 index 000000000..00570530e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/flatMap.d.ts @@ -0,0 +1,2 @@ +import { flatMap } from "./index"; +export = flatMap; diff --git a/libs/events/node_modules/@types/lodash/flatMapDeep.d.ts b/libs/events/node_modules/@types/lodash/flatMapDeep.d.ts new file mode 100755 index 000000000..c65639a1f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/flatMapDeep.d.ts @@ -0,0 +1,2 @@ +import { flatMapDeep } from "./index"; +export = flatMapDeep; diff --git a/libs/events/node_modules/@types/lodash/flatMapDepth.d.ts b/libs/events/node_modules/@types/lodash/flatMapDepth.d.ts new file mode 100755 index 000000000..7ec18534b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/flatMapDepth.d.ts @@ -0,0 +1,2 @@ +import { flatMapDepth } from "./index"; +export = flatMapDepth; diff --git a/libs/events/node_modules/@types/lodash/flatten.d.ts b/libs/events/node_modules/@types/lodash/flatten.d.ts new file mode 100755 index 000000000..43ac0f444 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/flatten.d.ts @@ -0,0 +1,2 @@ +import { flatten } from "./index"; +export = flatten; diff --git a/libs/events/node_modules/@types/lodash/flattenDeep.d.ts b/libs/events/node_modules/@types/lodash/flattenDeep.d.ts new file mode 100755 index 000000000..df08bfa55 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/flattenDeep.d.ts @@ -0,0 +1,2 @@ +import { flattenDeep } from "./index"; +export = flattenDeep; diff --git a/libs/events/node_modules/@types/lodash/flattenDepth.d.ts b/libs/events/node_modules/@types/lodash/flattenDepth.d.ts new file mode 100755 index 000000000..f6be541f8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/flattenDepth.d.ts @@ -0,0 +1,2 @@ +import { flattenDepth } from "./index"; +export = flattenDepth; diff --git a/libs/events/node_modules/@types/lodash/flip.d.ts b/libs/events/node_modules/@types/lodash/flip.d.ts new file mode 100755 index 000000000..48c9924ec --- /dev/null +++ b/libs/events/node_modules/@types/lodash/flip.d.ts @@ -0,0 +1,2 @@ +import { flip } from "./index"; +export = flip; diff --git a/libs/events/node_modules/@types/lodash/floor.d.ts b/libs/events/node_modules/@types/lodash/floor.d.ts new file mode 100755 index 000000000..a101e5de0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/floor.d.ts @@ -0,0 +1,2 @@ +import { floor } from "./index"; +export = floor; diff --git a/libs/events/node_modules/@types/lodash/flow.d.ts b/libs/events/node_modules/@types/lodash/flow.d.ts new file mode 100755 index 000000000..37af0d479 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/flow.d.ts @@ -0,0 +1,2 @@ +import { flow } from "./index"; +export = flow; diff --git a/libs/events/node_modules/@types/lodash/flowRight.d.ts b/libs/events/node_modules/@types/lodash/flowRight.d.ts new file mode 100755 index 000000000..6c63f3edc --- /dev/null +++ b/libs/events/node_modules/@types/lodash/flowRight.d.ts @@ -0,0 +1,2 @@ +import { flowRight } from "./index"; +export = flowRight; diff --git a/libs/events/node_modules/@types/lodash/forEach.d.ts b/libs/events/node_modules/@types/lodash/forEach.d.ts new file mode 100755 index 000000000..8416aab76 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/forEach.d.ts @@ -0,0 +1,2 @@ +import { forEach } from "./index"; +export = forEach; diff --git a/libs/events/node_modules/@types/lodash/forEachRight.d.ts b/libs/events/node_modules/@types/lodash/forEachRight.d.ts new file mode 100755 index 000000000..af65b5c1c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/forEachRight.d.ts @@ -0,0 +1,2 @@ +import { forEachRight } from "./index"; +export = forEachRight; diff --git a/libs/events/node_modules/@types/lodash/forIn.d.ts b/libs/events/node_modules/@types/lodash/forIn.d.ts new file mode 100755 index 000000000..77d6f4853 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/forIn.d.ts @@ -0,0 +1,2 @@ +import { forIn } from "./index"; +export = forIn; diff --git a/libs/events/node_modules/@types/lodash/forInRight.d.ts b/libs/events/node_modules/@types/lodash/forInRight.d.ts new file mode 100755 index 000000000..d73296942 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/forInRight.d.ts @@ -0,0 +1,2 @@ +import { forInRight } from "./index"; +export = forInRight; diff --git a/libs/events/node_modules/@types/lodash/forOwn.d.ts b/libs/events/node_modules/@types/lodash/forOwn.d.ts new file mode 100755 index 000000000..dfa930f27 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/forOwn.d.ts @@ -0,0 +1,2 @@ +import { forOwn } from "./index"; +export = forOwn; diff --git a/libs/events/node_modules/@types/lodash/forOwnRight.d.ts b/libs/events/node_modules/@types/lodash/forOwnRight.d.ts new file mode 100755 index 000000000..fddde6a77 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/forOwnRight.d.ts @@ -0,0 +1,2 @@ +import { forOwnRight } from "./index"; +export = forOwnRight; diff --git a/libs/events/node_modules/@types/lodash/fp.d.ts b/libs/events/node_modules/@types/lodash/fp.d.ts new file mode 100755 index 000000000..12f635f12 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp.d.ts @@ -0,0 +1,4950 @@ +// AUTO-GENERATED: do not modify this file directly. +// If you need to make changes, modify generate-fp.ts (if necessary), then open a terminal in types/lodash/scripts, and do: +// npm install && npm run generate + +import lodash = require("./index"); + +export = _; + +declare const _: _.LoDashFp; +declare namespace _ { + interface LodashAdd { + (augend: number): LodashAdd1x1; + (augend: lodash.__, addend: number): LodashAdd1x2; + (augend: number, addend: number): number; + } + type LodashAdd1x1 = (addend: number) => number; + type LodashAdd1x2 = (augend: number) => number; + interface LodashAfter { + any>(func: TFunc): LodashAfter1x1; + (func: lodash.__, n: number): LodashAfter1x2; + any>(func: TFunc, n: number): TFunc; + } + type LodashAfter1x1 any> = (n: number) => TFunc; + type LodashAfter1x2 = any>(func: TFunc) => TFunc; + interface LodashEvery { + (predicate: lodash.ValueIterateeCustom): LodashEvery1x1; + (predicate: lodash.__, collection: lodash.List | null | undefined): LodashEvery1x2; + (predicate: lodash.ValueIterateeCustom, collection: lodash.List | null | undefined): boolean; + (predicate: lodash.__, collection: T | null | undefined): LodashEvery2x2; + (predicate: lodash.ValueIterateeCustom, collection: T | null | undefined): boolean; + } + type LodashEvery1x1 = (collection: lodash.List | object | null | undefined) => boolean; + type LodashEvery1x2 = (predicate: lodash.ValueIterateeCustom) => boolean; + type LodashEvery2x2 = (predicate: lodash.ValueIterateeCustom) => boolean; + type LodashOverEvery = (predicates: lodash.Many<(...args: T[]) => boolean>) => (...args: T[]) => boolean; + type LodashConstant = (value: T) => () => T; + interface LodashSome { + (predicate: lodash.ValueIterateeCustom): LodashSome1x1; + (predicate: lodash.__, collection: lodash.List | null | undefined): LodashSome1x2; + (predicate: lodash.ValueIterateeCustom, collection: lodash.List | null | undefined): boolean; + (predicate: lodash.__, collection: T | null | undefined): LodashSome2x2; + (predicate: lodash.ValueIterateeCustom, collection: T | null | undefined): boolean; + } + type LodashSome1x1 = (collection: lodash.List | object | null | undefined) => boolean; + type LodashSome1x2 = (predicate: lodash.ValueIterateeCustom) => boolean; + type LodashSome2x2 = (predicate: lodash.ValueIterateeCustom) => boolean; + type LodashOverSome = (predicates: lodash.Many<(...args: T[]) => boolean>) => (...args: T[]) => boolean; + type LodashApply = (func: (...args: any[]) => TResult) => (...args: any[]) => TResult; + interface LodashAry { + (n: number): LodashAry1x1; + (n: lodash.__, func: (...args: any[]) => any): LodashAry1x2; + (n: number, func: (...args: any[]) => any): (...args: any[]) => any; + } + type LodashAry1x1 = (func: (...args: any[]) => any) => (...args: any[]) => any; + type LodashAry1x2 = (n: number) => (...args: any[]) => any; + interface LodashAssign { + (object: TObject): LodashAssign1x1; + (object: lodash.__, source: TSource): LodashAssign1x2; + (object: TObject, source: TSource): TObject & TSource; + } + type LodashAssign1x1 = (source: TSource) => TObject & TSource; + type LodashAssign1x2 = (object: TObject) => TObject & TSource; + interface LodashAssignAll { + (object: [TObject, TSource]): TObject & TSource; + (object: [TObject, TSource1, TSource2]): TObject & TSource1 & TSource2; + (object: [TObject, TSource1, TSource2, TSource3]): TObject & TSource1 & TSource2 & TSource3; + (object: [TObject, TSource1, TSource2, TSource3, TSource4]): TObject & TSource1 & TSource2 & TSource3 & TSource4; + (object: [TObject]): TObject; + (object: ReadonlyArray): any; + } + interface LodashAssignAllWith { + (customizer: lodash.AssignCustomizer): LodashAssignAllWith1x1; + (customizer: lodash.__, args: ReadonlyArray): LodashAssignAllWith1x2; + (customizer: lodash.AssignCustomizer, args: ReadonlyArray): any; + } + type LodashAssignAllWith1x1 = (args: ReadonlyArray) => any; + type LodashAssignAllWith1x2 = (customizer: lodash.AssignCustomizer) => any; + interface LodashAssignIn { + (object: TObject): LodashAssignIn1x1; + (object: lodash.__, source: TSource): LodashAssignIn1x2; + (object: TObject, source: TSource): TObject & TSource; + } + type LodashAssignIn1x1 = (source: TSource) => TObject & TSource; + type LodashAssignIn1x2 = (object: TObject) => TObject & TSource; + interface LodashAssignInAll { + (object: [TObject, TSource]): TObject & TSource; + (object: [TObject, TSource1, TSource2]): TObject & TSource1 & TSource2; + (object: [TObject, TSource1, TSource2, TSource3]): TObject & TSource1 & TSource2 & TSource3; + (object: [TObject, TSource1, TSource2, TSource3, TSource4]): TObject & TSource1 & TSource2 & TSource3 & TSource4; + (object: [TObject]): TObject; + (object: ReadonlyArray): TResult; + } + interface LodashAssignInAllWith { + (customizer: lodash.AssignCustomizer): LodashAssignInAllWith1x1; + (customizer: lodash.__, args: ReadonlyArray): LodashAssignInAllWith1x2; + (customizer: lodash.AssignCustomizer, args: ReadonlyArray): any; + } + type LodashAssignInAllWith1x1 = (args: ReadonlyArray) => any; + type LodashAssignInAllWith1x2 = (customizer: lodash.AssignCustomizer) => any; + interface LodashAssignInWith { + (customizer: lodash.AssignCustomizer): LodashAssignInWith1x1; + (customizer: lodash.__, object: TObject): LodashAssignInWith1x2; + (customizer: lodash.AssignCustomizer, object: TObject): LodashAssignInWith1x3; + (customizer: lodash.__, object: lodash.__, source: TSource): LodashAssignInWith1x4; + (customizer: lodash.AssignCustomizer, object: lodash.__, source: TSource): LodashAssignInWith1x5; + (customizer: lodash.__, object: TObject, source: TSource): LodashAssignInWith1x6; + (customizer: lodash.AssignCustomizer, object: TObject, source: TSource): TObject & TSource; + } + interface LodashAssignInWith1x1 { + (object: TObject): LodashAssignInWith1x3; + (object: lodash.__, source: TSource): LodashAssignInWith1x5; + (object: TObject, source: TSource): TObject & TSource; + } + interface LodashAssignInWith1x2 { + (customizer: lodash.AssignCustomizer): LodashAssignInWith1x3; + (customizer: lodash.__, source: TSource): LodashAssignInWith1x6; + (customizer: lodash.AssignCustomizer, source: TSource): TObject & TSource; + } + type LodashAssignInWith1x3 = (source: TSource) => TObject & TSource; + interface LodashAssignInWith1x4 { + (customizer: lodash.AssignCustomizer): LodashAssignInWith1x5; + (customizer: lodash.__, object: TObject): LodashAssignInWith1x6; + (customizer: lodash.AssignCustomizer, object: TObject): TObject & TSource; + } + type LodashAssignInWith1x5 = (object: TObject) => TObject & TSource; + type LodashAssignInWith1x6 = (customizer: lodash.AssignCustomizer) => TObject & TSource; + interface LodashAssignWith { + (customizer: lodash.AssignCustomizer): LodashAssignWith1x1; + (customizer: lodash.__, object: TObject): LodashAssignWith1x2; + (customizer: lodash.AssignCustomizer, object: TObject): LodashAssignWith1x3; + (customizer: lodash.__, object: lodash.__, source: TSource): LodashAssignWith1x4; + (customizer: lodash.AssignCustomizer, object: lodash.__, source: TSource): LodashAssignWith1x5; + (customizer: lodash.__, object: TObject, source: TSource): LodashAssignWith1x6; + (customizer: lodash.AssignCustomizer, object: TObject, source: TSource): TObject & TSource; + } + interface LodashAssignWith1x1 { + (object: TObject): LodashAssignWith1x3; + (object: lodash.__, source: TSource): LodashAssignWith1x5; + (object: TObject, source: TSource): TObject & TSource; + } + interface LodashAssignWith1x2 { + (customizer: lodash.AssignCustomizer): LodashAssignWith1x3; + (customizer: lodash.__, source: TSource): LodashAssignWith1x6; + (customizer: lodash.AssignCustomizer, source: TSource): TObject & TSource; + } + type LodashAssignWith1x3 = (source: TSource) => TObject & TSource; + interface LodashAssignWith1x4 { + (customizer: lodash.AssignCustomizer): LodashAssignWith1x5; + (customizer: lodash.__, object: TObject): LodashAssignWith1x6; + (customizer: lodash.AssignCustomizer, object: TObject): TObject & TSource; + } + type LodashAssignWith1x5 = (object: TObject) => TObject & TSource; + type LodashAssignWith1x6 = (customizer: lodash.AssignCustomizer) => TObject & TSource; + interface LodashSet { + (path: lodash.PropertyPath): LodashSet1x1; + (path: lodash.__, value: any): LodashSet1x2; + (path: lodash.PropertyPath, value: any): LodashSet1x3; + (path: lodash.__, value: lodash.__, object: T): LodashSet1x4; + (path: lodash.PropertyPath, value: lodash.__, object: T): LodashSet1x5; + (path: lodash.__, value: any, object: T): LodashSet1x6; + (path: lodash.PropertyPath, value: any, object: T): T; + (path: lodash.__, value: lodash.__, object: object): LodashSet2x4; + (path: lodash.PropertyPath, value: lodash.__, object: object): LodashSet2x5; + (path: lodash.__, value: any, object: object): LodashSet2x6; + (path: lodash.PropertyPath, value: any, object: object): TResult; + } + interface LodashSet1x1 { + (value: any): LodashSet1x3; + (value: lodash.__, object: T): LodashSet1x5; + (value: any, object: T): T; + (value: lodash.__, object: object): LodashSet2x5; + (value: any, object: object): TResult; + } + interface LodashSet1x2 { + (path: lodash.PropertyPath): LodashSet1x3; + (path: lodash.__, object: T): LodashSet1x6; + (path: lodash.PropertyPath, object: T): T; + (path: lodash.__, object: object): LodashSet2x6; + (path: lodash.PropertyPath, object: object): TResult; + } + interface LodashSet1x3 { + (object: T): T; + (object: object): TResult; + } + interface LodashSet1x4 { + (path: lodash.PropertyPath): LodashSet1x5; + (path: lodash.__, value: any): LodashSet1x6; + (path: lodash.PropertyPath, value: any): T; + } + type LodashSet1x5 = (value: any) => T; + type LodashSet1x6 = (path: lodash.PropertyPath) => T; + interface LodashSet2x4 { + (path: lodash.PropertyPath): LodashSet2x5; + (path: lodash.__, value: any): LodashSet2x6; + (path: lodash.PropertyPath, value: any): TResult; + } + type LodashSet2x5 = (value: any) => TResult; + type LodashSet2x6 = (path: lodash.PropertyPath) => TResult; + interface LodashAt { + (props: lodash.PropertyPath): LodashAt1x1; + (props: lodash.__, object: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashAt1x2; + (props: lodash.PropertyPath, object: lodash.Dictionary | lodash.NumericDictionary | null | undefined): T[]; + (props: lodash.Many): LodashAt2x1; + (props: lodash.__, object: T | null | undefined): LodashAt2x2; + (props: lodash.Many, object: T | null | undefined): Array; + } + type LodashAt1x1 = (object: lodash.Dictionary | lodash.NumericDictionary | null | undefined) => T[]; + type LodashAt1x2 = (props: lodash.PropertyPath) => T[]; + type LodashAt2x1 = (object: T | null | undefined) => Array; + type LodashAt2x2 = (props: lodash.Many) => Array; + type LodashAttempt = (func: (...args: any[]) => TResult) => TResult | Error; + interface LodashBefore { + any>(func: TFunc): LodashBefore1x1; + (func: lodash.__, n: number): LodashBefore1x2; + any>(func: TFunc, n: number): TFunc; + } + type LodashBefore1x1 any> = (n: number) => TFunc; + type LodashBefore1x2 = any>(func: TFunc) => TFunc; + interface LodashBind { + (func: (...args: any[]) => any): LodashBind1x1; + (func: lodash.__, thisArg: any): LodashBind1x2; + (func: (...args: any[]) => any, thisArg: any): (...args: any[]) => any; + placeholder: lodash.__; + } + type LodashBind1x1 = (thisArg: any) => (...args: any[]) => any; + type LodashBind1x2 = (func: (...args: any[]) => any) => (...args: any[]) => any; + interface LodashBindAll { + (methodNames: lodash.Many): LodashBindAll1x1; + (methodNames: lodash.__, object: T): LodashBindAll1x2; + (methodNames: lodash.Many, object: T): T; + } + type LodashBindAll1x1 = (object: T) => T; + type LodashBindAll1x2 = (methodNames: lodash.Many) => T; + interface LodashBindKey { + (object: object): LodashBindKey1x1; + (object: lodash.__, key: string): LodashBindKey1x2; + (object: object, key: string): (...args: any[]) => any; + placeholder: lodash.__; + } + type LodashBindKey1x1 = (key: string) => (...args: any[]) => any; + type LodashBindKey1x2 = (object: object) => (...args: any[]) => any; + type LodashCamelCase = (string: string) => string; + type LodashCapitalize = (string: string) => string; + type LodashCastArray = (value: lodash.Many) => T[]; + type LodashCeil = (n: number) => number; + interface LodashChunk { + (size: number): LodashChunk1x1; + (size: lodash.__, array: lodash.List | null | undefined): LodashChunk1x2; + (size: number, array: lodash.List | null | undefined): T[][]; + } + type LodashChunk1x1 = (array: lodash.List | null | undefined) => T[][]; + type LodashChunk1x2 = (size: number) => T[][]; + interface LodashClamp { + (lower: number): LodashClamp1x1; + (lower: lodash.__, upper: number): LodashClamp1x2; + (lower: number, upper: number): LodashClamp1x3; + (lower: lodash.__, upper: lodash.__, number: number): LodashClamp1x4; + (lower: number, upper: lodash.__, number: number): LodashClamp1x5; + (lower: lodash.__, upper: number, number: number): LodashClamp1x6; + (lower: number, upper: number, number: number): number; + } + interface LodashClamp1x1 { + (upper: number): LodashClamp1x3; + (upper: lodash.__, number: number): LodashClamp1x5; + (upper: number, number: number): number; + } + interface LodashClamp1x2 { + (lower: number): LodashClamp1x3; + (lower: lodash.__, number: number): LodashClamp1x6; + (lower: number, number: number): number; + } + type LodashClamp1x3 = (number: number) => number; + interface LodashClamp1x4 { + (lower: number): LodashClamp1x5; + (lower: lodash.__, upper: number): LodashClamp1x6; + (lower: number, upper: number): number; + } + type LodashClamp1x5 = (upper: number) => number; + type LodashClamp1x6 = (lower: number) => number; + type LodashClone = (value: T) => T; + type LodashCloneDeep = (value: T) => T; + interface LodashCloneDeepWith { + (customizer: lodash.CloneDeepWithCustomizer): LodashCloneDeepWith1x1; + (customizer: lodash.__, value: T): LodashCloneDeepWith1x2; + (customizer: lodash.CloneDeepWithCustomizer, value: T): any; + } + type LodashCloneDeepWith1x1 = (value: T) => any; + type LodashCloneDeepWith1x2 = (customizer: lodash.CloneDeepWithCustomizer) => any; + interface LodashCloneWith { + (customizer: lodash.CloneWithCustomizer): LodashCloneWith1x1; + (customizer: lodash.__, value: T): LodashCloneWith1x2; + (customizer: lodash.CloneWithCustomizer, value: T): TResult; + (customizer: lodash.CloneWithCustomizer): LodashCloneWith2x1; + (customizer: lodash.CloneWithCustomizer, value: T): TResult | T; + } + type LodashCloneWith1x1 = (value: T) => TResult; + interface LodashCloneWith1x2 { + (customizer: lodash.CloneWithCustomizer): TResult; + (customizer: lodash.CloneWithCustomizer): TResult | T; + } + type LodashCloneWith2x1 = (value: T) => TResult | T; + type LodashCompact = (array: lodash.List | null | undefined) => Array>; + type LodashNegate = (predicate: (...args: T) => any) => (...args: T) => boolean; + interface LodashFlowRight { + (f7: (a: R6) => R7, f6: (a: R5) => R6, f5: (a: R4) => R5, f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R7; + (f6: (a: R5) => R6, f5: (a: R4) => R5, f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R6; + (f5: (a: R4) => R5, f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R5; + (f4: (a: R3) => R4, f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R4; + (f3: (a: R2) => R3, f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R3; + (f2: (a: R1) => R2, f1: (...args: A) => R1): (...args: A) => R2; + (...func: Array any>>): (...args: any[]) => any; + } + interface LodashConcat { + (array: lodash.Many): LodashConcat1x1; + (array: lodash.__, values: lodash.Many): LodashConcat1x2; + (array: lodash.Many, values: lodash.Many): T[]; + } + type LodashConcat1x1 = (values: lodash.Many) => T[]; + type LodashConcat1x2 = (array: lodash.Many) => T[]; + interface LodashCond { + (pairs: Array>): () => R; + (pairs: Array>): (Target: T) => R; + } + interface LodashConformsTo { + (source: lodash.ConformsPredicateObject): LodashConformsTo1x1; + (source: lodash.__, object: T): LodashConformsTo1x2; + (source: lodash.ConformsPredicateObject, object: T): boolean; + } + type LodashConformsTo1x1 = (object: T) => boolean; + type LodashConformsTo1x2 = (source: lodash.ConformsPredicateObject) => boolean; + interface LodashContains { + (target: T): LodashContains1x1; + (target: lodash.__, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashContains1x2; + (target: T, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): boolean; + } + type LodashContains1x1 = (collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined) => boolean; + type LodashContains1x2 = (target: T) => boolean; + interface LodashCountBy { + (iteratee: lodash.ValueIteratee): LodashCountBy1x1; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashCountBy1x2; + (iteratee: lodash.ValueIteratee, collection: lodash.List | null | undefined): lodash.Dictionary; + (iteratee: lodash.__, collection: T | null | undefined): LodashCountBy2x2; + (iteratee: lodash.ValueIteratee, collection: T | null | undefined): lodash.Dictionary; + } + type LodashCountBy1x1 = (collection: lodash.List | object | null | undefined) => lodash.Dictionary; + type LodashCountBy1x2 = (iteratee: lodash.ValueIteratee) => lodash.Dictionary; + type LodashCountBy2x2 = (iteratee: lodash.ValueIteratee) => lodash.Dictionary; + type LodashCreate = (prototype: T) => T & U; + interface LodashCurry { + (func: (t1: T1) => R): lodash.CurriedFunction1; + (func: (t1: T1, t2: T2) => R): lodash.CurriedFunction2; + (func: (t1: T1, t2: T2, t3: T3) => R): lodash.CurriedFunction3; + (func: (t1: T1, t2: T2, t3: T3, t4: T4) => R): lodash.CurriedFunction4; + (func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R): lodash.CurriedFunction5; + (func: (...args: any[]) => any): (...args: any[]) => any; + placeholder: lodash.__; + } + interface LodashCurryN { + (arity: number): LodashCurryN1x1; + (arity: lodash.__, func: (t1: T1) => R): LodashCurryN1x2; + (arity: number, func: (t1: T1) => R): lodash.CurriedFunction1; + (arity: lodash.__, func: (t1: T1, t2: T2) => R): LodashCurryN2x2; + (arity: number, func: (t1: T1, t2: T2) => R): lodash.CurriedFunction2; + (arity: lodash.__, func: (t1: T1, t2: T2, t3: T3) => R): LodashCurryN3x2; + (arity: number, func: (t1: T1, t2: T2, t3: T3) => R): lodash.CurriedFunction3; + (arity: lodash.__, func: (t1: T1, t2: T2, t3: T3, t4: T4) => R): LodashCurryN4x2; + (arity: number, func: (t1: T1, t2: T2, t3: T3, t4: T4) => R): lodash.CurriedFunction4; + (arity: lodash.__, func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R): LodashCurryN5x2; + (arity: number, func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R): lodash.CurriedFunction5; + (arity: lodash.__, func: (...args: any[]) => any): LodashCurryN6x2; + (arity: number, func: (...args: any[]) => any): (...args: any[]) => any; + placeholder: lodash.__; + } + interface LodashCurryN1x1 { + (func: (t1: T1) => R): lodash.CurriedFunction1; + (func: (t1: T1, t2: T2) => R): lodash.CurriedFunction2; + (func: (t1: T1, t2: T2, t3: T3) => R): lodash.CurriedFunction3; + (func: (t1: T1, t2: T2, t3: T3, t4: T4) => R): lodash.CurriedFunction4; + (func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R): lodash.CurriedFunction5; + (func: (...args: any[]) => any): (...args: any[]) => any; + } + type LodashCurryN1x2 = (arity: number) => lodash.CurriedFunction1; + type LodashCurryN2x2 = (arity: number) => lodash.CurriedFunction2; + type LodashCurryN3x2 = (arity: number) => lodash.CurriedFunction3; + type LodashCurryN4x2 = (arity: number) => lodash.CurriedFunction4; + type LodashCurryN5x2 = (arity: number) => lodash.CurriedFunction5; + type LodashCurryN6x2 = (arity: number) => (...args: any[]) => any; + interface LodashCurryRight { + (func: (t1: T1) => R): lodash.RightCurriedFunction1; + (func: (t1: T1, t2: T2) => R): lodash.RightCurriedFunction2; + (func: (t1: T1, t2: T2, t3: T3) => R): lodash.RightCurriedFunction3; + (func: (t1: T1, t2: T2, t3: T3, t4: T4) => R): lodash.RightCurriedFunction4; + (func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R): lodash.RightCurriedFunction5; + (func: (...args: any[]) => any): (...args: any[]) => any; + placeholder: lodash.__; + } + interface LodashCurryRightN { + (arity: number): LodashCurryRightN1x1; + (arity: lodash.__, func: (t1: T1) => R): LodashCurryRightN1x2; + (arity: number, func: (t1: T1) => R): lodash.RightCurriedFunction1; + (arity: lodash.__, func: (t1: T1, t2: T2) => R): LodashCurryRightN2x2; + (arity: number, func: (t1: T1, t2: T2) => R): lodash.RightCurriedFunction2; + (arity: lodash.__, func: (t1: T1, t2: T2, t3: T3) => R): LodashCurryRightN3x2; + (arity: number, func: (t1: T1, t2: T2, t3: T3) => R): lodash.RightCurriedFunction3; + (arity: lodash.__, func: (t1: T1, t2: T2, t3: T3, t4: T4) => R): LodashCurryRightN4x2; + (arity: number, func: (t1: T1, t2: T2, t3: T3, t4: T4) => R): lodash.RightCurriedFunction4; + (arity: lodash.__, func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R): LodashCurryRightN5x2; + (arity: number, func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R): lodash.RightCurriedFunction5; + (arity: lodash.__, func: (...args: any[]) => any): LodashCurryRightN6x2; + (arity: number, func: (...args: any[]) => any): (...args: any[]) => any; + placeholder: lodash.__; + } + interface LodashCurryRightN1x1 { + (func: (t1: T1) => R): lodash.RightCurriedFunction1; + (func: (t1: T1, t2: T2) => R): lodash.RightCurriedFunction2; + (func: (t1: T1, t2: T2, t3: T3) => R): lodash.RightCurriedFunction3; + (func: (t1: T1, t2: T2, t3: T3, t4: T4) => R): lodash.RightCurriedFunction4; + (func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R): lodash.RightCurriedFunction5; + (func: (...args: any[]) => any): (...args: any[]) => any; + } + type LodashCurryRightN1x2 = (arity: number) => lodash.RightCurriedFunction1; + type LodashCurryRightN2x2 = (arity: number) => lodash.RightCurriedFunction2; + type LodashCurryRightN3x2 = (arity: number) => lodash.RightCurriedFunction3; + type LodashCurryRightN4x2 = (arity: number) => lodash.RightCurriedFunction4; + type LodashCurryRightN5x2 = (arity: number) => lodash.RightCurriedFunction5; + type LodashCurryRightN6x2 = (arity: number) => (...args: any[]) => any; + interface LodashDebounce { + (wait: number): LodashDebounce1x1; + any>(wait: lodash.__, func: T): LodashDebounce1x2; + any>(wait: number, func: T): lodash.DebouncedFunc; + } + type LodashDebounce1x1 = any>(func: T) => lodash.DebouncedFunc; + type LodashDebounce1x2 any> = (wait: number) => lodash.DebouncedFunc; + type LodashDeburr = (string: string) => string; + interface LodashDefaults { + (source: TSource): LodashDefaults1x1; + (source: lodash.__, object: TObject): LodashDefaults1x2; + (source: TSource, object: TObject): TSource & TObject; + } + type LodashDefaults1x1 = (object: TObject) => TSource & TObject; + type LodashDefaults1x2 = (source: TSource) => TSource & TObject; + interface LodashDefaultsAll { + (object: [TObject, TSource]): TSource & TObject; + (object: [TObject, TSource1, TSource2]): TSource2 & TSource1 & TObject; + (object: [TObject, TSource1, TSource2, TSource3]): TSource3 & TSource2 & TSource1 & TObject; + (object: [TObject, TSource1, TSource2, TSource3, TSource4]): TSource4 & TSource3 & TSource2 & TSource1 & TObject; + (object: [TObject]): TObject; + (object: ReadonlyArray): any; + } + interface LodashDefaultsDeep { + (sources: any): LodashDefaultsDeep1x1; + (sources: lodash.__, object: any): LodashDefaultsDeep1x2; + (sources: any, object: any): any; + } + type LodashDefaultsDeep1x1 = (object: any) => any; + type LodashDefaultsDeep1x2 = (sources: any) => any; + type LodashDefaultsDeepAll = (object: ReadonlyArray) => any; + interface LodashDefaultTo { + (defaultValue: T): LodashDefaultTo1x1; + (defaultValue: lodash.__, value: T | null | undefined): LodashDefaultTo1x2; + (defaultValue: T, value: T | null | undefined): T; + (defaultValue: TDefault): LodashDefaultTo2x1; + (defaultValue: TDefault, value: T | null | undefined): T | TDefault; + } + type LodashDefaultTo1x1 = (value: T | null | undefined) => T; + interface LodashDefaultTo1x2 { + (defaultValue: T): T; + (defaultValue: TDefault): T | TDefault; + } + type LodashDefaultTo2x1 = (value: T | null | undefined) => T | TDefault; + type LodashDefer = (func: (...args: any[]) => any, ...args: any[]) => number; + interface LodashDelay { + (wait: number): LodashDelay1x1; + (wait: lodash.__, func: (...args: any[]) => any): LodashDelay1x2; + (wait: number, func: (...args: any[]) => any): number; + } + type LodashDelay1x1 = (func: (...args: any[]) => any) => number; + type LodashDelay1x2 = (wait: number) => number; + interface LodashDifference { + (array: lodash.List | null | undefined): LodashDifference1x1; + (array: lodash.__, values: lodash.List): LodashDifference1x2; + (array: lodash.List | null | undefined, values: lodash.List): T[]; + } + type LodashDifference1x1 = (values: lodash.List) => T[]; + type LodashDifference1x2 = (array: lodash.List | null | undefined) => T[]; + interface LodashDifferenceBy { + (iteratee: lodash.ValueIteratee): LodashDifferenceBy1x1; + (iteratee: lodash.__, array: lodash.List | null | undefined): LodashDifferenceBy1x2; + (iteratee: lodash.ValueIteratee, array: lodash.List | null | undefined): LodashDifferenceBy1x3; + (iteratee: lodash.__, array: lodash.__, values: lodash.List): LodashDifferenceBy1x4; + (iteratee: lodash.ValueIteratee, array: lodash.__, values: lodash.List): LodashDifferenceBy1x5; + (iteratee: lodash.__, array: lodash.List | null | undefined, values: lodash.List): LodashDifferenceBy1x6; + (iteratee: lodash.ValueIteratee, array: lodash.List | null | undefined, values: lodash.List): T1[]; + } + interface LodashDifferenceBy1x1 { + (array: lodash.List | null | undefined): LodashDifferenceBy1x3; + (array: lodash.__, values: lodash.List): LodashDifferenceBy1x5; + (array: lodash.List | null | undefined, values: lodash.List): T1[]; + } + interface LodashDifferenceBy1x2 { + (iteratee: lodash.ValueIteratee): LodashDifferenceBy1x3; + (iteratee: lodash.__, values: lodash.List): LodashDifferenceBy1x6; + (iteratee: lodash.ValueIteratee, values: lodash.List): T1[]; + } + type LodashDifferenceBy1x3 = (values: lodash.List) => T1[]; + interface LodashDifferenceBy1x4 { + (iteratee: lodash.ValueIteratee): LodashDifferenceBy1x5; + (iteratee: lodash.__, array: lodash.List | null | undefined): LodashDifferenceBy1x6; + (iteratee: lodash.ValueIteratee, array: lodash.List | null | undefined): T1[]; + } + type LodashDifferenceBy1x5 = (array: lodash.List | null | undefined) => T1[]; + type LodashDifferenceBy1x6 = (iteratee: lodash.ValueIteratee) => T1[]; + interface LodashDifferenceWith { + (comparator: lodash.Comparator2): LodashDifferenceWith1x1; + (comparator: lodash.__, array: lodash.List | null | undefined): LodashDifferenceWith1x2; + (comparator: lodash.Comparator2, array: lodash.List | null | undefined): LodashDifferenceWith1x3; + (comparator: lodash.__, array: lodash.__, values: lodash.List): LodashDifferenceWith1x4; + (comparator: lodash.Comparator2, array: lodash.__, values: lodash.List): LodashDifferenceWith1x5; + (comparator: lodash.__, array: lodash.List | null | undefined, values: lodash.List): LodashDifferenceWith1x6; + (comparator: lodash.Comparator2, array: lodash.List | null | undefined, values: lodash.List): T1[]; + } + interface LodashDifferenceWith1x1 { + (array: lodash.List | null | undefined): LodashDifferenceWith1x3; + (array: lodash.__, values: lodash.List): LodashDifferenceWith1x5; + (array: lodash.List | null | undefined, values: lodash.List): T1[]; + } + interface LodashDifferenceWith1x2 { + (comparator: lodash.Comparator2): LodashDifferenceWith1x3; + (comparator: lodash.__, values: lodash.List): LodashDifferenceWith1x6; + (comparator: lodash.Comparator2, values: lodash.List): T1[]; + } + type LodashDifferenceWith1x3 = (values: lodash.List) => T1[]; + interface LodashDifferenceWith1x4 { + (comparator: lodash.Comparator2): LodashDifferenceWith1x5; + (comparator: lodash.__, array: lodash.List | null | undefined): LodashDifferenceWith1x6; + (comparator: lodash.Comparator2, array: lodash.List | null | undefined): T1[]; + } + type LodashDifferenceWith1x5 = (array: lodash.List | null | undefined) => T1[]; + type LodashDifferenceWith1x6 = (comparator: lodash.Comparator2) => T1[]; + interface LodashUnset { + (path: lodash.PropertyPath): LodashUnset1x1; + (path: lodash.__, object: T): LodashUnset1x2; + (path: lodash.PropertyPath, object: T): T; + } + type LodashUnset1x1 = (object: T) => T; + type LodashUnset1x2 = (path: lodash.PropertyPath) => T; + interface LodashDivide { + (dividend: number): LodashDivide1x1; + (dividend: lodash.__, divisor: number): LodashDivide1x2; + (dividend: number, divisor: number): number; + } + type LodashDivide1x1 = (divisor: number) => number; + type LodashDivide1x2 = (dividend: number) => number; + interface LodashDrop { + (n: number): LodashDrop1x1; + (n: lodash.__, array: lodash.List | null | undefined): LodashDrop1x2; + (n: number, array: lodash.List | null | undefined): T[]; + } + type LodashDrop1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashDrop1x2 = (n: number) => T[]; + interface LodashDropRight { + (n: number): LodashDropRight1x1; + (n: lodash.__, array: lodash.List | null | undefined): LodashDropRight1x2; + (n: number, array: lodash.List | null | undefined): T[]; + } + type LodashDropRight1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashDropRight1x2 = (n: number) => T[]; + interface LodashDropRightWhile { + (predicate: lodash.ValueIteratee): LodashDropRightWhile1x1; + (predicate: lodash.__, array: lodash.List | null | undefined): LodashDropRightWhile1x2; + (predicate: lodash.ValueIteratee, array: lodash.List | null | undefined): T[]; + } + type LodashDropRightWhile1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashDropRightWhile1x2 = (predicate: lodash.ValueIteratee) => T[]; + interface LodashDropWhile { + (predicate: lodash.ValueIteratee): LodashDropWhile1x1; + (predicate: lodash.__, array: lodash.List | null | undefined): LodashDropWhile1x2; + (predicate: lodash.ValueIteratee, array: lodash.List | null | undefined): T[]; + } + type LodashDropWhile1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashDropWhile1x2 = (predicate: lodash.ValueIteratee) => T[]; + interface LodashForEach { + (iteratee: (value: T) => any): LodashForEach1x1; + (iteratee: lodash.__, collection: ReadonlyArray): LodashForEach1x2; + (iteratee: (value: T) => any, collection: ReadonlyArray): T[]; + (iteratee: lodash.__, collection: lodash.List): LodashForEach2x2; + (iteratee: (value: T) => any, collection: lodash.List): lodash.List; + (iteratee: lodash.__, collection: T): LodashForEach3x2; + (iteratee: (value: T[keyof T]) => any, collection: T): T; + (iteratee: lodash.__, collection: TArray & (T[] | null | undefined)): LodashForEach4x2; + (iteratee: (value: T) => any, collection: TArray & (T[] | null | undefined)): TArray; + | null | undefined>(iteratee: lodash.__, collection: TList & (lodash.List | null | undefined)): LodashForEach5x2; + | null | undefined>(iteratee: (value: T) => any, collection: TList & (lodash.List | null | undefined)): TList; + (iteratee: lodash.__, collection: T | null | undefined): LodashForEach6x2; + (iteratee: (value: T[keyof T]) => any, collection: T | null | undefined): T | null | undefined; + } + interface LodashForEach1x1 { + (collection: ReadonlyArray): T[]; + (collection: lodash.List): lodash.List; + (collection: T1): T1; + (collection: TArray & (T[] | null | undefined)): TArray; + | null | undefined>(collection: TList & (lodash.List | null | undefined)): TList; + (collection: T1 | null | undefined): T1 | null | undefined; + } + type LodashForEach1x2 = (iteratee: (value: T) => any) => T[]; + type LodashForEach2x2 = (iteratee: (value: T) => any) => lodash.List; + type LodashForEach3x2 = (iteratee: (value: T[keyof T]) => any) => T; + type LodashForEach4x2 = (iteratee: (value: T) => any) => TArray; + type LodashForEach5x2 = (iteratee: (value: T) => any) => TList; + type LodashForEach6x2 = (iteratee: (value: T[keyof T]) => any) => T | null | undefined; + interface LodashForEachRight { + (iteratee: (value: T) => any): LodashForEachRight1x1; + (iteratee: lodash.__, collection: ReadonlyArray): LodashForEachRight1x2; + (iteratee: (value: T) => any, collection: ReadonlyArray): T[]; + (iteratee: lodash.__, collection: lodash.List): LodashForEachRight2x2; + (iteratee: (value: T) => any, collection: lodash.List): lodash.List; + (iteratee: lodash.__, collection: T): LodashForEachRight3x2; + (iteratee: (value: T[keyof T]) => any, collection: T): T; + (iteratee: lodash.__, collection: TArray & (T[] | null | undefined)): LodashForEachRight4x2; + (iteratee: (value: T) => any, collection: TArray & (T[] | null | undefined)): TArray; + | null | undefined>(iteratee: lodash.__, collection: TList & (lodash.List | null | undefined)): LodashForEachRight5x2; + | null | undefined>(iteratee: (value: T) => any, collection: TList & (lodash.List | null | undefined)): TList; + (iteratee: lodash.__, collection: T | null | undefined): LodashForEachRight6x2; + (iteratee: (value: T[keyof T]) => any, collection: T | null | undefined): T | null | undefined; + } + interface LodashForEachRight1x1 { + (collection: ReadonlyArray): T[]; + (collection: lodash.List): lodash.List; + (collection: T1): T1; + (collection: TArray & (T[] | null | undefined)): TArray; + | null | undefined>(collection: TList & (lodash.List | null | undefined)): TList; + (collection: T1 | null | undefined): T1 | null | undefined; + } + type LodashForEachRight1x2 = (iteratee: (value: T) => any) => T[]; + type LodashForEachRight2x2 = (iteratee: (value: T) => any) => lodash.List; + type LodashForEachRight3x2 = (iteratee: (value: T[keyof T]) => any) => T; + type LodashForEachRight4x2 = (iteratee: (value: T) => any) => TArray; + type LodashForEachRight5x2 = (iteratee: (value: T) => any) => TList; + type LodashForEachRight6x2 = (iteratee: (value: T[keyof T]) => any) => T | null | undefined; + interface LodashEndsWith { + (target: string): LodashEndsWith1x1; + (target: lodash.__, string: string): LodashEndsWith1x2; + (target: string, string: string): boolean; + } + type LodashEndsWith1x1 = (string: string) => boolean; + type LodashEndsWith1x2 = (target: string) => boolean; + interface LodashToPairs { + (object: lodash.Dictionary | lodash.NumericDictionary): Array<[string, T]>; + (object: object): Array<[string, any]>; + } + interface LodashToPairsIn { + (object: lodash.Dictionary | lodash.NumericDictionary): Array<[string, T]>; + (object: object): Array<[string, any]>; + } + interface LodashEq { + (value: any): LodashEq1x1; + (value: lodash.__, other: any): LodashEq1x2; + (value: any, other: any): boolean; + } + type LodashEq1x1 = (other: any) => boolean; + type LodashEq1x2 = (value: any) => boolean; + interface LodashIsEqual { + (value: any): LodashIsEqual1x1; + (value: lodash.__, other: any): LodashIsEqual1x2; + (value: any, other: any): boolean; + } + type LodashIsEqual1x1 = (other: any) => boolean; + type LodashIsEqual1x2 = (value: any) => boolean; + type LodashEscape = (string: string) => string; + type LodashEscapeRegExp = (string: string) => string; + interface LodashExtend { + (object: TObject): LodashExtend1x1; + (object: lodash.__, source: TSource): LodashExtend1x2; + (object: TObject, source: TSource): TObject & TSource; + } + type LodashExtend1x1 = (source: TSource) => TObject & TSource; + type LodashExtend1x2 = (object: TObject) => TObject & TSource; + interface LodashExtendAll { + (object: [TObject, TSource]): TObject & TSource; + (object: [TObject, TSource1, TSource2]): TObject & TSource1 & TSource2; + (object: [TObject, TSource1, TSource2, TSource3]): TObject & TSource1 & TSource2 & TSource3; + (object: [TObject, TSource1, TSource2, TSource3, TSource4]): TObject & TSource1 & TSource2 & TSource3 & TSource4; + (object: [TObject]): TObject; + (object: ReadonlyArray): TResult; + } + interface LodashExtendAllWith { + (customizer: lodash.AssignCustomizer): LodashExtendAllWith1x1; + (customizer: lodash.__, args: ReadonlyArray): LodashExtendAllWith1x2; + (customizer: lodash.AssignCustomizer, args: ReadonlyArray): any; + } + type LodashExtendAllWith1x1 = (args: ReadonlyArray) => any; + type LodashExtendAllWith1x2 = (customizer: lodash.AssignCustomizer) => any; + interface LodashExtendWith { + (customizer: lodash.AssignCustomizer): LodashExtendWith1x1; + (customizer: lodash.__, object: TObject): LodashExtendWith1x2; + (customizer: lodash.AssignCustomizer, object: TObject): LodashExtendWith1x3; + (customizer: lodash.__, object: lodash.__, source: TSource): LodashExtendWith1x4; + (customizer: lodash.AssignCustomizer, object: lodash.__, source: TSource): LodashExtendWith1x5; + (customizer: lodash.__, object: TObject, source: TSource): LodashExtendWith1x6; + (customizer: lodash.AssignCustomizer, object: TObject, source: TSource): TObject & TSource; + } + interface LodashExtendWith1x1 { + (object: TObject): LodashExtendWith1x3; + (object: lodash.__, source: TSource): LodashExtendWith1x5; + (object: TObject, source: TSource): TObject & TSource; + } + interface LodashExtendWith1x2 { + (customizer: lodash.AssignCustomizer): LodashExtendWith1x3; + (customizer: lodash.__, source: TSource): LodashExtendWith1x6; + (customizer: lodash.AssignCustomizer, source: TSource): TObject & TSource; + } + type LodashExtendWith1x3 = (source: TSource) => TObject & TSource; + interface LodashExtendWith1x4 { + (customizer: lodash.AssignCustomizer): LodashExtendWith1x5; + (customizer: lodash.__, object: TObject): LodashExtendWith1x6; + (customizer: lodash.AssignCustomizer, object: TObject): TObject & TSource; + } + type LodashExtendWith1x5 = (object: TObject) => TObject & TSource; + type LodashExtendWith1x6 = (customizer: lodash.AssignCustomizer) => TObject & TSource; + type LodashStubFalse = () => false; + interface LodashFill { + (start: number): LodashFill1x1; + (start: lodash.__, end: number): LodashFill1x2; + (start: number, end: number): LodashFill1x3; + (start: lodash.__, end: lodash.__, value: T): LodashFill1x4; + (start: number, end: lodash.__, value: T): LodashFill1x5; + (start: lodash.__, end: number, value: T): LodashFill1x6; + (start: number, end: number, value: T): LodashFill1x7; + (start: lodash.__, end: lodash.__, value: lodash.__, array: U[] | null | undefined): LodashFill1x8; + (start: number, end: lodash.__, value: lodash.__, array: U[] | null | undefined): LodashFill1x9; + (start: lodash.__, end: number, value: lodash.__, array: U[] | null | undefined): LodashFill1x10; + (start: number, end: number, value: lodash.__, array: U[] | null | undefined): LodashFill1x11; + (start: lodash.__, end: lodash.__, value: T, array: U[] | null | undefined): LodashFill1x12; + (start: number, end: lodash.__, value: T, array: U[] | null | undefined): LodashFill1x13; + (start: lodash.__, end: number, value: T, array: U[] | null | undefined): LodashFill1x14; + (start: number, end: number, value: T, array: U[] | null | undefined): Array; + (start: lodash.__, end: lodash.__, value: lodash.__, array: lodash.List | null | undefined): LodashFill2x8; + (start: number, end: lodash.__, value: lodash.__, array: lodash.List | null | undefined): LodashFill2x9; + (start: lodash.__, end: number, value: lodash.__, array: lodash.List | null | undefined): LodashFill2x10; + (start: number, end: number, value: lodash.__, array: lodash.List | null | undefined): LodashFill2x11; + (start: lodash.__, end: lodash.__, value: T, array: lodash.List | null | undefined): LodashFill2x12; + (start: number, end: lodash.__, value: T, array: lodash.List | null | undefined): LodashFill2x13; + (start: lodash.__, end: number, value: T, array: lodash.List | null | undefined): LodashFill2x14; + (start: number, end: number, value: T, array: lodash.List | null | undefined): lodash.List; + } + interface LodashFill1x1 { + (end: number): LodashFill1x3; + (end: lodash.__, value: T): LodashFill1x5; + (end: number, value: T): LodashFill1x7; + (end: lodash.__, value: lodash.__, array: U[] | null | undefined): LodashFill1x9; + (end: number, value: lodash.__, array: U[] | null | undefined): LodashFill1x11; + (end: lodash.__, value: T, array: U[] | null | undefined): LodashFill1x13; + (end: number, value: T, array: U[] | null | undefined): Array; + (end: lodash.__, value: lodash.__, array: lodash.List | null | undefined): LodashFill2x9; + (end: number, value: lodash.__, array: lodash.List | null | undefined): LodashFill2x11; + (end: lodash.__, value: T, array: lodash.List | null | undefined): LodashFill2x13; + (end: number, value: T, array: lodash.List | null | undefined): lodash.List; + } + interface LodashFill1x2 { + (start: number): LodashFill1x3; + (start: lodash.__, value: T): LodashFill1x6; + (start: number, value: T): LodashFill1x7; + (start: lodash.__, value: lodash.__, array: U[] | null | undefined): LodashFill1x10; + (start: number, value: lodash.__, array: U[] | null | undefined): LodashFill1x11; + (start: lodash.__, value: T, array: U[] | null | undefined): LodashFill1x14; + (start: number, value: T, array: U[] | null | undefined): Array; + (start: lodash.__, value: lodash.__, array: lodash.List | null | undefined): LodashFill2x10; + (start: number, value: lodash.__, array: lodash.List | null | undefined): LodashFill2x11; + (start: lodash.__, value: T, array: lodash.List | null | undefined): LodashFill2x14; + (start: number, value: T, array: lodash.List | null | undefined): lodash.List; + } + interface LodashFill1x3 { + (value: T): LodashFill1x7; + (value: lodash.__, array: U[] | null | undefined): LodashFill1x11; + (value: T, array: U[] | null | undefined): Array; + (value: lodash.__, array: lodash.List | null | undefined): LodashFill2x11; + (value: T, array: lodash.List | null | undefined): lodash.List; + } + interface LodashFill1x4 { + (start: number): LodashFill1x5; + (start: lodash.__, end: number): LodashFill1x6; + (start: number, end: number): LodashFill1x7; + (start: lodash.__, end: lodash.__, array: U[] | null | undefined): LodashFill1x12; + (start: number, end: lodash.__, array: U[] | null | undefined): LodashFill1x13; + (start: lodash.__, end: number, array: U[] | null | undefined): LodashFill1x14; + (start: number, end: number, array: U[] | null | undefined): Array; + (start: lodash.__, end: lodash.__, array: lodash.List | null | undefined): LodashFill2x12; + (start: number, end: lodash.__, array: lodash.List | null | undefined): LodashFill2x13; + (start: lodash.__, end: number, array: lodash.List | null | undefined): LodashFill2x14; + (start: number, end: number, array: lodash.List | null | undefined): lodash.List; + } + interface LodashFill1x5 { + (end: number): LodashFill1x7; + (end: lodash.__, array: U[] | null | undefined): LodashFill1x13; + (end: number, array: U[] | null | undefined): Array; + (end: lodash.__, array: lodash.List | null | undefined): LodashFill2x13; + (end: number, array: lodash.List | null | undefined): lodash.List; + } + interface LodashFill1x6 { + (start: number): LodashFill1x7; + (start: lodash.__, array: U[] | null | undefined): LodashFill1x14; + (start: number, array: U[] | null | undefined): Array; + (start: lodash.__, array: lodash.List | null | undefined): LodashFill2x14; + (start: number, array: lodash.List | null | undefined): lodash.List; + } + interface LodashFill1x7 { + (array: U[] | null | undefined): Array; + (array: lodash.List | null | undefined): lodash.List; + } + interface LodashFill1x8 { + (start: number): LodashFill1x9; + (start: lodash.__, end: number): LodashFill1x10; + (start: number, end: number): LodashFill1x11; + (start: lodash.__, end: lodash.__, value: T): LodashFill1x12; + (start: number, end: lodash.__, value: T): LodashFill1x13; + (start: lodash.__, end: number, value: T): LodashFill1x14; + (start: number, end: number, value: T): Array; + } + interface LodashFill1x9 { + (end: number): LodashFill1x11; + (end: lodash.__, value: T): LodashFill1x13; + (end: number, value: T): Array; + } + interface LodashFill1x10 { + (start: number): LodashFill1x11; + (start: lodash.__, value: T): LodashFill1x14; + (start: number, value: T): Array; + } + type LodashFill1x11 = (value: T) => Array; + interface LodashFill1x12 { + (start: number): LodashFill1x13; + (start: lodash.__, end: number): LodashFill1x14; + (start: number, end: number): Array; + } + type LodashFill1x13 = (end: number) => Array; + type LodashFill1x14 = (start: number) => Array; + interface LodashFill2x8 { + (start: number): LodashFill2x9; + (start: lodash.__, end: number): LodashFill2x10; + (start: number, end: number): LodashFill2x11; + (start: lodash.__, end: lodash.__, value: T): LodashFill2x12; + (start: number, end: lodash.__, value: T): LodashFill2x13; + (start: lodash.__, end: number, value: T): LodashFill2x14; + (start: number, end: number, value: T): lodash.List; + } + interface LodashFill2x9 { + (end: number): LodashFill2x11; + (end: lodash.__, value: T): LodashFill2x13; + (end: number, value: T): lodash.List; + } + interface LodashFill2x10 { + (start: number): LodashFill2x11; + (start: lodash.__, value: T): LodashFill2x14; + (start: number, value: T): lodash.List; + } + type LodashFill2x11 = (value: T) => lodash.List; + interface LodashFill2x12 { + (start: number): LodashFill2x13; + (start: lodash.__, end: number): LodashFill2x14; + (start: number, end: number): lodash.List; + } + type LodashFill2x13 = (end: number) => lodash.List; + type LodashFill2x14 = (start: number) => lodash.List; + interface LodashFilter { + (predicate: lodash.ValueIteratorTypeGuard): LodashFilter1x1; + (predicate: lodash.__, collection: lodash.List | null | undefined): LodashFilter1x2; + (predicate: lodash.ValueIteratorTypeGuard, collection: lodash.List | null | undefined): S[]; + (predicate: lodash.ValueIterateeCustom): LodashFilter2x1; + (predicate: lodash.ValueIterateeCustom, collection: lodash.List | null | undefined): T[]; + (predicate: lodash.ValueIteratorTypeGuard): LodashFilter3x1; + (predicate: lodash.__, collection: T | null | undefined): LodashFilter3x2; + (predicate: lodash.ValueIteratorTypeGuard, collection: T | null | undefined): S[]; + (predicate: lodash.ValueIterateeCustom, collection: T | null | undefined): Array; + } + type LodashFilter1x1 = (collection: lodash.List | null | undefined) => S[]; + interface LodashFilter1x2 { + (predicate: lodash.ValueIteratorTypeGuard): S[]; + (predicate: lodash.ValueIterateeCustom): T[]; + } + type LodashFilter2x1 = (collection: lodash.List | object | null | undefined) => T[]; + type LodashFilter3x1 = (collection: T | null | undefined) => S[]; + interface LodashFilter3x2 { + (predicate: lodash.ValueIteratorTypeGuard): S[]; + (predicate: lodash.ValueIterateeCustom): Array; + } + interface LodashFind { + (predicate: lodash.ValueIteratorTypeGuard): LodashFind1x1; + (predicate: lodash.__, collection: lodash.List | null | undefined): LodashFind1x2; + (predicate: lodash.ValueIteratorTypeGuard, collection: lodash.List | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFind2x1; + (predicate: lodash.ValueIterateeCustom, collection: lodash.List | null | undefined): T|undefined; + (predicate: lodash.ValueIteratorTypeGuard): LodashFind3x1; + (predicate: lodash.__, collection: T | null | undefined): LodashFind3x2; + (predicate: lodash.ValueIteratorTypeGuard, collection: T | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom, collection: T | null | undefined): T[keyof T]|undefined; + } + type LodashFind1x1 = (collection: lodash.List | null | undefined) => S|undefined; + interface LodashFind1x2 { + (predicate: lodash.ValueIteratorTypeGuard): S|undefined; + (predicate: lodash.ValueIterateeCustom): T|undefined; + } + type LodashFind2x1 = (collection: lodash.List | object | null | undefined) => T|undefined; + type LodashFind3x1 = (collection: T | null | undefined) => S|undefined; + interface LodashFind3x2 { + (predicate: lodash.ValueIteratorTypeGuard): S|undefined; + (predicate: lodash.ValueIterateeCustom): T[keyof T]|undefined; + } + interface LodashFindFrom { + (predicate: lodash.ValueIteratorTypeGuard): LodashFindFrom1x1; + (predicate: lodash.__, fromIndex: number): LodashFindFrom1x2; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number): LodashFindFrom1x3; + (predicate: lodash.__, fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindFrom1x4; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindFrom1x5; + (predicate: lodash.__, fromIndex: number, collection: lodash.List | null | undefined): LodashFindFrom1x6; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number, collection: lodash.List | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFindFrom2x1; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): LodashFindFrom2x3; + (predicate: lodash.ValueIterateeCustom, fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindFrom2x5; + (predicate: lodash.ValueIterateeCustom, fromIndex: number, collection: lodash.List | null | undefined): T|undefined; + (predicate: lodash.ValueIteratorTypeGuard): LodashFindFrom3x1; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number): LodashFindFrom3x3; + (predicate: lodash.__, fromIndex: lodash.__, collection: T | null | undefined): LodashFindFrom3x4; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: lodash.__, collection: T | null | undefined): LodashFindFrom3x5; + (predicate: lodash.__, fromIndex: number, collection: T | null | undefined): LodashFindFrom3x6; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number, collection: T | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom, fromIndex: lodash.__, collection: T | null | undefined): LodashFindFrom4x5; + (predicate: lodash.ValueIterateeCustom, fromIndex: number, collection: T | null | undefined): T[keyof T]|undefined; + } + interface LodashFindFrom1x1 { + (fromIndex: number): LodashFindFrom1x3; + (fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindFrom1x5; + (fromIndex: number, collection: lodash.List | null | undefined): S|undefined; + } + interface LodashFindFrom1x2 { + (predicate: lodash.ValueIteratorTypeGuard): LodashFindFrom1x3; + (predicate: lodash.__, collection: lodash.List | null | undefined): LodashFindFrom1x6; + (predicate: lodash.ValueIteratorTypeGuard, collection: lodash.List | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFindFrom2x3; + (predicate: lodash.ValueIterateeCustom, collection: lodash.List | null | undefined): T|undefined; + (predicate: lodash.ValueIteratorTypeGuard): LodashFindFrom3x3; + (predicate: lodash.__, collection: T | null | undefined): LodashFindFrom3x6; + (predicate: lodash.ValueIteratorTypeGuard, collection: T | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom, collection: T | null | undefined): T[keyof T]|undefined; + } + type LodashFindFrom1x3 = (collection: lodash.List | null | undefined) => S|undefined; + interface LodashFindFrom1x4 { + (predicate: lodash.ValueIteratorTypeGuard): LodashFindFrom1x5; + (predicate: lodash.__, fromIndex: number): LodashFindFrom1x6; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFindFrom2x5; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): T|undefined; + } + type LodashFindFrom1x5 = (fromIndex: number) => S|undefined; + interface LodashFindFrom1x6 { + (predicate: lodash.ValueIteratorTypeGuard): S|undefined; + (predicate: lodash.ValueIterateeCustom): T|undefined; + } + interface LodashFindFrom2x1 { + (fromIndex: number): LodashFindFrom2x3; + (fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindFrom2x5; + (fromIndex: number, collection: lodash.List | object | null | undefined): T|undefined; + (fromIndex: lodash.__, collection: T1 | null | undefined): LodashFindFrom4x5; + } + interface LodashFindFrom2x3 { + (collection: lodash.List | null | undefined): T|undefined; + (collection: object | null | undefined): object|undefined; + } + type LodashFindFrom2x5 = (fromIndex: number) => T|undefined; + interface LodashFindFrom3x1 { + (fromIndex: number): LodashFindFrom3x3; + (fromIndex: lodash.__, collection: T | null | undefined): LodashFindFrom3x5; + (fromIndex: number, collection: T | null | undefined): S|undefined; + } + type LodashFindFrom3x3 = (collection: T | null | undefined) => S|undefined; + interface LodashFindFrom3x4 { + (predicate: lodash.ValueIteratorTypeGuard): LodashFindFrom3x5; + (predicate: lodash.__, fromIndex: number): LodashFindFrom3x6; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFindFrom4x5; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): T[keyof T]|undefined; + } + type LodashFindFrom3x5 = (fromIndex: number) => S|undefined; + interface LodashFindFrom3x6 { + (predicate: lodash.ValueIteratorTypeGuard): S|undefined; + (predicate: lodash.ValueIterateeCustom): T[keyof T]|undefined; + } + type LodashFindFrom4x5 = (fromIndex: number) => T[keyof T]|undefined; + interface LodashFindIndex { + (predicate: lodash.ValueIterateeCustom): LodashFindIndex1x1; + (predicate: lodash.__, array: lodash.List | null | undefined): LodashFindIndex1x2; + (predicate: lodash.ValueIterateeCustom, array: lodash.List | null | undefined): number; + } + type LodashFindIndex1x1 = (array: lodash.List | null | undefined) => number; + type LodashFindIndex1x2 = (predicate: lodash.ValueIterateeCustom) => number; + interface LodashFindIndexFrom { + (predicate: lodash.ValueIterateeCustom): LodashFindIndexFrom1x1; + (predicate: lodash.__, fromIndex: number): LodashFindIndexFrom1x2; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): LodashFindIndexFrom1x3; + (predicate: lodash.__, fromIndex: lodash.__, array: lodash.List | null | undefined): LodashFindIndexFrom1x4; + (predicate: lodash.ValueIterateeCustom, fromIndex: lodash.__, array: lodash.List | null | undefined): LodashFindIndexFrom1x5; + (predicate: lodash.__, fromIndex: number, array: lodash.List | null | undefined): LodashFindIndexFrom1x6; + (predicate: lodash.ValueIterateeCustom, fromIndex: number, array: lodash.List | null | undefined): number; + } + interface LodashFindIndexFrom1x1 { + (fromIndex: number): LodashFindIndexFrom1x3; + (fromIndex: lodash.__, array: lodash.List | null | undefined): LodashFindIndexFrom1x5; + (fromIndex: number, array: lodash.List | null | undefined): number; + } + interface LodashFindIndexFrom1x2 { + (predicate: lodash.ValueIterateeCustom): LodashFindIndexFrom1x3; + (predicate: lodash.__, array: lodash.List | null | undefined): LodashFindIndexFrom1x6; + (predicate: lodash.ValueIterateeCustom, array: lodash.List | null | undefined): number; + } + type LodashFindIndexFrom1x3 = (array: lodash.List | null | undefined) => number; + interface LodashFindIndexFrom1x4 { + (predicate: lodash.ValueIterateeCustom): LodashFindIndexFrom1x5; + (predicate: lodash.__, fromIndex: number): LodashFindIndexFrom1x6; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): number; + } + type LodashFindIndexFrom1x5 = (fromIndex: number) => number; + type LodashFindIndexFrom1x6 = (predicate: lodash.ValueIterateeCustom) => number; + interface LodashFindKey { + (predicate: lodash.ValueIteratee): LodashFindKey1x1; + (predicate: lodash.__, object: T | null | undefined): LodashFindKey1x2; + (predicate: lodash.ValueIteratee, object: T | null | undefined): string | undefined; + } + type LodashFindKey1x1 = (object: object | null | undefined) => string | undefined; + type LodashFindKey1x2 = (predicate: lodash.ValueIteratee) => string | undefined; + interface LodashFindLast { + (predicate: lodash.ValueIteratorTypeGuard): LodashFindLast1x1; + (predicate: lodash.__, collection: lodash.List | null | undefined): LodashFindLast1x2; + (predicate: lodash.ValueIteratorTypeGuard, collection: lodash.List | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFindLast2x1; + (predicate: lodash.ValueIterateeCustom, collection: lodash.List | null | undefined): T|undefined; + (predicate: lodash.ValueIteratorTypeGuard): LodashFindLast3x1; + (predicate: lodash.__, collection: T | null | undefined): LodashFindLast3x2; + (predicate: lodash.ValueIteratorTypeGuard, collection: T | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom, collection: T | null | undefined): T[keyof T]|undefined; + } + type LodashFindLast1x1 = (collection: lodash.List | null | undefined) => S|undefined; + interface LodashFindLast1x2 { + (predicate: lodash.ValueIteratorTypeGuard): S|undefined; + (predicate: lodash.ValueIterateeCustom): T|undefined; + } + type LodashFindLast2x1 = (collection: lodash.List | object | null | undefined) => T|undefined; + type LodashFindLast3x1 = (collection: T | null | undefined) => S|undefined; + interface LodashFindLast3x2 { + (predicate: lodash.ValueIteratorTypeGuard): S|undefined; + (predicate: lodash.ValueIterateeCustom): T[keyof T]|undefined; + } + interface LodashFindLastFrom { + (predicate: lodash.ValueIteratorTypeGuard): LodashFindLastFrom1x1; + (predicate: lodash.__, fromIndex: number): LodashFindLastFrom1x2; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number): LodashFindLastFrom1x3; + (predicate: lodash.__, fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindLastFrom1x4; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindLastFrom1x5; + (predicate: lodash.__, fromIndex: number, collection: lodash.List | null | undefined): LodashFindLastFrom1x6; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number, collection: lodash.List | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFindLastFrom2x1; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): LodashFindLastFrom2x3; + (predicate: lodash.ValueIterateeCustom, fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindLastFrom2x5; + (predicate: lodash.ValueIterateeCustom, fromIndex: number, collection: lodash.List | null | undefined): T|undefined; + (predicate: lodash.ValueIteratorTypeGuard): LodashFindLastFrom3x1; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number): LodashFindLastFrom3x3; + (predicate: lodash.__, fromIndex: lodash.__, collection: T | null | undefined): LodashFindLastFrom3x4; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: lodash.__, collection: T | null | undefined): LodashFindLastFrom3x5; + (predicate: lodash.__, fromIndex: number, collection: T | null | undefined): LodashFindLastFrom3x6; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number, collection: T | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom, fromIndex: lodash.__, collection: T | null | undefined): LodashFindLastFrom4x5; + (predicate: lodash.ValueIterateeCustom, fromIndex: number, collection: T | null | undefined): T[keyof T]|undefined; + } + interface LodashFindLastFrom1x1 { + (fromIndex: number): LodashFindLastFrom1x3; + (fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindLastFrom1x5; + (fromIndex: number, collection: lodash.List | null | undefined): S|undefined; + } + interface LodashFindLastFrom1x2 { + (predicate: lodash.ValueIteratorTypeGuard): LodashFindLastFrom1x3; + (predicate: lodash.__, collection: lodash.List | null | undefined): LodashFindLastFrom1x6; + (predicate: lodash.ValueIteratorTypeGuard, collection: lodash.List | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFindLastFrom2x3; + (predicate: lodash.ValueIterateeCustom, collection: lodash.List | null | undefined): T|undefined; + (predicate: lodash.ValueIteratorTypeGuard): LodashFindLastFrom3x3; + (predicate: lodash.__, collection: T | null | undefined): LodashFindLastFrom3x6; + (predicate: lodash.ValueIteratorTypeGuard, collection: T | null | undefined): S|undefined; + (predicate: lodash.ValueIterateeCustom, collection: T | null | undefined): T[keyof T]|undefined; + } + type LodashFindLastFrom1x3 = (collection: lodash.List | null | undefined) => S|undefined; + interface LodashFindLastFrom1x4 { + (predicate: lodash.ValueIteratorTypeGuard): LodashFindLastFrom1x5; + (predicate: lodash.__, fromIndex: number): LodashFindLastFrom1x6; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFindLastFrom2x5; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): T|undefined; + } + type LodashFindLastFrom1x5 = (fromIndex: number) => S|undefined; + interface LodashFindLastFrom1x6 { + (predicate: lodash.ValueIteratorTypeGuard): S|undefined; + (predicate: lodash.ValueIterateeCustom): T|undefined; + } + interface LodashFindLastFrom2x1 { + (fromIndex: number): LodashFindLastFrom2x3; + (fromIndex: lodash.__, collection: lodash.List | null | undefined): LodashFindLastFrom2x5; + (fromIndex: number, collection: lodash.List | object | null | undefined): T|undefined; + (fromIndex: lodash.__, collection: T1 | null | undefined): LodashFindLastFrom4x5; + } + interface LodashFindLastFrom2x3 { + (collection: lodash.List | null | undefined): T|undefined; + (collection: object | null | undefined): object|undefined; + } + type LodashFindLastFrom2x5 = (fromIndex: number) => T|undefined; + interface LodashFindLastFrom3x1 { + (fromIndex: number): LodashFindLastFrom3x3; + (fromIndex: lodash.__, collection: T | null | undefined): LodashFindLastFrom3x5; + (fromIndex: number, collection: T | null | undefined): S|undefined; + } + type LodashFindLastFrom3x3 = (collection: T | null | undefined) => S|undefined; + interface LodashFindLastFrom3x4 { + (predicate: lodash.ValueIteratorTypeGuard): LodashFindLastFrom3x5; + (predicate: lodash.__, fromIndex: number): LodashFindLastFrom3x6; + (predicate: lodash.ValueIteratorTypeGuard, fromIndex: number): S|undefined; + (predicate: lodash.ValueIterateeCustom): LodashFindLastFrom4x5; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): T[keyof T]|undefined; + } + type LodashFindLastFrom3x5 = (fromIndex: number) => S|undefined; + interface LodashFindLastFrom3x6 { + (predicate: lodash.ValueIteratorTypeGuard): S|undefined; + (predicate: lodash.ValueIterateeCustom): T[keyof T]|undefined; + } + type LodashFindLastFrom4x5 = (fromIndex: number) => T[keyof T]|undefined; + interface LodashFindLastIndex { + (predicate: lodash.ValueIterateeCustom): LodashFindLastIndex1x1; + (predicate: lodash.__, array: lodash.List | null | undefined): LodashFindLastIndex1x2; + (predicate: lodash.ValueIterateeCustom, array: lodash.List | null | undefined): number; + } + type LodashFindLastIndex1x1 = (array: lodash.List | null | undefined) => number; + type LodashFindLastIndex1x2 = (predicate: lodash.ValueIterateeCustom) => number; + interface LodashFindLastIndexFrom { + (predicate: lodash.ValueIterateeCustom): LodashFindLastIndexFrom1x1; + (predicate: lodash.__, fromIndex: number): LodashFindLastIndexFrom1x2; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): LodashFindLastIndexFrom1x3; + (predicate: lodash.__, fromIndex: lodash.__, array: lodash.List | null | undefined): LodashFindLastIndexFrom1x4; + (predicate: lodash.ValueIterateeCustom, fromIndex: lodash.__, array: lodash.List | null | undefined): LodashFindLastIndexFrom1x5; + (predicate: lodash.__, fromIndex: number, array: lodash.List | null | undefined): LodashFindLastIndexFrom1x6; + (predicate: lodash.ValueIterateeCustom, fromIndex: number, array: lodash.List | null | undefined): number; + } + interface LodashFindLastIndexFrom1x1 { + (fromIndex: number): LodashFindLastIndexFrom1x3; + (fromIndex: lodash.__, array: lodash.List | null | undefined): LodashFindLastIndexFrom1x5; + (fromIndex: number, array: lodash.List | null | undefined): number; + } + interface LodashFindLastIndexFrom1x2 { + (predicate: lodash.ValueIterateeCustom): LodashFindLastIndexFrom1x3; + (predicate: lodash.__, array: lodash.List | null | undefined): LodashFindLastIndexFrom1x6; + (predicate: lodash.ValueIterateeCustom, array: lodash.List | null | undefined): number; + } + type LodashFindLastIndexFrom1x3 = (array: lodash.List | null | undefined) => number; + interface LodashFindLastIndexFrom1x4 { + (predicate: lodash.ValueIterateeCustom): LodashFindLastIndexFrom1x5; + (predicate: lodash.__, fromIndex: number): LodashFindLastIndexFrom1x6; + (predicate: lodash.ValueIterateeCustom, fromIndex: number): number; + } + type LodashFindLastIndexFrom1x5 = (fromIndex: number) => number; + type LodashFindLastIndexFrom1x6 = (predicate: lodash.ValueIterateeCustom) => number; + interface LodashFindLastKey { + (predicate: lodash.ValueIteratee): LodashFindLastKey1x1; + (predicate: lodash.__, object: T | null | undefined): LodashFindLastKey1x2; + (predicate: lodash.ValueIteratee, object: T | null | undefined): string | undefined; + } + type LodashFindLastKey1x1 = (object: object | null | undefined) => string | undefined; + type LodashFindLastKey1x2 = (predicate: lodash.ValueIteratee) => string | undefined; + type LodashHead = (array: lodash.List | null | undefined) => T | undefined; + interface LodashFlatMap { + (iteratee: (value: T) => lodash.Many): LodashFlatMap1x1; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashFlatMap1x2; + (iteratee: (value: T) => lodash.Many, collection: lodash.List | null | undefined): TResult[]; + (iteratee: (value: T[keyof T]) => lodash.Many): LodashFlatMap2x1; + (iteratee: lodash.__, collection: T | null | undefined): LodashFlatMap2x2; + (iteratee: (value: T[keyof T]) => lodash.Many, collection: T | null | undefined): TResult[]; + (iteratee: string): LodashFlatMap3x1; + (iteratee: lodash.__, collection: object | null | undefined): LodashFlatMap3x2; + (iteratee: string, collection: object | null | undefined): any[]; + (iteratee: object): LodashFlatMap4x1; + (iteratee: object, collection: object | null | undefined): boolean[]; + } + type LodashFlatMap1x1 = (collection: lodash.List | null | undefined) => TResult[]; + type LodashFlatMap1x2 = (iteratee: (value: T) => lodash.Many) => TResult[]; + type LodashFlatMap2x1 = (collection: T | null | undefined) => TResult[]; + type LodashFlatMap2x2 = (iteratee: (value: T[keyof T]) => lodash.Many) => TResult[]; + type LodashFlatMap3x1 = (collection: object | null | undefined) => any[]; + interface LodashFlatMap3x2 { + (iteratee: string): any[]; + (iteratee: object): boolean[]; + } + type LodashFlatMap4x1 = (collection: object | null | undefined) => boolean[]; + interface LodashFlatMapDeep { + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult): LodashFlatMapDeep1x1; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashFlatMapDeep1x2; + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult, collection: lodash.List | null | undefined): TResult[]; + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult): LodashFlatMapDeep2x1; + (iteratee: lodash.__, collection: T | null | undefined): LodashFlatMapDeep2x2; + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult, collection: T | null | undefined): TResult[]; + (iteratee: string): LodashFlatMapDeep3x1; + (iteratee: lodash.__, collection: object | null | undefined): LodashFlatMapDeep3x2; + (iteratee: string, collection: object | null | undefined): any[]; + (iteratee: object): LodashFlatMapDeep4x1; + (iteratee: object, collection: object | null | undefined): boolean[]; + } + type LodashFlatMapDeep1x1 = (collection: lodash.List | null | undefined) => TResult[]; + type LodashFlatMapDeep1x2 = (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult) => TResult[]; + type LodashFlatMapDeep2x1 = (collection: T | null | undefined) => TResult[]; + type LodashFlatMapDeep2x2 = (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult) => TResult[]; + type LodashFlatMapDeep3x1 = (collection: object | null | undefined) => any[]; + interface LodashFlatMapDeep3x2 { + (iteratee: string): any[]; + (iteratee: object): boolean[]; + } + type LodashFlatMapDeep4x1 = (collection: object | null | undefined) => boolean[]; + interface LodashFlatMapDepth { + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult): LodashFlatMapDepth1x1; + (iteratee: lodash.__, depth: number): LodashFlatMapDepth1x2; + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult, depth: number): LodashFlatMapDepth1x3; + (iteratee: lodash.__, depth: lodash.__, collection: lodash.List | null | undefined): LodashFlatMapDepth1x4; + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult, depth: lodash.__, collection: lodash.List | null | undefined): LodashFlatMapDepth1x5; + (iteratee: lodash.__, depth: number, collection: lodash.List | null | undefined): LodashFlatMapDepth1x6; + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult, depth: number, collection: lodash.List | null | undefined): TResult[]; + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult): LodashFlatMapDepth2x1; + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult, depth: number): LodashFlatMapDepth2x3; + (iteratee: lodash.__, depth: lodash.__, collection: T | null | undefined): LodashFlatMapDepth2x4; + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult, depth: lodash.__, collection: T | null | undefined): LodashFlatMapDepth2x5; + (iteratee: lodash.__, depth: number, collection: T | null | undefined): LodashFlatMapDepth2x6; + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult, depth: number, collection: T | null | undefined): TResult[]; + (iteratee: string): LodashFlatMapDepth3x1; + (iteratee: string, depth: number): LodashFlatMapDepth3x3; + (iteratee: lodash.__, depth: lodash.__, collection: object | null | undefined): LodashFlatMapDepth3x4; + (iteratee: string, depth: lodash.__, collection: object | null | undefined): LodashFlatMapDepth3x5; + (iteratee: lodash.__, depth: number, collection: object | null | undefined): LodashFlatMapDepth3x6; + (iteratee: string, depth: number, collection: object | null | undefined): any[]; + (iteratee: object): LodashFlatMapDepth4x1; + (iteratee: object, depth: number): LodashFlatMapDepth4x3; + (iteratee: object, depth: lodash.__, collection: object | null | undefined): LodashFlatMapDepth4x5; + (iteratee: object, depth: number, collection: object | null | undefined): boolean[]; + } + interface LodashFlatMapDepth1x1 { + (depth: number): LodashFlatMapDepth1x3; + (depth: lodash.__, collection: lodash.List | null | undefined): LodashFlatMapDepth1x5; + (depth: number, collection: lodash.List | null | undefined): TResult[]; + } + interface LodashFlatMapDepth1x2 { + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult): LodashFlatMapDepth1x3; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashFlatMapDepth1x6; + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult, collection: lodash.List | null | undefined): TResult[]; + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult): LodashFlatMapDepth2x3; + (iteratee: lodash.__, collection: T | null | undefined): LodashFlatMapDepth2x6; + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult, collection: T | null | undefined): TResult[]; + (iteratee: string): LodashFlatMapDepth3x3; + (iteratee: lodash.__, collection: object | null | undefined): LodashFlatMapDepth3x6; + (iteratee: string, collection: object | null | undefined): any[]; + (iteratee: object): LodashFlatMapDepth4x3; + (iteratee: object, collection: object | null | undefined): boolean[]; + } + type LodashFlatMapDepth1x3 = (collection: lodash.List | null | undefined) => TResult[]; + interface LodashFlatMapDepth1x4 { + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult): LodashFlatMapDepth1x5; + (iteratee: lodash.__, depth: number): LodashFlatMapDepth1x6; + (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult, depth: number): TResult[]; + } + type LodashFlatMapDepth1x5 = (depth: number) => TResult[]; + type LodashFlatMapDepth1x6 = (iteratee: (value: T) => lodash.ListOfRecursiveArraysOrValues | TResult) => TResult[]; + interface LodashFlatMapDepth2x1 { + (depth: number): LodashFlatMapDepth2x3; + (depth: lodash.__, collection: T | null | undefined): LodashFlatMapDepth2x5; + (depth: number, collection: T | null | undefined): TResult[]; + } + type LodashFlatMapDepth2x3 = (collection: T | null | undefined) => TResult[]; + interface LodashFlatMapDepth2x4 { + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult): LodashFlatMapDepth2x5; + (iteratee: lodash.__, depth: number): LodashFlatMapDepth2x6; + (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult, depth: number): TResult[]; + } + type LodashFlatMapDepth2x5 = (depth: number) => TResult[]; + type LodashFlatMapDepth2x6 = (iteratee: (value: T[keyof T]) => lodash.ListOfRecursiveArraysOrValues | TResult) => TResult[]; + interface LodashFlatMapDepth3x1 { + (depth: number): LodashFlatMapDepth3x3; + (depth: lodash.__, collection: object | null | undefined): LodashFlatMapDepth3x5; + (depth: number, collection: object | null | undefined): any[]; + } + type LodashFlatMapDepth3x3 = (collection: object | null | undefined) => any[]; + interface LodashFlatMapDepth3x4 { + (iteratee: string): LodashFlatMapDepth3x5; + (iteratee: lodash.__, depth: number): LodashFlatMapDepth3x6; + (iteratee: string, depth: number): any[]; + (iteratee: object): LodashFlatMapDepth4x5; + (iteratee: object, depth: number): boolean[]; + } + type LodashFlatMapDepth3x5 = (depth: number) => any[]; + interface LodashFlatMapDepth3x6 { + (iteratee: string): any[]; + (iteratee: object): boolean[]; + } + interface LodashFlatMapDepth4x1 { + (depth: number): LodashFlatMapDepth4x3; + (depth: lodash.__, collection: object | null | undefined): LodashFlatMapDepth4x5; + (depth: number, collection: object | null | undefined): boolean[]; + } + type LodashFlatMapDepth4x3 = (collection: object | null | undefined) => boolean[]; + type LodashFlatMapDepth4x5 = (depth: number) => boolean[]; + type LodashFlatten = (array: lodash.List> | null | undefined) => T[]; + type LodashFlattenDeep = (array: lodash.ListOfRecursiveArraysOrValues | null | undefined) => T[]; + interface LodashFlattenDepth { + (depth: number): LodashFlattenDepth1x1; + (depth: lodash.__, array: lodash.ListOfRecursiveArraysOrValues | null | undefined): LodashFlattenDepth1x2; + (depth: number, array: lodash.ListOfRecursiveArraysOrValues | null | undefined): T[]; + } + type LodashFlattenDepth1x1 = (array: lodash.ListOfRecursiveArraysOrValues | null | undefined) => T[]; + type LodashFlattenDepth1x2 = (depth: number) => T[]; + type LodashFlip = any>(func: T) => T; + type LodashFloor = (n: number) => number; + interface LodashFlow { + (f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6, f7: (a: R6) => R7): (...args: A) => R7; + (f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6, f7: (a: R6) => R7, ...func: Array any>>): (...args: A) => any; + (f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6): (...args: A) => R6; + (f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5): (...args: A) => R5; + (f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4): (...args: A) => R4; + (f1: (...args: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3): (...args: A) => R3; + (f1: (...args: A) => R1, f2: (a: R1) => R2): (...args: A) => R2; + (...func: Array any>>): (...args: any[]) => any; + } + interface LodashForIn { + (iteratee: (value: T) => any): LodashForIn1x1; + (iteratee: lodash.__, object: T): LodashForIn1x2; + (iteratee: (value: T[keyof T]) => any, object: T): T; + (iteratee: lodash.__, object: T | null | undefined): LodashForIn2x2; + (iteratee: (value: T[keyof T]) => any, object: T | null | undefined): T | null | undefined; + } + interface LodashForIn1x1 { + (object: T1): T1; + (object: T1 | null | undefined): T1 | null | undefined; + } + type LodashForIn1x2 = (iteratee: (value: T[keyof T]) => any) => T; + type LodashForIn2x2 = (iteratee: (value: T[keyof T]) => any) => T | null | undefined; + interface LodashForInRight { + (iteratee: (value: T) => any): LodashForInRight1x1; + (iteratee: lodash.__, object: T): LodashForInRight1x2; + (iteratee: (value: T[keyof T]) => any, object: T): T; + (iteratee: lodash.__, object: T | null | undefined): LodashForInRight2x2; + (iteratee: (value: T[keyof T]) => any, object: T | null | undefined): T | null | undefined; + } + interface LodashForInRight1x1 { + (object: T1): T1; + (object: T1 | null | undefined): T1 | null | undefined; + } + type LodashForInRight1x2 = (iteratee: (value: T[keyof T]) => any) => T; + type LodashForInRight2x2 = (iteratee: (value: T[keyof T]) => any) => T | null | undefined; + interface LodashForOwn { + (iteratee: (value: T) => any): LodashForOwn1x1; + (iteratee: lodash.__, object: T): LodashForOwn1x2; + (iteratee: (value: T[keyof T]) => any, object: T): T; + (iteratee: lodash.__, object: T | null | undefined): LodashForOwn2x2; + (iteratee: (value: T[keyof T]) => any, object: T | null | undefined): T | null | undefined; + } + interface LodashForOwn1x1 { + (object: T1): T1; + (object: T1 | null | undefined): T1 | null | undefined; + } + type LodashForOwn1x2 = (iteratee: (value: T[keyof T]) => any) => T; + type LodashForOwn2x2 = (iteratee: (value: T[keyof T]) => any) => T | null | undefined; + interface LodashForOwnRight { + (iteratee: (value: T) => any): LodashForOwnRight1x1; + (iteratee: lodash.__, object: T): LodashForOwnRight1x2; + (iteratee: (value: T[keyof T]) => any, object: T): T; + (iteratee: lodash.__, object: T | null | undefined): LodashForOwnRight2x2; + (iteratee: (value: T[keyof T]) => any, object: T | null | undefined): T | null | undefined; + } + interface LodashForOwnRight1x1 { + (object: T1): T1; + (object: T1 | null | undefined): T1 | null | undefined; + } + type LodashForOwnRight1x2 = (iteratee: (value: T[keyof T]) => any) => T; + type LodashForOwnRight2x2 = (iteratee: (value: T[keyof T]) => any) => T | null | undefined; + interface LodashFromPairs { + (pairs: lodash.List<[lodash.PropertyName, T]> | null | undefined): lodash.Dictionary; + (pairs: lodash.List | null | undefined): lodash.Dictionary; + } + type LodashFunctions = (object: any) => string[]; + type LodashFunctionsIn = (object: any) => string[]; + interface LodashGet { + (path: TKey | [TKey]): LodashGet1x1; + (path: lodash.__, object: TObject): LodashGet1x2; + (path: TKey | [TKey], object: TObject): TObject[TKey]; + (path: lodash.__, object: TObject | null | undefined): LodashGet2x2; + (path: TKey | [TKey], object: TObject | null | undefined): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): LodashGet3x1; + (path: [TKey1, TKey2], object: TObject): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2], object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): LodashGet5x1; + (path: [TKey1, TKey2, TKey3], object: TObject): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): LodashGet7x1; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + (path: number): LodashGet9x1; + (path: lodash.__, object: lodash.NumericDictionary): LodashGet9x2; + (path: number, object: lodash.NumericDictionary): T; + (path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashGet10x2; + (path: number, object: lodash.NumericDictionary | null | undefined): T | undefined; + (path: lodash.PropertyPath): LodashGet11x1; + (path: lodash.__, object: null | undefined): LodashGet11x2; + (path: lodash.PropertyPath, object: null | undefined): undefined; + (path: lodash.__, object: any): LodashGet12x2; + (path: lodash.PropertyPath, object: any): any; + } + interface LodashGet1x1 { + (object: TObject): TObject[TKey]; + (object: TObject | null | undefined): TObject[TKey] | undefined; + } + interface LodashGet1x2 { + (path: TKey | [TKey]): TObject[TKey]; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4]; + } + interface LodashGet2x2 { + (path: TKey | [TKey]): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashGet3x1 { + (object: TObject): TObject[TKey1][TKey2]; + (object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + } + interface LodashGet5x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + } + interface LodashGet7x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashGet9x1 { + (object: lodash.NumericDictionary): T; + (object: lodash.NumericDictionary | null | undefined): T | undefined; + } + type LodashGet9x2 = (path: number) => T; + type LodashGet10x2 = (path: number) => T | undefined; + interface LodashGet11x1 { + (object: null | undefined): undefined; + (object: any): any; + } + type LodashGet11x2 = (path: lodash.PropertyPath) => undefined; + type LodashGet12x2 = (path: lodash.PropertyPath) => any; + interface LodashGetOr { + (defaultValue: TDefault): LodashGetOr1x1; + (defaultValue: lodash.__, path: TKey | [TKey]): LodashGetOr1x2; + (defaultValue: TDefault, path: TKey | [TKey]): LodashGetOr1x3; + (defaultValue: lodash.__, path: lodash.__, object: TObject | null | undefined): LodashGetOr1x4; + (defaultValue: TDefault, path: lodash.__, object: TObject | null | undefined): LodashGetOr1x5; + (defaultValue: lodash.__, path: TKey | [TKey], object: TObject | null | undefined): LodashGetOr1x6; + (defaultValue: TDefault, path: TKey | [TKey], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2]): LodashGetOr2x2; + (defaultValue: TDefault, path: [TKey1, TKey2]): LodashGetOr2x3; + (defaultValue: lodash.__, path: [TKey1, TKey2], object: TObject | null | undefined): LodashGetOr2x6; + (defaultValue: TDefault, path: [TKey1, TKey2], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3]): LodashGetOr3x2; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3]): LodashGetOr3x3; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): LodashGetOr3x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3, TKey4]): LodashGetOr4x2; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3, TKey4]): LodashGetOr4x3; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): LodashGetOr4x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: number): LodashGetOr5x2; + (defaultValue: TDefault, path: number): LodashGetOr5x3; + (defaultValue: lodash.__, path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashGetOr5x4; + (defaultValue: TDefault, path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashGetOr5x5; + (defaultValue: lodash.__, path: number, object: lodash.NumericDictionary | null | undefined): LodashGetOr5x6; + (defaultValue: TDefault, path: number, object: lodash.NumericDictionary | null | undefined): T | TDefault; + (defaultValue: lodash.__, path: lodash.PropertyPath): LodashGetOr6x2; + (defaultValue: TDefault, path: lodash.PropertyPath): LodashGetOr6x3; + (defaultValue: lodash.__, path: lodash.__, object: null | undefined): LodashGetOr6x4; + (defaultValue: TDefault, path: lodash.__, object: null | undefined): LodashGetOr6x5; + (defaultValue: lodash.__, path: lodash.PropertyPath, object: null | undefined): LodashGetOr6x6; + (defaultValue: TDefault, path: lodash.PropertyPath, object: null | undefined): TDefault; + (defaultValue: any): LodashGetOr7x1; + (defaultValue: any, path: lodash.PropertyPath): LodashGetOr7x3; + (defaultValue: lodash.__, path: lodash.__, object: any): LodashGetOr7x4; + (defaultValue: any, path: lodash.__, object: any): LodashGetOr7x5; + (defaultValue: lodash.__, path: lodash.PropertyPath, object: any): LodashGetOr7x6; + (defaultValue: any, path: lodash.PropertyPath, object: any): any; + } + interface LodashGetOr1x1 { + (path: TKey | [TKey]): LodashGetOr1x3; + (path: lodash.__, object: TObject | null | undefined): LodashGetOr1x5; + (path: TKey | [TKey], object: TObject | null | undefined): Exclude | TDefault; + (path: [TKey1, TKey2]): LodashGetOr2x3; + (path: [TKey1, TKey2], object: TObject | null | undefined): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3]): LodashGetOr3x3; + (path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3, TKey4]): LodashGetOr4x3; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): Exclude | TDefault; + (path: number): LodashGetOr5x3; + (path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashGetOr5x5; + (path: number, object: lodash.NumericDictionary | null | undefined): T | TDefault; + (path: lodash.PropertyPath): LodashGetOr6x3; + (path: lodash.__, object: null | undefined): LodashGetOr6x5; + (path: lodash.PropertyPath, object: null | undefined): TDefault; + } + interface LodashGetOr1x2 { + (defaultValue: TDefault): LodashGetOr1x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashGetOr1x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashGetOr1x3 = (object: TObject | null | undefined) => Exclude | TDefault; + interface LodashGetOr1x4 { + (defaultValue: TDefault): LodashGetOr1x5; + (defaultValue: lodash.__, path: TKey | [TKey]): LodashGetOr1x6; + (defaultValue: TDefault, path: TKey | [TKey]): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2]): LodashGetOr2x6; + (defaultValue: TDefault, path: [TKey1, TKey2]): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3]): LodashGetOr3x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3]): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3, TKey4]): LodashGetOr4x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3, TKey4]): Exclude | TDefault; + } + interface LodashGetOr1x5 { + (path: TKey | [TKey]): Exclude | TDefault; + (path: [TKey1, TKey2]): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3]): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3, TKey4]): Exclude | TDefault; + } + type LodashGetOr1x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashGetOr2x2 { + (defaultValue: TDefault): LodashGetOr2x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashGetOr2x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashGetOr2x3 = (object: TObject | null | undefined) => Exclude | TDefault; + type LodashGetOr2x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashGetOr3x2 { + (defaultValue: TDefault): LodashGetOr3x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashGetOr3x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashGetOr3x3 = (object: TObject | null | undefined) => Exclude | TDefault; + type LodashGetOr3x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashGetOr4x2 { + (defaultValue: TDefault): LodashGetOr4x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashGetOr4x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashGetOr4x3 = (object: TObject | null | undefined) => Exclude | TDefault; + type LodashGetOr4x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashGetOr5x2 { + (defaultValue: TDefault): LodashGetOr5x3; + (defaultValue: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashGetOr5x6; + (defaultValue: TDefault, object: lodash.NumericDictionary | null | undefined): T | TDefault; + } + type LodashGetOr5x3 = (object: lodash.NumericDictionary | null | undefined) => T | TDefault; + interface LodashGetOr5x4 { + (defaultValue: TDefault): LodashGetOr5x5; + (defaultValue: lodash.__, path: number): LodashGetOr5x6; + (defaultValue: TDefault, path: number): T | TDefault; + } + type LodashGetOr5x5 = (path: number) => T | TDefault; + type LodashGetOr5x6 = (defaultValue: TDefault) => T | TDefault; + interface LodashGetOr6x2 { + (defaultValue: TDefault): LodashGetOr6x3; + (defaultValue: lodash.__, object: null | undefined): LodashGetOr6x6; + (defaultValue: TDefault, object: null | undefined): TDefault; + (defaultValue: any): LodashGetOr7x3; + (defaultValue: lodash.__, object: any): LodashGetOr7x6; + (defaultValue: any, object: any): any; + } + type LodashGetOr6x3 = (object: null | undefined) => TDefault; + interface LodashGetOr6x4 { + (defaultValue: TDefault): LodashGetOr6x5; + (defaultValue: lodash.__, path: lodash.PropertyPath): LodashGetOr6x6; + (defaultValue: TDefault, path: lodash.PropertyPath): TDefault; + } + type LodashGetOr6x5 = (path: lodash.PropertyPath) => TDefault; + type LodashGetOr6x6 = (defaultValue: TDefault) => TDefault; + interface LodashGetOr7x1 { + (path: lodash.PropertyPath): LodashGetOr7x3; + (path: lodash.__, object: any): LodashGetOr7x5; + (path: lodash.PropertyPath, object: any): any; + } + type LodashGetOr7x3 = (object: any) => any; + interface LodashGetOr7x4 { + (defaultValue: any): LodashGetOr7x5; + (defaultValue: lodash.__, path: lodash.PropertyPath): LodashGetOr7x6; + (defaultValue: any, path: lodash.PropertyPath): any; + } + type LodashGetOr7x5 = (path: lodash.PropertyPath) => any; + type LodashGetOr7x6 = (defaultValue: any) => any; + interface LodashGroupBy { + (iteratee: lodash.ValueIteratee): LodashGroupBy1x1; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashGroupBy1x2; + (iteratee: lodash.ValueIteratee, collection: lodash.List | null | undefined): lodash.Dictionary; + (iteratee: lodash.__, collection: T | null | undefined): LodashGroupBy2x2; + (iteratee: lodash.ValueIteratee, collection: T | null | undefined): lodash.Dictionary>; + } + type LodashGroupBy1x1 = (collection: lodash.List | object | null | undefined) => lodash.Dictionary; + type LodashGroupBy1x2 = (iteratee: lodash.ValueIteratee) => lodash.Dictionary; + type LodashGroupBy2x2 = (iteratee: lodash.ValueIteratee) => lodash.Dictionary>; + interface LodashGt { + (value: any): LodashGt1x1; + (value: lodash.__, other: any): LodashGt1x2; + (value: any, other: any): boolean; + } + type LodashGt1x1 = (other: any) => boolean; + type LodashGt1x2 = (value: any) => boolean; + interface LodashGte { + (value: any): LodashGte1x1; + (value: lodash.__, other: any): LodashGte1x2; + (value: any, other: any): boolean; + } + type LodashGte1x1 = (other: any) => boolean; + type LodashGte1x2 = (value: any) => boolean; + interface LodashHas { + (path: lodash.PropertyPath): LodashHas1x1; + (path: lodash.__, object: T): LodashHas1x2; + (path: lodash.PropertyPath, object: T): boolean; + } + type LodashHas1x1 = (object: T) => boolean; + type LodashHas1x2 = (path: lodash.PropertyPath) => boolean; + interface LodashHasIn { + (path: lodash.PropertyPath): LodashHasIn1x1; + (path: lodash.__, object: T): LodashHasIn1x2; + (path: lodash.PropertyPath, object: T): boolean; + } + type LodashHasIn1x1 = (object: T) => boolean; + type LodashHasIn1x2 = (path: lodash.PropertyPath) => boolean; + interface LodashIdentity { + (value: T): T; + (): undefined; + } + interface LodashIncludes { + (target: T): LodashIncludes1x1; + (target: lodash.__, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashIncludes1x2; + (target: T, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): boolean; + } + type LodashIncludes1x1 = (collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined) => boolean; + type LodashIncludes1x2 = (target: T) => boolean; + interface LodashIncludesFrom { + (target: T): LodashIncludesFrom1x1; + (target: lodash.__, fromIndex: number): LodashIncludesFrom1x2; + (target: T, fromIndex: number): LodashIncludesFrom1x3; + (target: lodash.__, fromIndex: lodash.__, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashIncludesFrom1x4; + (target: T, fromIndex: lodash.__, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashIncludesFrom1x5; + (target: lodash.__, fromIndex: number, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashIncludesFrom1x6; + (target: T, fromIndex: number, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): boolean; + } + interface LodashIncludesFrom1x1 { + (fromIndex: number): LodashIncludesFrom1x3; + (fromIndex: lodash.__, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashIncludesFrom1x5; + (fromIndex: number, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): boolean; + } + interface LodashIncludesFrom1x2 { + (target: T): LodashIncludesFrom1x3; + (target: lodash.__, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashIncludesFrom1x6; + (target: T, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): boolean; + } + type LodashIncludesFrom1x3 = (collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined) => boolean; + interface LodashIncludesFrom1x4 { + (target: T): LodashIncludesFrom1x5; + (target: lodash.__, fromIndex: number): LodashIncludesFrom1x6; + (target: T, fromIndex: number): boolean; + } + type LodashIncludesFrom1x5 = (fromIndex: number) => boolean; + type LodashIncludesFrom1x6 = (target: T) => boolean; + interface LodashKeyBy { + (iteratee: lodash.ValueIterateeCustom): LodashKeyBy1x1; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashKeyBy1x2; + (iteratee: lodash.ValueIterateeCustom, collection: lodash.List | null | undefined): lodash.Dictionary; + (iteratee: lodash.__, collection: T | null | undefined): LodashKeyBy2x2; + (iteratee: lodash.ValueIterateeCustom, collection: T | null | undefined): lodash.Dictionary; + } + type LodashKeyBy1x1 = (collection: lodash.List | object | null | undefined) => lodash.Dictionary; + type LodashKeyBy1x2 = (iteratee: lodash.ValueIterateeCustom) => lodash.Dictionary; + type LodashKeyBy2x2 = (iteratee: lodash.ValueIterateeCustom) => lodash.Dictionary; + interface LodashIndexOf { + (value: T): LodashIndexOf1x1; + (value: lodash.__, array: lodash.List | null | undefined): LodashIndexOf1x2; + (value: T, array: lodash.List | null | undefined): number; + } + type LodashIndexOf1x1 = (array: lodash.List | null | undefined) => number; + type LodashIndexOf1x2 = (value: T) => number; + interface LodashIndexOfFrom { + (value: T): LodashIndexOfFrom1x1; + (value: lodash.__, fromIndex: number): LodashIndexOfFrom1x2; + (value: T, fromIndex: number): LodashIndexOfFrom1x3; + (value: lodash.__, fromIndex: lodash.__, array: lodash.List | null | undefined): LodashIndexOfFrom1x4; + (value: T, fromIndex: lodash.__, array: lodash.List | null | undefined): LodashIndexOfFrom1x5; + (value: lodash.__, fromIndex: number, array: lodash.List | null | undefined): LodashIndexOfFrom1x6; + (value: T, fromIndex: number, array: lodash.List | null | undefined): number; + } + interface LodashIndexOfFrom1x1 { + (fromIndex: number): LodashIndexOfFrom1x3; + (fromIndex: lodash.__, array: lodash.List | null | undefined): LodashIndexOfFrom1x5; + (fromIndex: number, array: lodash.List | null | undefined): number; + } + interface LodashIndexOfFrom1x2 { + (value: T): LodashIndexOfFrom1x3; + (value: lodash.__, array: lodash.List | null | undefined): LodashIndexOfFrom1x6; + (value: T, array: lodash.List | null | undefined): number; + } + type LodashIndexOfFrom1x3 = (array: lodash.List | null | undefined) => number; + interface LodashIndexOfFrom1x4 { + (value: T): LodashIndexOfFrom1x5; + (value: lodash.__, fromIndex: number): LodashIndexOfFrom1x6; + (value: T, fromIndex: number): number; + } + type LodashIndexOfFrom1x5 = (fromIndex: number) => number; + type LodashIndexOfFrom1x6 = (value: T) => number; + type LodashInitial = (array: lodash.List | null | undefined) => T[]; + interface LodashInRange { + (start: number): LodashInRange1x1; + (start: lodash.__, end: number): LodashInRange1x2; + (start: number, end: number): LodashInRange1x3; + (start: lodash.__, end: lodash.__, n: number): LodashInRange1x4; + (start: number, end: lodash.__, n: number): LodashInRange1x5; + (start: lodash.__, end: number, n: number): LodashInRange1x6; + (start: number, end: number, n: number): boolean; + } + interface LodashInRange1x1 { + (end: number): LodashInRange1x3; + (end: lodash.__, n: number): LodashInRange1x5; + (end: number, n: number): boolean; + } + interface LodashInRange1x2 { + (start: number): LodashInRange1x3; + (start: lodash.__, n: number): LodashInRange1x6; + (start: number, n: number): boolean; + } + type LodashInRange1x3 = (n: number) => boolean; + interface LodashInRange1x4 { + (start: number): LodashInRange1x5; + (start: lodash.__, end: number): LodashInRange1x6; + (start: number, end: number): boolean; + } + type LodashInRange1x5 = (end: number) => boolean; + type LodashInRange1x6 = (start: number) => boolean; + interface LodashIntersection { + (arrays2: lodash.List | null | undefined): LodashIntersection1x1; + (arrays2: lodash.__, arrays: lodash.List | null | undefined): LodashIntersection1x2; + (arrays2: lodash.List | null | undefined, arrays: lodash.List | null | undefined): T[]; + } + type LodashIntersection1x1 = (arrays: lodash.List | null | undefined) => T[]; + type LodashIntersection1x2 = (arrays2: lodash.List | null | undefined) => T[]; + interface LodashIntersectionBy { + (iteratee: lodash.ValueIteratee): LodashIntersectionBy1x1; + (iteratee: lodash.__, array: lodash.List | null): LodashIntersectionBy1x2; + (iteratee: lodash.ValueIteratee, array: lodash.List | null): LodashIntersectionBy1x3; + (iteratee: lodash.__, array: lodash.__, values: lodash.List): LodashIntersectionBy1x4; + (iteratee: lodash.ValueIteratee, array: lodash.__, values: lodash.List): LodashIntersectionBy1x5; + (iteratee: lodash.__, array: lodash.List | null, values: lodash.List): LodashIntersectionBy1x6; + (iteratee: lodash.ValueIteratee, array: lodash.List | null, values: lodash.List): T1[]; + } + interface LodashIntersectionBy1x1 { + (array: lodash.List | null): LodashIntersectionBy1x3; + (array: lodash.__, values: lodash.List): LodashIntersectionBy1x5; + (array: lodash.List | null, values: lodash.List): T1[]; + } + interface LodashIntersectionBy1x2 { + (iteratee: lodash.ValueIteratee): LodashIntersectionBy1x3; + (iteratee: lodash.__, values: lodash.List): LodashIntersectionBy1x6; + (iteratee: lodash.ValueIteratee, values: lodash.List): T1[]; + } + type LodashIntersectionBy1x3 = (values: lodash.List) => T1[]; + interface LodashIntersectionBy1x4 { + (iteratee: lodash.ValueIteratee): LodashIntersectionBy1x5; + (iteratee: lodash.__, array: lodash.List | null): LodashIntersectionBy1x6; + (iteratee: lodash.ValueIteratee, array: lodash.List | null): T1[]; + } + type LodashIntersectionBy1x5 = (array: lodash.List | null) => T1[]; + type LodashIntersectionBy1x6 = (iteratee: lodash.ValueIteratee) => T1[]; + interface LodashIntersectionWith { + (comparator: lodash.Comparator2): LodashIntersectionWith1x1; + (comparator: lodash.__, array: lodash.List | null | undefined): LodashIntersectionWith1x2; + (comparator: lodash.Comparator2, array: lodash.List | null | undefined): LodashIntersectionWith1x3; + (comparator: lodash.__, array: lodash.__, values: lodash.List): LodashIntersectionWith1x4; + (comparator: lodash.Comparator2, array: lodash.__, values: lodash.List): LodashIntersectionWith1x5; + (comparator: lodash.__, array: lodash.List | null | undefined, values: lodash.List): LodashIntersectionWith1x6; + (comparator: lodash.Comparator2, array: lodash.List | null | undefined, values: lodash.List): T1[]; + } + interface LodashIntersectionWith1x1 { + (array: lodash.List | null | undefined): LodashIntersectionWith1x3; + (array: lodash.__, values: lodash.List): LodashIntersectionWith1x5; + (array: lodash.List | null | undefined, values: lodash.List): T1[]; + } + interface LodashIntersectionWith1x2 { + (comparator: lodash.Comparator2): LodashIntersectionWith1x3; + (comparator: lodash.__, values: lodash.List): LodashIntersectionWith1x6; + (comparator: lodash.Comparator2, values: lodash.List): T1[]; + } + type LodashIntersectionWith1x3 = (values: lodash.List) => T1[]; + interface LodashIntersectionWith1x4 { + (comparator: lodash.Comparator2): LodashIntersectionWith1x5; + (comparator: lodash.__, array: lodash.List | null | undefined): LodashIntersectionWith1x6; + (comparator: lodash.Comparator2, array: lodash.List | null | undefined): T1[]; + } + type LodashIntersectionWith1x5 = (array: lodash.List | null | undefined) => T1[]; + type LodashIntersectionWith1x6 = (comparator: lodash.Comparator2) => T1[]; + type LodashInvert = (object: object) => lodash.Dictionary; + interface LodashInvertBy { + (interatee: lodash.ValueIteratee): LodashInvertBy1x1; + (interatee: lodash.__, object: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashInvertBy1x2; + (interatee: lodash.ValueIteratee, object: lodash.Dictionary | lodash.NumericDictionary | null | undefined): lodash.Dictionary; + (interatee: lodash.__, object: T | null | undefined): LodashInvertBy2x2; + (interatee: lodash.ValueIteratee, object: T | null | undefined): lodash.Dictionary; + } + type LodashInvertBy1x1 = (object: lodash.Dictionary | lodash.NumericDictionary | object | null | undefined) => lodash.Dictionary; + type LodashInvertBy1x2 = (interatee: lodash.ValueIteratee) => lodash.Dictionary; + type LodashInvertBy2x2 = (interatee: lodash.ValueIteratee) => lodash.Dictionary; + interface LodashInvoke { + (path: lodash.PropertyPath): LodashInvoke1x1; + (path: lodash.__, object: any): LodashInvoke1x2; + (path: lodash.PropertyPath, object: any): any; + } + type LodashInvoke1x1 = (object: any) => any; + type LodashInvoke1x2 = (path: lodash.PropertyPath) => any; + interface LodashInvokeArgs { + (path: lodash.PropertyPath): LodashInvokeArgs1x1; + (path: lodash.__, args: ReadonlyArray): LodashInvokeArgs1x2; + (path: lodash.PropertyPath, args: ReadonlyArray): LodashInvokeArgs1x3; + (path: lodash.__, args: lodash.__, object: any): LodashInvokeArgs1x4; + (path: lodash.PropertyPath, args: lodash.__, object: any): LodashInvokeArgs1x5; + (path: lodash.__, args: ReadonlyArray, object: any): LodashInvokeArgs1x6; + (path: lodash.PropertyPath, args: ReadonlyArray, object: any): any; + } + interface LodashInvokeArgs1x1 { + (args: ReadonlyArray): LodashInvokeArgs1x3; + (args: lodash.__, object: any): LodashInvokeArgs1x5; + (args: ReadonlyArray, object: any): any; + } + interface LodashInvokeArgs1x2 { + (path: lodash.PropertyPath): LodashInvokeArgs1x3; + (path: lodash.__, object: any): LodashInvokeArgs1x6; + (path: lodash.PropertyPath, object: any): any; + } + type LodashInvokeArgs1x3 = (object: any) => any; + interface LodashInvokeArgs1x4 { + (path: lodash.PropertyPath): LodashInvokeArgs1x5; + (path: lodash.__, args: ReadonlyArray): LodashInvokeArgs1x6; + (path: lodash.PropertyPath, args: ReadonlyArray): any; + } + type LodashInvokeArgs1x5 = (args: ReadonlyArray) => any; + type LodashInvokeArgs1x6 = (path: lodash.PropertyPath) => any; + interface LodashInvokeArgsMap { + (methodName: string): LodashInvokeArgsMap1x1; + (methodNameOrMethod: lodash.__, args: ReadonlyArray): LodashInvokeArgsMap1x2; + (methodName: string, args: ReadonlyArray): LodashInvokeArgsMap1x3; + (methodNameOrMethod: lodash.__, args: lodash.__, collection: object | null | undefined): LodashInvokeArgsMap1x4; + (methodName: string, args: lodash.__, collection: object | null | undefined): LodashInvokeArgsMap1x5; + (methodNameOrMethod: lodash.__, args: ReadonlyArray, collection: object | null | undefined): LodashInvokeArgsMap1x6; + (methodName: string, args: ReadonlyArray, collection: object | null | undefined): any[]; + (method: (...args: any[]) => TResult): LodashInvokeArgsMap2x1; + (method: (...args: any[]) => TResult, args: ReadonlyArray): LodashInvokeArgsMap2x3; + (method: (...args: any[]) => TResult, args: lodash.__, collection: object | null | undefined): LodashInvokeArgsMap2x5; + (method: (...args: any[]) => TResult, args: ReadonlyArray, collection: object | null | undefined): TResult[]; + } + interface LodashInvokeArgsMap1x1 { + (args: ReadonlyArray): LodashInvokeArgsMap1x3; + (args: lodash.__, collection: object | null | undefined): LodashInvokeArgsMap1x5; + (args: ReadonlyArray, collection: object | null | undefined): any[]; + } + interface LodashInvokeArgsMap1x2 { + (methodName: string): LodashInvokeArgsMap1x3; + (methodNameOrMethod: lodash.__, collection: object | null | undefined): LodashInvokeArgsMap1x6; + (methodName: string, collection: object | null | undefined): any[]; + (method: (...args: any[]) => TResult): LodashInvokeArgsMap2x3; + (method: (...args: any[]) => TResult, collection: object | null | undefined): TResult[]; + } + type LodashInvokeArgsMap1x3 = (collection: object | null | undefined) => any[]; + interface LodashInvokeArgsMap1x4 { + (methodName: string): LodashInvokeArgsMap1x5; + (methodNameOrMethod: lodash.__, args: ReadonlyArray): LodashInvokeArgsMap1x6; + (methodName: string, args: ReadonlyArray): any[]; + (method: (...args: any[]) => TResult): LodashInvokeArgsMap2x5; + (method: (...args: any[]) => TResult, args: ReadonlyArray): TResult[]; + } + type LodashInvokeArgsMap1x5 = (args: ReadonlyArray) => any[]; + interface LodashInvokeArgsMap1x6 { + (methodName: string): any[]; + (method: (...args: any[]) => TResult): TResult[]; + } + interface LodashInvokeArgsMap2x1 { + (args: ReadonlyArray): LodashInvokeArgsMap2x3; + (args: lodash.__, collection: object | null | undefined): LodashInvokeArgsMap2x5; + (args: ReadonlyArray, collection: object | null | undefined): TResult[]; + } + type LodashInvokeArgsMap2x3 = (collection: object | null | undefined) => TResult[]; + type LodashInvokeArgsMap2x5 = (args: ReadonlyArray) => TResult[]; + interface LodashInvokeMap { + (methodName: string): LodashInvokeMap1x1; + (methodNameOrMethod: lodash.__, collection: object | null | undefined): LodashInvokeMap1x2; + (methodName: string, collection: object | null | undefined): any[]; + (method: (...args: any[]) => TResult): LodashInvokeMap2x1; + (method: (...args: any[]) => TResult, collection: object | null | undefined): TResult[]; + } + type LodashInvokeMap1x1 = (collection: object | null | undefined) => any[]; + interface LodashInvokeMap1x2 { + (methodName: string): any[]; + (method: (...args: any[]) => TResult): TResult[]; + } + type LodashInvokeMap2x1 = (collection: object | null | undefined) => TResult[]; + type LodashIsArguments = (value: any) => value is IArguments; + type LodashIsArray = (value: any) => value is any[]; + type LodashIsArrayBuffer = (value: any) => value is ArrayBuffer; + interface LodashIsArrayLike { + (t: T): boolean; + (value: ((...args: any[]) => any) | null | undefined): value is never; + (value: any): value is { length: number }; + } + interface LodashIsArrayLikeObject { + (value: T): boolean; + (value: ((...args: any[]) => any) | lodash.FunctionBase | string | boolean | number | null | undefined): value is never; + (value: any): value is object & { length: number }; + } + type LodashIsBoolean = (value: any) => value is boolean; + type LodashIsBuffer = (value: any) => boolean; + type LodashIsDate = (value: any) => value is Date; + type LodashIsElement = (value: any) => boolean; + interface LodashIsEmpty { + (value: T): boolean; + (value: string | null | undefined): value is '' | null | undefined; + (value: any[] | null | undefined): boolean; + (value: ReadonlyArray | null | undefined): value is Readonly<[]> | null | undefined; + (value: Map | Set | lodash.List | null | undefined): boolean; + (value: T | null | undefined): value is lodash.EmptyObjectOf | null | undefined; + (value?: any): boolean; + } + interface LodashIsEqualWith { + (customizer: lodash.IsEqualCustomizer): LodashIsEqualWith1x1; + (customizer: lodash.__, value: any): LodashIsEqualWith1x2; + (customizer: lodash.IsEqualCustomizer, value: any): LodashIsEqualWith1x3; + (customizer: lodash.__, value: lodash.__, other: any): LodashIsEqualWith1x4; + (customizer: lodash.IsEqualCustomizer, value: lodash.__, other: any): LodashIsEqualWith1x5; + (customizer: lodash.__, value: any, other: any): LodashIsEqualWith1x6; + (customizer: lodash.IsEqualCustomizer, value: any, other: any): boolean; + } + interface LodashIsEqualWith1x1 { + (value: any): LodashIsEqualWith1x3; + (value: lodash.__, other: any): LodashIsEqualWith1x5; + (value: any, other: any): boolean; + } + interface LodashIsEqualWith1x2 { + (customizer: lodash.IsEqualCustomizer): LodashIsEqualWith1x3; + (customizer: lodash.__, other: any): LodashIsEqualWith1x6; + (customizer: lodash.IsEqualCustomizer, other: any): boolean; + } + type LodashIsEqualWith1x3 = (other: any) => boolean; + interface LodashIsEqualWith1x4 { + (customizer: lodash.IsEqualCustomizer): LodashIsEqualWith1x5; + (customizer: lodash.__, value: any): LodashIsEqualWith1x6; + (customizer: lodash.IsEqualCustomizer, value: any): boolean; + } + type LodashIsEqualWith1x5 = (value: any) => boolean; + type LodashIsEqualWith1x6 = (customizer: lodash.IsEqualCustomizer) => boolean; + type LodashIsError = (value: any) => value is Error; + type LodashIsFinite = (value: any) => boolean; + type LodashIsFunction = (value: any) => value is (...args: any[]) => any; + type LodashIsInteger = (value: any) => boolean; + type LodashIsLength = (value: any) => boolean; + type LodashIsMap = (value: any) => value is Map; + interface LodashIsMatch { + (source: object): LodashIsMatch1x1; + (source: lodash.__, object: object): LodashIsMatch1x2; + (source: object, object: object): boolean; + } + type LodashIsMatch1x1 = (object: object) => boolean; + type LodashIsMatch1x2 = (source: object) => boolean; + interface LodashIsMatchWith { + (customizer: lodash.isMatchWithCustomizer): LodashIsMatchWith1x1; + (customizer: lodash.__, source: object): LodashIsMatchWith1x2; + (customizer: lodash.isMatchWithCustomizer, source: object): LodashIsMatchWith1x3; + (customizer: lodash.__, source: lodash.__, object: object): LodashIsMatchWith1x4; + (customizer: lodash.isMatchWithCustomizer, source: lodash.__, object: object): LodashIsMatchWith1x5; + (customizer: lodash.__, source: object, object: object): LodashIsMatchWith1x6; + (customizer: lodash.isMatchWithCustomizer, source: object, object: object): boolean; + } + interface LodashIsMatchWith1x1 { + (source: object): LodashIsMatchWith1x3; + (source: lodash.__, object: object): LodashIsMatchWith1x5; + (source: object, object: object): boolean; + } + interface LodashIsMatchWith1x2 { + (customizer: lodash.isMatchWithCustomizer): LodashIsMatchWith1x3; + (customizer: lodash.__, object: object): LodashIsMatchWith1x6; + (customizer: lodash.isMatchWithCustomizer, object: object): boolean; + } + type LodashIsMatchWith1x3 = (object: object) => boolean; + interface LodashIsMatchWith1x4 { + (customizer: lodash.isMatchWithCustomizer): LodashIsMatchWith1x5; + (customizer: lodash.__, source: object): LodashIsMatchWith1x6; + (customizer: lodash.isMatchWithCustomizer, source: object): boolean; + } + type LodashIsMatchWith1x5 = (source: object) => boolean; + type LodashIsMatchWith1x6 = (customizer: lodash.isMatchWithCustomizer) => boolean; + type LodashIsNaN = (value: any) => boolean; + type LodashIsNative = (value: any) => value is (...args: any[]) => any; + type LodashIsNil = (value: any) => value is null | undefined; + type LodashIsNull = (value: any) => value is null; + type LodashIsNumber = (value: any) => value is number; + type LodashIsObject = (value: any) => value is object; + type LodashIsObjectLike = (value: any) => boolean; + type LodashIsPlainObject = (value: any) => boolean; + type LodashIsRegExp = (value: any) => value is RegExp; + type LodashIsSafeInteger = (value: any) => boolean; + type LodashIsSet = (value: any) => value is Set; + type LodashIsString = (value: any) => value is string; + type LodashIsSymbol = (value: any) => value is symbol; + type LodashIsTypedArray = (value: any) => boolean; + type LodashIsUndefined = (value: any) => value is undefined; + type LodashIsWeakMap = (value: any) => value is WeakMap; + type LodashIsWeakSet = (value: any) => value is WeakSet; + interface LodashIteratee { + any>(func: TFunction): TFunction; + (func: string | object): (...args: any[]) => any; + } + interface LodashJoin { + (separator: string): LodashJoin1x1; + (separator: lodash.__, array: lodash.List | null | undefined): LodashJoin1x2; + (separator: string, array: lodash.List | null | undefined): string; + } + type LodashJoin1x1 = (array: lodash.List | null | undefined) => string; + type LodashJoin1x2 = (separator: string) => string; + type LodashOver = (iteratees: lodash.Many<(...args: any[]) => TResult>) => (...args: any[]) => TResult[]; + type LodashKebabCase = (string: string) => string; + type LodashKeys = (object: any) => string[]; + type LodashKeysIn = (object: any) => string[]; + type LodashLast = (array: lodash.List | null | undefined) => T | undefined; + interface LodashLastIndexOf { + (value: T): LodashLastIndexOf1x1; + (value: lodash.__, array: lodash.List | null | undefined): LodashLastIndexOf1x2; + (value: T, array: lodash.List | null | undefined): number; + } + type LodashLastIndexOf1x1 = (array: lodash.List | null | undefined) => number; + type LodashLastIndexOf1x2 = (value: T) => number; + interface LodashLastIndexOfFrom { + (value: T): LodashLastIndexOfFrom1x1; + (value: lodash.__, fromIndex: true|number): LodashLastIndexOfFrom1x2; + (value: T, fromIndex: true|number): LodashLastIndexOfFrom1x3; + (value: lodash.__, fromIndex: lodash.__, array: lodash.List | null | undefined): LodashLastIndexOfFrom1x4; + (value: T, fromIndex: lodash.__, array: lodash.List | null | undefined): LodashLastIndexOfFrom1x5; + (value: lodash.__, fromIndex: true|number, array: lodash.List | null | undefined): LodashLastIndexOfFrom1x6; + (value: T, fromIndex: true|number, array: lodash.List | null | undefined): number; + } + interface LodashLastIndexOfFrom1x1 { + (fromIndex: true|number): LodashLastIndexOfFrom1x3; + (fromIndex: lodash.__, array: lodash.List | null | undefined): LodashLastIndexOfFrom1x5; + (fromIndex: true|number, array: lodash.List | null | undefined): number; + } + interface LodashLastIndexOfFrom1x2 { + (value: T): LodashLastIndexOfFrom1x3; + (value: lodash.__, array: lodash.List | null | undefined): LodashLastIndexOfFrom1x6; + (value: T, array: lodash.List | null | undefined): number; + } + type LodashLastIndexOfFrom1x3 = (array: lodash.List | null | undefined) => number; + interface LodashLastIndexOfFrom1x4 { + (value: T): LodashLastIndexOfFrom1x5; + (value: lodash.__, fromIndex: true|number): LodashLastIndexOfFrom1x6; + (value: T, fromIndex: true|number): number; + } + type LodashLastIndexOfFrom1x5 = (fromIndex: true|number) => number; + type LodashLastIndexOfFrom1x6 = (value: T) => number; + type LodashLowerCase = (string: string) => string; + type LodashLowerFirst = (string: string) => string; + interface LodashLt { + (value: any): LodashLt1x1; + (value: lodash.__, other: any): LodashLt1x2; + (value: any, other: any): boolean; + } + type LodashLt1x1 = (other: any) => boolean; + type LodashLt1x2 = (value: any) => boolean; + interface LodashLte { + (value: any): LodashLte1x1; + (value: lodash.__, other: any): LodashLte1x2; + (value: any, other: any): boolean; + } + type LodashLte1x1 = (other: any) => boolean; + type LodashLte1x2 = (value: any) => boolean; + interface LodashMap { + (iteratee: (value: T) => TResult): LodashMap1x1; + (iteratee: lodash.__, collection: T[] | null | undefined): LodashMap1x2; + (iteratee: (value: T) => TResult, collection: T[] | lodash.List | null | undefined): TResult[]; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashMap2x2; + (iteratee: (value: T[keyof T]) => TResult): LodashMap3x1; + (iteratee: lodash.__, collection: T | null | undefined): LodashMap3x2; + (iteratee: (value: T[keyof T]) => TResult, collection: T | null | undefined): TResult[]; + (iteratee: K): LodashMap4x1; + (iteratee: lodash.__, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashMap4x2; + (iteratee: K, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): Array; + (iteratee: string): LodashMap5x1; + (iteratee: string, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): any[]; + (iteratee: object): LodashMap6x1; + (iteratee: object, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): boolean[]; + } + type LodashMap1x1 = (collection: T[] | lodash.List | null | undefined) => TResult[]; + type LodashMap1x2 = (iteratee: (value: T) => TResult) => TResult[]; + type LodashMap2x2 = (iteratee: (value: T) => TResult) => TResult[]; + type LodashMap3x1 = (collection: T | null | undefined) => TResult[]; + type LodashMap3x2 = (iteratee: (value: T[keyof T]) => TResult) => TResult[]; + type LodashMap4x1 = (collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined) => Array; + interface LodashMap4x2 { + (iteratee: K): Array; + (iteratee: string): any[]; + (iteratee: object): boolean[]; + } + type LodashMap5x1 = (collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined) => any[]; + type LodashMap6x1 = (collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined) => boolean[]; + interface LodashMapKeys { + (iteratee: lodash.ValueIteratee): LodashMapKeys1x1; + (iteratee: lodash.__, object: lodash.List | null | undefined): LodashMapKeys1x2; + (iteratee: lodash.ValueIteratee, object: lodash.List | null | undefined): lodash.Dictionary; + (iteratee: lodash.ValueIteratee): LodashMapKeys2x1; + (iteratee: lodash.__, object: T | null | undefined): LodashMapKeys2x2; + (iteratee: lodash.ValueIteratee, object: T | null | undefined): lodash.Dictionary; + } + type LodashMapKeys1x1 = (object: lodash.List | null | undefined) => lodash.Dictionary; + type LodashMapKeys1x2 = (iteratee: lodash.ValueIteratee) => lodash.Dictionary; + type LodashMapKeys2x1 = (object: T | null | undefined) => lodash.Dictionary; + type LodashMapKeys2x2 = (iteratee: lodash.ValueIteratee) => lodash.Dictionary; + interface LodashMapValues { + (callback: (value: T) => TResult): LodashMapValues1x1; + (callbackOrIterateeOrIterateeOrIteratee: lodash.__, obj: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashMapValues1x2; + (callback: (value: T) => TResult, obj: lodash.Dictionary | lodash.NumericDictionary | null | undefined): lodash.Dictionary; + (callback: (value: T[keyof T]) => TResult): LodashMapValues2x1; + (callbackOrIterateeOrIteratee: lodash.__, obj: T | null | undefined): LodashMapValues2x2; + (callback: (value: T[keyof T]) => TResult, obj: T | null | undefined): { [P in keyof T]: TResult }; + (iteratee: object): LodashMapValues3x1; + (iteratee: object, obj: lodash.Dictionary | lodash.NumericDictionary | null | undefined): lodash.Dictionary; + (iteratee: object, obj: T | null | undefined): { [P in keyof T]: boolean }; + (iteratee: TKey): LodashMapValues5x1; + (iteratee: TKey, obj: lodash.Dictionary | lodash.NumericDictionary | null | undefined): lodash.Dictionary; + (iteratee: string): LodashMapValues6x1; + (iteratee: string, obj: lodash.Dictionary | lodash.NumericDictionary | null | undefined): lodash.Dictionary; + (iteratee: string, obj: T | null | undefined): { [P in keyof T]: any }; + } + type LodashMapValues1x1 = (obj: lodash.Dictionary | lodash.NumericDictionary | null | undefined) => lodash.Dictionary; + interface LodashMapValues1x2 { + (callback: (value: T) => TResult): lodash.Dictionary; + (iteratee: object): lodash.Dictionary; + (iteratee: TKey): lodash.Dictionary; + (iteratee: string): lodash.Dictionary; + } + type LodashMapValues2x1 = (obj: T | null | undefined) => { [P in keyof T]: TResult }; + interface LodashMapValues2x2 { + (callback: (value: T[keyof T]) => TResult): { [P in keyof T]: TResult }; + (iteratee: object): { [P in keyof T]: boolean }; + (iteratee: string): { [P in keyof T]: any }; + } + interface LodashMapValues3x1 { + (obj: lodash.Dictionary | lodash.NumericDictionary | null | undefined): lodash.Dictionary; + (obj: T | null | undefined): { [P in keyof T]: boolean }; + } + type LodashMapValues5x1 = (obj: lodash.Dictionary | lodash.NumericDictionary | null | undefined) => lodash.Dictionary; + interface LodashMapValues6x1 { + (obj: lodash.Dictionary | lodash.NumericDictionary | null | undefined): lodash.Dictionary; + (obj: T | null | undefined): { [P in keyof T]: any }; + } + interface LodashMatchesProperty { + (path: lodash.PropertyPath): LodashMatchesProperty1x1; + (path: lodash.__, srcValue: T): LodashMatchesProperty1x2; + (path: lodash.PropertyPath, srcValue: T): (value: any) => boolean; + } + type LodashMatchesProperty1x1 = (srcValue: T) => (value: any) => boolean; + type LodashMatchesProperty1x2 = (path: lodash.PropertyPath) => (value: any) => boolean; + type LodashMax = (collection: lodash.List | null | undefined) => T | undefined; + interface LodashMaxBy { + (iteratee: lodash.ValueIteratee): LodashMaxBy1x1; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashMaxBy1x2; + (iteratee: lodash.ValueIteratee, collection: lodash.List | null | undefined): T | undefined; + } + type LodashMaxBy1x1 = (collection: lodash.List | null | undefined) => T | undefined; + type LodashMaxBy1x2 = (iteratee: lodash.ValueIteratee) => T | undefined; + type LodashMean = (collection: lodash.List | null | undefined) => number; + interface LodashMeanBy { + (iteratee: lodash.ValueIteratee): LodashMeanBy1x1; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashMeanBy1x2; + (iteratee: lodash.ValueIteratee, collection: lodash.List | null | undefined): number; + } + type LodashMeanBy1x1 = (collection: lodash.List | null | undefined) => number; + type LodashMeanBy1x2 = (iteratee: lodash.ValueIteratee) => number; + type LodashMemoize = any>(func: T) => T & lodash.MemoizedFunction; + interface LodashMerge { + (object: TObject): LodashMerge1x1; + (object: lodash.__, source: TSource): LodashMerge1x2; + (object: TObject, source: TSource): TObject & TSource; + } + type LodashMerge1x1 = (source: TSource) => TObject & TSource; + type LodashMerge1x2 = (object: TObject) => TObject & TSource; + interface LodashMergeAll { + (object: [TObject, TSource]): TObject & TSource; + (object: [TObject, TSource1, TSource2]): TObject & TSource1 & TSource2; + (object: [TObject, TSource1, TSource2, TSource3]): TObject & TSource1 & TSource2 & TSource3; + (object: [TObject, TSource1, TSource2, TSource3, TSource4]): TObject & TSource1 & TSource2 & TSource3 & TSource4; + (object: ReadonlyArray): any; + } + interface LodashMergeAllWith { + (customizer: lodash.MergeWithCustomizer): LodashMergeAllWith1x1; + (customizer: lodash.__, args: ReadonlyArray): LodashMergeAllWith1x2; + (customizer: lodash.MergeWithCustomizer, args: ReadonlyArray): any; + } + type LodashMergeAllWith1x1 = (args: ReadonlyArray) => any; + type LodashMergeAllWith1x2 = (customizer: lodash.MergeWithCustomizer) => any; + interface LodashMergeWith { + (customizer: lodash.MergeWithCustomizer): LodashMergeWith1x1; + (customizer: lodash.__, object: TObject): LodashMergeWith1x2; + (customizer: lodash.MergeWithCustomizer, object: TObject): LodashMergeWith1x3; + (customizer: lodash.__, object: lodash.__, source: TSource): LodashMergeWith1x4; + (customizer: lodash.MergeWithCustomizer, object: lodash.__, source: TSource): LodashMergeWith1x5; + (customizer: lodash.__, object: TObject, source: TSource): LodashMergeWith1x6; + (customizer: lodash.MergeWithCustomizer, object: TObject, source: TSource): TObject & TSource; + } + interface LodashMergeWith1x1 { + (object: TObject): LodashMergeWith1x3; + (object: lodash.__, source: TSource): LodashMergeWith1x5; + (object: TObject, source: TSource): TObject & TSource; + } + interface LodashMergeWith1x2 { + (customizer: lodash.MergeWithCustomizer): LodashMergeWith1x3; + (customizer: lodash.__, source: TSource): LodashMergeWith1x6; + (customizer: lodash.MergeWithCustomizer, source: TSource): TObject & TSource; + } + type LodashMergeWith1x3 = (source: TSource) => TObject & TSource; + interface LodashMergeWith1x4 { + (customizer: lodash.MergeWithCustomizer): LodashMergeWith1x5; + (customizer: lodash.__, object: TObject): LodashMergeWith1x6; + (customizer: lodash.MergeWithCustomizer, object: TObject): TObject & TSource; + } + type LodashMergeWith1x5 = (object: TObject) => TObject & TSource; + type LodashMergeWith1x6 = (customizer: lodash.MergeWithCustomizer) => TObject & TSource; + type LodashMethod = (path: lodash.PropertyPath) => (object: any) => any; + type LodashMethodOf = (object: object) => (path: lodash.PropertyPath) => any; + type LodashMin = (collection: lodash.List | null | undefined) => T | undefined; + interface LodashMinBy { + (iteratee: lodash.ValueIteratee): LodashMinBy1x1; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashMinBy1x2; + (iteratee: lodash.ValueIteratee, collection: lodash.List | null | undefined): T | undefined; + } + type LodashMinBy1x1 = (collection: lodash.List | null | undefined) => T | undefined; + type LodashMinBy1x2 = (iteratee: lodash.ValueIteratee) => T | undefined; + interface LodashMultiply { + (multiplier: number): LodashMultiply1x1; + (multiplier: lodash.__, multiplicand: number): LodashMultiply1x2; + (multiplier: number, multiplicand: number): number; + } + type LodashMultiply1x1 = (multiplicand: number) => number; + type LodashMultiply1x2 = (multiplier: number) => number; + type LodashNoConflict = () => typeof _; + type LodashNoop = (...args: any[]) => void; + type LodashNow = () => number; + interface LodashNth { + (n: number): LodashNth1x1; + (n: lodash.__, array: lodash.List | null | undefined): LodashNth1x2; + (n: number, array: lodash.List | null | undefined): T | undefined; + } + type LodashNth1x1 = (array: lodash.List | null | undefined) => T | undefined; + type LodashNth1x2 = (n: number) => T | undefined; + type LodashNthArg = (n: number) => (...args: any[]) => any; + interface LodashOmit { + (paths: lodash.Many): LodashOmit1x1; + (paths: lodash.__, object: T | null | undefined): LodashOmit1x2; + (paths: lodash.Many, object: T | null | undefined): lodash.Omit; + (paths: lodash.Many): LodashOmit2x1; + (paths: lodash.Many, object: T | null | undefined): lodash.PartialObject; + } + type LodashOmit1x1 = (object: T | null | undefined) => lodash.Omit; + interface LodashOmit1x2 { + (paths: lodash.Many): lodash.Omit; + (paths: lodash.Many): lodash.PartialObject; + } + type LodashOmit2x1 = (object: T | null | undefined) => lodash.PartialObject; + interface LodashOmitBy { + (predicate: lodash.ValueKeyIteratee): LodashOmitBy1x1; + (predicate: lodash.__, object: lodash.Dictionary | null | undefined): LodashOmitBy1x2; + (predicate: lodash.ValueKeyIteratee, object: lodash.Dictionary | null | undefined): lodash.Dictionary; + (predicate: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashOmitBy2x2; + (predicate: lodash.ValueKeyIteratee, object: lodash.NumericDictionary | null | undefined): lodash.NumericDictionary; + (predicate: lodash.__, object: T | null | undefined): LodashOmitBy3x2; + (predicate: lodash.ValueKeyIteratee, object: T | null | undefined): lodash.PartialObject; + } + interface LodashOmitBy1x1 { + (object: lodash.Dictionary | null | undefined): lodash.Dictionary; + (object: lodash.NumericDictionary | null | undefined): lodash.NumericDictionary; + (object: T1 | null | undefined): lodash.PartialObject; + } + type LodashOmitBy1x2 = (predicate: lodash.ValueKeyIteratee) => lodash.Dictionary; + type LodashOmitBy2x2 = (predicate: lodash.ValueKeyIteratee) => lodash.NumericDictionary; + type LodashOmitBy3x2 = (predicate: lodash.ValueKeyIteratee) => lodash.PartialObject; + type LodashOnce = any>(func: T) => T; + interface LodashOrderBy { + (iteratees: lodash.Many<(value: T) => lodash.NotVoid>): LodashOrderBy1x1; + (iteratees: lodash.__, orders: lodash.Many): LodashOrderBy1x2; + (iteratees: lodash.Many<(value: T) => lodash.NotVoid>, orders: lodash.Many): LodashOrderBy1x3; + (iteratees: lodash.__, orders: lodash.__, collection: lodash.List | null | undefined): LodashOrderBy1x4; + (iteratees: lodash.Many<(value: T) => lodash.NotVoid>, orders: lodash.__, collection: lodash.List | null | undefined): LodashOrderBy1x5; + (iteratees: lodash.__, orders: lodash.Many, collection: lodash.List | null | undefined): LodashOrderBy1x6; + (iteratees: lodash.Many<(value: T) => lodash.NotVoid> | lodash.Many>, orders: lodash.Many, collection: lodash.List | null | undefined): T[]; + (iteratees: lodash.Many>): LodashOrderBy2x1; + (iteratees: lodash.Many>, orders: lodash.Many): LodashOrderBy2x3; + (iteratees: lodash.Many>, orders: lodash.__, collection: lodash.List | null | undefined): LodashOrderBy2x5; + (iteratees: lodash.__, orders: lodash.__, collection: T | null | undefined): LodashOrderBy3x4; + (iteratees: lodash.Many<(value: T[keyof T]) => lodash.NotVoid>, orders: lodash.__, collection: T | null | undefined): LodashOrderBy3x5; + (iteratees: lodash.__, orders: lodash.Many, collection: T | null | undefined): LodashOrderBy3x6; + (iteratees: lodash.Many<(value: T[keyof T]) => lodash.NotVoid> | lodash.Many>, orders: lodash.Many, collection: T | null | undefined): Array; + (iteratees: lodash.Many>, orders: lodash.__, collection: T | null | undefined): LodashOrderBy4x5; + } + interface LodashOrderBy1x1 { + (orders: lodash.Many): LodashOrderBy1x3; + (orders: lodash.__, collection: lodash.List | null | undefined): LodashOrderBy1x5; + (orders: lodash.Many, collection: lodash.List | object | null | undefined): T[]; + (orders: lodash.__, collection: T1 | null | undefined): LodashOrderBy3x5; + } + interface LodashOrderBy1x2 { + (iteratees: lodash.Many<(value: T) => lodash.NotVoid>): LodashOrderBy1x3; + (iteratees: lodash.__, collection: lodash.List | null | undefined): LodashOrderBy1x6; + (iteratees: lodash.Many<(value: T) => lodash.NotVoid> | lodash.Many>, collection: lodash.List | null | undefined): T[]; + (iteratees: lodash.Many>): LodashOrderBy2x3; + (iteratees: lodash.__, collection: T | null | undefined): LodashOrderBy3x6; + (iteratees: lodash.Many<(value: T[keyof T]) => lodash.NotVoid> | lodash.Many>, collection: T | null | undefined): Array; + } + interface LodashOrderBy1x3 { + (collection: lodash.List | null | undefined): T[]; + (collection: object | null | undefined): object[]; + } + interface LodashOrderBy1x4 { + (iteratees: lodash.Many<(value: T) => lodash.NotVoid>): LodashOrderBy1x5; + (iteratees: lodash.__, orders: lodash.Many): LodashOrderBy1x6; + (iteratees: lodash.Many<(value: T) => lodash.NotVoid> | lodash.Many>, orders: lodash.Many): T[]; + (iteratees: lodash.Many>): LodashOrderBy2x5; + } + type LodashOrderBy1x5 = (orders: lodash.Many) => T[]; + type LodashOrderBy1x6 = (iteratees: lodash.Many<(value: T) => lodash.NotVoid> | lodash.Many>) => T[]; + interface LodashOrderBy2x1 { + (orders: lodash.Many): LodashOrderBy2x3; + (orders: lodash.__, collection: lodash.List | null | undefined): LodashOrderBy2x5; + (orders: lodash.Many, collection: lodash.List | object | null | undefined): T[]; + (orders: lodash.__, collection: T1 | null | undefined): LodashOrderBy4x5; + } + interface LodashOrderBy2x3 { + (collection: lodash.List | null | undefined): T[]; + (collection: object | null | undefined): object[]; + } + type LodashOrderBy2x5 = (orders: lodash.Many) => T[]; + interface LodashOrderBy3x4 { + (iteratees: lodash.Many<(value: T[keyof T]) => lodash.NotVoid>): LodashOrderBy3x5; + (iteratees: lodash.__, orders: lodash.Many): LodashOrderBy3x6; + (iteratees: lodash.Many<(value: T[keyof T]) => lodash.NotVoid> | lodash.Many>, orders: lodash.Many): Array; + (iteratees: lodash.Many>): LodashOrderBy4x5; + } + type LodashOrderBy3x5 = (orders: lodash.Many) => Array; + type LodashOrderBy3x6 = (iteratees: lodash.Many<(value: T[keyof T]) => lodash.NotVoid> | lodash.Many>) => Array; + type LodashOrderBy4x5 = (orders: lodash.Many) => Array; + interface LodashOverArgs { + (func: (...args: any[]) => any): LodashOverArgs1x1; + (func: lodash.__, transforms: lodash.Many<(...args: any[]) => any>): LodashOverArgs1x2; + (func: (...args: any[]) => any, transforms: lodash.Many<(...args: any[]) => any>): (...args: any[]) => any; + } + type LodashOverArgs1x1 = (transforms: lodash.Many<(...args: any[]) => any>) => (...args: any[]) => any; + type LodashOverArgs1x2 = (func: (...args: any[]) => any) => (...args: any[]) => any; + interface LodashPad { + (length: number): LodashPad1x1; + (length: lodash.__, string: string): LodashPad1x2; + (length: number, string: string): string; + } + type LodashPad1x1 = (string: string) => string; + type LodashPad1x2 = (length: number) => string; + interface LodashPadChars { + (chars: string): LodashPadChars1x1; + (chars: lodash.__, length: number): LodashPadChars1x2; + (chars: string, length: number): LodashPadChars1x3; + (chars: lodash.__, length: lodash.__, string: string): LodashPadChars1x4; + (chars: string, length: lodash.__, string: string): LodashPadChars1x5; + (chars: lodash.__, length: number, string: string): LodashPadChars1x6; + (chars: string, length: number, string: string): string; + } + interface LodashPadChars1x1 { + (length: number): LodashPadChars1x3; + (length: lodash.__, string: string): LodashPadChars1x5; + (length: number, string: string): string; + } + interface LodashPadChars1x2 { + (chars: string): LodashPadChars1x3; + (chars: lodash.__, string: string): LodashPadChars1x6; + (chars: string, string: string): string; + } + type LodashPadChars1x3 = (string: string) => string; + interface LodashPadChars1x4 { + (chars: string): LodashPadChars1x5; + (chars: lodash.__, length: number): LodashPadChars1x6; + (chars: string, length: number): string; + } + type LodashPadChars1x5 = (length: number) => string; + type LodashPadChars1x6 = (chars: string) => string; + interface LodashPadCharsEnd { + (chars: string): LodashPadCharsEnd1x1; + (chars: lodash.__, length: number): LodashPadCharsEnd1x2; + (chars: string, length: number): LodashPadCharsEnd1x3; + (chars: lodash.__, length: lodash.__, string: string): LodashPadCharsEnd1x4; + (chars: string, length: lodash.__, string: string): LodashPadCharsEnd1x5; + (chars: lodash.__, length: number, string: string): LodashPadCharsEnd1x6; + (chars: string, length: number, string: string): string; + } + interface LodashPadCharsEnd1x1 { + (length: number): LodashPadCharsEnd1x3; + (length: lodash.__, string: string): LodashPadCharsEnd1x5; + (length: number, string: string): string; + } + interface LodashPadCharsEnd1x2 { + (chars: string): LodashPadCharsEnd1x3; + (chars: lodash.__, string: string): LodashPadCharsEnd1x6; + (chars: string, string: string): string; + } + type LodashPadCharsEnd1x3 = (string: string) => string; + interface LodashPadCharsEnd1x4 { + (chars: string): LodashPadCharsEnd1x5; + (chars: lodash.__, length: number): LodashPadCharsEnd1x6; + (chars: string, length: number): string; + } + type LodashPadCharsEnd1x5 = (length: number) => string; + type LodashPadCharsEnd1x6 = (chars: string) => string; + interface LodashPadCharsStart { + (chars: string): LodashPadCharsStart1x1; + (chars: lodash.__, length: number): LodashPadCharsStart1x2; + (chars: string, length: number): LodashPadCharsStart1x3; + (chars: lodash.__, length: lodash.__, string: string): LodashPadCharsStart1x4; + (chars: string, length: lodash.__, string: string): LodashPadCharsStart1x5; + (chars: lodash.__, length: number, string: string): LodashPadCharsStart1x6; + (chars: string, length: number, string: string): string; + } + interface LodashPadCharsStart1x1 { + (length: number): LodashPadCharsStart1x3; + (length: lodash.__, string: string): LodashPadCharsStart1x5; + (length: number, string: string): string; + } + interface LodashPadCharsStart1x2 { + (chars: string): LodashPadCharsStart1x3; + (chars: lodash.__, string: string): LodashPadCharsStart1x6; + (chars: string, string: string): string; + } + type LodashPadCharsStart1x3 = (string: string) => string; + interface LodashPadCharsStart1x4 { + (chars: string): LodashPadCharsStart1x5; + (chars: lodash.__, length: number): LodashPadCharsStart1x6; + (chars: string, length: number): string; + } + type LodashPadCharsStart1x5 = (length: number) => string; + type LodashPadCharsStart1x6 = (chars: string) => string; + interface LodashPadEnd { + (length: number): LodashPadEnd1x1; + (length: lodash.__, string: string): LodashPadEnd1x2; + (length: number, string: string): string; + } + type LodashPadEnd1x1 = (string: string) => string; + type LodashPadEnd1x2 = (length: number) => string; + interface LodashPadStart { + (length: number): LodashPadStart1x1; + (length: lodash.__, string: string): LodashPadStart1x2; + (length: number, string: string): string; + } + type LodashPadStart1x1 = (string: string) => string; + type LodashPadStart1x2 = (length: number) => string; + interface LodashParseInt { + (radix: number): LodashParseInt1x1; + (radix: lodash.__, string: string): LodashParseInt1x2; + (radix: number, string: string): number; + } + type LodashParseInt1x1 = (string: string) => number; + type LodashParseInt1x2 = (radix: number) => number; + interface LodashPartial { + (func: lodash.Function2): LodashPartial1x1; + (func: lodash.__, plc1: [lodash.__, T2]): LodashPartial1x2; + (func: lodash.Function2, plc1: [lodash.__, T2]): lodash.Function1; + (func: lodash.Function3): LodashPartial2x1; + (func: lodash.Function3, plc1: [lodash.__, T2]): lodash.Function2; + (func: lodash.__, plc1: [lodash.__, lodash.__, T3]): LodashPartial3x2; + (func: lodash.Function3, plc1: [lodash.__, lodash.__, T3]): lodash.Function2; + (func: lodash.__, arg1: [T1, lodash.__, T3]): LodashPartial4x2; + (func: lodash.Function3, arg1: [T1, lodash.__, T3]): lodash.Function1; + (func: lodash.__, plc1: [lodash.__, T2, T3]): LodashPartial5x2; + (func: lodash.Function3, plc1: [lodash.__, T2, T3]): lodash.Function1; + (func: lodash.Function4): LodashPartial6x1; + (func: lodash.Function4, plc1: [lodash.__, T2]): lodash.Function3; + (func: lodash.Function4, plc1: [lodash.__, lodash.__, T3]): lodash.Function3; + (func: lodash.Function4, arg1: [T1, lodash.__, T3]): lodash.Function2; + (func: lodash.Function4, plc1: [lodash.__, T2, T3]): lodash.Function2; + (func: lodash.__, arg1OrT1: [T1, T2, T3]): LodashPartial10x2; + (func: lodash.Function4, arg1: [T1, T2, T3]): lodash.Function1; + (func: lodash.__, plc1: [lodash.__, lodash.__, lodash.__, T4]): LodashPartial11x2; + (func: lodash.Function4, plc1: [lodash.__, lodash.__, lodash.__, T4]): lodash.Function3; + (func: lodash.__, arg1: [T1, lodash.__, lodash.__, T4]): LodashPartial12x2; + (func: lodash.Function4, arg1: [T1, lodash.__, lodash.__, T4]): lodash.Function2; + (func: lodash.__, plc1: [lodash.__, T2, lodash.__, T4]): LodashPartial13x2; + (func: lodash.Function4, plc1: [lodash.__, T2, lodash.__, T4]): lodash.Function2; + (func: lodash.__, arg1: [T1, T2, lodash.__, T4]): LodashPartial14x2; + (func: lodash.Function4, arg1: [T1, T2, lodash.__, T4]): lodash.Function1; + (func: lodash.__, plc1: [lodash.__, lodash.__, T3, T4]): LodashPartial15x2; + (func: lodash.Function4, plc1: [lodash.__, lodash.__, T3, T4]): lodash.Function2; + (func: lodash.__, arg1: [T1, lodash.__, T3, T4]): LodashPartial16x2; + (func: lodash.Function4, arg1: [T1, lodash.__, T3, T4]): lodash.Function1; + (func: lodash.__, plc1: [lodash.__, T2, T3, T4]): LodashPartial17x2; + (func: lodash.Function4, plc1: [lodash.__, T2, T3, T4]): lodash.Function1; + (func: (t1: T1, ...ts: TS) => R): LodashPartial18x1; + (func: lodash.__, arg1: [T1]): LodashPartial18x2; + (func: (t1: T1, ...ts: TS) => R, arg1: [T1]): (...ts: TS) => R; + (func: (t1: T1, t2: T2, ...ts: TS) => R): LodashPartial19x1; + (func: lodash.__, t1: [T1, T2]): LodashPartial19x2; + (func: (t1: T1, t2: T2, ...ts: TS) => R, t1: [T1, T2]): (...ts: TS) => R; + (func: (t1: T1, t2: T2, t3: T3, ...ts: TS) => R): LodashPartial20x1; + (func: (t1: T1, t2: T2, t3: T3, ...ts: TS) => R, t1: [T1, T2, T3]): (...ts: TS) => R; + (func: (t1: T1, t2: T2, t3: T3, t4: T4, ...ts: TS) => R): LodashPartial21x1; + (func: lodash.__, t1: [T1, T2, T3, T4]): LodashPartial21x2; + (func: (t1: T1, t2: T2, t3: T3, t4: T4, ...ts: TS) => R, t1: [T1, T2, T3, T4]): (...ts: TS) => R; + placeholder: lodash.__; + } + type LodashPartial1x1 = (plc1: [lodash.__, T2]) => lodash.Function1; + interface LodashPartial1x2 { + (func: lodash.Function2): lodash.Function1; + (func: lodash.Function3): lodash.Function2; + (func: lodash.Function4): lodash.Function3; + } + interface LodashPartial2x1 { + (plc1: [lodash.__, T2]): lodash.Function2; + (plc1: [lodash.__, lodash.__, T3]): lodash.Function2; + (arg1: [T1, lodash.__, T3]): lodash.Function1; + (plc1: [lodash.__, T2, T3]): lodash.Function1; + } + interface LodashPartial3x2 { + (func: lodash.Function3): lodash.Function2; + (func: lodash.Function4): lodash.Function3; + } + interface LodashPartial4x2 { + (func: lodash.Function3): lodash.Function1; + (func: lodash.Function4): lodash.Function2; + } + interface LodashPartial5x2 { + (func: lodash.Function3): lodash.Function1; + (func: lodash.Function4): lodash.Function2; + } + interface LodashPartial6x1 { + (plc1: [lodash.__, T2]): lodash.Function3; + (plc1: [lodash.__, lodash.__, T3]): lodash.Function3; + (arg1: [T1, lodash.__, T3]): lodash.Function2; + (plc1: [lodash.__, T2, T3]): lodash.Function2; + (arg1: [T1, T2, T3]): lodash.Function1; + (plc1: [lodash.__, lodash.__, lodash.__, T4]): lodash.Function3; + (arg1: [T1, lodash.__, lodash.__, T4]): lodash.Function2; + (plc1: [lodash.__, T2, lodash.__, T4]): lodash.Function2; + (arg1: [T1, T2, lodash.__, T4]): lodash.Function1; + (plc1: [lodash.__, lodash.__, T3, T4]): lodash.Function2; + (arg1: [T1, lodash.__, T3, T4]): lodash.Function1; + (plc1: [lodash.__, T2, T3, T4]): lodash.Function1; + } + interface LodashPartial10x2 { + (func: lodash.Function4): lodash.Function1; + (func: (t1: T1, t2: T2, t3: T3, ...ts: TS) => R): (...ts: TS) => R; + } + type LodashPartial11x2 = (func: lodash.Function4) => lodash.Function3; + type LodashPartial12x2 = (func: lodash.Function4) => lodash.Function2; + type LodashPartial13x2 = (func: lodash.Function4) => lodash.Function2; + type LodashPartial14x2 = (func: lodash.Function4) => lodash.Function1; + type LodashPartial15x2 = (func: lodash.Function4) => lodash.Function2; + type LodashPartial16x2 = (func: lodash.Function4) => lodash.Function1; + type LodashPartial17x2 = (func: lodash.Function4) => lodash.Function1; + type LodashPartial18x1 = (arg1: [T1]) => (...ts: TS) => R; + type LodashPartial18x2 = (func: (t1: T1, ...ts: TS) => R) => (...ts: TS) => R; + type LodashPartial19x1 = (t1: [T1, T2]) => (...ts: TS) => R; + type LodashPartial19x2 = (func: (t1: T1, t2: T2, ...ts: TS) => R) => (...ts: TS) => R; + type LodashPartial20x1 = (t1: [T1, T2, T3]) => (...ts: TS) => R; + type LodashPartial21x1 = (t1: [T1, T2, T3, T4]) => (...ts: TS) => R; + type LodashPartial21x2 = (func: (t1: T1, t2: T2, t3: T3, t4: T4, ...ts: TS) => R) => (...ts: TS) => R; + interface LodashPartialRight { + (func: lodash.Function1): LodashPartialRight1x1; + (func: lodash.__, arg1: [T1]): LodashPartialRight1x2; + (func: lodash.Function1, arg1: [T1]): lodash.Function0; + (func: lodash.Function2): LodashPartialRight2x1; + (func: lodash.__, arg1: [T1, lodash.__]): LodashPartialRight2x2; + (func: lodash.Function2, arg1: [T1, lodash.__]): lodash.Function1; + (func: lodash.__, arg2: [T2]): LodashPartialRight3x2; + (func: lodash.Function2, arg2: [T2]): lodash.Function1; + (func: lodash.__, arg1: [T1, T2]): LodashPartialRight4x2; + (func: lodash.Function2, arg1: [T1, T2]): lodash.Function0; + (func: lodash.Function3): LodashPartialRight5x1; + (func: lodash.__, arg1: [T1, lodash.__, lodash.__]): LodashPartialRight5x2; + (func: lodash.Function3, arg1: [T1, lodash.__, lodash.__]): lodash.Function2; + (func: lodash.__, arg2: [T2, lodash.__]): LodashPartialRight6x2; + (func: lodash.Function3, arg2: [T2, lodash.__]): lodash.Function2; + (func: lodash.__, arg1: [T1, T2, lodash.__]): LodashPartialRight7x2; + (func: lodash.Function3, arg1: [T1, T2, lodash.__]): lodash.Function1; + (func: lodash.__, arg3: [T3]): LodashPartialRight8x2; + (func: lodash.Function3, arg3: [T3]): lodash.Function2; + (func: lodash.__, arg1: [T1, lodash.__, T3]): LodashPartialRight9x2; + (func: lodash.Function3, arg1: [T1, lodash.__, T3]): lodash.Function1; + (func: lodash.__, arg2: [T2, T3]): LodashPartialRight10x2; + (func: lodash.Function3, arg2: [T2, T3]): lodash.Function1; + (func: lodash.__, arg1: [T1, T2, T3]): LodashPartialRight11x2; + (func: lodash.Function3, arg1: [T1, T2, T3]): lodash.Function0; + (func: lodash.Function4): LodashPartialRight12x1; + (func: lodash.__, arg1: [T1, lodash.__, lodash.__, lodash.__]): LodashPartialRight12x2; + (func: lodash.Function4, arg1: [T1, lodash.__, lodash.__, lodash.__]): lodash.Function3; + (func: lodash.__, arg2: [T2, lodash.__, lodash.__]): LodashPartialRight13x2; + (func: lodash.Function4, arg2: [T2, lodash.__, lodash.__]): lodash.Function3; + (func: lodash.__, arg1: [T1, T2, lodash.__, lodash.__]): LodashPartialRight14x2; + (func: lodash.Function4, arg1: [T1, T2, lodash.__, lodash.__]): lodash.Function2; + (func: lodash.__, arg3: [T3, lodash.__]): LodashPartialRight15x2; + (func: lodash.Function4, arg3: [T3, lodash.__]): lodash.Function3; + (func: lodash.__, arg1: [T1, lodash.__, T3, lodash.__]): LodashPartialRight16x2; + (func: lodash.Function4, arg1: [T1, lodash.__, T3, lodash.__]): lodash.Function2; + (func: lodash.__, arg2: [T2, T3, lodash.__]): LodashPartialRight17x2; + (func: lodash.Function4, arg2: [T2, T3, lodash.__]): lodash.Function2; + (func: lodash.__, arg1: [T1, T2, T3, lodash.__]): LodashPartialRight18x2; + (func: lodash.Function4, arg1: [T1, T2, T3, lodash.__]): lodash.Function1; + (func: lodash.__, arg4: [T4]): LodashPartialRight19x2; + (func: lodash.Function4, arg4: [T4]): lodash.Function3; + (func: lodash.__, arg1: [T1, lodash.__, lodash.__, T4]): LodashPartialRight20x2; + (func: lodash.Function4, arg1: [T1, lodash.__, lodash.__, T4]): lodash.Function2; + (func: lodash.__, arg2: [T2, lodash.__, T4]): LodashPartialRight21x2; + (func: lodash.Function4, arg2: [T2, lodash.__, T4]): lodash.Function2; + (func: lodash.__, arg1: [T1, T2, lodash.__, T4]): LodashPartialRight22x2; + (func: lodash.Function4, arg1: [T1, T2, lodash.__, T4]): lodash.Function1; + (func: lodash.__, arg3: [T3, T4]): LodashPartialRight23x2; + (func: lodash.Function4, arg3: [T3, T4]): lodash.Function2; + (func: lodash.__, arg1: [T1, lodash.__, T3, T4]): LodashPartialRight24x2; + (func: lodash.Function4, arg1: [T1, lodash.__, T3, T4]): lodash.Function1; + (func: lodash.__, arg2: [T2, T3, T4]): LodashPartialRight25x2; + (func: lodash.Function4, arg2: [T2, T3, T4]): lodash.Function1; + (func: lodash.__, arg1: [T1, T2, T3, T4]): LodashPartialRight26x2; + (func: lodash.Function4, arg1: [T1, T2, T3, T4]): lodash.Function0; + (func: (...args: any[]) => any): LodashPartialRight27x1; + (func: lodash.__, args: ReadonlyArray): LodashPartialRight27x2; + (func: (...args: any[]) => any, args: ReadonlyArray): (...args: any[]) => any; + placeholder: lodash.__; + } + type LodashPartialRight1x1 = (arg1: [T1]) => lodash.Function0; + type LodashPartialRight1x2 = (func: lodash.Function1) => lodash.Function0; + interface LodashPartialRight2x1 { + (arg1: [T1, lodash.__]): lodash.Function1; + (arg2: [T2]): lodash.Function1; + (arg1: [T1, T2]): lodash.Function0; + } + type LodashPartialRight2x2 = (func: lodash.Function2) => lodash.Function1; + type LodashPartialRight3x2 = (func: lodash.Function2) => lodash.Function1; + type LodashPartialRight4x2 = (func: lodash.Function2) => lodash.Function0; + interface LodashPartialRight5x1 { + (arg1: [T1, lodash.__, lodash.__]): lodash.Function2; + (arg2: [T2, lodash.__]): lodash.Function2; + (arg1: [T1, T2, lodash.__]): lodash.Function1; + (arg3: [T3]): lodash.Function2; + (arg1: [T1, lodash.__, T3]): lodash.Function1; + (arg2: [T2, T3]): lodash.Function1; + (arg1: [T1, T2, T3]): lodash.Function0; + } + type LodashPartialRight5x2 = (func: lodash.Function3) => lodash.Function2; + type LodashPartialRight6x2 = (func: lodash.Function3) => lodash.Function2; + type LodashPartialRight7x2 = (func: lodash.Function3) => lodash.Function1; + type LodashPartialRight8x2 = (func: lodash.Function3) => lodash.Function2; + type LodashPartialRight9x2 = (func: lodash.Function3) => lodash.Function1; + type LodashPartialRight10x2 = (func: lodash.Function3) => lodash.Function1; + type LodashPartialRight11x2 = (func: lodash.Function3) => lodash.Function0; + interface LodashPartialRight12x1 { + (arg1: [T1, lodash.__, lodash.__, lodash.__]): lodash.Function3; + (arg2: [T2, lodash.__, lodash.__]): lodash.Function3; + (arg1: [T1, T2, lodash.__, lodash.__]): lodash.Function2; + (arg3: [T3, lodash.__]): lodash.Function3; + (arg1: [T1, lodash.__, T3, lodash.__]): lodash.Function2; + (arg2: [T2, T3, lodash.__]): lodash.Function2; + (arg1: [T1, T2, T3, lodash.__]): lodash.Function1; + (arg4: [T4]): lodash.Function3; + (arg1: [T1, lodash.__, lodash.__, T4]): lodash.Function2; + (arg2: [T2, lodash.__, T4]): lodash.Function2; + (arg1: [T1, T2, lodash.__, T4]): lodash.Function1; + (arg3: [T3, T4]): lodash.Function2; + (arg1: [T1, lodash.__, T3, T4]): lodash.Function1; + (arg2: [T2, T3, T4]): lodash.Function1; + (arg1: [T1, T2, T3, T4]): lodash.Function0; + } + type LodashPartialRight12x2 = (func: lodash.Function4) => lodash.Function3; + type LodashPartialRight13x2 = (func: lodash.Function4) => lodash.Function3; + type LodashPartialRight14x2 = (func: lodash.Function4) => lodash.Function2; + type LodashPartialRight15x2 = (func: lodash.Function4) => lodash.Function3; + type LodashPartialRight16x2 = (func: lodash.Function4) => lodash.Function2; + type LodashPartialRight17x2 = (func: lodash.Function4) => lodash.Function2; + type LodashPartialRight18x2 = (func: lodash.Function4) => lodash.Function1; + type LodashPartialRight19x2 = (func: lodash.Function4) => lodash.Function3; + type LodashPartialRight20x2 = (func: lodash.Function4) => lodash.Function2; + type LodashPartialRight21x2 = (func: lodash.Function4) => lodash.Function2; + type LodashPartialRight22x2 = (func: lodash.Function4) => lodash.Function1; + type LodashPartialRight23x2 = (func: lodash.Function4) => lodash.Function2; + type LodashPartialRight24x2 = (func: lodash.Function4) => lodash.Function1; + type LodashPartialRight25x2 = (func: lodash.Function4) => lodash.Function1; + type LodashPartialRight26x2 = (func: lodash.Function4) => lodash.Function0; + type LodashPartialRight27x1 = (args: ReadonlyArray) => (...args: any[]) => any; + type LodashPartialRight27x2 = (func: (...args: any[]) => any) => (...args: any[]) => any; + interface LodashPartition { + (callback: lodash.ValueIteratorTypeGuard): LodashPartition1x1; + (callback: lodash.__, collection: lodash.List | null | undefined): LodashPartition1x2; + (callback: lodash.ValueIteratorTypeGuard, collection: lodash.List | null | undefined): [U[], Array>]; + (callback: lodash.ValueIteratee): LodashPartition2x1; + (callback: lodash.ValueIteratee, collection: lodash.List | null | undefined): [T[], T[]]; + (callback: lodash.__, collection: T | null | undefined): LodashPartition3x2; + (callback: lodash.ValueIteratee, collection: T | null | undefined): [Array, Array]; + } + type LodashPartition1x1 = (collection: lodash.List | null | undefined) => [U[], Array>]; + interface LodashPartition1x2 { + (callback: lodash.ValueIteratorTypeGuard): [U[], Array>]; + (callback: lodash.ValueIteratee): [T[], T[]]; + } + type LodashPartition2x1 = (collection: lodash.List | object | null | undefined) => [T[], T[]]; + type LodashPartition3x2 = (callback: lodash.ValueIteratee) => [Array, Array]; + interface LodashPath { + (path: TKey | [TKey]): LodashPath1x1; + (path: lodash.__, object: TObject): LodashPath1x2; + (path: TKey | [TKey], object: TObject): TObject[TKey]; + (path: lodash.__, object: TObject | null | undefined): LodashPath2x2; + (path: TKey | [TKey], object: TObject | null | undefined): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): LodashPath3x1; + (path: [TKey1, TKey2], object: TObject): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2], object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): LodashPath5x1; + (path: [TKey1, TKey2, TKey3], object: TObject): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): LodashPath7x1; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + (path: number): LodashPath9x1; + (path: lodash.__, object: lodash.NumericDictionary): LodashPath9x2; + (path: number, object: lodash.NumericDictionary): T; + (path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPath10x2; + (path: number, object: lodash.NumericDictionary | null | undefined): T | undefined; + (path: lodash.PropertyPath): LodashPath11x1; + (path: lodash.__, object: null | undefined): LodashPath11x2; + (path: lodash.PropertyPath, object: null | undefined): undefined; + (path: lodash.__, object: any): LodashPath12x2; + (path: lodash.PropertyPath, object: any): any; + } + interface LodashPath1x1 { + (object: TObject): TObject[TKey]; + (object: TObject | null | undefined): TObject[TKey] | undefined; + } + interface LodashPath1x2 { + (path: TKey | [TKey]): TObject[TKey]; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4]; + } + interface LodashPath2x2 { + (path: TKey | [TKey]): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashPath3x1 { + (object: TObject): TObject[TKey1][TKey2]; + (object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + } + interface LodashPath5x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + } + interface LodashPath7x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashPath9x1 { + (object: lodash.NumericDictionary): T; + (object: lodash.NumericDictionary | null | undefined): T | undefined; + } + type LodashPath9x2 = (path: number) => T; + type LodashPath10x2 = (path: number) => T | undefined; + interface LodashPath11x1 { + (object: null | undefined): undefined; + (object: any): any; + } + type LodashPath11x2 = (path: lodash.PropertyPath) => undefined; + type LodashPath12x2 = (path: lodash.PropertyPath) => any; + interface LodashPathOr { + (defaultValue: TDefault): LodashPathOr1x1; + (defaultValue: lodash.__, path: TKey | [TKey]): LodashPathOr1x2; + (defaultValue: TDefault, path: TKey | [TKey]): LodashPathOr1x3; + (defaultValue: lodash.__, path: lodash.__, object: TObject | null | undefined): LodashPathOr1x4; + (defaultValue: TDefault, path: lodash.__, object: TObject | null | undefined): LodashPathOr1x5; + (defaultValue: lodash.__, path: TKey | [TKey], object: TObject | null | undefined): LodashPathOr1x6; + (defaultValue: TDefault, path: TKey | [TKey], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2]): LodashPathOr2x2; + (defaultValue: TDefault, path: [TKey1, TKey2]): LodashPathOr2x3; + (defaultValue: lodash.__, path: [TKey1, TKey2], object: TObject | null | undefined): LodashPathOr2x6; + (defaultValue: TDefault, path: [TKey1, TKey2], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3]): LodashPathOr3x2; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3]): LodashPathOr3x3; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): LodashPathOr3x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3, TKey4]): LodashPathOr4x2; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3, TKey4]): LodashPathOr4x3; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): LodashPathOr4x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: number): LodashPathOr5x2; + (defaultValue: TDefault, path: number): LodashPathOr5x3; + (defaultValue: lodash.__, path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPathOr5x4; + (defaultValue: TDefault, path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPathOr5x5; + (defaultValue: lodash.__, path: number, object: lodash.NumericDictionary | null | undefined): LodashPathOr5x6; + (defaultValue: TDefault, path: number, object: lodash.NumericDictionary | null | undefined): T | TDefault; + (defaultValue: lodash.__, path: lodash.PropertyPath): LodashPathOr6x2; + (defaultValue: TDefault, path: lodash.PropertyPath): LodashPathOr6x3; + (defaultValue: lodash.__, path: lodash.__, object: null | undefined): LodashPathOr6x4; + (defaultValue: TDefault, path: lodash.__, object: null | undefined): LodashPathOr6x5; + (defaultValue: lodash.__, path: lodash.PropertyPath, object: null | undefined): LodashPathOr6x6; + (defaultValue: TDefault, path: lodash.PropertyPath, object: null | undefined): TDefault; + (defaultValue: any): LodashPathOr7x1; + (defaultValue: any, path: lodash.PropertyPath): LodashPathOr7x3; + (defaultValue: lodash.__, path: lodash.__, object: any): LodashPathOr7x4; + (defaultValue: any, path: lodash.__, object: any): LodashPathOr7x5; + (defaultValue: lodash.__, path: lodash.PropertyPath, object: any): LodashPathOr7x6; + (defaultValue: any, path: lodash.PropertyPath, object: any): any; + } + interface LodashPathOr1x1 { + (path: TKey | [TKey]): LodashPathOr1x3; + (path: lodash.__, object: TObject | null | undefined): LodashPathOr1x5; + (path: TKey | [TKey], object: TObject | null | undefined): Exclude | TDefault; + (path: [TKey1, TKey2]): LodashPathOr2x3; + (path: [TKey1, TKey2], object: TObject | null | undefined): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3]): LodashPathOr3x3; + (path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3, TKey4]): LodashPathOr4x3; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): Exclude | TDefault; + (path: number): LodashPathOr5x3; + (path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPathOr5x5; + (path: number, object: lodash.NumericDictionary | null | undefined): T | TDefault; + (path: lodash.PropertyPath): LodashPathOr6x3; + (path: lodash.__, object: null | undefined): LodashPathOr6x5; + (path: lodash.PropertyPath, object: null | undefined): TDefault; + } + interface LodashPathOr1x2 { + (defaultValue: TDefault): LodashPathOr1x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashPathOr1x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashPathOr1x3 = (object: TObject | null | undefined) => Exclude | TDefault; + interface LodashPathOr1x4 { + (defaultValue: TDefault): LodashPathOr1x5; + (defaultValue: lodash.__, path: TKey | [TKey]): LodashPathOr1x6; + (defaultValue: TDefault, path: TKey | [TKey]): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2]): LodashPathOr2x6; + (defaultValue: TDefault, path: [TKey1, TKey2]): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3]): LodashPathOr3x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3]): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3, TKey4]): LodashPathOr4x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3, TKey4]): Exclude | TDefault; + } + interface LodashPathOr1x5 { + (path: TKey | [TKey]): Exclude | TDefault; + (path: [TKey1, TKey2]): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3]): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3, TKey4]): Exclude | TDefault; + } + type LodashPathOr1x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashPathOr2x2 { + (defaultValue: TDefault): LodashPathOr2x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashPathOr2x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashPathOr2x3 = (object: TObject | null | undefined) => Exclude | TDefault; + type LodashPathOr2x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashPathOr3x2 { + (defaultValue: TDefault): LodashPathOr3x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashPathOr3x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashPathOr3x3 = (object: TObject | null | undefined) => Exclude | TDefault; + type LodashPathOr3x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashPathOr4x2 { + (defaultValue: TDefault): LodashPathOr4x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashPathOr4x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashPathOr4x3 = (object: TObject | null | undefined) => Exclude | TDefault; + type LodashPathOr4x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashPathOr5x2 { + (defaultValue: TDefault): LodashPathOr5x3; + (defaultValue: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPathOr5x6; + (defaultValue: TDefault, object: lodash.NumericDictionary | null | undefined): T | TDefault; + } + type LodashPathOr5x3 = (object: lodash.NumericDictionary | null | undefined) => T | TDefault; + interface LodashPathOr5x4 { + (defaultValue: TDefault): LodashPathOr5x5; + (defaultValue: lodash.__, path: number): LodashPathOr5x6; + (defaultValue: TDefault, path: number): T | TDefault; + } + type LodashPathOr5x5 = (path: number) => T | TDefault; + type LodashPathOr5x6 = (defaultValue: TDefault) => T | TDefault; + interface LodashPathOr6x2 { + (defaultValue: TDefault): LodashPathOr6x3; + (defaultValue: lodash.__, object: null | undefined): LodashPathOr6x6; + (defaultValue: TDefault, object: null | undefined): TDefault; + (defaultValue: any): LodashPathOr7x3; + (defaultValue: lodash.__, object: any): LodashPathOr7x6; + (defaultValue: any, object: any): any; + } + type LodashPathOr6x3 = (object: null | undefined) => TDefault; + interface LodashPathOr6x4 { + (defaultValue: TDefault): LodashPathOr6x5; + (defaultValue: lodash.__, path: lodash.PropertyPath): LodashPathOr6x6; + (defaultValue: TDefault, path: lodash.PropertyPath): TDefault; + } + type LodashPathOr6x5 = (path: lodash.PropertyPath) => TDefault; + type LodashPathOr6x6 = (defaultValue: TDefault) => TDefault; + interface LodashPathOr7x1 { + (path: lodash.PropertyPath): LodashPathOr7x3; + (path: lodash.__, object: any): LodashPathOr7x5; + (path: lodash.PropertyPath, object: any): any; + } + type LodashPathOr7x3 = (object: any) => any; + interface LodashPathOr7x4 { + (defaultValue: any): LodashPathOr7x5; + (defaultValue: lodash.__, path: lodash.PropertyPath): LodashPathOr7x6; + (defaultValue: any, path: lodash.PropertyPath): any; + } + type LodashPathOr7x5 = (path: lodash.PropertyPath) => any; + type LodashPathOr7x6 = (defaultValue: any) => any; + interface LodashPick { + (props: lodash.Many): LodashPick1x1; + (props: lodash.__, object: T): LodashPick1x2; + (props: lodash.Many, object: T): Pick; + (props: lodash.PropertyPath): LodashPick2x1; + (props: lodash.__, object: T | null | undefined): LodashPick2x2; + (props: lodash.PropertyPath, object: T | null | undefined): lodash.PartialObject; + } + type LodashPick1x1 = (object: T) => Pick; + type LodashPick1x2 = (props: lodash.Many) => Pick; + type LodashPick2x1 = (object: T | null | undefined) => lodash.PartialObject; + type LodashPick2x2 = (props: lodash.PropertyPath) => lodash.PartialObject; + interface LodashPickBy { + (predicate: lodash.ValueKeyIterateeTypeGuard): LodashPickBy1x1; + (predicate: lodash.__, object: lodash.Dictionary | null | undefined): LodashPickBy1x2; + (predicate: lodash.ValueKeyIterateeTypeGuard, object: lodash.Dictionary | null | undefined): lodash.Dictionary; + (predicate: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPickBy2x2; + (predicate: lodash.ValueKeyIterateeTypeGuard, object: lodash.NumericDictionary | null | undefined): lodash.NumericDictionary; + (predicate: lodash.ValueKeyIteratee): LodashPickBy3x1; + (predicate: lodash.ValueKeyIteratee, object: lodash.Dictionary | null | undefined): lodash.Dictionary; + (predicate: lodash.ValueKeyIteratee, object: lodash.NumericDictionary | null | undefined): lodash.NumericDictionary; + (predicate: lodash.__, object: T | null | undefined): LodashPickBy5x2; + (predicate: lodash.ValueKeyIteratee, object: T | null | undefined): lodash.PartialObject; + } + interface LodashPickBy1x1 { + (object: lodash.Dictionary | null | undefined): lodash.Dictionary; + (object: lodash.NumericDictionary | null | undefined): lodash.NumericDictionary; + } + interface LodashPickBy1x2 { + (predicate: lodash.ValueKeyIterateeTypeGuard): lodash.Dictionary; + (predicate: lodash.ValueKeyIteratee): lodash.Dictionary; + } + interface LodashPickBy2x2 { + (predicate: lodash.ValueKeyIterateeTypeGuard): lodash.NumericDictionary; + (predicate: lodash.ValueKeyIteratee): lodash.NumericDictionary; + } + interface LodashPickBy3x1 { + (object: lodash.Dictionary | null | undefined): lodash.Dictionary; + (object: lodash.NumericDictionary | null | undefined): lodash.NumericDictionary; + (object: T1 | null | undefined): lodash.PartialObject; + } + type LodashPickBy5x2 = (predicate: lodash.ValueKeyIteratee) => lodash.PartialObject; + interface LodashProp { + (path: TKey | [TKey]): LodashProp1x1; + (path: lodash.__, object: TObject): LodashProp1x2; + (path: TKey | [TKey], object: TObject): TObject[TKey]; + (path: lodash.__, object: TObject | null | undefined): LodashProp2x2; + (path: TKey | [TKey], object: TObject | null | undefined): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): LodashProp3x1; + (path: [TKey1, TKey2], object: TObject): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2], object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): LodashProp5x1; + (path: [TKey1, TKey2, TKey3], object: TObject): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): LodashProp7x1; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + (path: number): LodashProp9x1; + (path: lodash.__, object: lodash.NumericDictionary): LodashProp9x2; + (path: number, object: lodash.NumericDictionary): T; + (path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashProp10x2; + (path: number, object: lodash.NumericDictionary | null | undefined): T | undefined; + (path: lodash.PropertyPath): LodashProp11x1; + (path: lodash.__, object: null | undefined): LodashProp11x2; + (path: lodash.PropertyPath, object: null | undefined): undefined; + (path: lodash.__, object: any): LodashProp12x2; + (path: lodash.PropertyPath, object: any): any; + } + interface LodashProp1x1 { + (object: TObject): TObject[TKey]; + (object: TObject | null | undefined): TObject[TKey] | undefined; + } + interface LodashProp1x2 { + (path: TKey | [TKey]): TObject[TKey]; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4]; + } + interface LodashProp2x2 { + (path: TKey | [TKey]): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashProp3x1 { + (object: TObject): TObject[TKey1][TKey2]; + (object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + } + interface LodashProp5x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + } + interface LodashProp7x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashProp9x1 { + (object: lodash.NumericDictionary): T; + (object: lodash.NumericDictionary | null | undefined): T | undefined; + } + type LodashProp9x2 = (path: number) => T; + type LodashProp10x2 = (path: number) => T | undefined; + interface LodashProp11x1 { + (object: null | undefined): undefined; + (object: any): any; + } + type LodashProp11x2 = (path: lodash.PropertyPath) => undefined; + type LodashProp12x2 = (path: lodash.PropertyPath) => any; + interface LodashProperty { + (path: TKey | [TKey]): LodashProperty1x1; + (path: lodash.__, object: TObject): LodashProperty1x2; + (path: TKey | [TKey], object: TObject): TObject[TKey]; + (path: lodash.__, object: TObject | null | undefined): LodashProperty2x2; + (path: TKey | [TKey], object: TObject | null | undefined): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): LodashProperty3x1; + (path: [TKey1, TKey2], object: TObject): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2], object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): LodashProperty5x1; + (path: [TKey1, TKey2, TKey3], object: TObject): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): LodashProperty7x1; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + (path: number): LodashProperty9x1; + (path: lodash.__, object: lodash.NumericDictionary): LodashProperty9x2; + (path: number, object: lodash.NumericDictionary): T; + (path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashProperty10x2; + (path: number, object: lodash.NumericDictionary | null | undefined): T | undefined; + (path: lodash.PropertyPath): LodashProperty11x1; + (path: lodash.__, object: null | undefined): LodashProperty11x2; + (path: lodash.PropertyPath, object: null | undefined): undefined; + (path: lodash.__, object: any): LodashProperty12x2; + (path: lodash.PropertyPath, object: any): any; + } + interface LodashProperty1x1 { + (object: TObject): TObject[TKey]; + (object: TObject | null | undefined): TObject[TKey] | undefined; + } + interface LodashProperty1x2 { + (path: TKey | [TKey]): TObject[TKey]; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4]; + } + interface LodashProperty2x2 { + (path: TKey | [TKey]): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashProperty3x1 { + (object: TObject): TObject[TKey1][TKey2]; + (object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + } + interface LodashProperty5x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + } + interface LodashProperty7x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashProperty9x1 { + (object: lodash.NumericDictionary): T; + (object: lodash.NumericDictionary | null | undefined): T | undefined; + } + type LodashProperty9x2 = (path: number) => T; + type LodashProperty10x2 = (path: number) => T | undefined; + interface LodashProperty11x1 { + (object: null | undefined): undefined; + (object: any): any; + } + type LodashProperty11x2 = (path: lodash.PropertyPath) => undefined; + type LodashProperty12x2 = (path: lodash.PropertyPath) => any; + interface LodashPropertyOf { + (path: TKey | [TKey]): LodashPropertyOf1x1; + (path: lodash.__, object: TObject): LodashPropertyOf1x2; + (path: TKey | [TKey], object: TObject): TObject[TKey]; + (path: lodash.__, object: TObject | null | undefined): LodashPropertyOf2x2; + (path: TKey | [TKey], object: TObject | null | undefined): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): LodashPropertyOf3x1; + (path: [TKey1, TKey2], object: TObject): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2], object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): LodashPropertyOf5x1; + (path: [TKey1, TKey2, TKey3], object: TObject): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): LodashPropertyOf7x1; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + (path: number): LodashPropertyOf9x1; + (path: lodash.__, object: lodash.NumericDictionary): LodashPropertyOf9x2; + (path: number, object: lodash.NumericDictionary): T; + (path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPropertyOf10x2; + (path: number, object: lodash.NumericDictionary | null | undefined): T | undefined; + (path: lodash.PropertyPath): LodashPropertyOf11x1; + (path: lodash.__, object: null | undefined): LodashPropertyOf11x2; + (path: lodash.PropertyPath, object: null | undefined): undefined; + (path: lodash.__, object: any): LodashPropertyOf12x2; + (path: lodash.PropertyPath, object: any): any; + } + interface LodashPropertyOf1x1 { + (object: TObject): TObject[TKey]; + (object: TObject | null | undefined): TObject[TKey] | undefined; + } + interface LodashPropertyOf1x2 { + (path: TKey | [TKey]): TObject[TKey]; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2]; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3]; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4]; + } + interface LodashPropertyOf2x2 { + (path: TKey | [TKey]): TObject[TKey] | undefined; + (path: [TKey1, TKey2]): TObject[TKey1][TKey2] | undefined; + (path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3] | undefined; + (path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashPropertyOf3x1 { + (object: TObject): TObject[TKey1][TKey2]; + (object: TObject | null | undefined): TObject[TKey1][TKey2] | undefined; + } + interface LodashPropertyOf5x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3] | undefined; + } + interface LodashPropertyOf7x1 { + (object: TObject): TObject[TKey1][TKey2][TKey3][TKey4]; + (object: TObject | null | undefined): TObject[TKey1][TKey2][TKey3][TKey4] | undefined; + } + interface LodashPropertyOf9x1 { + (object: lodash.NumericDictionary): T; + (object: lodash.NumericDictionary | null | undefined): T | undefined; + } + type LodashPropertyOf9x2 = (path: number) => T; + type LodashPropertyOf10x2 = (path: number) => T | undefined; + interface LodashPropertyOf11x1 { + (object: null | undefined): undefined; + (object: any): any; + } + type LodashPropertyOf11x2 = (path: lodash.PropertyPath) => undefined; + type LodashPropertyOf12x2 = (path: lodash.PropertyPath) => any; + interface LodashPropOr { + (defaultValue: TDefault): LodashPropOr1x1; + (defaultValue: lodash.__, path: TKey | [TKey]): LodashPropOr1x2; + (defaultValue: TDefault, path: TKey | [TKey]): LodashPropOr1x3; + (defaultValue: lodash.__, path: lodash.__, object: TObject | null | undefined): LodashPropOr1x4; + (defaultValue: TDefault, path: lodash.__, object: TObject | null | undefined): LodashPropOr1x5; + (defaultValue: lodash.__, path: TKey | [TKey], object: TObject | null | undefined): LodashPropOr1x6; + (defaultValue: TDefault, path: TKey | [TKey], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2]): LodashPropOr2x2; + (defaultValue: TDefault, path: [TKey1, TKey2]): LodashPropOr2x3; + (defaultValue: lodash.__, path: [TKey1, TKey2], object: TObject | null | undefined): LodashPropOr2x6; + (defaultValue: TDefault, path: [TKey1, TKey2], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3]): LodashPropOr3x2; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3]): LodashPropOr3x3; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): LodashPropOr3x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3, TKey4]): LodashPropOr4x2; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3, TKey4]): LodashPropOr4x3; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): LodashPropOr4x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): Exclude | TDefault; + (defaultValue: lodash.__, path: number): LodashPropOr5x2; + (defaultValue: TDefault, path: number): LodashPropOr5x3; + (defaultValue: lodash.__, path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPropOr5x4; + (defaultValue: TDefault, path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPropOr5x5; + (defaultValue: lodash.__, path: number, object: lodash.NumericDictionary | null | undefined): LodashPropOr5x6; + (defaultValue: TDefault, path: number, object: lodash.NumericDictionary | null | undefined): T | TDefault; + (defaultValue: lodash.__, path: lodash.PropertyPath): LodashPropOr6x2; + (defaultValue: TDefault, path: lodash.PropertyPath): LodashPropOr6x3; + (defaultValue: lodash.__, path: lodash.__, object: null | undefined): LodashPropOr6x4; + (defaultValue: TDefault, path: lodash.__, object: null | undefined): LodashPropOr6x5; + (defaultValue: lodash.__, path: lodash.PropertyPath, object: null | undefined): LodashPropOr6x6; + (defaultValue: TDefault, path: lodash.PropertyPath, object: null | undefined): TDefault; + (defaultValue: any): LodashPropOr7x1; + (defaultValue: any, path: lodash.PropertyPath): LodashPropOr7x3; + (defaultValue: lodash.__, path: lodash.__, object: any): LodashPropOr7x4; + (defaultValue: any, path: lodash.__, object: any): LodashPropOr7x5; + (defaultValue: lodash.__, path: lodash.PropertyPath, object: any): LodashPropOr7x6; + (defaultValue: any, path: lodash.PropertyPath, object: any): any; + } + interface LodashPropOr1x1 { + (path: TKey | [TKey]): LodashPropOr1x3; + (path: lodash.__, object: TObject | null | undefined): LodashPropOr1x5; + (path: TKey | [TKey], object: TObject | null | undefined): Exclude | TDefault; + (path: [TKey1, TKey2]): LodashPropOr2x3; + (path: [TKey1, TKey2], object: TObject | null | undefined): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3]): LodashPropOr3x3; + (path: [TKey1, TKey2, TKey3], object: TObject | null | undefined): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3, TKey4]): LodashPropOr4x3; + (path: [TKey1, TKey2, TKey3, TKey4], object: TObject | null | undefined): Exclude | TDefault; + (path: number): LodashPropOr5x3; + (path: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPropOr5x5; + (path: number, object: lodash.NumericDictionary | null | undefined): T | TDefault; + (path: lodash.PropertyPath): LodashPropOr6x3; + (path: lodash.__, object: null | undefined): LodashPropOr6x5; + (path: lodash.PropertyPath, object: null | undefined): TDefault; + } + interface LodashPropOr1x2 { + (defaultValue: TDefault): LodashPropOr1x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashPropOr1x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashPropOr1x3 = (object: TObject | null | undefined) => Exclude | TDefault; + interface LodashPropOr1x4 { + (defaultValue: TDefault): LodashPropOr1x5; + (defaultValue: lodash.__, path: TKey | [TKey]): LodashPropOr1x6; + (defaultValue: TDefault, path: TKey | [TKey]): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2]): LodashPropOr2x6; + (defaultValue: TDefault, path: [TKey1, TKey2]): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3]): LodashPropOr3x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3]): Exclude | TDefault; + (defaultValue: lodash.__, path: [TKey1, TKey2, TKey3, TKey4]): LodashPropOr4x6; + (defaultValue: TDefault, path: [TKey1, TKey2, TKey3, TKey4]): Exclude | TDefault; + } + interface LodashPropOr1x5 { + (path: TKey | [TKey]): Exclude | TDefault; + (path: [TKey1, TKey2]): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3]): Exclude | TDefault; + (path: [TKey1, TKey2, TKey3, TKey4]): Exclude | TDefault; + } + type LodashPropOr1x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashPropOr2x2 { + (defaultValue: TDefault): LodashPropOr2x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashPropOr2x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashPropOr2x3 = (object: TObject | null | undefined) => Exclude | TDefault; + type LodashPropOr2x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashPropOr3x2 { + (defaultValue: TDefault): LodashPropOr3x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashPropOr3x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashPropOr3x3 = (object: TObject | null | undefined) => Exclude | TDefault; + type LodashPropOr3x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashPropOr4x2 { + (defaultValue: TDefault): LodashPropOr4x3; + (defaultValue: lodash.__, object: TObject | null | undefined): LodashPropOr4x6; + (defaultValue: TDefault, object: TObject | null | undefined): Exclude | TDefault; + } + type LodashPropOr4x3 = (object: TObject | null | undefined) => Exclude | TDefault; + type LodashPropOr4x6 = (defaultValue: TDefault) => Exclude | TDefault; + interface LodashPropOr5x2 { + (defaultValue: TDefault): LodashPropOr5x3; + (defaultValue: lodash.__, object: lodash.NumericDictionary | null | undefined): LodashPropOr5x6; + (defaultValue: TDefault, object: lodash.NumericDictionary | null | undefined): T | TDefault; + } + type LodashPropOr5x3 = (object: lodash.NumericDictionary | null | undefined) => T | TDefault; + interface LodashPropOr5x4 { + (defaultValue: TDefault): LodashPropOr5x5; + (defaultValue: lodash.__, path: number): LodashPropOr5x6; + (defaultValue: TDefault, path: number): T | TDefault; + } + type LodashPropOr5x5 = (path: number) => T | TDefault; + type LodashPropOr5x6 = (defaultValue: TDefault) => T | TDefault; + interface LodashPropOr6x2 { + (defaultValue: TDefault): LodashPropOr6x3; + (defaultValue: lodash.__, object: null | undefined): LodashPropOr6x6; + (defaultValue: TDefault, object: null | undefined): TDefault; + (defaultValue: any): LodashPropOr7x3; + (defaultValue: lodash.__, object: any): LodashPropOr7x6; + (defaultValue: any, object: any): any; + } + type LodashPropOr6x3 = (object: null | undefined) => TDefault; + interface LodashPropOr6x4 { + (defaultValue: TDefault): LodashPropOr6x5; + (defaultValue: lodash.__, path: lodash.PropertyPath): LodashPropOr6x6; + (defaultValue: TDefault, path: lodash.PropertyPath): TDefault; + } + type LodashPropOr6x5 = (path: lodash.PropertyPath) => TDefault; + type LodashPropOr6x6 = (defaultValue: TDefault) => TDefault; + interface LodashPropOr7x1 { + (path: lodash.PropertyPath): LodashPropOr7x3; + (path: lodash.__, object: any): LodashPropOr7x5; + (path: lodash.PropertyPath, object: any): any; + } + type LodashPropOr7x3 = (object: any) => any; + interface LodashPropOr7x4 { + (defaultValue: any): LodashPropOr7x5; + (defaultValue: lodash.__, path: lodash.PropertyPath): LodashPropOr7x6; + (defaultValue: any, path: lodash.PropertyPath): any; + } + type LodashPropOr7x5 = (path: lodash.PropertyPath) => any; + type LodashPropOr7x6 = (defaultValue: any) => any; + interface LodashPull { + (values: T): LodashPull1x1; + (values: lodash.__, array: ReadonlyArray): LodashPull1x2; + (values: T, array: ReadonlyArray): T[]; + (values: lodash.__, array: lodash.List): LodashPull2x2; + (values: T, array: lodash.List): lodash.List; + } + interface LodashPull1x1 { + (array: ReadonlyArray): T[]; + (array: lodash.List): lodash.List; + } + type LodashPull1x2 = (values: T) => T[]; + type LodashPull2x2 = (values: T) => lodash.List; + interface LodashPullAll { + (values: lodash.List): LodashPullAll1x1; + (values: lodash.__, array: ReadonlyArray): LodashPullAll1x2; + (values: lodash.List, array: ReadonlyArray): T[]; + (values: lodash.__, array: lodash.List): LodashPullAll2x2; + (values: lodash.List, array: lodash.List): lodash.List; + } + interface LodashPullAll1x1 { + (array: ReadonlyArray): T[]; + (array: lodash.List): lodash.List; + } + type LodashPullAll1x2 = (values: lodash.List) => T[]; + type LodashPullAll2x2 = (values: lodash.List) => lodash.List; + interface LodashPullAllBy { + (iteratee: lodash.ValueIteratee): LodashPullAllBy1x1; + (iteratee: lodash.__, values: lodash.List): LodashPullAllBy1x2; + (iteratee: lodash.ValueIteratee, values: lodash.List): LodashPullAllBy1x3; + (iteratee: lodash.__, values: lodash.__, array: ReadonlyArray): LodashPullAllBy1x4; + (iteratee: lodash.ValueIteratee, values: lodash.__, array: ReadonlyArray): LodashPullAllBy1x5; + (iteratee: lodash.__, values: lodash.List, array: ReadonlyArray): LodashPullAllBy1x6; + (iteratee: lodash.ValueIteratee, values: lodash.List, array: ReadonlyArray): T[]; + (iteratee: lodash.__, values: lodash.__, array: lodash.List): LodashPullAllBy2x4; + (iteratee: lodash.ValueIteratee, values: lodash.__, array: lodash.List): LodashPullAllBy2x5; + (iteratee: lodash.__, values: lodash.List, array: lodash.List): LodashPullAllBy2x6; + (iteratee: lodash.ValueIteratee, values: lodash.List, array: lodash.List): lodash.List; + (iteratee: lodash.ValueIteratee): LodashPullAllBy3x1; + (iteratee: lodash.__, values: lodash.List): LodashPullAllBy3x2; + (iteratee: lodash.ValueIteratee, values: lodash.List): LodashPullAllBy3x3; + (iteratee: lodash.__, values: lodash.__, array: ReadonlyArray): LodashPullAllBy3x4; + (iteratee: lodash.ValueIteratee, values: lodash.__, array: ReadonlyArray): LodashPullAllBy3x5; + (iteratee: lodash.__, values: lodash.List, array: ReadonlyArray): LodashPullAllBy3x6; + (iteratee: lodash.ValueIteratee, values: lodash.List, array: ReadonlyArray): T1[]; + (iteratee: lodash.__, values: lodash.__, array: lodash.List): LodashPullAllBy4x4; + (iteratee: lodash.ValueIteratee, values: lodash.__, array: lodash.List): LodashPullAllBy4x5; + (iteratee: lodash.__, values: lodash.List, array: lodash.List): LodashPullAllBy4x6; + (iteratee: lodash.ValueIteratee, values: lodash.List, array: lodash.List): lodash.List; + } + interface LodashPullAllBy1x1 { + (values: lodash.List): LodashPullAllBy1x3; + (values: lodash.__, array: ReadonlyArray): LodashPullAllBy1x5; + (values: lodash.List, array: ReadonlyArray): T[]; + (values: lodash.__, array: lodash.List): LodashPullAllBy2x5; + (values: lodash.List, array: lodash.List): lodash.List; + } + interface LodashPullAllBy1x2 { + (iteratee: lodash.ValueIteratee): LodashPullAllBy1x3; + (iteratee: lodash.__, array: ReadonlyArray): LodashPullAllBy1x6; + (iteratee: lodash.ValueIteratee, array: ReadonlyArray): T[]; + (iteratee: lodash.__, array: lodash.List): LodashPullAllBy2x6; + (iteratee: lodash.ValueIteratee, array: lodash.List): lodash.List; + } + interface LodashPullAllBy1x3 { + (array: ReadonlyArray): T[]; + (array: lodash.List): lodash.List; + } + interface LodashPullAllBy1x4 { + (iteratee: lodash.ValueIteratee): LodashPullAllBy1x5; + (iteratee: lodash.__, values: lodash.List): LodashPullAllBy1x6; + (iteratee: lodash.ValueIteratee, values: lodash.List): T[]; + } + type LodashPullAllBy1x5 = (values: lodash.List) => T[]; + type LodashPullAllBy1x6 = (iteratee: lodash.ValueIteratee) => T[]; + interface LodashPullAllBy2x4 { + (iteratee: lodash.ValueIteratee): LodashPullAllBy2x5; + (iteratee: lodash.__, values: lodash.List): LodashPullAllBy2x6; + (iteratee: lodash.ValueIteratee, values: lodash.List): lodash.List; + } + type LodashPullAllBy2x5 = (values: lodash.List) => lodash.List; + type LodashPullAllBy2x6 = (iteratee: lodash.ValueIteratee) => lodash.List; + interface LodashPullAllBy3x1 { + (values: lodash.List): LodashPullAllBy3x3; + (values: lodash.__, array: ReadonlyArray): LodashPullAllBy3x5; + (values: lodash.List, array: ReadonlyArray): T1[]; + (values: lodash.__, array: lodash.List): LodashPullAllBy4x5; + (values: lodash.List, array: lodash.List): lodash.List; + } + interface LodashPullAllBy3x2 { + (iteratee: lodash.ValueIteratee): LodashPullAllBy3x3; + (iteratee: lodash.__, array: ReadonlyArray): LodashPullAllBy3x6; + (iteratee: lodash.ValueIteratee, array: ReadonlyArray): T1[]; + (iteratee: lodash.__, array: lodash.List): LodashPullAllBy4x6; + (iteratee: lodash.ValueIteratee, array: lodash.List): lodash.List; + } + interface LodashPullAllBy3x3 { + (array: ReadonlyArray): T1[]; + (array: lodash.List): lodash.List; + } + interface LodashPullAllBy3x4 { + (iteratee: lodash.ValueIteratee): LodashPullAllBy3x5; + (iteratee: lodash.__, values: lodash.List): LodashPullAllBy3x6; + (iteratee: lodash.ValueIteratee, values: lodash.List): T1[]; + } + type LodashPullAllBy3x5 = (values: lodash.List) => T1[]; + type LodashPullAllBy3x6 = (iteratee: lodash.ValueIteratee) => T1[]; + interface LodashPullAllBy4x4 { + (iteratee: lodash.ValueIteratee): LodashPullAllBy4x5; + (iteratee: lodash.__, values: lodash.List): LodashPullAllBy4x6; + (iteratee: lodash.ValueIteratee, values: lodash.List): lodash.List; + } + type LodashPullAllBy4x5 = (values: lodash.List) => lodash.List; + type LodashPullAllBy4x6 = (iteratee: lodash.ValueIteratee) => lodash.List; + interface LodashPullAllWith { + (comparator: lodash.Comparator): LodashPullAllWith1x1; + (comparator: lodash.__, values: lodash.List): LodashPullAllWith1x2; + (comparator: lodash.Comparator, values: lodash.List): LodashPullAllWith1x3; + (comparator: lodash.__, values: lodash.__, array: ReadonlyArray): LodashPullAllWith1x4; + (comparator: lodash.Comparator, values: lodash.__, array: ReadonlyArray): LodashPullAllWith1x5; + (comparator: lodash.__, values: lodash.List, array: ReadonlyArray): LodashPullAllWith1x6; + (comparator: lodash.Comparator, values: lodash.List, array: ReadonlyArray): T[]; + (comparator: lodash.__, values: lodash.__, array: lodash.List): LodashPullAllWith2x4; + (comparator: lodash.Comparator, values: lodash.__, array: lodash.List): LodashPullAllWith2x5; + (comparator: lodash.__, values: lodash.List, array: lodash.List): LodashPullAllWith2x6; + (comparator: lodash.Comparator, values: lodash.List, array: lodash.List): lodash.List; + (comparator: lodash.Comparator2): LodashPullAllWith3x1; + (comparator: lodash.__, values: lodash.List): LodashPullAllWith3x2; + (comparator: lodash.Comparator2, values: lodash.List): LodashPullAllWith3x3; + (comparator: lodash.__, values: lodash.__, array: ReadonlyArray): LodashPullAllWith3x4; + (comparator: lodash.Comparator2, values: lodash.__, array: ReadonlyArray): LodashPullAllWith3x5; + (comparator: lodash.__, values: lodash.List, array: ReadonlyArray): LodashPullAllWith3x6; + (comparator: lodash.Comparator2, values: lodash.List, array: ReadonlyArray): T1[]; + (comparator: lodash.__, values: lodash.__, array: lodash.List): LodashPullAllWith4x4; + (comparator: lodash.Comparator2, values: lodash.__, array: lodash.List): LodashPullAllWith4x5; + (comparator: lodash.__, values: lodash.List, array: lodash.List): LodashPullAllWith4x6; + (comparator: lodash.Comparator2, values: lodash.List, array: lodash.List): lodash.List; + } + interface LodashPullAllWith1x1 { + (values: lodash.List): LodashPullAllWith1x3; + (values: lodash.__, array: ReadonlyArray): LodashPullAllWith1x5; + (values: lodash.List, array: ReadonlyArray): T[]; + (values: lodash.__, array: lodash.List): LodashPullAllWith2x5; + (values: lodash.List, array: lodash.List): lodash.List; + } + interface LodashPullAllWith1x2 { + (comparator: lodash.Comparator): LodashPullAllWith1x3; + (comparator: lodash.__, array: ReadonlyArray): LodashPullAllWith1x6; + (comparator: lodash.Comparator, array: ReadonlyArray): T[]; + (comparator: lodash.__, array: lodash.List): LodashPullAllWith2x6; + (comparator: lodash.Comparator, array: lodash.List): lodash.List; + } + interface LodashPullAllWith1x3 { + (array: ReadonlyArray): T[]; + (array: lodash.List): lodash.List; + } + interface LodashPullAllWith1x4 { + (comparator: lodash.Comparator): LodashPullAllWith1x5; + (comparator: lodash.__, values: lodash.List): LodashPullAllWith1x6; + (comparator: lodash.Comparator, values: lodash.List): T[]; + } + type LodashPullAllWith1x5 = (values: lodash.List) => T[]; + type LodashPullAllWith1x6 = (comparator: lodash.Comparator) => T[]; + interface LodashPullAllWith2x4 { + (comparator: lodash.Comparator): LodashPullAllWith2x5; + (comparator: lodash.__, values: lodash.List): LodashPullAllWith2x6; + (comparator: lodash.Comparator, values: lodash.List): lodash.List; + } + type LodashPullAllWith2x5 = (values: lodash.List) => lodash.List; + type LodashPullAllWith2x6 = (comparator: lodash.Comparator) => lodash.List; + interface LodashPullAllWith3x1 { + (values: lodash.List): LodashPullAllWith3x3; + (values: lodash.__, array: ReadonlyArray): LodashPullAllWith3x5; + (values: lodash.List, array: ReadonlyArray): T1[]; + (values: lodash.__, array: lodash.List): LodashPullAllWith4x5; + (values: lodash.List, array: lodash.List): lodash.List; + } + interface LodashPullAllWith3x2 { + (comparator: lodash.Comparator2): LodashPullAllWith3x3; + (comparator: lodash.__, array: ReadonlyArray): LodashPullAllWith3x6; + (comparator: lodash.Comparator2, array: ReadonlyArray): T1[]; + (comparator: lodash.__, array: lodash.List): LodashPullAllWith4x6; + (comparator: lodash.Comparator2, array: lodash.List): lodash.List; + } + interface LodashPullAllWith3x3 { + (array: ReadonlyArray): T1[]; + (array: lodash.List): lodash.List; + } + interface LodashPullAllWith3x4 { + (comparator: lodash.Comparator2): LodashPullAllWith3x5; + (comparator: lodash.__, values: lodash.List): LodashPullAllWith3x6; + (comparator: lodash.Comparator2, values: lodash.List): T1[]; + } + type LodashPullAllWith3x5 = (values: lodash.List) => T1[]; + type LodashPullAllWith3x6 = (comparator: lodash.Comparator2) => T1[]; + interface LodashPullAllWith4x4 { + (comparator: lodash.Comparator2): LodashPullAllWith4x5; + (comparator: lodash.__, values: lodash.List): LodashPullAllWith4x6; + (comparator: lodash.Comparator2, values: lodash.List): lodash.List; + } + type LodashPullAllWith4x5 = (values: lodash.List) => lodash.List; + type LodashPullAllWith4x6 = (comparator: lodash.Comparator2) => lodash.List; + interface LodashPullAt { + (indexes: lodash.Many): LodashPullAt1x1; + (indexes: lodash.__, array: ReadonlyArray): LodashPullAt1x2; + (indexes: lodash.Many, array: ReadonlyArray): T[]; + (indexes: lodash.__, array: lodash.List): LodashPullAt2x2; + (indexes: lodash.Many, array: lodash.List): lodash.List; + } + interface LodashPullAt1x1 { + (array: ReadonlyArray): T[]; + (array: lodash.List): lodash.List; + } + type LodashPullAt1x2 = (indexes: lodash.Many) => T[]; + type LodashPullAt2x2 = (indexes: lodash.Many) => lodash.List; + interface LodashRandom { + (maxOrMin: number): LodashRandom1x1; + (max: lodash.__, floating: boolean): LodashRandom1x2; + (maxOrMin: number, floatingOrMax: boolean | number): number; + (min: lodash.__, max: number): LodashRandom2x2; + } + type LodashRandom1x1 = (floatingOrMax: boolean | number) => number; + type LodashRandom1x2 = (max: number) => number; + type LodashRandom2x2 = (min: number) => number; + interface LodashRange { + (start: number): LodashRange1x1; + (start: lodash.__, end: number): LodashRange1x2; + (start: number, end: number): number[]; + } + type LodashRange1x1 = (end: number) => number[]; + type LodashRange1x2 = (start: number) => number[]; + interface LodashRangeRight { + (start: number): LodashRangeRight1x1; + (start: lodash.__, end: number): LodashRangeRight1x2; + (start: number, end: number): number[]; + } + type LodashRangeRight1x1 = (end: number) => number[]; + type LodashRangeRight1x2 = (start: number) => number[]; + interface LodashRangeStep { + (start: number): LodashRangeStep1x1; + (start: lodash.__, end: number): LodashRangeStep1x2; + (start: number, end: number): LodashRangeStep1x3; + (start: lodash.__, end: lodash.__, step: number): LodashRangeStep1x4; + (start: number, end: lodash.__, step: number): LodashRangeStep1x5; + (start: lodash.__, end: number, step: number): LodashRangeStep1x6; + (start: number, end: number, step: number): number[]; + } + interface LodashRangeStep1x1 { + (end: number): LodashRangeStep1x3; + (end: lodash.__, step: number): LodashRangeStep1x5; + (end: number, step: number): number[]; + } + interface LodashRangeStep1x2 { + (start: number): LodashRangeStep1x3; + (start: lodash.__, step: number): LodashRangeStep1x6; + (start: number, step: number): number[]; + } + type LodashRangeStep1x3 = (step: number) => number[]; + interface LodashRangeStep1x4 { + (start: number): LodashRangeStep1x5; + (start: lodash.__, end: number): LodashRangeStep1x6; + (start: number, end: number): number[]; + } + type LodashRangeStep1x5 = (end: number) => number[]; + type LodashRangeStep1x6 = (start: number) => number[]; + interface LodashRangeStepRight { + (start: number): LodashRangeStepRight1x1; + (start: lodash.__, end: number): LodashRangeStepRight1x2; + (start: number, end: number): LodashRangeStepRight1x3; + (start: lodash.__, end: lodash.__, step: number): LodashRangeStepRight1x4; + (start: number, end: lodash.__, step: number): LodashRangeStepRight1x5; + (start: lodash.__, end: number, step: number): LodashRangeStepRight1x6; + (start: number, end: number, step: number): number[]; + } + interface LodashRangeStepRight1x1 { + (end: number): LodashRangeStepRight1x3; + (end: lodash.__, step: number): LodashRangeStepRight1x5; + (end: number, step: number): number[]; + } + interface LodashRangeStepRight1x2 { + (start: number): LodashRangeStepRight1x3; + (start: lodash.__, step: number): LodashRangeStepRight1x6; + (start: number, step: number): number[]; + } + type LodashRangeStepRight1x3 = (step: number) => number[]; + interface LodashRangeStepRight1x4 { + (start: number): LodashRangeStepRight1x5; + (start: lodash.__, end: number): LodashRangeStepRight1x6; + (start: number, end: number): number[]; + } + type LodashRangeStepRight1x5 = (end: number) => number[]; + type LodashRangeStepRight1x6 = (start: number) => number[]; + interface LodashRearg { + (indexes: lodash.Many): LodashRearg1x1; + (indexes: lodash.__, func: (...args: any[]) => any): LodashRearg1x2; + (indexes: lodash.Many, func: (...args: any[]) => any): (...args: any[]) => any; + } + type LodashRearg1x1 = (func: (...args: any[]) => any) => (...args: any[]) => any; + type LodashRearg1x2 = (indexes: lodash.Many) => (...args: any[]) => any; + interface LodashReduce { + (callback: lodash.MemoIteratorCapped): LodashReduce1x1; + (callback: lodash.__, accumulator: TResult): LodashReduce1x2; + (callback: lodash.MemoIteratorCapped, accumulator: TResult): LodashReduce1x3; + (callback: lodash.__, accumulator: lodash.__, collection: T[] | null | undefined): LodashReduce1x4; + (callback: lodash.MemoIteratorCapped, accumulator: lodash.__, collection: T[] | null | undefined): LodashReduce1x5; + (callback: lodash.__, accumulator: TResult, collection: T[] | null | undefined): LodashReduce1x6; + (callback: lodash.MemoIteratorCapped, accumulator: TResult, collection: T[] | lodash.List | null | undefined): TResult; + (callback: lodash.__, accumulator: lodash.__, collection: lodash.List | null | undefined): LodashReduce2x4; + (callback: lodash.MemoIteratorCapped, accumulator: lodash.__, collection: lodash.List | null | undefined): LodashReduce2x5; + (callback: lodash.__, accumulator: TResult, collection: lodash.List | null | undefined): LodashReduce2x6; + (callback: lodash.MemoIteratorCapped): LodashReduce3x1; + (callback: lodash.MemoIteratorCapped, accumulator: TResult): LodashReduce3x3; + (callback: lodash.__, accumulator: lodash.__, collection: T | null | undefined): LodashReduce3x4; + (callback: lodash.MemoIteratorCapped, accumulator: lodash.__, collection: T | null | undefined): LodashReduce3x5; + (callback: lodash.__, accumulator: TResult, collection: T | null | undefined): LodashReduce3x6; + (callback: lodash.MemoIteratorCapped, accumulator: TResult, collection: T | null | undefined): TResult; + } + interface LodashReduce1x1 { + (accumulator: TResult): LodashReduce1x3; + (accumulator: lodash.__, collection: T[] | null | undefined): LodashReduce1x5; + (accumulator: TResult, collection: T[] | lodash.List | null | undefined): TResult; + (accumulator: lodash.__, collection: lodash.List | null | undefined): LodashReduce2x5; + } + interface LodashReduce1x2 { + (callback: lodash.MemoIteratorCapped): LodashReduce1x3; + (callback: lodash.__, collection: T[] | null | undefined): LodashReduce1x6; + (callback: lodash.MemoIteratorCapped, collection: T[] | lodash.List | null | undefined): TResult; + (callback: lodash.__, collection: lodash.List | null | undefined): LodashReduce2x6; + (callback: lodash.MemoIteratorCapped): LodashReduce3x3; + (callback: lodash.__, collection: T | null | undefined): LodashReduce3x6; + (callback: lodash.MemoIteratorCapped, collection: T | null | undefined): TResult; + } + type LodashReduce1x3 = (collection: T[] | lodash.List | null | undefined) => TResult; + interface LodashReduce1x4 { + (callback: lodash.MemoIteratorCapped): LodashReduce1x5; + (callback: lodash.__, accumulator: TResult): LodashReduce1x6; + (callback: lodash.MemoIteratorCapped, accumulator: TResult): TResult; + } + type LodashReduce1x5 = (accumulator: TResult) => TResult; + type LodashReduce1x6 = (callback: lodash.MemoIteratorCapped) => TResult; + interface LodashReduce2x4 { + (callback: lodash.MemoIteratorCapped): LodashReduce2x5; + (callback: lodash.__, accumulator: TResult): LodashReduce2x6; + (callback: lodash.MemoIteratorCapped, accumulator: TResult): TResult; + } + type LodashReduce2x5 = (accumulator: TResult) => TResult; + type LodashReduce2x6 = (callback: lodash.MemoIteratorCapped) => TResult; + interface LodashReduce3x1 { + (accumulator: TResult): LodashReduce3x3; + (accumulator: lodash.__, collection: T | null | undefined): LodashReduce3x5; + (accumulator: TResult, collection: T | null | undefined): TResult; + } + type LodashReduce3x3 = (collection: T | null | undefined) => TResult; + interface LodashReduce3x4 { + (callback: lodash.MemoIteratorCapped): LodashReduce3x5; + (callback: lodash.__, accumulator: TResult): LodashReduce3x6; + (callback: lodash.MemoIteratorCapped, accumulator: TResult): TResult; + } + type LodashReduce3x5 = (accumulator: TResult) => TResult; + type LodashReduce3x6 = (callback: lodash.MemoIteratorCapped) => TResult; + interface LodashReduceRight { + (callback: lodash.MemoIteratorCappedRight): LodashReduceRight1x1; + (callback: lodash.__, accumulator: TResult): LodashReduceRight1x2; + (callback: lodash.MemoIteratorCappedRight, accumulator: TResult): LodashReduceRight1x3; + (callback: lodash.__, accumulator: lodash.__, collection: T[] | null | undefined): LodashReduceRight1x4; + (callback: lodash.MemoIteratorCappedRight, accumulator: lodash.__, collection: T[] | null | undefined): LodashReduceRight1x5; + (callback: lodash.__, accumulator: TResult, collection: T[] | null | undefined): LodashReduceRight1x6; + (callback: lodash.MemoIteratorCappedRight, accumulator: TResult, collection: T[] | lodash.List | null | undefined): TResult; + (callback: lodash.__, accumulator: lodash.__, collection: lodash.List | null | undefined): LodashReduceRight2x4; + (callback: lodash.MemoIteratorCappedRight, accumulator: lodash.__, collection: lodash.List | null | undefined): LodashReduceRight2x5; + (callback: lodash.__, accumulator: TResult, collection: lodash.List | null | undefined): LodashReduceRight2x6; + (callback: lodash.MemoIteratorCappedRight): LodashReduceRight3x1; + (callback: lodash.MemoIteratorCappedRight, accumulator: TResult): LodashReduceRight3x3; + (callback: lodash.__, accumulator: lodash.__, collection: T | null | undefined): LodashReduceRight3x4; + (callback: lodash.MemoIteratorCappedRight, accumulator: lodash.__, collection: T | null | undefined): LodashReduceRight3x5; + (callback: lodash.__, accumulator: TResult, collection: T | null | undefined): LodashReduceRight3x6; + (callback: lodash.MemoIteratorCappedRight, accumulator: TResult, collection: T | null | undefined): TResult; + } + interface LodashReduceRight1x1 { + (accumulator: TResult): LodashReduceRight1x3; + (accumulator: lodash.__, collection: T[] | null | undefined): LodashReduceRight1x5; + (accumulator: TResult, collection: T[] | lodash.List | null | undefined): TResult; + (accumulator: lodash.__, collection: lodash.List | null | undefined): LodashReduceRight2x5; + } + interface LodashReduceRight1x2 { + (callback: lodash.MemoIteratorCappedRight): LodashReduceRight1x3; + (callback: lodash.__, collection: T[] | null | undefined): LodashReduceRight1x6; + (callback: lodash.MemoIteratorCappedRight, collection: T[] | lodash.List | null | undefined): TResult; + (callback: lodash.__, collection: lodash.List | null | undefined): LodashReduceRight2x6; + (callback: lodash.MemoIteratorCappedRight): LodashReduceRight3x3; + (callback: lodash.__, collection: T | null | undefined): LodashReduceRight3x6; + (callback: lodash.MemoIteratorCappedRight, collection: T | null | undefined): TResult; + } + type LodashReduceRight1x3 = (collection: T[] | lodash.List | null | undefined) => TResult; + interface LodashReduceRight1x4 { + (callback: lodash.MemoIteratorCappedRight): LodashReduceRight1x5; + (callback: lodash.__, accumulator: TResult): LodashReduceRight1x6; + (callback: lodash.MemoIteratorCappedRight, accumulator: TResult): TResult; + } + type LodashReduceRight1x5 = (accumulator: TResult) => TResult; + type LodashReduceRight1x6 = (callback: lodash.MemoIteratorCappedRight) => TResult; + interface LodashReduceRight2x4 { + (callback: lodash.MemoIteratorCappedRight): LodashReduceRight2x5; + (callback: lodash.__, accumulator: TResult): LodashReduceRight2x6; + (callback: lodash.MemoIteratorCappedRight, accumulator: TResult): TResult; + } + type LodashReduceRight2x5 = (accumulator: TResult) => TResult; + type LodashReduceRight2x6 = (callback: lodash.MemoIteratorCappedRight) => TResult; + interface LodashReduceRight3x1 { + (accumulator: TResult): LodashReduceRight3x3; + (accumulator: lodash.__, collection: T | null | undefined): LodashReduceRight3x5; + (accumulator: TResult, collection: T | null | undefined): TResult; + } + type LodashReduceRight3x3 = (collection: T | null | undefined) => TResult; + interface LodashReduceRight3x4 { + (callback: lodash.MemoIteratorCappedRight): LodashReduceRight3x5; + (callback: lodash.__, accumulator: TResult): LodashReduceRight3x6; + (callback: lodash.MemoIteratorCappedRight, accumulator: TResult): TResult; + } + type LodashReduceRight3x5 = (accumulator: TResult) => TResult; + type LodashReduceRight3x6 = (callback: lodash.MemoIteratorCappedRight) => TResult; + interface LodashReject { + (predicate: lodash.ValueIterateeCustom): LodashReject1x1; + (predicate: lodash.__, collection: lodash.List | null | undefined): LodashReject1x2; + (predicate: lodash.ValueIterateeCustom, collection: lodash.List | null | undefined): T[]; + (predicate: lodash.__, collection: T | null | undefined): LodashReject2x2; + (predicate: lodash.ValueIterateeCustom, collection: T | null | undefined): Array; + } + type LodashReject1x1 = (collection: lodash.List | object | null | undefined) => T[]; + type LodashReject1x2 = (predicate: lodash.ValueIterateeCustom) => T[]; + type LodashReject2x2 = (predicate: lodash.ValueIterateeCustom) => Array; + interface LodashRemove { + (predicate: lodash.ValueIteratee): LodashRemove1x1; + (predicate: lodash.__, array: lodash.List): LodashRemove1x2; + (predicate: lodash.ValueIteratee, array: lodash.List): T[]; + } + type LodashRemove1x1 = (array: lodash.List) => T[]; + type LodashRemove1x2 = (predicate: lodash.ValueIteratee) => T[]; + interface LodashRepeat { + (n: number): LodashRepeat1x1; + (n: lodash.__, string: string): LodashRepeat1x2; + (n: number, string: string): string; + } + type LodashRepeat1x1 = (string: string) => string; + type LodashRepeat1x2 = (n: number) => string; + interface LodashReplace { + (pattern: RegExp | string): LodashReplace1x1; + (pattern: lodash.__, replacement: lodash.ReplaceFunction | string): LodashReplace1x2; + (pattern: RegExp | string, replacement: lodash.ReplaceFunction | string): LodashReplace1x3; + (pattern: lodash.__, replacement: lodash.__, string: string): LodashReplace1x4; + (pattern: RegExp | string, replacement: lodash.__, string: string): LodashReplace1x5; + (pattern: lodash.__, replacement: lodash.ReplaceFunction | string, string: string): LodashReplace1x6; + (pattern: RegExp | string, replacement: lodash.ReplaceFunction | string, string: string): string; + } + interface LodashReplace1x1 { + (replacement: lodash.ReplaceFunction | string): LodashReplace1x3; + (replacement: lodash.__, string: string): LodashReplace1x5; + (replacement: lodash.ReplaceFunction | string, string: string): string; + } + interface LodashReplace1x2 { + (pattern: RegExp | string): LodashReplace1x3; + (pattern: lodash.__, string: string): LodashReplace1x6; + (pattern: RegExp | string, string: string): string; + } + type LodashReplace1x3 = (string: string) => string; + interface LodashReplace1x4 { + (pattern: RegExp | string): LodashReplace1x5; + (pattern: lodash.__, replacement: lodash.ReplaceFunction | string): LodashReplace1x6; + (pattern: RegExp | string, replacement: lodash.ReplaceFunction | string): string; + } + type LodashReplace1x5 = (replacement: lodash.ReplaceFunction | string) => string; + type LodashReplace1x6 = (pattern: RegExp | string) => string; + type LodashRest = (func: (...args: any[]) => any) => (...args: any[]) => any; + interface LodashRestFrom { + (start: number): LodashRestFrom1x1; + (start: lodash.__, func: (...args: any[]) => any): LodashRestFrom1x2; + (start: number, func: (...args: any[]) => any): (...args: any[]) => any; + } + type LodashRestFrom1x1 = (func: (...args: any[]) => any) => (...args: any[]) => any; + type LodashRestFrom1x2 = (start: number) => (...args: any[]) => any; + interface LodashResult { + (path: lodash.PropertyPath): LodashResult1x1; + (path: lodash.__, object: any): LodashResult1x2; + (path: lodash.PropertyPath, object: any): TResult; + } + type LodashResult1x1 = (object: any) => TResult; + type LodashResult1x2 = (path: lodash.PropertyPath) => TResult; + type LodashReverse = >(array: TList) => TList; + type LodashRound = (n: number) => number; + type LodashRunInContext = (context: object) => lodash.LoDashStatic; + interface LodashSample { + (collection: readonly [T, ...T[]]): T; + (collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): T | undefined; + (collection: T | null | undefined): T[keyof T] | undefined; + } + interface LodashSampleSize { + (n: number): LodashSampleSize1x1; + (n: lodash.__, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): LodashSampleSize1x2; + (n: number, collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): T[]; + (n: lodash.__, collection: T | null | undefined): LodashSampleSize2x2; + (n: number, collection: T | null | undefined): Array; + } + interface LodashSampleSize1x1 { + (collection: lodash.Dictionary | lodash.NumericDictionary | null | undefined): T[]; + (collection: T | null | undefined): Array; + } + type LodashSampleSize1x2 = (n: number) => T[]; + type LodashSampleSize2x2 = (n: number) => Array; + interface LodashSetWith { + (customizer: lodash.SetWithCustomizer): LodashSetWith1x1; + (customizer: lodash.__, path: lodash.PropertyPath): LodashSetWith1x2; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath): LodashSetWith1x3; + (customizer: lodash.__, path: lodash.__, value: any): LodashSetWith1x4; + (customizer: lodash.SetWithCustomizer, path: lodash.__, value: any): LodashSetWith1x5; + (customizer: lodash.__, path: lodash.PropertyPath, value: any): LodashSetWith1x6; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, value: any): LodashSetWith1x7; + (customizer: lodash.__, path: lodash.__, value: lodash.__, object: T): LodashSetWith1x8; + (customizer: lodash.SetWithCustomizer, path: lodash.__, value: lodash.__, object: T): LodashSetWith1x9; + (customizer: lodash.__, path: lodash.PropertyPath, value: lodash.__, object: T): LodashSetWith1x10; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, value: lodash.__, object: T): LodashSetWith1x11; + (customizer: lodash.__, path: lodash.__, value: any, object: T): LodashSetWith1x12; + (customizer: lodash.SetWithCustomizer, path: lodash.__, value: any, object: T): LodashSetWith1x13; + (customizer: lodash.__, path: lodash.PropertyPath, value: any, object: T): LodashSetWith1x14; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, value: any, object: T): T; + } + interface LodashSetWith1x1 { + (path: lodash.PropertyPath): LodashSetWith1x3; + (path: lodash.__, value: any): LodashSetWith1x5; + (path: lodash.PropertyPath, value: any): LodashSetWith1x7; + (path: lodash.__, value: lodash.__, object: T): LodashSetWith1x9; + (path: lodash.PropertyPath, value: lodash.__, object: T): LodashSetWith1x11; + (path: lodash.__, value: any, object: T): LodashSetWith1x13; + (path: lodash.PropertyPath, value: any, object: T): T; + } + interface LodashSetWith1x2 { + (customizer: lodash.SetWithCustomizer): LodashSetWith1x3; + (customizer: lodash.__, value: any): LodashSetWith1x6; + (customizer: lodash.SetWithCustomizer, value: any): LodashSetWith1x7; + (customizer: lodash.__, value: lodash.__, object: T): LodashSetWith1x10; + (customizer: lodash.SetWithCustomizer, value: lodash.__, object: T): LodashSetWith1x11; + (customizer: lodash.__, value: any, object: T): LodashSetWith1x14; + (customizer: lodash.SetWithCustomizer, value: any, object: T): T; + } + interface LodashSetWith1x3 { + (value: any): LodashSetWith1x7; + (value: lodash.__, object: T): LodashSetWith1x11; + (value: any, object: T): T; + } + interface LodashSetWith1x4 { + (customizer: lodash.SetWithCustomizer): LodashSetWith1x5; + (customizer: lodash.__, path: lodash.PropertyPath): LodashSetWith1x6; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath): LodashSetWith1x7; + (customizer: lodash.__, path: lodash.__, object: T): LodashSetWith1x12; + (customizer: lodash.SetWithCustomizer, path: lodash.__, object: T): LodashSetWith1x13; + (customizer: lodash.__, path: lodash.PropertyPath, object: T): LodashSetWith1x14; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, object: T): T; + } + interface LodashSetWith1x5 { + (path: lodash.PropertyPath): LodashSetWith1x7; + (path: lodash.__, object: T): LodashSetWith1x13; + (path: lodash.PropertyPath, object: T): T; + } + interface LodashSetWith1x6 { + (customizer: lodash.SetWithCustomizer): LodashSetWith1x7; + (customizer: lodash.__, object: T): LodashSetWith1x14; + (customizer: lodash.SetWithCustomizer, object: T): T; + } + type LodashSetWith1x7 = (object: T) => T; + interface LodashSetWith1x8 { + (customizer: lodash.SetWithCustomizer): LodashSetWith1x9; + (customizer: lodash.__, path: lodash.PropertyPath): LodashSetWith1x10; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath): LodashSetWith1x11; + (customizer: lodash.__, path: lodash.__, value: any): LodashSetWith1x12; + (customizer: lodash.SetWithCustomizer, path: lodash.__, value: any): LodashSetWith1x13; + (customizer: lodash.__, path: lodash.PropertyPath, value: any): LodashSetWith1x14; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, value: any): T; + } + interface LodashSetWith1x9 { + (path: lodash.PropertyPath): LodashSetWith1x11; + (path: lodash.__, value: any): LodashSetWith1x13; + (path: lodash.PropertyPath, value: any): T; + } + interface LodashSetWith1x10 { + (customizer: lodash.SetWithCustomizer): LodashSetWith1x11; + (customizer: lodash.__, value: any): LodashSetWith1x14; + (customizer: lodash.SetWithCustomizer, value: any): T; + } + type LodashSetWith1x11 = (value: any) => T; + interface LodashSetWith1x12 { + (customizer: lodash.SetWithCustomizer): LodashSetWith1x13; + (customizer: lodash.__, path: lodash.PropertyPath): LodashSetWith1x14; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath): T; + } + type LodashSetWith1x13 = (path: lodash.PropertyPath) => T; + type LodashSetWith1x14 = (customizer: lodash.SetWithCustomizer) => T; + interface LodashShuffle { + (collection: lodash.List | null | undefined): T[]; + (collection: T | null | undefined): Array; + } + type LodashSize = (collection: object | string | null | undefined) => number; + interface LodashSlice { + (start: number): LodashSlice1x1; + (start: lodash.__, end: number): LodashSlice1x2; + (start: number, end: number): LodashSlice1x3; + (start: lodash.__, end: lodash.__, array: lodash.List | null | undefined): LodashSlice1x4; + (start: number, end: lodash.__, array: lodash.List | null | undefined): LodashSlice1x5; + (start: lodash.__, end: number, array: lodash.List | null | undefined): LodashSlice1x6; + (start: number, end: number, array: lodash.List | null | undefined): T[]; + } + interface LodashSlice1x1 { + (end: number): LodashSlice1x3; + (end: lodash.__, array: lodash.List | null | undefined): LodashSlice1x5; + (end: number, array: lodash.List | null | undefined): T[]; + } + interface LodashSlice1x2 { + (start: number): LodashSlice1x3; + (start: lodash.__, array: lodash.List | null | undefined): LodashSlice1x6; + (start: number, array: lodash.List | null | undefined): T[]; + } + type LodashSlice1x3 = (array: lodash.List | null | undefined) => T[]; + interface LodashSlice1x4 { + (start: number): LodashSlice1x5; + (start: lodash.__, end: number): LodashSlice1x6; + (start: number, end: number): T[]; + } + type LodashSlice1x5 = (end: number) => T[]; + type LodashSlice1x6 = (start: number) => T[]; + type LodashSnakeCase = (string: string) => string; + interface LodashSortBy { + (iteratees: lodash.Many>): LodashSortBy1x1; + (iteratees: lodash.__, collection: lodash.List | null | undefined): LodashSortBy1x2; + (iteratees: lodash.Many>, collection: lodash.List | null | undefined): T[]; + (iteratees: lodash.__, collection: T | null | undefined): LodashSortBy2x2; + (iteratees: lodash.Many>, collection: T | null | undefined): Array; + } + type LodashSortBy1x1 = (collection: lodash.List | object | null | undefined) => T[]; + type LodashSortBy1x2 = (iteratees: lodash.Many>) => T[]; + type LodashSortBy2x2 = (iteratees: lodash.Many>) => Array; + interface LodashSortedIndex { + (value: T): LodashSortedIndex1x1; + (value: lodash.__, array: lodash.List | null | undefined): LodashSortedIndex1x2; + (value: T, array: lodash.List | null | undefined): number; + } + type LodashSortedIndex1x1 = (array: lodash.List | null | undefined) => number; + type LodashSortedIndex1x2 = (value: T) => number; + interface LodashSortedIndexBy { + (iteratee: lodash.ValueIteratee): LodashSortedIndexBy1x1; + (iteratee: lodash.__, value: T): LodashSortedIndexBy1x2; + (iteratee: lodash.ValueIteratee, value: T): LodashSortedIndexBy1x3; + (iteratee: lodash.__, value: lodash.__, array: lodash.List | null | undefined): LodashSortedIndexBy1x4; + (iteratee: lodash.ValueIteratee, value: lodash.__, array: lodash.List | null | undefined): LodashSortedIndexBy1x5; + (iteratee: lodash.__, value: T, array: lodash.List | null | undefined): LodashSortedIndexBy1x6; + (iteratee: lodash.ValueIteratee, value: T, array: lodash.List | null | undefined): number; + } + interface LodashSortedIndexBy1x1 { + (value: T): LodashSortedIndexBy1x3; + (value: lodash.__, array: lodash.List | null | undefined): LodashSortedIndexBy1x5; + (value: T, array: lodash.List | null | undefined): number; + } + interface LodashSortedIndexBy1x2 { + (iteratee: lodash.ValueIteratee): LodashSortedIndexBy1x3; + (iteratee: lodash.__, array: lodash.List | null | undefined): LodashSortedIndexBy1x6; + (iteratee: lodash.ValueIteratee, array: lodash.List | null | undefined): number; + } + type LodashSortedIndexBy1x3 = (array: lodash.List | null | undefined) => number; + interface LodashSortedIndexBy1x4 { + (iteratee: lodash.ValueIteratee): LodashSortedIndexBy1x5; + (iteratee: lodash.__, value: T): LodashSortedIndexBy1x6; + (iteratee: lodash.ValueIteratee, value: T): number; + } + type LodashSortedIndexBy1x5 = (value: T) => number; + type LodashSortedIndexBy1x6 = (iteratee: lodash.ValueIteratee) => number; + interface LodashSortedIndexOf { + (value: T): LodashSortedIndexOf1x1; + (value: lodash.__, array: lodash.List | null | undefined): LodashSortedIndexOf1x2; + (value: T, array: lodash.List | null | undefined): number; + } + type LodashSortedIndexOf1x1 = (array: lodash.List | null | undefined) => number; + type LodashSortedIndexOf1x2 = (value: T) => number; + interface LodashSortedLastIndex { + (value: T): LodashSortedLastIndex1x1; + (value: lodash.__, array: lodash.List | null | undefined): LodashSortedLastIndex1x2; + (value: T, array: lodash.List | null | undefined): number; + } + type LodashSortedLastIndex1x1 = (array: lodash.List | null | undefined) => number; + type LodashSortedLastIndex1x2 = (value: T) => number; + interface LodashSortedLastIndexBy { + (iteratee: lodash.ValueIteratee): LodashSortedLastIndexBy1x1; + (iteratee: lodash.__, value: T): LodashSortedLastIndexBy1x2; + (iteratee: lodash.ValueIteratee, value: T): LodashSortedLastIndexBy1x3; + (iteratee: lodash.__, value: lodash.__, array: lodash.List | null | undefined): LodashSortedLastIndexBy1x4; + (iteratee: lodash.ValueIteratee, value: lodash.__, array: lodash.List | null | undefined): LodashSortedLastIndexBy1x5; + (iteratee: lodash.__, value: T, array: lodash.List | null | undefined): LodashSortedLastIndexBy1x6; + (iteratee: lodash.ValueIteratee, value: T, array: lodash.List | null | undefined): number; + } + interface LodashSortedLastIndexBy1x1 { + (value: T): LodashSortedLastIndexBy1x3; + (value: lodash.__, array: lodash.List | null | undefined): LodashSortedLastIndexBy1x5; + (value: T, array: lodash.List | null | undefined): number; + } + interface LodashSortedLastIndexBy1x2 { + (iteratee: lodash.ValueIteratee): LodashSortedLastIndexBy1x3; + (iteratee: lodash.__, array: lodash.List | null | undefined): LodashSortedLastIndexBy1x6; + (iteratee: lodash.ValueIteratee, array: lodash.List | null | undefined): number; + } + type LodashSortedLastIndexBy1x3 = (array: lodash.List | null | undefined) => number; + interface LodashSortedLastIndexBy1x4 { + (iteratee: lodash.ValueIteratee): LodashSortedLastIndexBy1x5; + (iteratee: lodash.__, value: T): LodashSortedLastIndexBy1x6; + (iteratee: lodash.ValueIteratee, value: T): number; + } + type LodashSortedLastIndexBy1x5 = (value: T) => number; + type LodashSortedLastIndexBy1x6 = (iteratee: lodash.ValueIteratee) => number; + interface LodashSortedLastIndexOf { + (value: T): LodashSortedLastIndexOf1x1; + (value: lodash.__, array: lodash.List | null | undefined): LodashSortedLastIndexOf1x2; + (value: T, array: lodash.List | null | undefined): number; + } + type LodashSortedLastIndexOf1x1 = (array: lodash.List | null | undefined) => number; + type LodashSortedLastIndexOf1x2 = (value: T) => number; + type LodashSortedUniq = (array: lodash.List | null | undefined) => T[]; + interface LodashSortedUniqBy { + (iteratee: lodash.ValueIteratee): LodashSortedUniqBy1x1; + (iteratee: lodash.__, array: lodash.List | null | undefined): LodashSortedUniqBy1x2; + (iteratee: lodash.ValueIteratee, array: lodash.List | null | undefined): T[]; + } + type LodashSortedUniqBy1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashSortedUniqBy1x2 = (iteratee: lodash.ValueIteratee) => T[]; + interface LodashSplit { + (separator: RegExp | string): LodashSplit1x1; + (separator: lodash.__, string: string | null | undefined): LodashSplit1x2; + (separator: RegExp | string, string: string | null | undefined): string[]; + } + type LodashSplit1x1 = (string: string | null | undefined) => string[]; + type LodashSplit1x2 = (separator: RegExp | string) => string[]; + type LodashSpread = (func: (...args: any[]) => TResult) => (...args: any[]) => TResult; + interface LodashSpreadFrom { + (start: number): LodashSpreadFrom1x1; + (start: lodash.__, func: (...args: any[]) => TResult): LodashSpreadFrom1x2; + (start: number, func: (...args: any[]) => TResult): (...args: any[]) => TResult; + } + type LodashSpreadFrom1x1 = (func: (...args: any[]) => TResult) => (...args: any[]) => TResult; + type LodashSpreadFrom1x2 = (start: number) => (...args: any[]) => TResult; + type LodashStartCase = (string: string) => string; + interface LodashStartsWith { + (target: string): LodashStartsWith1x1; + (target: lodash.__, string: string): LodashStartsWith1x2; + (target: string, string: string): boolean; + } + type LodashStartsWith1x1 = (string: string) => boolean; + type LodashStartsWith1x2 = (target: string) => boolean; + type LodashStubArray = () => any[]; + type LodashStubObject = () => any; + type LodashStubString = () => string; + type LodashStubTrue = () => true; + interface LodashSubtract { + (minuend: number): LodashSubtract1x1; + (minuend: lodash.__, subtrahend: number): LodashSubtract1x2; + (minuend: number, subtrahend: number): number; + } + type LodashSubtract1x1 = (subtrahend: number) => number; + type LodashSubtract1x2 = (minuend: number) => number; + type LodashSum = (collection: lodash.List | null | undefined) => number; + interface LodashSumBy { + (iteratee: ((value: T) => number) | string): LodashSumBy1x1; + (iteratee: lodash.__, collection: lodash.List | null | undefined): LodashSumBy1x2; + (iteratee: ((value: T) => number) | string, collection: lodash.List | null | undefined): number; + } + type LodashSumBy1x1 = (collection: lodash.List | null | undefined) => number; + type LodashSumBy1x2 = (iteratee: ((value: T) => number) | string) => number; + interface LodashXor { + (arrays2: lodash.List | null | undefined): LodashXor1x1; + (arrays2: lodash.__, arrays: lodash.List | null | undefined): LodashXor1x2; + (arrays2: lodash.List | null | undefined, arrays: lodash.List | null | undefined): T[]; + } + type LodashXor1x1 = (arrays: lodash.List | null | undefined) => T[]; + type LodashXor1x2 = (arrays2: lodash.List | null | undefined) => T[]; + interface LodashXorBy { + (iteratee: lodash.ValueIteratee): LodashXorBy1x1; + (iteratee: lodash.__, arrays: lodash.List | null | undefined): LodashXorBy1x2; + (iteratee: lodash.ValueIteratee, arrays: lodash.List | null | undefined): LodashXorBy1x3; + (iteratee: lodash.__, arrays: lodash.__, arrays2: lodash.List | null | undefined): LodashXorBy1x4; + (iteratee: lodash.ValueIteratee, arrays: lodash.__, arrays2: lodash.List | null | undefined): LodashXorBy1x5; + (iteratee: lodash.__, arrays: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): LodashXorBy1x6; + (iteratee: lodash.ValueIteratee, arrays: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): T[]; + } + interface LodashXorBy1x1 { + (arrays: lodash.List | null | undefined): LodashXorBy1x3; + (arrays: lodash.__, arrays2: lodash.List | null | undefined): LodashXorBy1x5; + (arrays: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): T[]; + } + interface LodashXorBy1x2 { + (iteratee: lodash.ValueIteratee): LodashXorBy1x3; + (iteratee: lodash.__, arrays2: lodash.List | null | undefined): LodashXorBy1x6; + (iteratee: lodash.ValueIteratee, arrays2: lodash.List | null | undefined): T[]; + } + type LodashXorBy1x3 = (arrays2: lodash.List | null | undefined) => T[]; + interface LodashXorBy1x4 { + (iteratee: lodash.ValueIteratee): LodashXorBy1x5; + (iteratee: lodash.__, arrays: lodash.List | null | undefined): LodashXorBy1x6; + (iteratee: lodash.ValueIteratee, arrays: lodash.List | null | undefined): T[]; + } + type LodashXorBy1x5 = (arrays: lodash.List | null | undefined) => T[]; + type LodashXorBy1x6 = (iteratee: lodash.ValueIteratee) => T[]; + interface LodashXorWith { + (comparator: lodash.Comparator): LodashXorWith1x1; + (comparator: lodash.__, arrays: lodash.List | null | undefined): LodashXorWith1x2; + (comparator: lodash.Comparator, arrays: lodash.List | null | undefined): LodashXorWith1x3; + (comparator: lodash.__, arrays: lodash.__, arrays2: lodash.List | null | undefined): LodashXorWith1x4; + (comparator: lodash.Comparator, arrays: lodash.__, arrays2: lodash.List | null | undefined): LodashXorWith1x5; + (comparator: lodash.__, arrays: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): LodashXorWith1x6; + (comparator: lodash.Comparator, arrays: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): T[]; + } + interface LodashXorWith1x1 { + (arrays: lodash.List | null | undefined): LodashXorWith1x3; + (arrays: lodash.__, arrays2: lodash.List | null | undefined): LodashXorWith1x5; + (arrays: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): T[]; + } + interface LodashXorWith1x2 { + (comparator: lodash.Comparator): LodashXorWith1x3; + (comparator: lodash.__, arrays2: lodash.List | null | undefined): LodashXorWith1x6; + (comparator: lodash.Comparator, arrays2: lodash.List | null | undefined): T[]; + } + type LodashXorWith1x3 = (arrays2: lodash.List | null | undefined) => T[]; + interface LodashXorWith1x4 { + (comparator: lodash.Comparator): LodashXorWith1x5; + (comparator: lodash.__, arrays: lodash.List | null | undefined): LodashXorWith1x6; + (comparator: lodash.Comparator, arrays: lodash.List | null | undefined): T[]; + } + type LodashXorWith1x5 = (arrays: lodash.List | null | undefined) => T[]; + type LodashXorWith1x6 = (comparator: lodash.Comparator) => T[]; + type LodashTail = (array: lodash.List | null | undefined) => T[]; + interface LodashTake { + (n: number): LodashTake1x1; + (n: lodash.__, array: lodash.List | null | undefined): LodashTake1x2; + (n: number, array: lodash.List | null | undefined): T[]; + } + type LodashTake1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashTake1x2 = (n: number) => T[]; + interface LodashTakeRight { + (n: number): LodashTakeRight1x1; + (n: lodash.__, array: lodash.List | null | undefined): LodashTakeRight1x2; + (n: number, array: lodash.List | null | undefined): T[]; + } + type LodashTakeRight1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashTakeRight1x2 = (n: number) => T[]; + interface LodashTakeRightWhile { + (predicate: lodash.ValueIteratee): LodashTakeRightWhile1x1; + (predicate: lodash.__, array: lodash.List | null | undefined): LodashTakeRightWhile1x2; + (predicate: lodash.ValueIteratee, array: lodash.List | null | undefined): T[]; + } + type LodashTakeRightWhile1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashTakeRightWhile1x2 = (predicate: lodash.ValueIteratee) => T[]; + interface LodashTakeWhile { + (predicate: lodash.ValueIteratee): LodashTakeWhile1x1; + (predicate: lodash.__, array: lodash.List | null | undefined): LodashTakeWhile1x2; + (predicate: lodash.ValueIteratee, array: lodash.List | null | undefined): T[]; + } + type LodashTakeWhile1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashTakeWhile1x2 = (predicate: lodash.ValueIteratee) => T[]; + interface LodashTap { + (interceptor: (value: T) => void): LodashTap1x1; + (interceptor: lodash.__, value: T): LodashTap1x2; + (interceptor: (value: T) => void, value: T): T; + } + type LodashTap1x1 = (value: T) => T; + type LodashTap1x2 = (interceptor: (value: T) => void) => T; + type LodashTemplate = (string: string) => lodash.TemplateExecutor; + interface LodashThrottle { + (wait: number): LodashThrottle1x1; + any>(wait: lodash.__, func: T): LodashThrottle1x2; + any>(wait: number, func: T): lodash.DebouncedFunc; + } + type LodashThrottle1x1 = any>(func: T) => lodash.DebouncedFunc; + type LodashThrottle1x2 any> = (wait: number) => lodash.DebouncedFunc; + interface LodashThru { + (interceptor: (value: T) => TResult): LodashThru1x1; + (interceptor: lodash.__, value: T): LodashThru1x2; + (interceptor: (value: T) => TResult, value: T): TResult; + } + type LodashThru1x1 = (value: T) => TResult; + type LodashThru1x2 = (interceptor: (value: T) => TResult) => TResult; + interface LodashTimes { + (iteratee: (num: number) => TResult): LodashTimes1x1; + (iteratee: lodash.__, n: number): LodashTimes1x2; + (iteratee: (num: number) => TResult, n: number): TResult[]; + } + type LodashTimes1x1 = (n: number) => TResult[]; + type LodashTimes1x2 = (iteratee: (num: number) => TResult) => TResult[]; + interface LodashToArray { + (value: lodash.Dictionary | lodash.NumericDictionary | null | undefined): T[]; + (value: T): Array; + (): any[]; + } + type LodashToFinite = (value: any) => number; + type LodashToInteger = (value: any) => number; + type LodashToLength = (value: any) => number; + type LodashToLower = (string: string) => string; + type LodashToNumber = (value: any) => number; + type LodashToPath = (value: any) => string[]; + type LodashToPlainObject = (value: any) => any; + type LodashToSafeInteger = (value: any) => number; + type LodashToString = (value: any) => string; + type LodashToUpper = (string: string) => string; + interface LodashTransform { + (iteratee: lodash.MemoVoidIteratorCapped): LodashTransform1x1; + (iteratee: lodash.__, accumulator: TResult): LodashTransform1x2; + (iteratee: lodash.MemoVoidIteratorCapped, accumulator: TResult): LodashTransform1x3; + (iteratee: lodash.__, accumulator: lodash.__, object: ReadonlyArray): LodashTransform1x4; + (iteratee: lodash.MemoVoidIteratorCapped, accumulator: lodash.__, object: ReadonlyArray): LodashTransform1x5; + (iteratee: lodash.__, accumulator: TResult, object: ReadonlyArray): LodashTransform1x6; + (iteratee: lodash.MemoVoidIteratorCapped, accumulator: TResult, object: ReadonlyArray | lodash.Dictionary): TResult; + (iteratee: lodash.__, accumulator: lodash.__, object: lodash.Dictionary): LodashTransform2x4; + (iteratee: lodash.MemoVoidIteratorCapped, accumulator: lodash.__, object: lodash.Dictionary): LodashTransform2x5; + (iteratee: lodash.__, accumulator: TResult, object: lodash.Dictionary): LodashTransform2x6; + } + interface LodashTransform1x1 { + (accumulator: TResult): LodashTransform1x3; + (accumulator: lodash.__, object: ReadonlyArray): LodashTransform1x5; + (accumulator: TResult, object: ReadonlyArray | lodash.Dictionary): TResult; + (accumulator: lodash.__, object: lodash.Dictionary): LodashTransform2x5; + } + interface LodashTransform1x2 { + (iteratee: lodash.MemoVoidIteratorCapped): LodashTransform1x3; + (iteratee: lodash.__, object: ReadonlyArray): LodashTransform1x6; + (iteratee: lodash.MemoVoidIteratorCapped, object: ReadonlyArray | lodash.Dictionary): TResult; + (iteratee: lodash.__, object: lodash.Dictionary): LodashTransform2x6; + } + type LodashTransform1x3 = (object: ReadonlyArray | lodash.Dictionary) => TResult; + interface LodashTransform1x4 { + (iteratee: lodash.MemoVoidIteratorCapped): LodashTransform1x5; + (iteratee: lodash.__, accumulator: TResult): LodashTransform1x6; + (iteratee: lodash.MemoVoidIteratorCapped, accumulator: TResult): TResult; + } + type LodashTransform1x5 = (accumulator: TResult) => TResult; + type LodashTransform1x6 = (iteratee: lodash.MemoVoidIteratorCapped) => TResult; + interface LodashTransform2x4 { + (iteratee: lodash.MemoVoidIteratorCapped): LodashTransform2x5; + (iteratee: lodash.__, accumulator: TResult): LodashTransform2x6; + (iteratee: lodash.MemoVoidIteratorCapped, accumulator: TResult): TResult; + } + type LodashTransform2x5 = (accumulator: TResult) => TResult; + type LodashTransform2x6 = (iteratee: lodash.MemoVoidIteratorCapped) => TResult; + type LodashTrim = (string: string) => string; + interface LodashTrimChars { + (chars: string): LodashTrimChars1x1; + (chars: lodash.__, string: string): LodashTrimChars1x2; + (chars: string, string: string): string; + } + type LodashTrimChars1x1 = (string: string) => string; + type LodashTrimChars1x2 = (chars: string) => string; + interface LodashTrimCharsEnd { + (chars: string): LodashTrimCharsEnd1x1; + (chars: lodash.__, string: string): LodashTrimCharsEnd1x2; + (chars: string, string: string): string; + } + type LodashTrimCharsEnd1x1 = (string: string) => string; + type LodashTrimCharsEnd1x2 = (chars: string) => string; + interface LodashTrimCharsStart { + (chars: string): LodashTrimCharsStart1x1; + (chars: lodash.__, string: string): LodashTrimCharsStart1x2; + (chars: string, string: string): string; + } + type LodashTrimCharsStart1x1 = (string: string) => string; + type LodashTrimCharsStart1x2 = (chars: string) => string; + type LodashTrimEnd = (string: string) => string; + type LodashTrimStart = (string: string) => string; + interface LodashTruncate { + (options: lodash.TruncateOptions): LodashTruncate1x1; + (options: lodash.__, string: string): LodashTruncate1x2; + (options: lodash.TruncateOptions, string: string): string; + } + type LodashTruncate1x1 = (string: string) => string; + type LodashTruncate1x2 = (options: lodash.TruncateOptions) => string; + type LodashUnapply = (func: (...args: any[]) => any) => (...args: any[]) => any; + type LodashUnary = (func: (arg1: T, ...args: any[]) => TResult) => (arg1: T) => TResult; + type LodashUnescape = (string: string) => string; + interface LodashUnion { + (arrays2: lodash.List | null | undefined): LodashUnion1x1; + (arrays2: lodash.__, arrays: lodash.List | null | undefined): LodashUnion1x2; + (arrays2: lodash.List | null | undefined, arrays: lodash.List | null | undefined): T[]; + } + type LodashUnion1x1 = (arrays: lodash.List | null | undefined) => T[]; + type LodashUnion1x2 = (arrays2: lodash.List | null | undefined) => T[]; + interface LodashUnionBy { + (iteratee: lodash.ValueIteratee): LodashUnionBy1x1; + (iteratee: lodash.__, arrays1: lodash.List | null | undefined): LodashUnionBy1x2; + (iteratee: lodash.ValueIteratee, arrays1: lodash.List | null | undefined): LodashUnionBy1x3; + (iteratee: lodash.__, arrays1: lodash.__, arrays2: lodash.List | null | undefined): LodashUnionBy1x4; + (iteratee: lodash.ValueIteratee, arrays1: lodash.__, arrays2: lodash.List | null | undefined): LodashUnionBy1x5; + (iteratee: lodash.__, arrays1: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): LodashUnionBy1x6; + (iteratee: lodash.ValueIteratee, arrays1: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): T[]; + } + interface LodashUnionBy1x1 { + (arrays1: lodash.List | null | undefined): LodashUnionBy1x3; + (arrays1: lodash.__, arrays2: lodash.List | null | undefined): LodashUnionBy1x5; + (arrays1: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): T[]; + } + interface LodashUnionBy1x2 { + (iteratee: lodash.ValueIteratee): LodashUnionBy1x3; + (iteratee: lodash.__, arrays2: lodash.List | null | undefined): LodashUnionBy1x6; + (iteratee: lodash.ValueIteratee, arrays2: lodash.List | null | undefined): T[]; + } + type LodashUnionBy1x3 = (arrays2: lodash.List | null | undefined) => T[]; + interface LodashUnionBy1x4 { + (iteratee: lodash.ValueIteratee): LodashUnionBy1x5; + (iteratee: lodash.__, arrays1: lodash.List | null | undefined): LodashUnionBy1x6; + (iteratee: lodash.ValueIteratee, arrays1: lodash.List | null | undefined): T[]; + } + type LodashUnionBy1x5 = (arrays1: lodash.List | null | undefined) => T[]; + type LodashUnionBy1x6 = (iteratee: lodash.ValueIteratee) => T[]; + interface LodashUnionWith { + (comparator: lodash.Comparator): LodashUnionWith1x1; + (comparator: lodash.__, arrays: lodash.List | null | undefined): LodashUnionWith1x2; + (comparator: lodash.Comparator, arrays: lodash.List | null | undefined): LodashUnionWith1x3; + (comparator: lodash.__, arrays: lodash.__, arrays2: lodash.List | null | undefined): LodashUnionWith1x4; + (comparator: lodash.Comparator, arrays: lodash.__, arrays2: lodash.List | null | undefined): LodashUnionWith1x5; + (comparator: lodash.__, arrays: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): LodashUnionWith1x6; + (comparator: lodash.Comparator, arrays: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): T[]; + } + interface LodashUnionWith1x1 { + (arrays: lodash.List | null | undefined): LodashUnionWith1x3; + (arrays: lodash.__, arrays2: lodash.List | null | undefined): LodashUnionWith1x5; + (arrays: lodash.List | null | undefined, arrays2: lodash.List | null | undefined): T[]; + } + interface LodashUnionWith1x2 { + (comparator: lodash.Comparator): LodashUnionWith1x3; + (comparator: lodash.__, arrays2: lodash.List | null | undefined): LodashUnionWith1x6; + (comparator: lodash.Comparator, arrays2: lodash.List | null | undefined): T[]; + } + type LodashUnionWith1x3 = (arrays2: lodash.List | null | undefined) => T[]; + interface LodashUnionWith1x4 { + (comparator: lodash.Comparator): LodashUnionWith1x5; + (comparator: lodash.__, arrays: lodash.List | null | undefined): LodashUnionWith1x6; + (comparator: lodash.Comparator, arrays: lodash.List | null | undefined): T[]; + } + type LodashUnionWith1x5 = (arrays: lodash.List | null | undefined) => T[]; + type LodashUnionWith1x6 = (comparator: lodash.Comparator) => T[]; + type LodashUniq = (array: lodash.List | null | undefined) => T[]; + interface LodashUniqBy { + (iteratee: lodash.ValueIteratee): LodashUniqBy1x1; + (iteratee: lodash.__, array: lodash.List | null | undefined): LodashUniqBy1x2; + (iteratee: lodash.ValueIteratee, array: lodash.List | null | undefined): T[]; + } + type LodashUniqBy1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashUniqBy1x2 = (iteratee: lodash.ValueIteratee) => T[]; + type LodashUniqueId = (prefix: string) => string; + interface LodashUniqWith { + (comparator: lodash.Comparator): LodashUniqWith1x1; + (comparator: lodash.__, array: lodash.List | null | undefined): LodashUniqWith1x2; + (comparator: lodash.Comparator, array: lodash.List | null | undefined): T[]; + } + type LodashUniqWith1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashUniqWith1x2 = (comparator: lodash.Comparator) => T[]; + type LodashUnzip = (array: T[][] | lodash.List> | null | undefined) => T[][]; + interface LodashUnzipWith { + (iteratee: (...values: T[]) => TResult): LodashUnzipWith1x1; + (iteratee: lodash.__, array: lodash.List> | null | undefined): LodashUnzipWith1x2; + (iteratee: (...values: T[]) => TResult, array: lodash.List> | null | undefined): TResult[]; + } + type LodashUnzipWith1x1 = (array: lodash.List> | null | undefined) => TResult[]; + type LodashUnzipWith1x2 = (iteratee: (...values: T[]) => TResult) => TResult[]; + interface LodashUpdate { + (path: lodash.PropertyPath): LodashUpdate1x1; + (path: lodash.__, updater: (value: any) => any): LodashUpdate1x2; + (path: lodash.PropertyPath, updater: (value: any) => any): LodashUpdate1x3; + (path: lodash.__, updater: lodash.__, object: object): LodashUpdate1x4; + (path: lodash.PropertyPath, updater: lodash.__, object: object): LodashUpdate1x5; + (path: lodash.__, updater: (value: any) => any, object: object): LodashUpdate1x6; + (path: lodash.PropertyPath, updater: (value: any) => any, object: object): any; + } + interface LodashUpdate1x1 { + (updater: (value: any) => any): LodashUpdate1x3; + (updater: lodash.__, object: object): LodashUpdate1x5; + (updater: (value: any) => any, object: object): any; + } + interface LodashUpdate1x2 { + (path: lodash.PropertyPath): LodashUpdate1x3; + (path: lodash.__, object: object): LodashUpdate1x6; + (path: lodash.PropertyPath, object: object): any; + } + type LodashUpdate1x3 = (object: object) => any; + interface LodashUpdate1x4 { + (path: lodash.PropertyPath): LodashUpdate1x5; + (path: lodash.__, updater: (value: any) => any): LodashUpdate1x6; + (path: lodash.PropertyPath, updater: (value: any) => any): any; + } + type LodashUpdate1x5 = (updater: (value: any) => any) => any; + type LodashUpdate1x6 = (path: lodash.PropertyPath) => any; + interface LodashUpdateWith { + (customizer: lodash.SetWithCustomizer): LodashUpdateWith1x1; + (customizer: lodash.__, path: lodash.PropertyPath): LodashUpdateWith1x2; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath): LodashUpdateWith1x3; + (customizer: lodash.__, path: lodash.__, updater: (oldValue: any) => any): LodashUpdateWith1x4; + (customizer: lodash.SetWithCustomizer, path: lodash.__, updater: (oldValue: any) => any): LodashUpdateWith1x5; + (customizer: lodash.__, path: lodash.PropertyPath, updater: (oldValue: any) => any): LodashUpdateWith1x6; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, updater: (oldValue: any) => any): LodashUpdateWith1x7; + (customizer: lodash.__, path: lodash.__, updater: lodash.__, object: T): LodashUpdateWith1x8; + (customizer: lodash.SetWithCustomizer, path: lodash.__, updater: lodash.__, object: T): LodashUpdateWith1x9; + (customizer: lodash.__, path: lodash.PropertyPath, updater: lodash.__, object: T): LodashUpdateWith1x10; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, updater: lodash.__, object: T): LodashUpdateWith1x11; + (customizer: lodash.__, path: lodash.__, updater: (oldValue: any) => any, object: T): LodashUpdateWith1x12; + (customizer: lodash.SetWithCustomizer, path: lodash.__, updater: (oldValue: any) => any, object: T): LodashUpdateWith1x13; + (customizer: lodash.__, path: lodash.PropertyPath, updater: (oldValue: any) => any, object: T): LodashUpdateWith1x14; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, updater: (oldValue: any) => any, object: T): T; + } + interface LodashUpdateWith1x1 { + (path: lodash.PropertyPath): LodashUpdateWith1x3; + (path: lodash.__, updater: (oldValue: any) => any): LodashUpdateWith1x5; + (path: lodash.PropertyPath, updater: (oldValue: any) => any): LodashUpdateWith1x7; + (path: lodash.__, updater: lodash.__, object: T): LodashUpdateWith1x9; + (path: lodash.PropertyPath, updater: lodash.__, object: T): LodashUpdateWith1x11; + (path: lodash.__, updater: (oldValue: any) => any, object: T): LodashUpdateWith1x13; + (path: lodash.PropertyPath, updater: (oldValue: any) => any, object: T): T; + } + interface LodashUpdateWith1x2 { + (customizer: lodash.SetWithCustomizer): LodashUpdateWith1x3; + (customizer: lodash.__, updater: (oldValue: any) => any): LodashUpdateWith1x6; + (customizer: lodash.SetWithCustomizer, updater: (oldValue: any) => any): LodashUpdateWith1x7; + (customizer: lodash.__, updater: lodash.__, object: T): LodashUpdateWith1x10; + (customizer: lodash.SetWithCustomizer, updater: lodash.__, object: T): LodashUpdateWith1x11; + (customizer: lodash.__, updater: (oldValue: any) => any, object: T): LodashUpdateWith1x14; + (customizer: lodash.SetWithCustomizer, updater: (oldValue: any) => any, object: T): T; + } + interface LodashUpdateWith1x3 { + (updater: (oldValue: any) => any): LodashUpdateWith1x7; + (updater: lodash.__, object: T): LodashUpdateWith1x11; + (updater: (oldValue: any) => any, object: T): T; + } + interface LodashUpdateWith1x4 { + (customizer: lodash.SetWithCustomizer): LodashUpdateWith1x5; + (customizer: lodash.__, path: lodash.PropertyPath): LodashUpdateWith1x6; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath): LodashUpdateWith1x7; + (customizer: lodash.__, path: lodash.__, object: T): LodashUpdateWith1x12; + (customizer: lodash.SetWithCustomizer, path: lodash.__, object: T): LodashUpdateWith1x13; + (customizer: lodash.__, path: lodash.PropertyPath, object: T): LodashUpdateWith1x14; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, object: T): T; + } + interface LodashUpdateWith1x5 { + (path: lodash.PropertyPath): LodashUpdateWith1x7; + (path: lodash.__, object: T): LodashUpdateWith1x13; + (path: lodash.PropertyPath, object: T): T; + } + interface LodashUpdateWith1x6 { + (customizer: lodash.SetWithCustomizer): LodashUpdateWith1x7; + (customizer: lodash.__, object: T): LodashUpdateWith1x14; + (customizer: lodash.SetWithCustomizer, object: T): T; + } + type LodashUpdateWith1x7 = (object: T) => T; + interface LodashUpdateWith1x8 { + (customizer: lodash.SetWithCustomizer): LodashUpdateWith1x9; + (customizer: lodash.__, path: lodash.PropertyPath): LodashUpdateWith1x10; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath): LodashUpdateWith1x11; + (customizer: lodash.__, path: lodash.__, updater: (oldValue: any) => any): LodashUpdateWith1x12; + (customizer: lodash.SetWithCustomizer, path: lodash.__, updater: (oldValue: any) => any): LodashUpdateWith1x13; + (customizer: lodash.__, path: lodash.PropertyPath, updater: (oldValue: any) => any): LodashUpdateWith1x14; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath, updater: (oldValue: any) => any): T; + } + interface LodashUpdateWith1x9 { + (path: lodash.PropertyPath): LodashUpdateWith1x11; + (path: lodash.__, updater: (oldValue: any) => any): LodashUpdateWith1x13; + (path: lodash.PropertyPath, updater: (oldValue: any) => any): T; + } + interface LodashUpdateWith1x10 { + (customizer: lodash.SetWithCustomizer): LodashUpdateWith1x11; + (customizer: lodash.__, updater: (oldValue: any) => any): LodashUpdateWith1x14; + (customizer: lodash.SetWithCustomizer, updater: (oldValue: any) => any): T; + } + type LodashUpdateWith1x11 = (updater: (oldValue: any) => any) => T; + interface LodashUpdateWith1x12 { + (customizer: lodash.SetWithCustomizer): LodashUpdateWith1x13; + (customizer: lodash.__, path: lodash.PropertyPath): LodashUpdateWith1x14; + (customizer: lodash.SetWithCustomizer, path: lodash.PropertyPath): T; + } + type LodashUpdateWith1x13 = (path: lodash.PropertyPath) => T; + type LodashUpdateWith1x14 = (customizer: lodash.SetWithCustomizer) => T; + type LodashUpperCase = (string: string) => string; + type LodashUpperFirst = (string: string) => string; + interface LodashValues { + (object: lodash.Dictionary | lodash.NumericDictionary | lodash.List | null | undefined): T[]; + (object: T | null | undefined): Array; + (object: any): any[]; + } + interface LodashValuesIn { + (object: lodash.Dictionary | lodash.NumericDictionary | lodash.List | null | undefined): T[]; + (object: T | null | undefined): Array; + } + interface LodashWithout { + (values: ReadonlyArray): LodashWithout1x1; + (values: lodash.__, array: lodash.List | null | undefined): LodashWithout1x2; + (values: ReadonlyArray, array: lodash.List | null | undefined): T[]; + } + type LodashWithout1x1 = (array: lodash.List | null | undefined) => T[]; + type LodashWithout1x2 = (values: ReadonlyArray) => T[]; + type LodashWords = (string: string) => string[]; + interface LodashWrap { + (wrapper: (value: T, ...args: TArgs[]) => TResult): LodashWrap1x1; + (wrapper: lodash.__, value: T): LodashWrap1x2; + (wrapper: (value: T, ...args: TArgs[]) => TResult, value: T): (...args: TArgs[]) => TResult; + } + type LodashWrap1x1 = (value: T) => (...args: TArgs[]) => TResult; + type LodashWrap1x2 = (wrapper: (value: T, ...args: TArgs[]) => TResult) => (...args: TArgs[]) => TResult; + interface LodashZip { + (arrays1: lodash.List): LodashZip1x1; + (arrays1: lodash.__, arrays2: lodash.List): LodashZip1x2; + (arrays1: lodash.List, arrays2: lodash.List): Array<[T1 | undefined, T2 | undefined]>; + } + type LodashZip1x1 = (arrays2: lodash.List) => Array<[T1 | undefined, T2 | undefined]>; + type LodashZip1x2 = (arrays1: lodash.List) => Array<[T1 | undefined, T2 | undefined]>; + interface LodashZipAll { + (arrays1: [lodash.List, lodash.List]): Array<[T1 | undefined, T2 | undefined]>; + (arrays1: [lodash.List, lodash.List, lodash.List]): Array<[T1 | undefined, T2 | undefined, T3 | undefined]>; + (arrays1: [lodash.List, lodash.List, lodash.List, lodash.List]): Array<[T1 | undefined, T2 | undefined, T3 | undefined, T4 | undefined]>; + (arrays1: [lodash.List, lodash.List, lodash.List, lodash.List, lodash.List]): Array<[T1 | undefined, T2 | undefined, T3 | undefined, T4 | undefined, T5 | undefined]>; + (arrays: ReadonlyArray | null | undefined>): Array>; + } + interface LodashZipObject { + (props: lodash.List): LodashZipObject1x1; + (props: lodash.__, values: lodash.List): LodashZipObject1x2; + (props: lodash.List, values: lodash.List): lodash.Dictionary; + } + type LodashZipObject1x1 = (values: lodash.List) => lodash.Dictionary; + type LodashZipObject1x2 = (props: lodash.List) => lodash.Dictionary; + interface LodashZipObjectDeep { + (paths: lodash.List): LodashZipObjectDeep1x1; + (paths: lodash.__, values: lodash.List): LodashZipObjectDeep1x2; + (paths: lodash.List, values: lodash.List): object; + } + type LodashZipObjectDeep1x1 = (values: lodash.List) => object; + type LodashZipObjectDeep1x2 = (paths: lodash.List) => object; + interface LodashZipWith { + (iteratee: (value1: T1, value2: T2) => TResult): LodashZipWith1x1; + (iteratee: lodash.__, arrays1: lodash.List): LodashZipWith1x2; + (iteratee: (value1: T1, value2: T2) => TResult, arrays1: lodash.List): LodashZipWith1x3; + (iteratee: lodash.__, arrays1: lodash.__, arrays2: lodash.List): LodashZipWith1x4; + (iteratee: (value1: T1, value2: T2) => TResult, arrays1: lodash.__, arrays2: lodash.List): LodashZipWith1x5; + (iteratee: lodash.__, arrays1: lodash.List, arrays2: lodash.List): LodashZipWith1x6; + (iteratee: (value1: T1, value2: T2) => TResult, arrays1: lodash.List, arrays2: lodash.List): TResult[]; + } + interface LodashZipWith1x1 { + (arrays1: lodash.List): LodashZipWith1x3; + (arrays1: lodash.__, arrays2: lodash.List): LodashZipWith1x5; + (arrays1: lodash.List, arrays2: lodash.List): TResult[]; + } + interface LodashZipWith1x2 { + (iteratee: (value1: T1, value2: T2) => TResult): LodashZipWith1x3; + (iteratee: lodash.__, arrays2: lodash.List): LodashZipWith1x6; + (iteratee: (value1: T1, value2: T2) => TResult, arrays2: lodash.List): TResult[]; + } + type LodashZipWith1x3 = (arrays2: lodash.List) => TResult[]; + interface LodashZipWith1x4 { + (iteratee: (value1: T1, value2: T2) => TResult): LodashZipWith1x5; + (iteratee: lodash.__, arrays1: lodash.List): LodashZipWith1x6; + (iteratee: (value1: T1, value2: T2) => TResult, arrays1: lodash.List): TResult[]; + } + type LodashZipWith1x5 = (arrays1: lodash.List) => TResult[]; + type LodashZipWith1x6 = (iteratee: (value1: T1, value2: T2) => TResult) => TResult[]; + + interface LoDashFp { + add: LodashAdd; + after: LodashAfter; + all: LodashEvery; + allPass: LodashOverEvery; + always: LodashConstant; + any: LodashSome; + anyPass: LodashOverSome; + apply: LodashApply; + ary: LodashAry; + assign: LodashAssign; + assignAll: LodashAssignAll; + assignAllWith: LodashAssignAllWith; + assignIn: LodashAssignIn; + assignInAll: LodashAssignInAll; + assignInAllWith: LodashAssignInAllWith; + assignInWith: LodashAssignInWith; + assignWith: LodashAssignWith; + assoc: LodashSet; + assocPath: LodashSet; + at: LodashAt; + attempt: LodashAttempt; + before: LodashBefore; + bind: LodashBind; + bindAll: LodashBindAll; + bindKey: LodashBindKey; + camelCase: LodashCamelCase; + capitalize: LodashCapitalize; + castArray: LodashCastArray; + ceil: LodashCeil; + chunk: LodashChunk; + clamp: LodashClamp; + clone: LodashClone; + cloneDeep: LodashCloneDeep; + cloneDeepWith: LodashCloneDeepWith; + cloneWith: LodashCloneWith; + compact: LodashCompact; + complement: LodashNegate; + compose: LodashFlowRight; + concat: LodashConcat; + cond: LodashCond; + conforms: LodashConformsTo; + conformsTo: LodashConformsTo; + constant: LodashConstant; + contains: LodashContains; + countBy: LodashCountBy; + create: LodashCreate; + curry: LodashCurry; + curryN: LodashCurryN; + curryRight: LodashCurryRight; + curryRightN: LodashCurryRightN; + debounce: LodashDebounce; + deburr: LodashDeburr; + defaults: LodashDefaults; + defaultsAll: LodashDefaultsAll; + defaultsDeep: LodashDefaultsDeep; + defaultsDeepAll: LodashDefaultsDeepAll; + defaultTo: LodashDefaultTo; + defer: LodashDefer; + delay: LodashDelay; + difference: LodashDifference; + differenceBy: LodashDifferenceBy; + differenceWith: LodashDifferenceWith; + dissoc: LodashUnset; + dissocPath: LodashUnset; + divide: LodashDivide; + drop: LodashDrop; + dropLast: LodashDropRight; + dropLastWhile: LodashDropRightWhile; + dropRight: LodashDropRight; + dropRightWhile: LodashDropRightWhile; + dropWhile: LodashDropWhile; + each: LodashForEach; + eachRight: LodashForEachRight; + endsWith: LodashEndsWith; + entries: LodashToPairs; + entriesIn: LodashToPairsIn; + eq: LodashEq; + equals: LodashIsEqual; + escape: LodashEscape; + escapeRegExp: LodashEscapeRegExp; + every: LodashEvery; + extend: LodashExtend; + extendAll: LodashExtendAll; + extendAllWith: LodashExtendAllWith; + extendWith: LodashExtendWith; + F: LodashStubFalse; + fill: LodashFill; + filter: LodashFilter; + find: LodashFind; + findFrom: LodashFindFrom; + findIndex: LodashFindIndex; + findIndexFrom: LodashFindIndexFrom; + findKey: LodashFindKey; + findLast: LodashFindLast; + findLastFrom: LodashFindLastFrom; + findLastIndex: LodashFindLastIndex; + findLastIndexFrom: LodashFindLastIndexFrom; + findLastKey: LodashFindLastKey; + first: LodashHead; + flatMap: LodashFlatMap; + flatMapDeep: LodashFlatMapDeep; + flatMapDepth: LodashFlatMapDepth; + flatten: LodashFlatten; + flattenDeep: LodashFlattenDeep; + flattenDepth: LodashFlattenDepth; + flip: LodashFlip; + floor: LodashFloor; + flow: LodashFlow; + flowRight: LodashFlowRight; + forEach: LodashForEach; + forEachRight: LodashForEachRight; + forIn: LodashForIn; + forInRight: LodashForInRight; + forOwn: LodashForOwn; + forOwnRight: LodashForOwnRight; + fromPairs: LodashFromPairs; + functions: LodashFunctions; + functionsIn: LodashFunctionsIn; + get: LodashGet; + getOr: LodashGetOr; + groupBy: LodashGroupBy; + gt: LodashGt; + gte: LodashGte; + has: LodashHas; + hasIn: LodashHasIn; + head: LodashHead; + identical: LodashEq; + identity: LodashIdentity; + includes: LodashIncludes; + includesFrom: LodashIncludesFrom; + indexBy: LodashKeyBy; + indexOf: LodashIndexOf; + indexOfFrom: LodashIndexOfFrom; + init: LodashInitial; + initial: LodashInitial; + inRange: LodashInRange; + intersection: LodashIntersection; + intersectionBy: LodashIntersectionBy; + intersectionWith: LodashIntersectionWith; + invert: LodashInvert; + invertBy: LodashInvertBy; + invertObj: LodashInvert; + invoke: LodashInvoke; + invokeArgs: LodashInvokeArgs; + invokeArgsMap: LodashInvokeArgsMap; + invokeMap: LodashInvokeMap; + isArguments: LodashIsArguments; + isArray: LodashIsArray; + isArrayBuffer: LodashIsArrayBuffer; + isArrayLike: LodashIsArrayLike; + isArrayLikeObject: LodashIsArrayLikeObject; + isBoolean: LodashIsBoolean; + isBuffer: LodashIsBuffer; + isDate: LodashIsDate; + isElement: LodashIsElement; + isEmpty: LodashIsEmpty; + isEqual: LodashIsEqual; + isEqualWith: LodashIsEqualWith; + isError: LodashIsError; + isFinite: LodashIsFinite; + isFunction: LodashIsFunction; + isInteger: LodashIsInteger; + isLength: LodashIsLength; + isMap: LodashIsMap; + isMatch: LodashIsMatch; + isMatchWith: LodashIsMatchWith; + isNaN: LodashIsNaN; + isNative: LodashIsNative; + isNil: LodashIsNil; + isNull: LodashIsNull; + isNumber: LodashIsNumber; + isObject: LodashIsObject; + isObjectLike: LodashIsObjectLike; + isPlainObject: LodashIsPlainObject; + isRegExp: LodashIsRegExp; + isSafeInteger: LodashIsSafeInteger; + isSet: LodashIsSet; + isString: LodashIsString; + isSymbol: LodashIsSymbol; + isTypedArray: LodashIsTypedArray; + isUndefined: LodashIsUndefined; + isWeakMap: LodashIsWeakMap; + isWeakSet: LodashIsWeakSet; + iteratee: LodashIteratee; + join: LodashJoin; + juxt: LodashOver; + kebabCase: LodashKebabCase; + keyBy: LodashKeyBy; + keys: LodashKeys; + keysIn: LodashKeysIn; + last: LodashLast; + lastIndexOf: LodashLastIndexOf; + lastIndexOfFrom: LodashLastIndexOfFrom; + lowerCase: LodashLowerCase; + lowerFirst: LodashLowerFirst; + lt: LodashLt; + lte: LodashLte; + map: LodashMap; + mapKeys: LodashMapKeys; + mapValues: LodashMapValues; + matches: LodashIsMatch; + matchesProperty: LodashMatchesProperty; + max: LodashMax; + maxBy: LodashMaxBy; + mean: LodashMean; + meanBy: LodashMeanBy; + memoize: LodashMemoize; + merge: LodashMerge; + mergeAll: LodashMergeAll; + mergeAllWith: LodashMergeAllWith; + mergeWith: LodashMergeWith; + method: LodashMethod; + methodOf: LodashMethodOf; + min: LodashMin; + minBy: LodashMinBy; + multiply: LodashMultiply; + nAry: LodashAry; + negate: LodashNegate; + noConflict: LodashNoConflict; + noop: LodashNoop; + now: LodashNow; + nth: LodashNth; + nthArg: LodashNthArg; + omit: LodashOmit; + omitAll: LodashOmit; + omitBy: LodashOmitBy; + once: LodashOnce; + orderBy: LodashOrderBy; + over: LodashOver; + overArgs: LodashOverArgs; + overEvery: LodashOverEvery; + overSome: LodashOverSome; + pad: LodashPad; + padChars: LodashPadChars; + padCharsEnd: LodashPadCharsEnd; + padCharsStart: LodashPadCharsStart; + padEnd: LodashPadEnd; + padStart: LodashPadStart; + parseInt: LodashParseInt; + partial: LodashPartial; + partialRight: LodashPartialRight; + partition: LodashPartition; + path: LodashPath; + pathEq: LodashMatchesProperty; + pathOr: LodashPathOr; + paths: LodashAt; + pick: LodashPick; + pickAll: LodashPick; + pickBy: LodashPickBy; + pipe: LodashFlow; + pluck: LodashMap; + prop: LodashProp; + propEq: LodashMatchesProperty; + property: LodashProperty; + propertyOf: LodashPropertyOf; + propOr: LodashPropOr; + props: LodashAt; + pull: LodashPull; + pullAll: LodashPullAll; + pullAllBy: LodashPullAllBy; + pullAllWith: LodashPullAllWith; + pullAt: LodashPullAt; + random: LodashRandom; + range: LodashRange; + rangeRight: LodashRangeRight; + rangeStep: LodashRangeStep; + rangeStepRight: LodashRangeStepRight; + rearg: LodashRearg; + reduce: LodashReduce; + reduceRight: LodashReduceRight; + reject: LodashReject; + remove: LodashRemove; + repeat: LodashRepeat; + replace: LodashReplace; + rest: LodashRest; + restFrom: LodashRestFrom; + result: LodashResult; + reverse: LodashReverse; + round: LodashRound; + runInContext: LodashRunInContext; + sample: LodashSample; + sampleSize: LodashSampleSize; + set: LodashSet; + setWith: LodashSetWith; + shuffle: LodashShuffle; + size: LodashSize; + slice: LodashSlice; + snakeCase: LodashSnakeCase; + some: LodashSome; + sortBy: LodashSortBy; + sortedIndex: LodashSortedIndex; + sortedIndexBy: LodashSortedIndexBy; + sortedIndexOf: LodashSortedIndexOf; + sortedLastIndex: LodashSortedLastIndex; + sortedLastIndexBy: LodashSortedLastIndexBy; + sortedLastIndexOf: LodashSortedLastIndexOf; + sortedUniq: LodashSortedUniq; + sortedUniqBy: LodashSortedUniqBy; + split: LodashSplit; + spread: LodashSpread; + spreadFrom: LodashSpreadFrom; + startCase: LodashStartCase; + startsWith: LodashStartsWith; + stubArray: LodashStubArray; + stubFalse: LodashStubFalse; + stubObject: LodashStubObject; + stubString: LodashStubString; + stubTrue: LodashStubTrue; + subtract: LodashSubtract; + sum: LodashSum; + sumBy: LodashSumBy; + symmetricDifference: LodashXor; + symmetricDifferenceBy: LodashXorBy; + symmetricDifferenceWith: LodashXorWith; + T: LodashStubTrue; + tail: LodashTail; + take: LodashTake; + takeLast: LodashTakeRight; + takeLastWhile: LodashTakeRightWhile; + takeRight: LodashTakeRight; + takeRightWhile: LodashTakeRightWhile; + takeWhile: LodashTakeWhile; + tap: LodashTap; + template: LodashTemplate; + throttle: LodashThrottle; + thru: LodashThru; + times: LodashTimes; + toArray: LodashToArray; + toFinite: LodashToFinite; + toInteger: LodashToInteger; + toLength: LodashToLength; + toLower: LodashToLower; + toNumber: LodashToNumber; + toPairs: LodashToPairs; + toPairsIn: LodashToPairsIn; + toPath: LodashToPath; + toPlainObject: LodashToPlainObject; + toSafeInteger: LodashToSafeInteger; + toString: LodashToString; + toUpper: LodashToUpper; + transform: LodashTransform; + trim: LodashTrim; + trimChars: LodashTrimChars; + trimCharsEnd: LodashTrimCharsEnd; + trimCharsStart: LodashTrimCharsStart; + trimEnd: LodashTrimEnd; + trimStart: LodashTrimStart; + truncate: LodashTruncate; + unapply: LodashUnapply; + unary: LodashUnary; + unescape: LodashUnescape; + union: LodashUnion; + unionBy: LodashUnionBy; + unionWith: LodashUnionWith; + uniq: LodashUniq; + uniqBy: LodashUniqBy; + uniqueId: LodashUniqueId; + uniqWith: LodashUniqWith; + unnest: LodashFlatten; + unset: LodashUnset; + unzip: LodashUnzip; + unzipWith: LodashUnzipWith; + update: LodashUpdate; + updateWith: LodashUpdateWith; + upperCase: LodashUpperCase; + upperFirst: LodashUpperFirst; + useWith: LodashOverArgs; + values: LodashValues; + valuesIn: LodashValuesIn; + where: LodashConformsTo; + whereEq: LodashIsMatch; + without: LodashWithout; + words: LodashWords; + wrap: LodashWrap; + xor: LodashXor; + xorBy: LodashXorBy; + xorWith: LodashXorWith; + zip: LodashZip; + zipAll: LodashZipAll; + zipObj: LodashZipObject; + zipObject: LodashZipObject; + zipObjectDeep: LodashZipObjectDeep; + zipWith: LodashZipWith; + __: lodash.__; + placeholder: lodash.__; + } +} diff --git a/libs/events/node_modules/@types/lodash/fp/F.d.ts b/libs/events/node_modules/@types/lodash/fp/F.d.ts new file mode 100755 index 000000000..33fc57930 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/F.d.ts @@ -0,0 +1,2 @@ +import { F } from "../fp"; +export = F; diff --git a/libs/events/node_modules/@types/lodash/fp/T.d.ts b/libs/events/node_modules/@types/lodash/fp/T.d.ts new file mode 100755 index 000000000..886606ef6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/T.d.ts @@ -0,0 +1,2 @@ +import { T } from "../fp"; +export = T; diff --git a/libs/events/node_modules/@types/lodash/fp/__.d.ts b/libs/events/node_modules/@types/lodash/fp/__.d.ts new file mode 100755 index 000000000..aec0a5142 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/__.d.ts @@ -0,0 +1,3 @@ +import _ = require("../index"); +declare const __: _.__; +export = __; diff --git a/libs/events/node_modules/@types/lodash/fp/add.d.ts b/libs/events/node_modules/@types/lodash/fp/add.d.ts new file mode 100755 index 000000000..47c9c6a1a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/add.d.ts @@ -0,0 +1,2 @@ +import { add } from "../fp"; +export = add; diff --git a/libs/events/node_modules/@types/lodash/fp/after.d.ts b/libs/events/node_modules/@types/lodash/fp/after.d.ts new file mode 100755 index 000000000..93863a561 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/after.d.ts @@ -0,0 +1,2 @@ +import { after } from "../fp"; +export = after; diff --git a/libs/events/node_modules/@types/lodash/fp/all.d.ts b/libs/events/node_modules/@types/lodash/fp/all.d.ts new file mode 100755 index 000000000..5ca0f7073 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/all.d.ts @@ -0,0 +1,2 @@ +import { all } from "../fp"; +export = all; diff --git a/libs/events/node_modules/@types/lodash/fp/allPass.d.ts b/libs/events/node_modules/@types/lodash/fp/allPass.d.ts new file mode 100755 index 000000000..5013913ef --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/allPass.d.ts @@ -0,0 +1,2 @@ +import { allPass } from "../fp"; +export = allPass; diff --git a/libs/events/node_modules/@types/lodash/fp/always.d.ts b/libs/events/node_modules/@types/lodash/fp/always.d.ts new file mode 100755 index 000000000..07bd82d47 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/always.d.ts @@ -0,0 +1,2 @@ +import { always } from "../fp"; +export = always; diff --git a/libs/events/node_modules/@types/lodash/fp/any.d.ts b/libs/events/node_modules/@types/lodash/fp/any.d.ts new file mode 100755 index 000000000..5d8c38f27 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/any.d.ts @@ -0,0 +1,2 @@ +import { any } from "../fp"; +export = any; diff --git a/libs/events/node_modules/@types/lodash/fp/anyPass.d.ts b/libs/events/node_modules/@types/lodash/fp/anyPass.d.ts new file mode 100755 index 000000000..b69becfaf --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/anyPass.d.ts @@ -0,0 +1,2 @@ +import { anyPass } from "../fp"; +export = anyPass; diff --git a/libs/events/node_modules/@types/lodash/fp/apply.d.ts b/libs/events/node_modules/@types/lodash/fp/apply.d.ts new file mode 100755 index 000000000..e13c42c5d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/apply.d.ts @@ -0,0 +1,2 @@ +import { apply } from "../fp"; +export = apply; diff --git a/libs/events/node_modules/@types/lodash/fp/ary.d.ts b/libs/events/node_modules/@types/lodash/fp/ary.d.ts new file mode 100755 index 000000000..932d7f45f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/ary.d.ts @@ -0,0 +1,2 @@ +import { ary } from "../fp"; +export = ary; diff --git a/libs/events/node_modules/@types/lodash/fp/assign.d.ts b/libs/events/node_modules/@types/lodash/fp/assign.d.ts new file mode 100755 index 000000000..cf173104a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assign.d.ts @@ -0,0 +1,2 @@ +import { assign } from "../fp"; +export = assign; diff --git a/libs/events/node_modules/@types/lodash/fp/assignAll.d.ts b/libs/events/node_modules/@types/lodash/fp/assignAll.d.ts new file mode 100755 index 000000000..f95b06b47 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assignAll.d.ts @@ -0,0 +1,2 @@ +import { assignAll } from "../fp"; +export = assignAll; diff --git a/libs/events/node_modules/@types/lodash/fp/assignAllWith.d.ts b/libs/events/node_modules/@types/lodash/fp/assignAllWith.d.ts new file mode 100755 index 000000000..c2695a07a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assignAllWith.d.ts @@ -0,0 +1,2 @@ +import { assignAllWith } from "../fp"; +export = assignAllWith; diff --git a/libs/events/node_modules/@types/lodash/fp/assignIn.d.ts b/libs/events/node_modules/@types/lodash/fp/assignIn.d.ts new file mode 100755 index 000000000..f6cdee768 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assignIn.d.ts @@ -0,0 +1,2 @@ +import { assignIn } from "../fp"; +export = assignIn; diff --git a/libs/events/node_modules/@types/lodash/fp/assignInAll.d.ts b/libs/events/node_modules/@types/lodash/fp/assignInAll.d.ts new file mode 100755 index 000000000..539344b67 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assignInAll.d.ts @@ -0,0 +1,2 @@ +import { assignInAll } from "../fp"; +export = assignInAll; diff --git a/libs/events/node_modules/@types/lodash/fp/assignInAllWith.d.ts b/libs/events/node_modules/@types/lodash/fp/assignInAllWith.d.ts new file mode 100755 index 000000000..3b421fb33 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assignInAllWith.d.ts @@ -0,0 +1,2 @@ +import { assignInAllWith } from "../fp"; +export = assignInAllWith; diff --git a/libs/events/node_modules/@types/lodash/fp/assignInWith.d.ts b/libs/events/node_modules/@types/lodash/fp/assignInWith.d.ts new file mode 100755 index 000000000..c410091c6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assignInWith.d.ts @@ -0,0 +1,2 @@ +import { assignInWith } from "../fp"; +export = assignInWith; diff --git a/libs/events/node_modules/@types/lodash/fp/assignWith.d.ts b/libs/events/node_modules/@types/lodash/fp/assignWith.d.ts new file mode 100755 index 000000000..2205db011 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assignWith.d.ts @@ -0,0 +1,2 @@ +import { assignWith } from "../fp"; +export = assignWith; diff --git a/libs/events/node_modules/@types/lodash/fp/assoc.d.ts b/libs/events/node_modules/@types/lodash/fp/assoc.d.ts new file mode 100755 index 000000000..2a2e29c6f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assoc.d.ts @@ -0,0 +1,2 @@ +import { assoc } from "../fp"; +export = assoc; diff --git a/libs/events/node_modules/@types/lodash/fp/assocPath.d.ts b/libs/events/node_modules/@types/lodash/fp/assocPath.d.ts new file mode 100755 index 000000000..e2dd5179e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/assocPath.d.ts @@ -0,0 +1,2 @@ +import { assocPath } from "../fp"; +export = assocPath; diff --git a/libs/events/node_modules/@types/lodash/fp/at.d.ts b/libs/events/node_modules/@types/lodash/fp/at.d.ts new file mode 100755 index 000000000..beefa3343 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/at.d.ts @@ -0,0 +1,2 @@ +import { at } from "../fp"; +export = at; diff --git a/libs/events/node_modules/@types/lodash/fp/attempt.d.ts b/libs/events/node_modules/@types/lodash/fp/attempt.d.ts new file mode 100755 index 000000000..72d60af08 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/attempt.d.ts @@ -0,0 +1,2 @@ +import { attempt } from "../fp"; +export = attempt; diff --git a/libs/events/node_modules/@types/lodash/fp/before.d.ts b/libs/events/node_modules/@types/lodash/fp/before.d.ts new file mode 100755 index 000000000..ead286909 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/before.d.ts @@ -0,0 +1,2 @@ +import { before } from "../fp"; +export = before; diff --git a/libs/events/node_modules/@types/lodash/fp/bind.d.ts b/libs/events/node_modules/@types/lodash/fp/bind.d.ts new file mode 100755 index 000000000..a312192a3 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/bind.d.ts @@ -0,0 +1,2 @@ +import { bind } from "../fp"; +export = bind; diff --git a/libs/events/node_modules/@types/lodash/fp/bindAll.d.ts b/libs/events/node_modules/@types/lodash/fp/bindAll.d.ts new file mode 100755 index 000000000..4f7c7dbff --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/bindAll.d.ts @@ -0,0 +1,2 @@ +import { bindAll } from "../fp"; +export = bindAll; diff --git a/libs/events/node_modules/@types/lodash/fp/bindKey.d.ts b/libs/events/node_modules/@types/lodash/fp/bindKey.d.ts new file mode 100755 index 000000000..8986b2f3a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/bindKey.d.ts @@ -0,0 +1,2 @@ +import { bindKey } from "../fp"; +export = bindKey; diff --git a/libs/events/node_modules/@types/lodash/fp/camelCase.d.ts b/libs/events/node_modules/@types/lodash/fp/camelCase.d.ts new file mode 100755 index 000000000..be6628dd2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/camelCase.d.ts @@ -0,0 +1,2 @@ +import { camelCase } from "../fp"; +export = camelCase; diff --git a/libs/events/node_modules/@types/lodash/fp/capitalize.d.ts b/libs/events/node_modules/@types/lodash/fp/capitalize.d.ts new file mode 100755 index 000000000..7dc552f9e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/capitalize.d.ts @@ -0,0 +1,2 @@ +import { capitalize } from "../fp"; +export = capitalize; diff --git a/libs/events/node_modules/@types/lodash/fp/castArray.d.ts b/libs/events/node_modules/@types/lodash/fp/castArray.d.ts new file mode 100755 index 000000000..a431805ad --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/castArray.d.ts @@ -0,0 +1,2 @@ +import { castArray } from "../fp"; +export = castArray; diff --git a/libs/events/node_modules/@types/lodash/fp/ceil.d.ts b/libs/events/node_modules/@types/lodash/fp/ceil.d.ts new file mode 100755 index 000000000..13cd7317b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/ceil.d.ts @@ -0,0 +1,2 @@ +import { ceil } from "../fp"; +export = ceil; diff --git a/libs/events/node_modules/@types/lodash/fp/chunk.d.ts b/libs/events/node_modules/@types/lodash/fp/chunk.d.ts new file mode 100755 index 000000000..2e4066660 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/chunk.d.ts @@ -0,0 +1,2 @@ +import { chunk } from "../fp"; +export = chunk; diff --git a/libs/events/node_modules/@types/lodash/fp/clamp.d.ts b/libs/events/node_modules/@types/lodash/fp/clamp.d.ts new file mode 100755 index 000000000..121c6f9b9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/clamp.d.ts @@ -0,0 +1,2 @@ +import { clamp } from "../fp"; +export = clamp; diff --git a/libs/events/node_modules/@types/lodash/fp/clone.d.ts b/libs/events/node_modules/@types/lodash/fp/clone.d.ts new file mode 100755 index 000000000..9edf0c8d1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/clone.d.ts @@ -0,0 +1,2 @@ +import { clone } from "../fp"; +export = clone; diff --git a/libs/events/node_modules/@types/lodash/fp/cloneDeep.d.ts b/libs/events/node_modules/@types/lodash/fp/cloneDeep.d.ts new file mode 100755 index 000000000..3bdab159a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/cloneDeep.d.ts @@ -0,0 +1,2 @@ +import { cloneDeep } from "../fp"; +export = cloneDeep; diff --git a/libs/events/node_modules/@types/lodash/fp/cloneDeepWith.d.ts b/libs/events/node_modules/@types/lodash/fp/cloneDeepWith.d.ts new file mode 100755 index 000000000..57cf5af8b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/cloneDeepWith.d.ts @@ -0,0 +1,2 @@ +import { cloneDeepWith } from "../fp"; +export = cloneDeepWith; diff --git a/libs/events/node_modules/@types/lodash/fp/cloneWith.d.ts b/libs/events/node_modules/@types/lodash/fp/cloneWith.d.ts new file mode 100755 index 000000000..9c63e1369 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/cloneWith.d.ts @@ -0,0 +1,2 @@ +import { cloneWith } from "../fp"; +export = cloneWith; diff --git a/libs/events/node_modules/@types/lodash/fp/compact.d.ts b/libs/events/node_modules/@types/lodash/fp/compact.d.ts new file mode 100755 index 000000000..6ca154704 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/compact.d.ts @@ -0,0 +1,2 @@ +import { compact } from "../fp"; +export = compact; diff --git a/libs/events/node_modules/@types/lodash/fp/complement.d.ts b/libs/events/node_modules/@types/lodash/fp/complement.d.ts new file mode 100755 index 000000000..e4c311253 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/complement.d.ts @@ -0,0 +1,2 @@ +import { complement } from "../fp"; +export = complement; diff --git a/libs/events/node_modules/@types/lodash/fp/compose.d.ts b/libs/events/node_modules/@types/lodash/fp/compose.d.ts new file mode 100755 index 000000000..7950c7c58 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/compose.d.ts @@ -0,0 +1,2 @@ +import { compose } from "../fp"; +export = compose; diff --git a/libs/events/node_modules/@types/lodash/fp/concat.d.ts b/libs/events/node_modules/@types/lodash/fp/concat.d.ts new file mode 100755 index 000000000..5e109d1da --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/concat.d.ts @@ -0,0 +1,2 @@ +import { concat } from "../fp"; +export = concat; diff --git a/libs/events/node_modules/@types/lodash/fp/cond.d.ts b/libs/events/node_modules/@types/lodash/fp/cond.d.ts new file mode 100755 index 000000000..b9216e308 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/cond.d.ts @@ -0,0 +1,2 @@ +import { cond } from "../fp"; +export = cond; diff --git a/libs/events/node_modules/@types/lodash/fp/conforms.d.ts b/libs/events/node_modules/@types/lodash/fp/conforms.d.ts new file mode 100755 index 000000000..9bd3353f4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/conforms.d.ts @@ -0,0 +1,2 @@ +import { conforms } from "../fp"; +export = conforms; diff --git a/libs/events/node_modules/@types/lodash/fp/conformsTo.d.ts b/libs/events/node_modules/@types/lodash/fp/conformsTo.d.ts new file mode 100755 index 000000000..ad1728006 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/conformsTo.d.ts @@ -0,0 +1,2 @@ +import { conformsTo } from "../fp"; +export = conformsTo; diff --git a/libs/events/node_modules/@types/lodash/fp/constant.d.ts b/libs/events/node_modules/@types/lodash/fp/constant.d.ts new file mode 100755 index 000000000..ef80ff57c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/constant.d.ts @@ -0,0 +1,2 @@ +import { constant } from "../fp"; +export = constant; diff --git a/libs/events/node_modules/@types/lodash/fp/contains.d.ts b/libs/events/node_modules/@types/lodash/fp/contains.d.ts new file mode 100755 index 000000000..6c29e95f1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/contains.d.ts @@ -0,0 +1,2 @@ +import { contains } from "../fp"; +export = contains; diff --git a/libs/events/node_modules/@types/lodash/fp/convert.d.ts b/libs/events/node_modules/@types/lodash/fp/convert.d.ts new file mode 100755 index 000000000..c06ecd937 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/convert.d.ts @@ -0,0 +1,15 @@ +interface ConvertOptions { + cap?: boolean; + curry?: boolean; + fixed?: boolean; + immutable?: boolean; + rearg?: boolean; +} + +interface Convert { + (func: object, options?: ConvertOptions): any; + (name: string, func: (...args: any[]) => any, options?: ConvertOptions): any; +} + +declare const convert: Convert; +export = convert; diff --git a/libs/events/node_modules/@types/lodash/fp/countBy.d.ts b/libs/events/node_modules/@types/lodash/fp/countBy.d.ts new file mode 100755 index 000000000..e3725c352 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/countBy.d.ts @@ -0,0 +1,2 @@ +import { countBy } from "../fp"; +export = countBy; diff --git a/libs/events/node_modules/@types/lodash/fp/create.d.ts b/libs/events/node_modules/@types/lodash/fp/create.d.ts new file mode 100755 index 000000000..2818e10e8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/create.d.ts @@ -0,0 +1,2 @@ +import { create } from "../fp"; +export = create; diff --git a/libs/events/node_modules/@types/lodash/fp/curry.d.ts b/libs/events/node_modules/@types/lodash/fp/curry.d.ts new file mode 100755 index 000000000..e8fcf1ded --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/curry.d.ts @@ -0,0 +1,2 @@ +import { curry } from "../fp"; +export = curry; diff --git a/libs/events/node_modules/@types/lodash/fp/curryN.d.ts b/libs/events/node_modules/@types/lodash/fp/curryN.d.ts new file mode 100755 index 000000000..55b579b71 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/curryN.d.ts @@ -0,0 +1,2 @@ +import { curryN } from "../fp"; +export = curryN; diff --git a/libs/events/node_modules/@types/lodash/fp/curryRight.d.ts b/libs/events/node_modules/@types/lodash/fp/curryRight.d.ts new file mode 100755 index 000000000..d431f3c67 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/curryRight.d.ts @@ -0,0 +1,2 @@ +import { curryRight } from "../fp"; +export = curryRight; diff --git a/libs/events/node_modules/@types/lodash/fp/curryRightN.d.ts b/libs/events/node_modules/@types/lodash/fp/curryRightN.d.ts new file mode 100755 index 000000000..89866d16a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/curryRightN.d.ts @@ -0,0 +1,2 @@ +import { curryRightN } from "../fp"; +export = curryRightN; diff --git a/libs/events/node_modules/@types/lodash/fp/debounce.d.ts b/libs/events/node_modules/@types/lodash/fp/debounce.d.ts new file mode 100755 index 000000000..88b003cbb --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/debounce.d.ts @@ -0,0 +1,2 @@ +import { debounce } from "../fp"; +export = debounce; diff --git a/libs/events/node_modules/@types/lodash/fp/deburr.d.ts b/libs/events/node_modules/@types/lodash/fp/deburr.d.ts new file mode 100755 index 000000000..769abfb50 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/deburr.d.ts @@ -0,0 +1,2 @@ +import { deburr } from "../fp"; +export = deburr; diff --git a/libs/events/node_modules/@types/lodash/fp/defaultTo.d.ts b/libs/events/node_modules/@types/lodash/fp/defaultTo.d.ts new file mode 100755 index 000000000..e02cc46fe --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/defaultTo.d.ts @@ -0,0 +1,2 @@ +import { defaultTo } from "../fp"; +export = defaultTo; diff --git a/libs/events/node_modules/@types/lodash/fp/defaults.d.ts b/libs/events/node_modules/@types/lodash/fp/defaults.d.ts new file mode 100755 index 000000000..132e47ba2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/defaults.d.ts @@ -0,0 +1,2 @@ +import { defaults } from "../fp"; +export = defaults; diff --git a/libs/events/node_modules/@types/lodash/fp/defaultsAll.d.ts b/libs/events/node_modules/@types/lodash/fp/defaultsAll.d.ts new file mode 100755 index 000000000..1f2a3309e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/defaultsAll.d.ts @@ -0,0 +1,2 @@ +import { defaultsAll } from "../fp"; +export = defaultsAll; diff --git a/libs/events/node_modules/@types/lodash/fp/defaultsDeep.d.ts b/libs/events/node_modules/@types/lodash/fp/defaultsDeep.d.ts new file mode 100755 index 000000000..6268a0259 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/defaultsDeep.d.ts @@ -0,0 +1,2 @@ +import { defaultsDeep } from "../fp"; +export = defaultsDeep; diff --git a/libs/events/node_modules/@types/lodash/fp/defaultsDeepAll.d.ts b/libs/events/node_modules/@types/lodash/fp/defaultsDeepAll.d.ts new file mode 100755 index 000000000..779166623 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/defaultsDeepAll.d.ts @@ -0,0 +1,2 @@ +import { defaultsDeepAll } from "../fp"; +export = defaultsDeepAll; diff --git a/libs/events/node_modules/@types/lodash/fp/defer.d.ts b/libs/events/node_modules/@types/lodash/fp/defer.d.ts new file mode 100755 index 000000000..f8be4ae8e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/defer.d.ts @@ -0,0 +1,2 @@ +import { defer } from "../fp"; +export = defer; diff --git a/libs/events/node_modules/@types/lodash/fp/delay.d.ts b/libs/events/node_modules/@types/lodash/fp/delay.d.ts new file mode 100755 index 000000000..2f0c39909 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/delay.d.ts @@ -0,0 +1,2 @@ +import { delay } from "../fp"; +export = delay; diff --git a/libs/events/node_modules/@types/lodash/fp/difference.d.ts b/libs/events/node_modules/@types/lodash/fp/difference.d.ts new file mode 100755 index 000000000..944808504 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/difference.d.ts @@ -0,0 +1,2 @@ +import { difference } from "../fp"; +export = difference; diff --git a/libs/events/node_modules/@types/lodash/fp/differenceBy.d.ts b/libs/events/node_modules/@types/lodash/fp/differenceBy.d.ts new file mode 100755 index 000000000..52ba5b80a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/differenceBy.d.ts @@ -0,0 +1,2 @@ +import { differenceBy } from "../fp"; +export = differenceBy; diff --git a/libs/events/node_modules/@types/lodash/fp/differenceWith.d.ts b/libs/events/node_modules/@types/lodash/fp/differenceWith.d.ts new file mode 100755 index 000000000..fd3c9a2cd --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/differenceWith.d.ts @@ -0,0 +1,2 @@ +import { differenceWith } from "../fp"; +export = differenceWith; diff --git a/libs/events/node_modules/@types/lodash/fp/dissoc.d.ts b/libs/events/node_modules/@types/lodash/fp/dissoc.d.ts new file mode 100755 index 000000000..9b0fd6bb9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/dissoc.d.ts @@ -0,0 +1,2 @@ +import { dissoc } from "../fp"; +export = dissoc; diff --git a/libs/events/node_modules/@types/lodash/fp/dissocPath.d.ts b/libs/events/node_modules/@types/lodash/fp/dissocPath.d.ts new file mode 100755 index 000000000..a201aa4b8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/dissocPath.d.ts @@ -0,0 +1,2 @@ +import { dissocPath } from "../fp"; +export = dissocPath; diff --git a/libs/events/node_modules/@types/lodash/fp/divide.d.ts b/libs/events/node_modules/@types/lodash/fp/divide.d.ts new file mode 100755 index 000000000..5cd02e49d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/divide.d.ts @@ -0,0 +1,2 @@ +import { divide } from "../fp"; +export = divide; diff --git a/libs/events/node_modules/@types/lodash/fp/drop.d.ts b/libs/events/node_modules/@types/lodash/fp/drop.d.ts new file mode 100755 index 000000000..bc3b9b204 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/drop.d.ts @@ -0,0 +1,2 @@ +import { drop } from "../fp"; +export = drop; diff --git a/libs/events/node_modules/@types/lodash/fp/dropLast.d.ts b/libs/events/node_modules/@types/lodash/fp/dropLast.d.ts new file mode 100755 index 000000000..1dd388ae1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/dropLast.d.ts @@ -0,0 +1,2 @@ +import { dropLast } from "../fp"; +export = dropLast; diff --git a/libs/events/node_modules/@types/lodash/fp/dropLastWhile.d.ts b/libs/events/node_modules/@types/lodash/fp/dropLastWhile.d.ts new file mode 100755 index 000000000..97529a6a4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/dropLastWhile.d.ts @@ -0,0 +1,2 @@ +import { dropLastWhile } from "../fp"; +export = dropLastWhile; diff --git a/libs/events/node_modules/@types/lodash/fp/dropRight.d.ts b/libs/events/node_modules/@types/lodash/fp/dropRight.d.ts new file mode 100755 index 000000000..a2740ff02 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/dropRight.d.ts @@ -0,0 +1,2 @@ +import { dropRight } from "../fp"; +export = dropRight; diff --git a/libs/events/node_modules/@types/lodash/fp/dropRightWhile.d.ts b/libs/events/node_modules/@types/lodash/fp/dropRightWhile.d.ts new file mode 100755 index 000000000..1a5aa5fe3 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/dropRightWhile.d.ts @@ -0,0 +1,2 @@ +import { dropRightWhile } from "../fp"; +export = dropRightWhile; diff --git a/libs/events/node_modules/@types/lodash/fp/dropWhile.d.ts b/libs/events/node_modules/@types/lodash/fp/dropWhile.d.ts new file mode 100755 index 000000000..2cab8d869 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/dropWhile.d.ts @@ -0,0 +1,2 @@ +import { dropWhile } from "../fp"; +export = dropWhile; diff --git a/libs/events/node_modules/@types/lodash/fp/each.d.ts b/libs/events/node_modules/@types/lodash/fp/each.d.ts new file mode 100755 index 000000000..af1d3b20a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/each.d.ts @@ -0,0 +1,2 @@ +import { each } from "../fp"; +export = each; diff --git a/libs/events/node_modules/@types/lodash/fp/eachRight.d.ts b/libs/events/node_modules/@types/lodash/fp/eachRight.d.ts new file mode 100755 index 000000000..5ca2934ab --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/eachRight.d.ts @@ -0,0 +1,2 @@ +import { eachRight } from "../fp"; +export = eachRight; diff --git a/libs/events/node_modules/@types/lodash/fp/endsWith.d.ts b/libs/events/node_modules/@types/lodash/fp/endsWith.d.ts new file mode 100755 index 000000000..7e1b243d6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/endsWith.d.ts @@ -0,0 +1,2 @@ +import { endsWith } from "../fp"; +export = endsWith; diff --git a/libs/events/node_modules/@types/lodash/fp/entries.d.ts b/libs/events/node_modules/@types/lodash/fp/entries.d.ts new file mode 100755 index 000000000..534c7bda3 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/entries.d.ts @@ -0,0 +1,2 @@ +import { entries } from "../fp"; +export = entries; diff --git a/libs/events/node_modules/@types/lodash/fp/entriesIn.d.ts b/libs/events/node_modules/@types/lodash/fp/entriesIn.d.ts new file mode 100755 index 000000000..932b17f62 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/entriesIn.d.ts @@ -0,0 +1,2 @@ +import { entriesIn } from "../fp"; +export = entriesIn; diff --git a/libs/events/node_modules/@types/lodash/fp/eq.d.ts b/libs/events/node_modules/@types/lodash/fp/eq.d.ts new file mode 100755 index 000000000..4778846a3 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/eq.d.ts @@ -0,0 +1,2 @@ +import { eq } from "../fp"; +export = eq; diff --git a/libs/events/node_modules/@types/lodash/fp/equals.d.ts b/libs/events/node_modules/@types/lodash/fp/equals.d.ts new file mode 100755 index 000000000..18ec108d6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/equals.d.ts @@ -0,0 +1,2 @@ +import { equals } from "../fp"; +export = equals; diff --git a/libs/events/node_modules/@types/lodash/fp/escape.d.ts b/libs/events/node_modules/@types/lodash/fp/escape.d.ts new file mode 100755 index 000000000..36e7e8755 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/escape.d.ts @@ -0,0 +1,2 @@ +import { escape } from "../fp"; +export = escape; diff --git a/libs/events/node_modules/@types/lodash/fp/escapeRegExp.d.ts b/libs/events/node_modules/@types/lodash/fp/escapeRegExp.d.ts new file mode 100755 index 000000000..6adc20e80 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/escapeRegExp.d.ts @@ -0,0 +1,2 @@ +import { escapeRegExp } from "../fp"; +export = escapeRegExp; diff --git a/libs/events/node_modules/@types/lodash/fp/every.d.ts b/libs/events/node_modules/@types/lodash/fp/every.d.ts new file mode 100755 index 000000000..7fbeaf7b1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/every.d.ts @@ -0,0 +1,2 @@ +import { every } from "../fp"; +export = every; diff --git a/libs/events/node_modules/@types/lodash/fp/extend.d.ts b/libs/events/node_modules/@types/lodash/fp/extend.d.ts new file mode 100755 index 000000000..cbe294ee0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/extend.d.ts @@ -0,0 +1,2 @@ +import { extend } from "../fp"; +export = extend; diff --git a/libs/events/node_modules/@types/lodash/fp/extendAll.d.ts b/libs/events/node_modules/@types/lodash/fp/extendAll.d.ts new file mode 100755 index 000000000..92cb3d6e0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/extendAll.d.ts @@ -0,0 +1,2 @@ +import { extendAll } from "../fp"; +export = extendAll; diff --git a/libs/events/node_modules/@types/lodash/fp/extendAllWith.d.ts b/libs/events/node_modules/@types/lodash/fp/extendAllWith.d.ts new file mode 100755 index 000000000..712d1d8ee --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/extendAllWith.d.ts @@ -0,0 +1,2 @@ +import { extendAllWith } from "../fp"; +export = extendAllWith; diff --git a/libs/events/node_modules/@types/lodash/fp/extendWith.d.ts b/libs/events/node_modules/@types/lodash/fp/extendWith.d.ts new file mode 100755 index 000000000..9681360bb --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/extendWith.d.ts @@ -0,0 +1,2 @@ +import { extendWith } from "../fp"; +export = extendWith; diff --git a/libs/events/node_modules/@types/lodash/fp/fill.d.ts b/libs/events/node_modules/@types/lodash/fp/fill.d.ts new file mode 100755 index 000000000..577801504 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/fill.d.ts @@ -0,0 +1,2 @@ +import { fill } from "../fp"; +export = fill; diff --git a/libs/events/node_modules/@types/lodash/fp/filter.d.ts b/libs/events/node_modules/@types/lodash/fp/filter.d.ts new file mode 100755 index 000000000..861974134 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/filter.d.ts @@ -0,0 +1,2 @@ +import { filter } from "../fp"; +export = filter; diff --git a/libs/events/node_modules/@types/lodash/fp/find.d.ts b/libs/events/node_modules/@types/lodash/fp/find.d.ts new file mode 100755 index 000000000..06418fb45 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/find.d.ts @@ -0,0 +1,2 @@ +import { find } from "../fp"; +export = find; diff --git a/libs/events/node_modules/@types/lodash/fp/findFrom.d.ts b/libs/events/node_modules/@types/lodash/fp/findFrom.d.ts new file mode 100755 index 000000000..64275d0c8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/findFrom.d.ts @@ -0,0 +1,2 @@ +import { findFrom } from "../fp"; +export = findFrom; diff --git a/libs/events/node_modules/@types/lodash/fp/findIndex.d.ts b/libs/events/node_modules/@types/lodash/fp/findIndex.d.ts new file mode 100755 index 000000000..77d1f7b6b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/findIndex.d.ts @@ -0,0 +1,2 @@ +import { findIndex } from "../fp"; +export = findIndex; diff --git a/libs/events/node_modules/@types/lodash/fp/findIndexFrom.d.ts b/libs/events/node_modules/@types/lodash/fp/findIndexFrom.d.ts new file mode 100755 index 000000000..22330adc5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/findIndexFrom.d.ts @@ -0,0 +1,2 @@ +import { findIndexFrom } from "../fp"; +export = findIndexFrom; diff --git a/libs/events/node_modules/@types/lodash/fp/findKey.d.ts b/libs/events/node_modules/@types/lodash/fp/findKey.d.ts new file mode 100755 index 000000000..c5a225a77 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/findKey.d.ts @@ -0,0 +1,2 @@ +import { findKey } from "../fp"; +export = findKey; diff --git a/libs/events/node_modules/@types/lodash/fp/findLast.d.ts b/libs/events/node_modules/@types/lodash/fp/findLast.d.ts new file mode 100755 index 000000000..b400c946b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/findLast.d.ts @@ -0,0 +1,2 @@ +import { findLast } from "../fp"; +export = findLast; diff --git a/libs/events/node_modules/@types/lodash/fp/findLastFrom.d.ts b/libs/events/node_modules/@types/lodash/fp/findLastFrom.d.ts new file mode 100755 index 000000000..1f034dfa8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/findLastFrom.d.ts @@ -0,0 +1,2 @@ +import { findLastFrom } from "../fp"; +export = findLastFrom; diff --git a/libs/events/node_modules/@types/lodash/fp/findLastIndex.d.ts b/libs/events/node_modules/@types/lodash/fp/findLastIndex.d.ts new file mode 100755 index 000000000..51ee410fb --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/findLastIndex.d.ts @@ -0,0 +1,2 @@ +import { findLastIndex } from "../fp"; +export = findLastIndex; diff --git a/libs/events/node_modules/@types/lodash/fp/findLastIndexFrom.d.ts b/libs/events/node_modules/@types/lodash/fp/findLastIndexFrom.d.ts new file mode 100755 index 000000000..08bd53a08 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/findLastIndexFrom.d.ts @@ -0,0 +1,2 @@ +import { findLastIndexFrom } from "../fp"; +export = findLastIndexFrom; diff --git a/libs/events/node_modules/@types/lodash/fp/findLastKey.d.ts b/libs/events/node_modules/@types/lodash/fp/findLastKey.d.ts new file mode 100755 index 000000000..7437a9ddd --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/findLastKey.d.ts @@ -0,0 +1,2 @@ +import { findLastKey } from "../fp"; +export = findLastKey; diff --git a/libs/events/node_modules/@types/lodash/fp/first.d.ts b/libs/events/node_modules/@types/lodash/fp/first.d.ts new file mode 100755 index 000000000..4554ad0e9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/first.d.ts @@ -0,0 +1,2 @@ +import { first } from "../fp"; +export = first; diff --git a/libs/events/node_modules/@types/lodash/fp/flatMap.d.ts b/libs/events/node_modules/@types/lodash/fp/flatMap.d.ts new file mode 100755 index 000000000..eb6d80434 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/flatMap.d.ts @@ -0,0 +1,2 @@ +import { flatMap } from "../fp"; +export = flatMap; diff --git a/libs/events/node_modules/@types/lodash/fp/flatMapDeep.d.ts b/libs/events/node_modules/@types/lodash/fp/flatMapDeep.d.ts new file mode 100755 index 000000000..0ce4db480 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/flatMapDeep.d.ts @@ -0,0 +1,2 @@ +import { flatMapDeep } from "../fp"; +export = flatMapDeep; diff --git a/libs/events/node_modules/@types/lodash/fp/flatMapDepth.d.ts b/libs/events/node_modules/@types/lodash/fp/flatMapDepth.d.ts new file mode 100755 index 000000000..b60af92cc --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/flatMapDepth.d.ts @@ -0,0 +1,2 @@ +import { flatMapDepth } from "../fp"; +export = flatMapDepth; diff --git a/libs/events/node_modules/@types/lodash/fp/flatten.d.ts b/libs/events/node_modules/@types/lodash/fp/flatten.d.ts new file mode 100755 index 000000000..02c051ff0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/flatten.d.ts @@ -0,0 +1,2 @@ +import { flatten } from "../fp"; +export = flatten; diff --git a/libs/events/node_modules/@types/lodash/fp/flattenDeep.d.ts b/libs/events/node_modules/@types/lodash/fp/flattenDeep.d.ts new file mode 100755 index 000000000..44b40e3a1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/flattenDeep.d.ts @@ -0,0 +1,2 @@ +import { flattenDeep } from "../fp"; +export = flattenDeep; diff --git a/libs/events/node_modules/@types/lodash/fp/flattenDepth.d.ts b/libs/events/node_modules/@types/lodash/fp/flattenDepth.d.ts new file mode 100755 index 000000000..f046f2086 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/flattenDepth.d.ts @@ -0,0 +1,2 @@ +import { flattenDepth } from "../fp"; +export = flattenDepth; diff --git a/libs/events/node_modules/@types/lodash/fp/flip.d.ts b/libs/events/node_modules/@types/lodash/fp/flip.d.ts new file mode 100755 index 000000000..e5b3b7d4f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/flip.d.ts @@ -0,0 +1,2 @@ +import { flip } from "../fp"; +export = flip; diff --git a/libs/events/node_modules/@types/lodash/fp/floor.d.ts b/libs/events/node_modules/@types/lodash/fp/floor.d.ts new file mode 100755 index 000000000..167ab9543 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/floor.d.ts @@ -0,0 +1,2 @@ +import { floor } from "../fp"; +export = floor; diff --git a/libs/events/node_modules/@types/lodash/fp/flow.d.ts b/libs/events/node_modules/@types/lodash/fp/flow.d.ts new file mode 100755 index 000000000..97f0fb82b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/flow.d.ts @@ -0,0 +1,2 @@ +import { flow } from "../fp"; +export = flow; diff --git a/libs/events/node_modules/@types/lodash/fp/flowRight.d.ts b/libs/events/node_modules/@types/lodash/fp/flowRight.d.ts new file mode 100755 index 000000000..f148feaad --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/flowRight.d.ts @@ -0,0 +1,2 @@ +import { flowRight } from "../fp"; +export = flowRight; diff --git a/libs/events/node_modules/@types/lodash/fp/forEach.d.ts b/libs/events/node_modules/@types/lodash/fp/forEach.d.ts new file mode 100755 index 000000000..f8aa7a4a1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/forEach.d.ts @@ -0,0 +1,2 @@ +import { forEach } from "../fp"; +export = forEach; diff --git a/libs/events/node_modules/@types/lodash/fp/forEachRight.d.ts b/libs/events/node_modules/@types/lodash/fp/forEachRight.d.ts new file mode 100755 index 000000000..135a4243a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/forEachRight.d.ts @@ -0,0 +1,2 @@ +import { forEachRight } from "../fp"; +export = forEachRight; diff --git a/libs/events/node_modules/@types/lodash/fp/forIn.d.ts b/libs/events/node_modules/@types/lodash/fp/forIn.d.ts new file mode 100755 index 000000000..dab37b107 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/forIn.d.ts @@ -0,0 +1,2 @@ +import { forIn } from "../fp"; +export = forIn; diff --git a/libs/events/node_modules/@types/lodash/fp/forInRight.d.ts b/libs/events/node_modules/@types/lodash/fp/forInRight.d.ts new file mode 100755 index 000000000..c560df0ce --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/forInRight.d.ts @@ -0,0 +1,2 @@ +import { forInRight } from "../fp"; +export = forInRight; diff --git a/libs/events/node_modules/@types/lodash/fp/forOwn.d.ts b/libs/events/node_modules/@types/lodash/fp/forOwn.d.ts new file mode 100755 index 000000000..7099c48a9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/forOwn.d.ts @@ -0,0 +1,2 @@ +import { forOwn } from "../fp"; +export = forOwn; diff --git a/libs/events/node_modules/@types/lodash/fp/forOwnRight.d.ts b/libs/events/node_modules/@types/lodash/fp/forOwnRight.d.ts new file mode 100755 index 000000000..f1e392886 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/forOwnRight.d.ts @@ -0,0 +1,2 @@ +import { forOwnRight } from "../fp"; +export = forOwnRight; diff --git a/libs/events/node_modules/@types/lodash/fp/fromPairs.d.ts b/libs/events/node_modules/@types/lodash/fp/fromPairs.d.ts new file mode 100755 index 000000000..b0d0082a5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/fromPairs.d.ts @@ -0,0 +1,2 @@ +import { fromPairs } from "../fp"; +export = fromPairs; diff --git a/libs/events/node_modules/@types/lodash/fp/functions.d.ts b/libs/events/node_modules/@types/lodash/fp/functions.d.ts new file mode 100755 index 000000000..727d68e13 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/functions.d.ts @@ -0,0 +1,2 @@ +import { functions } from "../fp"; +export = functions; diff --git a/libs/events/node_modules/@types/lodash/fp/functionsIn.d.ts b/libs/events/node_modules/@types/lodash/fp/functionsIn.d.ts new file mode 100755 index 000000000..448746e61 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/functionsIn.d.ts @@ -0,0 +1,2 @@ +import { functionsIn } from "../fp"; +export = functionsIn; diff --git a/libs/events/node_modules/@types/lodash/fp/get.d.ts b/libs/events/node_modules/@types/lodash/fp/get.d.ts new file mode 100755 index 000000000..ff3ab8b09 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/get.d.ts @@ -0,0 +1,2 @@ +import { get } from "../fp"; +export = get; diff --git a/libs/events/node_modules/@types/lodash/fp/getOr.d.ts b/libs/events/node_modules/@types/lodash/fp/getOr.d.ts new file mode 100755 index 000000000..ce3d5bba3 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/getOr.d.ts @@ -0,0 +1,2 @@ +import { getOr } from "../fp"; +export = getOr; diff --git a/libs/events/node_modules/@types/lodash/fp/groupBy.d.ts b/libs/events/node_modules/@types/lodash/fp/groupBy.d.ts new file mode 100755 index 000000000..813830aa0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/groupBy.d.ts @@ -0,0 +1,2 @@ +import { groupBy } from "../fp"; +export = groupBy; diff --git a/libs/events/node_modules/@types/lodash/fp/gt.d.ts b/libs/events/node_modules/@types/lodash/fp/gt.d.ts new file mode 100755 index 000000000..517071f51 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/gt.d.ts @@ -0,0 +1,2 @@ +import { gt } from "../fp"; +export = gt; diff --git a/libs/events/node_modules/@types/lodash/fp/gte.d.ts b/libs/events/node_modules/@types/lodash/fp/gte.d.ts new file mode 100755 index 000000000..5f6d85c7f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/gte.d.ts @@ -0,0 +1,2 @@ +import { gte } from "../fp"; +export = gte; diff --git a/libs/events/node_modules/@types/lodash/fp/has.d.ts b/libs/events/node_modules/@types/lodash/fp/has.d.ts new file mode 100755 index 000000000..8cbda7fb8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/has.d.ts @@ -0,0 +1,2 @@ +import { has } from "../fp"; +export = has; diff --git a/libs/events/node_modules/@types/lodash/fp/hasIn.d.ts b/libs/events/node_modules/@types/lodash/fp/hasIn.d.ts new file mode 100755 index 000000000..7e06a87ae --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/hasIn.d.ts @@ -0,0 +1,2 @@ +import { hasIn } from "../fp"; +export = hasIn; diff --git a/libs/events/node_modules/@types/lodash/fp/head.d.ts b/libs/events/node_modules/@types/lodash/fp/head.d.ts new file mode 100755 index 000000000..4a7d5e59c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/head.d.ts @@ -0,0 +1,2 @@ +import { head } from "../fp"; +export = head; diff --git a/libs/events/node_modules/@types/lodash/fp/identical.d.ts b/libs/events/node_modules/@types/lodash/fp/identical.d.ts new file mode 100755 index 000000000..954dff556 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/identical.d.ts @@ -0,0 +1,2 @@ +import { identical } from "../fp"; +export = identical; diff --git a/libs/events/node_modules/@types/lodash/fp/identity.d.ts b/libs/events/node_modules/@types/lodash/fp/identity.d.ts new file mode 100755 index 000000000..97e613c6c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/identity.d.ts @@ -0,0 +1,2 @@ +import { identity } from "../fp"; +export = identity; diff --git a/libs/events/node_modules/@types/lodash/fp/inRange.d.ts b/libs/events/node_modules/@types/lodash/fp/inRange.d.ts new file mode 100755 index 000000000..06ed31268 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/inRange.d.ts @@ -0,0 +1,2 @@ +import { inRange } from "../fp"; +export = inRange; diff --git a/libs/events/node_modules/@types/lodash/fp/includes.d.ts b/libs/events/node_modules/@types/lodash/fp/includes.d.ts new file mode 100755 index 000000000..afc998428 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/includes.d.ts @@ -0,0 +1,2 @@ +import { includes } from "../fp"; +export = includes; diff --git a/libs/events/node_modules/@types/lodash/fp/includesFrom.d.ts b/libs/events/node_modules/@types/lodash/fp/includesFrom.d.ts new file mode 100755 index 000000000..13042d029 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/includesFrom.d.ts @@ -0,0 +1,2 @@ +import { includesFrom } from "../fp"; +export = includesFrom; diff --git a/libs/events/node_modules/@types/lodash/fp/indexBy.d.ts b/libs/events/node_modules/@types/lodash/fp/indexBy.d.ts new file mode 100755 index 000000000..f3f75a41f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/indexBy.d.ts @@ -0,0 +1,2 @@ +import { indexBy } from "../fp"; +export = indexBy; diff --git a/libs/events/node_modules/@types/lodash/fp/indexOf.d.ts b/libs/events/node_modules/@types/lodash/fp/indexOf.d.ts new file mode 100755 index 000000000..8078c468f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/indexOf.d.ts @@ -0,0 +1,2 @@ +import { indexOf } from "../fp"; +export = indexOf; diff --git a/libs/events/node_modules/@types/lodash/fp/indexOfFrom.d.ts b/libs/events/node_modules/@types/lodash/fp/indexOfFrom.d.ts new file mode 100755 index 000000000..fe66609f7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/indexOfFrom.d.ts @@ -0,0 +1,2 @@ +import { indexOfFrom } from "../fp"; +export = indexOfFrom; diff --git a/libs/events/node_modules/@types/lodash/fp/init.d.ts b/libs/events/node_modules/@types/lodash/fp/init.d.ts new file mode 100755 index 000000000..2f37ecd28 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/init.d.ts @@ -0,0 +1,2 @@ +import { init } from "../fp"; +export = init; diff --git a/libs/events/node_modules/@types/lodash/fp/initial.d.ts b/libs/events/node_modules/@types/lodash/fp/initial.d.ts new file mode 100755 index 000000000..446da0678 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/initial.d.ts @@ -0,0 +1,2 @@ +import { initial } from "../fp"; +export = initial; diff --git a/libs/events/node_modules/@types/lodash/fp/intersection.d.ts b/libs/events/node_modules/@types/lodash/fp/intersection.d.ts new file mode 100755 index 000000000..41d791584 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/intersection.d.ts @@ -0,0 +1,2 @@ +import { intersection } from "../fp"; +export = intersection; diff --git a/libs/events/node_modules/@types/lodash/fp/intersectionBy.d.ts b/libs/events/node_modules/@types/lodash/fp/intersectionBy.d.ts new file mode 100755 index 000000000..a123ddda0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/intersectionBy.d.ts @@ -0,0 +1,2 @@ +import { intersectionBy } from "../fp"; +export = intersectionBy; diff --git a/libs/events/node_modules/@types/lodash/fp/intersectionWith.d.ts b/libs/events/node_modules/@types/lodash/fp/intersectionWith.d.ts new file mode 100755 index 000000000..9ad994157 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/intersectionWith.d.ts @@ -0,0 +1,2 @@ +import { intersectionWith } from "../fp"; +export = intersectionWith; diff --git a/libs/events/node_modules/@types/lodash/fp/invert.d.ts b/libs/events/node_modules/@types/lodash/fp/invert.d.ts new file mode 100755 index 000000000..a41c2bc24 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/invert.d.ts @@ -0,0 +1,2 @@ +import { invert } from "../fp"; +export = invert; diff --git a/libs/events/node_modules/@types/lodash/fp/invertBy.d.ts b/libs/events/node_modules/@types/lodash/fp/invertBy.d.ts new file mode 100755 index 000000000..e28f7135f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/invertBy.d.ts @@ -0,0 +1,2 @@ +import { invertBy } from "../fp"; +export = invertBy; diff --git a/libs/events/node_modules/@types/lodash/fp/invertObj.d.ts b/libs/events/node_modules/@types/lodash/fp/invertObj.d.ts new file mode 100755 index 000000000..2e16c4f8f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/invertObj.d.ts @@ -0,0 +1,2 @@ +import { invertObj } from "../fp"; +export = invertObj; diff --git a/libs/events/node_modules/@types/lodash/fp/invoke.d.ts b/libs/events/node_modules/@types/lodash/fp/invoke.d.ts new file mode 100755 index 000000000..1a9ce3b35 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/invoke.d.ts @@ -0,0 +1,2 @@ +import { invoke } from "../fp"; +export = invoke; diff --git a/libs/events/node_modules/@types/lodash/fp/invokeArgs.d.ts b/libs/events/node_modules/@types/lodash/fp/invokeArgs.d.ts new file mode 100755 index 000000000..8b498e0ec --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/invokeArgs.d.ts @@ -0,0 +1,2 @@ +import { invokeArgs } from "../fp"; +export = invokeArgs; diff --git a/libs/events/node_modules/@types/lodash/fp/invokeArgsMap.d.ts b/libs/events/node_modules/@types/lodash/fp/invokeArgsMap.d.ts new file mode 100755 index 000000000..f5ba3e7ec --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/invokeArgsMap.d.ts @@ -0,0 +1,2 @@ +import { invokeArgsMap } from "../fp"; +export = invokeArgsMap; diff --git a/libs/events/node_modules/@types/lodash/fp/invokeMap.d.ts b/libs/events/node_modules/@types/lodash/fp/invokeMap.d.ts new file mode 100755 index 000000000..9f0aea9c1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/invokeMap.d.ts @@ -0,0 +1,2 @@ +import { invokeMap } from "../fp"; +export = invokeMap; diff --git a/libs/events/node_modules/@types/lodash/fp/isArguments.d.ts b/libs/events/node_modules/@types/lodash/fp/isArguments.d.ts new file mode 100755 index 000000000..23c438c0a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isArguments.d.ts @@ -0,0 +1,2 @@ +import { isArguments } from "../fp"; +export = isArguments; diff --git a/libs/events/node_modules/@types/lodash/fp/isArray.d.ts b/libs/events/node_modules/@types/lodash/fp/isArray.d.ts new file mode 100755 index 000000000..dadecce65 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isArray.d.ts @@ -0,0 +1,2 @@ +import { isArray } from "../fp"; +export = isArray; diff --git a/libs/events/node_modules/@types/lodash/fp/isArrayBuffer.d.ts b/libs/events/node_modules/@types/lodash/fp/isArrayBuffer.d.ts new file mode 100755 index 000000000..32018346b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isArrayBuffer.d.ts @@ -0,0 +1,2 @@ +import { isArrayBuffer } from "../fp"; +export = isArrayBuffer; diff --git a/libs/events/node_modules/@types/lodash/fp/isArrayLike.d.ts b/libs/events/node_modules/@types/lodash/fp/isArrayLike.d.ts new file mode 100755 index 000000000..2be9b54c9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isArrayLike.d.ts @@ -0,0 +1,2 @@ +import { isArrayLike } from "../fp"; +export = isArrayLike; diff --git a/libs/events/node_modules/@types/lodash/fp/isArrayLikeObject.d.ts b/libs/events/node_modules/@types/lodash/fp/isArrayLikeObject.d.ts new file mode 100755 index 000000000..709f5135f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isArrayLikeObject.d.ts @@ -0,0 +1,2 @@ +import { isArrayLikeObject } from "../fp"; +export = isArrayLikeObject; diff --git a/libs/events/node_modules/@types/lodash/fp/isBoolean.d.ts b/libs/events/node_modules/@types/lodash/fp/isBoolean.d.ts new file mode 100755 index 000000000..605cb2cb7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isBoolean.d.ts @@ -0,0 +1,2 @@ +import { isBoolean } from "../fp"; +export = isBoolean; diff --git a/libs/events/node_modules/@types/lodash/fp/isBuffer.d.ts b/libs/events/node_modules/@types/lodash/fp/isBuffer.d.ts new file mode 100755 index 000000000..3d06b548c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isBuffer.d.ts @@ -0,0 +1,2 @@ +import { isBuffer } from "../fp"; +export = isBuffer; diff --git a/libs/events/node_modules/@types/lodash/fp/isDate.d.ts b/libs/events/node_modules/@types/lodash/fp/isDate.d.ts new file mode 100755 index 000000000..979594f99 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isDate.d.ts @@ -0,0 +1,2 @@ +import { isDate } from "../fp"; +export = isDate; diff --git a/libs/events/node_modules/@types/lodash/fp/isElement.d.ts b/libs/events/node_modules/@types/lodash/fp/isElement.d.ts new file mode 100755 index 000000000..26739ad95 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isElement.d.ts @@ -0,0 +1,2 @@ +import { isElement } from "../fp"; +export = isElement; diff --git a/libs/events/node_modules/@types/lodash/fp/isEmpty.d.ts b/libs/events/node_modules/@types/lodash/fp/isEmpty.d.ts new file mode 100755 index 000000000..ed9b33f82 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isEmpty.d.ts @@ -0,0 +1,2 @@ +import { isEmpty } from "../fp"; +export = isEmpty; diff --git a/libs/events/node_modules/@types/lodash/fp/isEqual.d.ts b/libs/events/node_modules/@types/lodash/fp/isEqual.d.ts new file mode 100755 index 000000000..0a51c5c80 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isEqual.d.ts @@ -0,0 +1,2 @@ +import { isEqual } from "../fp"; +export = isEqual; diff --git a/libs/events/node_modules/@types/lodash/fp/isEqualWith.d.ts b/libs/events/node_modules/@types/lodash/fp/isEqualWith.d.ts new file mode 100755 index 000000000..27fa4414c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isEqualWith.d.ts @@ -0,0 +1,2 @@ +import { isEqualWith } from "../fp"; +export = isEqualWith; diff --git a/libs/events/node_modules/@types/lodash/fp/isError.d.ts b/libs/events/node_modules/@types/lodash/fp/isError.d.ts new file mode 100755 index 000000000..4adb9885c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isError.d.ts @@ -0,0 +1,2 @@ +import { isError } from "../fp"; +export = isError; diff --git a/libs/events/node_modules/@types/lodash/fp/isFinite.d.ts b/libs/events/node_modules/@types/lodash/fp/isFinite.d.ts new file mode 100755 index 000000000..5641edc0a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isFinite.d.ts @@ -0,0 +1,2 @@ +import { isFinite } from "../fp"; +export = isFinite; diff --git a/libs/events/node_modules/@types/lodash/fp/isFunction.d.ts b/libs/events/node_modules/@types/lodash/fp/isFunction.d.ts new file mode 100755 index 000000000..3404e7487 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isFunction.d.ts @@ -0,0 +1,2 @@ +import { isFunction } from "../fp"; +export = isFunction; diff --git a/libs/events/node_modules/@types/lodash/fp/isInteger.d.ts b/libs/events/node_modules/@types/lodash/fp/isInteger.d.ts new file mode 100755 index 000000000..310df9347 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isInteger.d.ts @@ -0,0 +1,2 @@ +import { isInteger } from "../fp"; +export = isInteger; diff --git a/libs/events/node_modules/@types/lodash/fp/isLength.d.ts b/libs/events/node_modules/@types/lodash/fp/isLength.d.ts new file mode 100755 index 000000000..3073b672b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isLength.d.ts @@ -0,0 +1,2 @@ +import { isLength } from "../fp"; +export = isLength; diff --git a/libs/events/node_modules/@types/lodash/fp/isMap.d.ts b/libs/events/node_modules/@types/lodash/fp/isMap.d.ts new file mode 100755 index 000000000..e76745c1e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isMap.d.ts @@ -0,0 +1,2 @@ +import { isMap } from "../fp"; +export = isMap; diff --git a/libs/events/node_modules/@types/lodash/fp/isMatch.d.ts b/libs/events/node_modules/@types/lodash/fp/isMatch.d.ts new file mode 100755 index 000000000..58a0a2db9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isMatch.d.ts @@ -0,0 +1,2 @@ +import { isMatch } from "../fp"; +export = isMatch; diff --git a/libs/events/node_modules/@types/lodash/fp/isMatchWith.d.ts b/libs/events/node_modules/@types/lodash/fp/isMatchWith.d.ts new file mode 100755 index 000000000..40ff3a691 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isMatchWith.d.ts @@ -0,0 +1,2 @@ +import { isMatchWith } from "../fp"; +export = isMatchWith; diff --git a/libs/events/node_modules/@types/lodash/fp/isNaN.d.ts b/libs/events/node_modules/@types/lodash/fp/isNaN.d.ts new file mode 100755 index 000000000..2f92885d0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isNaN.d.ts @@ -0,0 +1,2 @@ +import { isNaN } from "../fp"; +export = isNaN; diff --git a/libs/events/node_modules/@types/lodash/fp/isNative.d.ts b/libs/events/node_modules/@types/lodash/fp/isNative.d.ts new file mode 100755 index 000000000..6e189a8e5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isNative.d.ts @@ -0,0 +1,2 @@ +import { isNative } from "../fp"; +export = isNative; diff --git a/libs/events/node_modules/@types/lodash/fp/isNil.d.ts b/libs/events/node_modules/@types/lodash/fp/isNil.d.ts new file mode 100755 index 000000000..0baee7ff8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isNil.d.ts @@ -0,0 +1,2 @@ +import { isNil } from "../fp"; +export = isNil; diff --git a/libs/events/node_modules/@types/lodash/fp/isNull.d.ts b/libs/events/node_modules/@types/lodash/fp/isNull.d.ts new file mode 100755 index 000000000..5e5fad557 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isNull.d.ts @@ -0,0 +1,2 @@ +import { isNull } from "../fp"; +export = isNull; diff --git a/libs/events/node_modules/@types/lodash/fp/isNumber.d.ts b/libs/events/node_modules/@types/lodash/fp/isNumber.d.ts new file mode 100755 index 000000000..93368f172 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isNumber.d.ts @@ -0,0 +1,2 @@ +import { isNumber } from "../fp"; +export = isNumber; diff --git a/libs/events/node_modules/@types/lodash/fp/isObject.d.ts b/libs/events/node_modules/@types/lodash/fp/isObject.d.ts new file mode 100755 index 000000000..7e9e2575a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isObject.d.ts @@ -0,0 +1,2 @@ +import { isObject } from "../fp"; +export = isObject; diff --git a/libs/events/node_modules/@types/lodash/fp/isObjectLike.d.ts b/libs/events/node_modules/@types/lodash/fp/isObjectLike.d.ts new file mode 100755 index 000000000..ba03ddc0f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isObjectLike.d.ts @@ -0,0 +1,2 @@ +import { isObjectLike } from "../fp"; +export = isObjectLike; diff --git a/libs/events/node_modules/@types/lodash/fp/isPlainObject.d.ts b/libs/events/node_modules/@types/lodash/fp/isPlainObject.d.ts new file mode 100755 index 000000000..87da4bdb4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isPlainObject.d.ts @@ -0,0 +1,2 @@ +import { isPlainObject } from "../fp"; +export = isPlainObject; diff --git a/libs/events/node_modules/@types/lodash/fp/isRegExp.d.ts b/libs/events/node_modules/@types/lodash/fp/isRegExp.d.ts new file mode 100755 index 000000000..47edf50a1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isRegExp.d.ts @@ -0,0 +1,2 @@ +import { isRegExp } from "../fp"; +export = isRegExp; diff --git a/libs/events/node_modules/@types/lodash/fp/isSafeInteger.d.ts b/libs/events/node_modules/@types/lodash/fp/isSafeInteger.d.ts new file mode 100755 index 000000000..a32b12cfd --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isSafeInteger.d.ts @@ -0,0 +1,2 @@ +import { isSafeInteger } from "../fp"; +export = isSafeInteger; diff --git a/libs/events/node_modules/@types/lodash/fp/isSet.d.ts b/libs/events/node_modules/@types/lodash/fp/isSet.d.ts new file mode 100755 index 000000000..85e493338 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isSet.d.ts @@ -0,0 +1,2 @@ +import { isSet } from "../fp"; +export = isSet; diff --git a/libs/events/node_modules/@types/lodash/fp/isString.d.ts b/libs/events/node_modules/@types/lodash/fp/isString.d.ts new file mode 100755 index 000000000..9a2149451 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isString.d.ts @@ -0,0 +1,2 @@ +import { isString } from "../fp"; +export = isString; diff --git a/libs/events/node_modules/@types/lodash/fp/isSymbol.d.ts b/libs/events/node_modules/@types/lodash/fp/isSymbol.d.ts new file mode 100755 index 000000000..3d82e9719 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isSymbol.d.ts @@ -0,0 +1,2 @@ +import { isSymbol } from "../fp"; +export = isSymbol; diff --git a/libs/events/node_modules/@types/lodash/fp/isTypedArray.d.ts b/libs/events/node_modules/@types/lodash/fp/isTypedArray.d.ts new file mode 100755 index 000000000..fce6c44a6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isTypedArray.d.ts @@ -0,0 +1,2 @@ +import { isTypedArray } from "../fp"; +export = isTypedArray; diff --git a/libs/events/node_modules/@types/lodash/fp/isUndefined.d.ts b/libs/events/node_modules/@types/lodash/fp/isUndefined.d.ts new file mode 100755 index 000000000..ccb010033 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isUndefined.d.ts @@ -0,0 +1,2 @@ +import { isUndefined } from "../fp"; +export = isUndefined; diff --git a/libs/events/node_modules/@types/lodash/fp/isWeakMap.d.ts b/libs/events/node_modules/@types/lodash/fp/isWeakMap.d.ts new file mode 100755 index 000000000..11edaab05 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isWeakMap.d.ts @@ -0,0 +1,2 @@ +import { isWeakMap } from "../fp"; +export = isWeakMap; diff --git a/libs/events/node_modules/@types/lodash/fp/isWeakSet.d.ts b/libs/events/node_modules/@types/lodash/fp/isWeakSet.d.ts new file mode 100755 index 000000000..6d877e9e2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/isWeakSet.d.ts @@ -0,0 +1,2 @@ +import { isWeakSet } from "../fp"; +export = isWeakSet; diff --git a/libs/events/node_modules/@types/lodash/fp/iteratee.d.ts b/libs/events/node_modules/@types/lodash/fp/iteratee.d.ts new file mode 100755 index 000000000..0ec2832c8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/iteratee.d.ts @@ -0,0 +1,2 @@ +import { iteratee } from "../fp"; +export = iteratee; diff --git a/libs/events/node_modules/@types/lodash/fp/join.d.ts b/libs/events/node_modules/@types/lodash/fp/join.d.ts new file mode 100755 index 000000000..beee04ccf --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/join.d.ts @@ -0,0 +1,2 @@ +import { join } from "../fp"; +export = join; diff --git a/libs/events/node_modules/@types/lodash/fp/juxt.d.ts b/libs/events/node_modules/@types/lodash/fp/juxt.d.ts new file mode 100755 index 000000000..5e972d448 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/juxt.d.ts @@ -0,0 +1,2 @@ +import { juxt } from "../fp"; +export = juxt; diff --git a/libs/events/node_modules/@types/lodash/fp/kebabCase.d.ts b/libs/events/node_modules/@types/lodash/fp/kebabCase.d.ts new file mode 100755 index 000000000..8231b1593 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/kebabCase.d.ts @@ -0,0 +1,2 @@ +import { kebabCase } from "../fp"; +export = kebabCase; diff --git a/libs/events/node_modules/@types/lodash/fp/keyBy.d.ts b/libs/events/node_modules/@types/lodash/fp/keyBy.d.ts new file mode 100755 index 000000000..e4b138109 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/keyBy.d.ts @@ -0,0 +1,2 @@ +import { keyBy } from "../fp"; +export = keyBy; diff --git a/libs/events/node_modules/@types/lodash/fp/keys.d.ts b/libs/events/node_modules/@types/lodash/fp/keys.d.ts new file mode 100755 index 000000000..032348445 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/keys.d.ts @@ -0,0 +1,2 @@ +import { keys } from "../fp"; +export = keys; diff --git a/libs/events/node_modules/@types/lodash/fp/keysIn.d.ts b/libs/events/node_modules/@types/lodash/fp/keysIn.d.ts new file mode 100755 index 000000000..f6f348285 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/keysIn.d.ts @@ -0,0 +1,2 @@ +import { keysIn } from "../fp"; +export = keysIn; diff --git a/libs/events/node_modules/@types/lodash/fp/last.d.ts b/libs/events/node_modules/@types/lodash/fp/last.d.ts new file mode 100755 index 000000000..f74171a30 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/last.d.ts @@ -0,0 +1,2 @@ +import { last } from "../fp"; +export = last; diff --git a/libs/events/node_modules/@types/lodash/fp/lastIndexOf.d.ts b/libs/events/node_modules/@types/lodash/fp/lastIndexOf.d.ts new file mode 100755 index 000000000..2d60e6483 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/lastIndexOf.d.ts @@ -0,0 +1,2 @@ +import { lastIndexOf } from "../fp"; +export = lastIndexOf; diff --git a/libs/events/node_modules/@types/lodash/fp/lastIndexOfFrom.d.ts b/libs/events/node_modules/@types/lodash/fp/lastIndexOfFrom.d.ts new file mode 100755 index 000000000..7a2f23e5a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/lastIndexOfFrom.d.ts @@ -0,0 +1,2 @@ +import { lastIndexOfFrom } from "../fp"; +export = lastIndexOfFrom; diff --git a/libs/events/node_modules/@types/lodash/fp/lowerCase.d.ts b/libs/events/node_modules/@types/lodash/fp/lowerCase.d.ts new file mode 100755 index 000000000..1a5360fdb --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/lowerCase.d.ts @@ -0,0 +1,2 @@ +import { lowerCase } from "../fp"; +export = lowerCase; diff --git a/libs/events/node_modules/@types/lodash/fp/lowerFirst.d.ts b/libs/events/node_modules/@types/lodash/fp/lowerFirst.d.ts new file mode 100755 index 000000000..23ce92585 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/lowerFirst.d.ts @@ -0,0 +1,2 @@ +import { lowerFirst } from "../fp"; +export = lowerFirst; diff --git a/libs/events/node_modules/@types/lodash/fp/lt.d.ts b/libs/events/node_modules/@types/lodash/fp/lt.d.ts new file mode 100755 index 000000000..a309bdce1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/lt.d.ts @@ -0,0 +1,2 @@ +import { lt } from "../fp"; +export = lt; diff --git a/libs/events/node_modules/@types/lodash/fp/lte.d.ts b/libs/events/node_modules/@types/lodash/fp/lte.d.ts new file mode 100755 index 000000000..0d4af2cbe --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/lte.d.ts @@ -0,0 +1,2 @@ +import { lte } from "../fp"; +export = lte; diff --git a/libs/events/node_modules/@types/lodash/fp/map.d.ts b/libs/events/node_modules/@types/lodash/fp/map.d.ts new file mode 100755 index 000000000..17d014caf --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/map.d.ts @@ -0,0 +1,2 @@ +import { map } from "../fp"; +export = map; diff --git a/libs/events/node_modules/@types/lodash/fp/mapKeys.d.ts b/libs/events/node_modules/@types/lodash/fp/mapKeys.d.ts new file mode 100755 index 000000000..acc6d752d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/mapKeys.d.ts @@ -0,0 +1,2 @@ +import { mapKeys } from "../fp"; +export = mapKeys; diff --git a/libs/events/node_modules/@types/lodash/fp/mapValues.d.ts b/libs/events/node_modules/@types/lodash/fp/mapValues.d.ts new file mode 100755 index 000000000..abef821aa --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/mapValues.d.ts @@ -0,0 +1,2 @@ +import { mapValues } from "../fp"; +export = mapValues; diff --git a/libs/events/node_modules/@types/lodash/fp/matches.d.ts b/libs/events/node_modules/@types/lodash/fp/matches.d.ts new file mode 100755 index 000000000..e9796de4f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/matches.d.ts @@ -0,0 +1,2 @@ +import { matches } from "../fp"; +export = matches; diff --git a/libs/events/node_modules/@types/lodash/fp/matchesProperty.d.ts b/libs/events/node_modules/@types/lodash/fp/matchesProperty.d.ts new file mode 100755 index 000000000..81db8f75d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/matchesProperty.d.ts @@ -0,0 +1,2 @@ +import { matchesProperty } from "../fp"; +export = matchesProperty; diff --git a/libs/events/node_modules/@types/lodash/fp/max.d.ts b/libs/events/node_modules/@types/lodash/fp/max.d.ts new file mode 100755 index 000000000..7b08dc52c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/max.d.ts @@ -0,0 +1,2 @@ +import { max } from "../fp"; +export = max; diff --git a/libs/events/node_modules/@types/lodash/fp/maxBy.d.ts b/libs/events/node_modules/@types/lodash/fp/maxBy.d.ts new file mode 100755 index 000000000..68f30dd89 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/maxBy.d.ts @@ -0,0 +1,2 @@ +import { maxBy } from "../fp"; +export = maxBy; diff --git a/libs/events/node_modules/@types/lodash/fp/mean.d.ts b/libs/events/node_modules/@types/lodash/fp/mean.d.ts new file mode 100755 index 000000000..a0b7e22e5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/mean.d.ts @@ -0,0 +1,2 @@ +import { mean } from "../fp"; +export = mean; diff --git a/libs/events/node_modules/@types/lodash/fp/meanBy.d.ts b/libs/events/node_modules/@types/lodash/fp/meanBy.d.ts new file mode 100755 index 000000000..d76afd77c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/meanBy.d.ts @@ -0,0 +1,2 @@ +import { meanBy } from "../fp"; +export = meanBy; diff --git a/libs/events/node_modules/@types/lodash/fp/memoize.d.ts b/libs/events/node_modules/@types/lodash/fp/memoize.d.ts new file mode 100755 index 000000000..a60b79caf --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/memoize.d.ts @@ -0,0 +1,2 @@ +import { memoize } from "../fp"; +export = memoize; diff --git a/libs/events/node_modules/@types/lodash/fp/merge.d.ts b/libs/events/node_modules/@types/lodash/fp/merge.d.ts new file mode 100755 index 000000000..f80117b7e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/merge.d.ts @@ -0,0 +1,2 @@ +import { merge } from "../fp"; +export = merge; diff --git a/libs/events/node_modules/@types/lodash/fp/mergeAll.d.ts b/libs/events/node_modules/@types/lodash/fp/mergeAll.d.ts new file mode 100755 index 000000000..6b462d85c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/mergeAll.d.ts @@ -0,0 +1,2 @@ +import { mergeAll } from "../fp"; +export = mergeAll; diff --git a/libs/events/node_modules/@types/lodash/fp/mergeAllWith.d.ts b/libs/events/node_modules/@types/lodash/fp/mergeAllWith.d.ts new file mode 100755 index 000000000..3d2f7f296 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/mergeAllWith.d.ts @@ -0,0 +1,2 @@ +import { mergeAllWith } from "../fp"; +export = mergeAllWith; diff --git a/libs/events/node_modules/@types/lodash/fp/mergeWith.d.ts b/libs/events/node_modules/@types/lodash/fp/mergeWith.d.ts new file mode 100755 index 000000000..d1f541e81 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/mergeWith.d.ts @@ -0,0 +1,2 @@ +import { mergeWith } from "../fp"; +export = mergeWith; diff --git a/libs/events/node_modules/@types/lodash/fp/method.d.ts b/libs/events/node_modules/@types/lodash/fp/method.d.ts new file mode 100755 index 000000000..f9f2ee879 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/method.d.ts @@ -0,0 +1,2 @@ +import { method } from "../fp"; +export = method; diff --git a/libs/events/node_modules/@types/lodash/fp/methodOf.d.ts b/libs/events/node_modules/@types/lodash/fp/methodOf.d.ts new file mode 100755 index 000000000..a9e0e4fe1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/methodOf.d.ts @@ -0,0 +1,2 @@ +import { methodOf } from "../fp"; +export = methodOf; diff --git a/libs/events/node_modules/@types/lodash/fp/min.d.ts b/libs/events/node_modules/@types/lodash/fp/min.d.ts new file mode 100755 index 000000000..7c80ab0ff --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/min.d.ts @@ -0,0 +1,2 @@ +import { min } from "../fp"; +export = min; diff --git a/libs/events/node_modules/@types/lodash/fp/minBy.d.ts b/libs/events/node_modules/@types/lodash/fp/minBy.d.ts new file mode 100755 index 000000000..020a8f506 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/minBy.d.ts @@ -0,0 +1,2 @@ +import { minBy } from "../fp"; +export = minBy; diff --git a/libs/events/node_modules/@types/lodash/fp/multiply.d.ts b/libs/events/node_modules/@types/lodash/fp/multiply.d.ts new file mode 100755 index 000000000..b3e5f3abd --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/multiply.d.ts @@ -0,0 +1,2 @@ +import { multiply } from "../fp"; +export = multiply; diff --git a/libs/events/node_modules/@types/lodash/fp/nAry.d.ts b/libs/events/node_modules/@types/lodash/fp/nAry.d.ts new file mode 100755 index 000000000..882e4a37d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/nAry.d.ts @@ -0,0 +1,2 @@ +import { nAry } from "../fp"; +export = nAry; diff --git a/libs/events/node_modules/@types/lodash/fp/negate.d.ts b/libs/events/node_modules/@types/lodash/fp/negate.d.ts new file mode 100755 index 000000000..a7693c192 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/negate.d.ts @@ -0,0 +1,2 @@ +import { negate } from "../fp"; +export = negate; diff --git a/libs/events/node_modules/@types/lodash/fp/noConflict.d.ts b/libs/events/node_modules/@types/lodash/fp/noConflict.d.ts new file mode 100755 index 000000000..7694f5aa5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/noConflict.d.ts @@ -0,0 +1,2 @@ +import { noConflict } from "../fp"; +export = noConflict; diff --git a/libs/events/node_modules/@types/lodash/fp/noop.d.ts b/libs/events/node_modules/@types/lodash/fp/noop.d.ts new file mode 100755 index 000000000..5b6a27b61 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/noop.d.ts @@ -0,0 +1,2 @@ +import { noop } from "../fp"; +export = noop; diff --git a/libs/events/node_modules/@types/lodash/fp/now.d.ts b/libs/events/node_modules/@types/lodash/fp/now.d.ts new file mode 100755 index 000000000..fdbbd2bcf --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/now.d.ts @@ -0,0 +1,2 @@ +import { now } from "../fp"; +export = now; diff --git a/libs/events/node_modules/@types/lodash/fp/nth.d.ts b/libs/events/node_modules/@types/lodash/fp/nth.d.ts new file mode 100755 index 000000000..e3987e17c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/nth.d.ts @@ -0,0 +1,2 @@ +import { nth } from "../fp"; +export = nth; diff --git a/libs/events/node_modules/@types/lodash/fp/nthArg.d.ts b/libs/events/node_modules/@types/lodash/fp/nthArg.d.ts new file mode 100755 index 000000000..216c9bbab --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/nthArg.d.ts @@ -0,0 +1,2 @@ +import { nthArg } from "../fp"; +export = nthArg; diff --git a/libs/events/node_modules/@types/lodash/fp/omit.d.ts b/libs/events/node_modules/@types/lodash/fp/omit.d.ts new file mode 100755 index 000000000..1cd1b7fcc --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/omit.d.ts @@ -0,0 +1,2 @@ +import { omit } from "../fp"; +export = omit; diff --git a/libs/events/node_modules/@types/lodash/fp/omitAll.d.ts b/libs/events/node_modules/@types/lodash/fp/omitAll.d.ts new file mode 100755 index 000000000..dab5cfa5f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/omitAll.d.ts @@ -0,0 +1,2 @@ +import { omitAll } from "../fp"; +export = omitAll; diff --git a/libs/events/node_modules/@types/lodash/fp/omitBy.d.ts b/libs/events/node_modules/@types/lodash/fp/omitBy.d.ts new file mode 100755 index 000000000..8be4f5b40 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/omitBy.d.ts @@ -0,0 +1,2 @@ +import { omitBy } from "../fp"; +export = omitBy; diff --git a/libs/events/node_modules/@types/lodash/fp/once.d.ts b/libs/events/node_modules/@types/lodash/fp/once.d.ts new file mode 100755 index 000000000..24d859cc5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/once.d.ts @@ -0,0 +1,2 @@ +import { once } from "../fp"; +export = once; diff --git a/libs/events/node_modules/@types/lodash/fp/orderBy.d.ts b/libs/events/node_modules/@types/lodash/fp/orderBy.d.ts new file mode 100755 index 000000000..9443fcfc2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/orderBy.d.ts @@ -0,0 +1,2 @@ +import { orderBy } from "../fp"; +export = orderBy; diff --git a/libs/events/node_modules/@types/lodash/fp/over.d.ts b/libs/events/node_modules/@types/lodash/fp/over.d.ts new file mode 100755 index 000000000..1bd2502fd --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/over.d.ts @@ -0,0 +1,2 @@ +import { over } from "../fp"; +export = over; diff --git a/libs/events/node_modules/@types/lodash/fp/overArgs.d.ts b/libs/events/node_modules/@types/lodash/fp/overArgs.d.ts new file mode 100755 index 000000000..c054c9270 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/overArgs.d.ts @@ -0,0 +1,2 @@ +import { overArgs } from "../fp"; +export = overArgs; diff --git a/libs/events/node_modules/@types/lodash/fp/overEvery.d.ts b/libs/events/node_modules/@types/lodash/fp/overEvery.d.ts new file mode 100755 index 000000000..1cf8b4061 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/overEvery.d.ts @@ -0,0 +1,2 @@ +import { overEvery } from "../fp"; +export = overEvery; diff --git a/libs/events/node_modules/@types/lodash/fp/overSome.d.ts b/libs/events/node_modules/@types/lodash/fp/overSome.d.ts new file mode 100755 index 000000000..6b098b73b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/overSome.d.ts @@ -0,0 +1,2 @@ +import { overSome } from "../fp"; +export = overSome; diff --git a/libs/events/node_modules/@types/lodash/fp/pad.d.ts b/libs/events/node_modules/@types/lodash/fp/pad.d.ts new file mode 100755 index 000000000..a5519771d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pad.d.ts @@ -0,0 +1,2 @@ +import { pad } from "../fp"; +export = pad; diff --git a/libs/events/node_modules/@types/lodash/fp/padChars.d.ts b/libs/events/node_modules/@types/lodash/fp/padChars.d.ts new file mode 100755 index 000000000..74d1aabbb --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/padChars.d.ts @@ -0,0 +1,2 @@ +import { padChars } from "../fp"; +export = padChars; diff --git a/libs/events/node_modules/@types/lodash/fp/padCharsEnd.d.ts b/libs/events/node_modules/@types/lodash/fp/padCharsEnd.d.ts new file mode 100755 index 000000000..3a468dc11 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/padCharsEnd.d.ts @@ -0,0 +1,2 @@ +import { padCharsEnd } from "../fp"; +export = padCharsEnd; diff --git a/libs/events/node_modules/@types/lodash/fp/padCharsStart.d.ts b/libs/events/node_modules/@types/lodash/fp/padCharsStart.d.ts new file mode 100755 index 000000000..a22523505 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/padCharsStart.d.ts @@ -0,0 +1,2 @@ +import { padCharsStart } from "../fp"; +export = padCharsStart; diff --git a/libs/events/node_modules/@types/lodash/fp/padEnd.d.ts b/libs/events/node_modules/@types/lodash/fp/padEnd.d.ts new file mode 100755 index 000000000..5c4e4d80b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/padEnd.d.ts @@ -0,0 +1,2 @@ +import { padEnd } from "../fp"; +export = padEnd; diff --git a/libs/events/node_modules/@types/lodash/fp/padStart.d.ts b/libs/events/node_modules/@types/lodash/fp/padStart.d.ts new file mode 100755 index 000000000..a4fca5d1e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/padStart.d.ts @@ -0,0 +1,2 @@ +import { padStart } from "../fp"; +export = padStart; diff --git a/libs/events/node_modules/@types/lodash/fp/parseInt.d.ts b/libs/events/node_modules/@types/lodash/fp/parseInt.d.ts new file mode 100755 index 000000000..47aff97b7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/parseInt.d.ts @@ -0,0 +1,2 @@ +import { parseInt } from "../fp"; +export = parseInt; diff --git a/libs/events/node_modules/@types/lodash/fp/partial.d.ts b/libs/events/node_modules/@types/lodash/fp/partial.d.ts new file mode 100755 index 000000000..f5ebd726e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/partial.d.ts @@ -0,0 +1,2 @@ +import { partial } from "../fp"; +export = partial; diff --git a/libs/events/node_modules/@types/lodash/fp/partialRight.d.ts b/libs/events/node_modules/@types/lodash/fp/partialRight.d.ts new file mode 100755 index 000000000..bc0fa1b9c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/partialRight.d.ts @@ -0,0 +1,2 @@ +import { partialRight } from "../fp"; +export = partialRight; diff --git a/libs/events/node_modules/@types/lodash/fp/partition.d.ts b/libs/events/node_modules/@types/lodash/fp/partition.d.ts new file mode 100755 index 000000000..6ad41cd7d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/partition.d.ts @@ -0,0 +1,2 @@ +import { partition } from "../fp"; +export = partition; diff --git a/libs/events/node_modules/@types/lodash/fp/path.d.ts b/libs/events/node_modules/@types/lodash/fp/path.d.ts new file mode 100755 index 000000000..db86d6023 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/path.d.ts @@ -0,0 +1,2 @@ +import { path } from "../fp"; +export = path; diff --git a/libs/events/node_modules/@types/lodash/fp/pathEq.d.ts b/libs/events/node_modules/@types/lodash/fp/pathEq.d.ts new file mode 100755 index 000000000..9f328756c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pathEq.d.ts @@ -0,0 +1,2 @@ +import { pathEq } from "../fp"; +export = pathEq; diff --git a/libs/events/node_modules/@types/lodash/fp/pathOr.d.ts b/libs/events/node_modules/@types/lodash/fp/pathOr.d.ts new file mode 100755 index 000000000..6cad6b183 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pathOr.d.ts @@ -0,0 +1,2 @@ +import { pathOr } from "../fp"; +export = pathOr; diff --git a/libs/events/node_modules/@types/lodash/fp/paths.d.ts b/libs/events/node_modules/@types/lodash/fp/paths.d.ts new file mode 100755 index 000000000..1e6eb8908 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/paths.d.ts @@ -0,0 +1,2 @@ +import { paths } from "../fp"; +export = paths; diff --git a/libs/events/node_modules/@types/lodash/fp/pick.d.ts b/libs/events/node_modules/@types/lodash/fp/pick.d.ts new file mode 100755 index 000000000..4772ecacc --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pick.d.ts @@ -0,0 +1,2 @@ +import { pick } from "../fp"; +export = pick; diff --git a/libs/events/node_modules/@types/lodash/fp/pickAll.d.ts b/libs/events/node_modules/@types/lodash/fp/pickAll.d.ts new file mode 100755 index 000000000..38d2e3fe2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pickAll.d.ts @@ -0,0 +1,2 @@ +import { pickAll } from "../fp"; +export = pickAll; diff --git a/libs/events/node_modules/@types/lodash/fp/pickBy.d.ts b/libs/events/node_modules/@types/lodash/fp/pickBy.d.ts new file mode 100755 index 000000000..0b192629e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pickBy.d.ts @@ -0,0 +1,2 @@ +import { pickBy } from "../fp"; +export = pickBy; diff --git a/libs/events/node_modules/@types/lodash/fp/pipe.d.ts b/libs/events/node_modules/@types/lodash/fp/pipe.d.ts new file mode 100755 index 000000000..a53a04823 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pipe.d.ts @@ -0,0 +1,2 @@ +import { pipe } from "../fp"; +export = pipe; diff --git a/libs/events/node_modules/@types/lodash/fp/placeholder.d.ts b/libs/events/node_modules/@types/lodash/fp/placeholder.d.ts new file mode 100755 index 000000000..ddaed8ed1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/placeholder.d.ts @@ -0,0 +1,3 @@ +import _ = require("../index"); +declare const placeholder: _.__; +export = placeholder; diff --git a/libs/events/node_modules/@types/lodash/fp/pluck.d.ts b/libs/events/node_modules/@types/lodash/fp/pluck.d.ts new file mode 100755 index 000000000..c5c916f81 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pluck.d.ts @@ -0,0 +1,2 @@ +import { pluck } from "../fp"; +export = pluck; diff --git a/libs/events/node_modules/@types/lodash/fp/prop.d.ts b/libs/events/node_modules/@types/lodash/fp/prop.d.ts new file mode 100755 index 000000000..f2061e7d6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/prop.d.ts @@ -0,0 +1,2 @@ +import { prop } from "../fp"; +export = prop; diff --git a/libs/events/node_modules/@types/lodash/fp/propEq.d.ts b/libs/events/node_modules/@types/lodash/fp/propEq.d.ts new file mode 100755 index 000000000..5e3f4b413 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/propEq.d.ts @@ -0,0 +1,2 @@ +import { propEq } from "../fp"; +export = propEq; diff --git a/libs/events/node_modules/@types/lodash/fp/propOr.d.ts b/libs/events/node_modules/@types/lodash/fp/propOr.d.ts new file mode 100755 index 000000000..feabcf6e9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/propOr.d.ts @@ -0,0 +1,2 @@ +import { propOr } from "../fp"; +export = propOr; diff --git a/libs/events/node_modules/@types/lodash/fp/property.d.ts b/libs/events/node_modules/@types/lodash/fp/property.d.ts new file mode 100755 index 000000000..aaa6c2571 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/property.d.ts @@ -0,0 +1,2 @@ +import { property } from "../fp"; +export = property; diff --git a/libs/events/node_modules/@types/lodash/fp/propertyOf.d.ts b/libs/events/node_modules/@types/lodash/fp/propertyOf.d.ts new file mode 100755 index 000000000..a4d55130c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/propertyOf.d.ts @@ -0,0 +1,2 @@ +import { propertyOf } from "../fp"; +export = propertyOf; diff --git a/libs/events/node_modules/@types/lodash/fp/props.d.ts b/libs/events/node_modules/@types/lodash/fp/props.d.ts new file mode 100755 index 000000000..46addba7a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/props.d.ts @@ -0,0 +1,2 @@ +import { props } from "../fp"; +export = props; diff --git a/libs/events/node_modules/@types/lodash/fp/pull.d.ts b/libs/events/node_modules/@types/lodash/fp/pull.d.ts new file mode 100755 index 000000000..801cf3377 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pull.d.ts @@ -0,0 +1,2 @@ +import { pull } from "../fp"; +export = pull; diff --git a/libs/events/node_modules/@types/lodash/fp/pullAll.d.ts b/libs/events/node_modules/@types/lodash/fp/pullAll.d.ts new file mode 100755 index 000000000..042fe89ac --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pullAll.d.ts @@ -0,0 +1,2 @@ +import { pullAll } from "../fp"; +export = pullAll; diff --git a/libs/events/node_modules/@types/lodash/fp/pullAllBy.d.ts b/libs/events/node_modules/@types/lodash/fp/pullAllBy.d.ts new file mode 100755 index 000000000..5e5de1fc0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pullAllBy.d.ts @@ -0,0 +1,2 @@ +import { pullAllBy } from "../fp"; +export = pullAllBy; diff --git a/libs/events/node_modules/@types/lodash/fp/pullAllWith.d.ts b/libs/events/node_modules/@types/lodash/fp/pullAllWith.d.ts new file mode 100755 index 000000000..0c448bf8c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pullAllWith.d.ts @@ -0,0 +1,2 @@ +import { pullAllWith } from "../fp"; +export = pullAllWith; diff --git a/libs/events/node_modules/@types/lodash/fp/pullAt.d.ts b/libs/events/node_modules/@types/lodash/fp/pullAt.d.ts new file mode 100755 index 000000000..4bdffd993 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/pullAt.d.ts @@ -0,0 +1,2 @@ +import { pullAt } from "../fp"; +export = pullAt; diff --git a/libs/events/node_modules/@types/lodash/fp/random.d.ts b/libs/events/node_modules/@types/lodash/fp/random.d.ts new file mode 100755 index 000000000..a69555ca1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/random.d.ts @@ -0,0 +1,2 @@ +import { random } from "../fp"; +export = random; diff --git a/libs/events/node_modules/@types/lodash/fp/range.d.ts b/libs/events/node_modules/@types/lodash/fp/range.d.ts new file mode 100755 index 000000000..ace50ce46 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/range.d.ts @@ -0,0 +1,2 @@ +import { range } from "../fp"; +export = range; diff --git a/libs/events/node_modules/@types/lodash/fp/rangeRight.d.ts b/libs/events/node_modules/@types/lodash/fp/rangeRight.d.ts new file mode 100755 index 000000000..20c8baefa --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/rangeRight.d.ts @@ -0,0 +1,2 @@ +import { rangeRight } from "../fp"; +export = rangeRight; diff --git a/libs/events/node_modules/@types/lodash/fp/rangeStep.d.ts b/libs/events/node_modules/@types/lodash/fp/rangeStep.d.ts new file mode 100755 index 000000000..e5f4c891c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/rangeStep.d.ts @@ -0,0 +1,2 @@ +import { rangeStep } from "../fp"; +export = rangeStep; diff --git a/libs/events/node_modules/@types/lodash/fp/rangeStepRight.d.ts b/libs/events/node_modules/@types/lodash/fp/rangeStepRight.d.ts new file mode 100755 index 000000000..6c7add468 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/rangeStepRight.d.ts @@ -0,0 +1,2 @@ +import { rangeStepRight } from "../fp"; +export = rangeStepRight; diff --git a/libs/events/node_modules/@types/lodash/fp/rearg.d.ts b/libs/events/node_modules/@types/lodash/fp/rearg.d.ts new file mode 100755 index 000000000..5c407d13a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/rearg.d.ts @@ -0,0 +1,2 @@ +import { rearg } from "../fp"; +export = rearg; diff --git a/libs/events/node_modules/@types/lodash/fp/reduce.d.ts b/libs/events/node_modules/@types/lodash/fp/reduce.d.ts new file mode 100755 index 000000000..e262f3937 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/reduce.d.ts @@ -0,0 +1,2 @@ +import { reduce } from "../fp"; +export = reduce; diff --git a/libs/events/node_modules/@types/lodash/fp/reduceRight.d.ts b/libs/events/node_modules/@types/lodash/fp/reduceRight.d.ts new file mode 100755 index 000000000..fa54fa3a5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/reduceRight.d.ts @@ -0,0 +1,2 @@ +import { reduceRight } from "../fp"; +export = reduceRight; diff --git a/libs/events/node_modules/@types/lodash/fp/reject.d.ts b/libs/events/node_modules/@types/lodash/fp/reject.d.ts new file mode 100755 index 000000000..d0a12af96 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/reject.d.ts @@ -0,0 +1,2 @@ +import { reject } from "../fp"; +export = reject; diff --git a/libs/events/node_modules/@types/lodash/fp/remove.d.ts b/libs/events/node_modules/@types/lodash/fp/remove.d.ts new file mode 100755 index 000000000..e0da9b147 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/remove.d.ts @@ -0,0 +1,2 @@ +import { remove } from "../fp"; +export = remove; diff --git a/libs/events/node_modules/@types/lodash/fp/repeat.d.ts b/libs/events/node_modules/@types/lodash/fp/repeat.d.ts new file mode 100755 index 000000000..1f757a277 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/repeat.d.ts @@ -0,0 +1,2 @@ +import { repeat } from "../fp"; +export = repeat; diff --git a/libs/events/node_modules/@types/lodash/fp/replace.d.ts b/libs/events/node_modules/@types/lodash/fp/replace.d.ts new file mode 100755 index 000000000..c7a75d1fa --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/replace.d.ts @@ -0,0 +1,2 @@ +import { replace } from "../fp"; +export = replace; diff --git a/libs/events/node_modules/@types/lodash/fp/rest.d.ts b/libs/events/node_modules/@types/lodash/fp/rest.d.ts new file mode 100755 index 000000000..b059d673e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/rest.d.ts @@ -0,0 +1,2 @@ +import { rest } from "../fp"; +export = rest; diff --git a/libs/events/node_modules/@types/lodash/fp/restFrom.d.ts b/libs/events/node_modules/@types/lodash/fp/restFrom.d.ts new file mode 100755 index 000000000..218edbd5a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/restFrom.d.ts @@ -0,0 +1,2 @@ +import { restFrom } from "../fp"; +export = restFrom; diff --git a/libs/events/node_modules/@types/lodash/fp/result.d.ts b/libs/events/node_modules/@types/lodash/fp/result.d.ts new file mode 100755 index 000000000..5a919dd45 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/result.d.ts @@ -0,0 +1,2 @@ +import { result } from "../fp"; +export = result; diff --git a/libs/events/node_modules/@types/lodash/fp/reverse.d.ts b/libs/events/node_modules/@types/lodash/fp/reverse.d.ts new file mode 100755 index 000000000..f754d6aac --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/reverse.d.ts @@ -0,0 +1,2 @@ +import { reverse } from "../fp"; +export = reverse; diff --git a/libs/events/node_modules/@types/lodash/fp/round.d.ts b/libs/events/node_modules/@types/lodash/fp/round.d.ts new file mode 100755 index 000000000..02f4e6f30 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/round.d.ts @@ -0,0 +1,2 @@ +import { round } from "../fp"; +export = round; diff --git a/libs/events/node_modules/@types/lodash/fp/runInContext.d.ts b/libs/events/node_modules/@types/lodash/fp/runInContext.d.ts new file mode 100755 index 000000000..6041db705 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/runInContext.d.ts @@ -0,0 +1,2 @@ +import { runInContext } from "../fp"; +export = runInContext; diff --git a/libs/events/node_modules/@types/lodash/fp/sample.d.ts b/libs/events/node_modules/@types/lodash/fp/sample.d.ts new file mode 100755 index 000000000..f2fcf1ac0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sample.d.ts @@ -0,0 +1,2 @@ +import { sample } from "../fp"; +export = sample; diff --git a/libs/events/node_modules/@types/lodash/fp/sampleSize.d.ts b/libs/events/node_modules/@types/lodash/fp/sampleSize.d.ts new file mode 100755 index 000000000..41a3cabf9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sampleSize.d.ts @@ -0,0 +1,2 @@ +import { sampleSize } from "../fp"; +export = sampleSize; diff --git a/libs/events/node_modules/@types/lodash/fp/set.d.ts b/libs/events/node_modules/@types/lodash/fp/set.d.ts new file mode 100755 index 000000000..57960cba7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/set.d.ts @@ -0,0 +1,2 @@ +import { set } from "../fp"; +export = set; diff --git a/libs/events/node_modules/@types/lodash/fp/setWith.d.ts b/libs/events/node_modules/@types/lodash/fp/setWith.d.ts new file mode 100755 index 000000000..800a49429 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/setWith.d.ts @@ -0,0 +1,2 @@ +import { setWith } from "../fp"; +export = setWith; diff --git a/libs/events/node_modules/@types/lodash/fp/shuffle.d.ts b/libs/events/node_modules/@types/lodash/fp/shuffle.d.ts new file mode 100755 index 000000000..7f0728264 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/shuffle.d.ts @@ -0,0 +1,2 @@ +import { shuffle } from "../fp"; +export = shuffle; diff --git a/libs/events/node_modules/@types/lodash/fp/size.d.ts b/libs/events/node_modules/@types/lodash/fp/size.d.ts new file mode 100755 index 000000000..657c8b7c2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/size.d.ts @@ -0,0 +1,2 @@ +import { size } from "../fp"; +export = size; diff --git a/libs/events/node_modules/@types/lodash/fp/slice.d.ts b/libs/events/node_modules/@types/lodash/fp/slice.d.ts new file mode 100755 index 000000000..fabbbe0ee --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/slice.d.ts @@ -0,0 +1,2 @@ +import { slice } from "../fp"; +export = slice; diff --git a/libs/events/node_modules/@types/lodash/fp/snakeCase.d.ts b/libs/events/node_modules/@types/lodash/fp/snakeCase.d.ts new file mode 100755 index 000000000..a06ac452f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/snakeCase.d.ts @@ -0,0 +1,2 @@ +import { snakeCase } from "../fp"; +export = snakeCase; diff --git a/libs/events/node_modules/@types/lodash/fp/some.d.ts b/libs/events/node_modules/@types/lodash/fp/some.d.ts new file mode 100755 index 000000000..870b23160 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/some.d.ts @@ -0,0 +1,2 @@ +import { some } from "../fp"; +export = some; diff --git a/libs/events/node_modules/@types/lodash/fp/sortBy.d.ts b/libs/events/node_modules/@types/lodash/fp/sortBy.d.ts new file mode 100755 index 000000000..72c5799b3 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sortBy.d.ts @@ -0,0 +1,2 @@ +import { sortBy } from "../fp"; +export = sortBy; diff --git a/libs/events/node_modules/@types/lodash/fp/sortedIndex.d.ts b/libs/events/node_modules/@types/lodash/fp/sortedIndex.d.ts new file mode 100755 index 000000000..35b57feed --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sortedIndex.d.ts @@ -0,0 +1,2 @@ +import { sortedIndex } from "../fp"; +export = sortedIndex; diff --git a/libs/events/node_modules/@types/lodash/fp/sortedIndexBy.d.ts b/libs/events/node_modules/@types/lodash/fp/sortedIndexBy.d.ts new file mode 100755 index 000000000..f6968df69 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sortedIndexBy.d.ts @@ -0,0 +1,2 @@ +import { sortedIndexBy } from "../fp"; +export = sortedIndexBy; diff --git a/libs/events/node_modules/@types/lodash/fp/sortedIndexOf.d.ts b/libs/events/node_modules/@types/lodash/fp/sortedIndexOf.d.ts new file mode 100755 index 000000000..beeb6db0c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sortedIndexOf.d.ts @@ -0,0 +1,2 @@ +import { sortedIndexOf } from "../fp"; +export = sortedIndexOf; diff --git a/libs/events/node_modules/@types/lodash/fp/sortedLastIndex.d.ts b/libs/events/node_modules/@types/lodash/fp/sortedLastIndex.d.ts new file mode 100755 index 000000000..eea77a038 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sortedLastIndex.d.ts @@ -0,0 +1,2 @@ +import { sortedLastIndex } from "../fp"; +export = sortedLastIndex; diff --git a/libs/events/node_modules/@types/lodash/fp/sortedLastIndexBy.d.ts b/libs/events/node_modules/@types/lodash/fp/sortedLastIndexBy.d.ts new file mode 100755 index 000000000..6c8e4ee54 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sortedLastIndexBy.d.ts @@ -0,0 +1,2 @@ +import { sortedLastIndexBy } from "../fp"; +export = sortedLastIndexBy; diff --git a/libs/events/node_modules/@types/lodash/fp/sortedLastIndexOf.d.ts b/libs/events/node_modules/@types/lodash/fp/sortedLastIndexOf.d.ts new file mode 100755 index 000000000..a02caf3ce --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sortedLastIndexOf.d.ts @@ -0,0 +1,2 @@ +import { sortedLastIndexOf } from "../fp"; +export = sortedLastIndexOf; diff --git a/libs/events/node_modules/@types/lodash/fp/sortedUniq.d.ts b/libs/events/node_modules/@types/lodash/fp/sortedUniq.d.ts new file mode 100755 index 000000000..03d8e691e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sortedUniq.d.ts @@ -0,0 +1,2 @@ +import { sortedUniq } from "../fp"; +export = sortedUniq; diff --git a/libs/events/node_modules/@types/lodash/fp/sortedUniqBy.d.ts b/libs/events/node_modules/@types/lodash/fp/sortedUniqBy.d.ts new file mode 100755 index 000000000..466981a26 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sortedUniqBy.d.ts @@ -0,0 +1,2 @@ +import { sortedUniqBy } from "../fp"; +export = sortedUniqBy; diff --git a/libs/events/node_modules/@types/lodash/fp/split.d.ts b/libs/events/node_modules/@types/lodash/fp/split.d.ts new file mode 100755 index 000000000..8274d4081 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/split.d.ts @@ -0,0 +1,2 @@ +import { split } from "../fp"; +export = split; diff --git a/libs/events/node_modules/@types/lodash/fp/spread.d.ts b/libs/events/node_modules/@types/lodash/fp/spread.d.ts new file mode 100755 index 000000000..44eb90cd2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/spread.d.ts @@ -0,0 +1,2 @@ +import { spread } from "../fp"; +export = spread; diff --git a/libs/events/node_modules/@types/lodash/fp/spreadFrom.d.ts b/libs/events/node_modules/@types/lodash/fp/spreadFrom.d.ts new file mode 100755 index 000000000..7eb840b03 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/spreadFrom.d.ts @@ -0,0 +1,2 @@ +import { spreadFrom } from "../fp"; +export = spreadFrom; diff --git a/libs/events/node_modules/@types/lodash/fp/startCase.d.ts b/libs/events/node_modules/@types/lodash/fp/startCase.d.ts new file mode 100755 index 000000000..4f580aa5d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/startCase.d.ts @@ -0,0 +1,2 @@ +import { startCase } from "../fp"; +export = startCase; diff --git a/libs/events/node_modules/@types/lodash/fp/startsWith.d.ts b/libs/events/node_modules/@types/lodash/fp/startsWith.d.ts new file mode 100755 index 000000000..f84397dc6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/startsWith.d.ts @@ -0,0 +1,2 @@ +import { startsWith } from "../fp"; +export = startsWith; diff --git a/libs/events/node_modules/@types/lodash/fp/stubArray.d.ts b/libs/events/node_modules/@types/lodash/fp/stubArray.d.ts new file mode 100755 index 000000000..8ff910e59 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/stubArray.d.ts @@ -0,0 +1,2 @@ +import { stubArray } from "../fp"; +export = stubArray; diff --git a/libs/events/node_modules/@types/lodash/fp/stubFalse.d.ts b/libs/events/node_modules/@types/lodash/fp/stubFalse.d.ts new file mode 100755 index 000000000..4cc041482 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/stubFalse.d.ts @@ -0,0 +1,2 @@ +import { stubFalse } from "../fp"; +export = stubFalse; diff --git a/libs/events/node_modules/@types/lodash/fp/stubObject.d.ts b/libs/events/node_modules/@types/lodash/fp/stubObject.d.ts new file mode 100755 index 000000000..d7c826997 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/stubObject.d.ts @@ -0,0 +1,2 @@ +import { stubObject } from "../fp"; +export = stubObject; diff --git a/libs/events/node_modules/@types/lodash/fp/stubString.d.ts b/libs/events/node_modules/@types/lodash/fp/stubString.d.ts new file mode 100755 index 000000000..cbfa44975 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/stubString.d.ts @@ -0,0 +1,2 @@ +import { stubString } from "../fp"; +export = stubString; diff --git a/libs/events/node_modules/@types/lodash/fp/stubTrue.d.ts b/libs/events/node_modules/@types/lodash/fp/stubTrue.d.ts new file mode 100755 index 000000000..0ed7e5b92 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/stubTrue.d.ts @@ -0,0 +1,2 @@ +import { stubTrue } from "../fp"; +export = stubTrue; diff --git a/libs/events/node_modules/@types/lodash/fp/subtract.d.ts b/libs/events/node_modules/@types/lodash/fp/subtract.d.ts new file mode 100755 index 000000000..201301b30 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/subtract.d.ts @@ -0,0 +1,2 @@ +import { subtract } from "../fp"; +export = subtract; diff --git a/libs/events/node_modules/@types/lodash/fp/sum.d.ts b/libs/events/node_modules/@types/lodash/fp/sum.d.ts new file mode 100755 index 000000000..6d7d02026 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sum.d.ts @@ -0,0 +1,2 @@ +import { sum } from "../fp"; +export = sum; diff --git a/libs/events/node_modules/@types/lodash/fp/sumBy.d.ts b/libs/events/node_modules/@types/lodash/fp/sumBy.d.ts new file mode 100755 index 000000000..3f44c3f6c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/sumBy.d.ts @@ -0,0 +1,2 @@ +import { sumBy } from "../fp"; +export = sumBy; diff --git a/libs/events/node_modules/@types/lodash/fp/symmetricDifference.d.ts b/libs/events/node_modules/@types/lodash/fp/symmetricDifference.d.ts new file mode 100755 index 000000000..cba1d1f70 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/symmetricDifference.d.ts @@ -0,0 +1,2 @@ +import { symmetricDifference } from "../fp"; +export = symmetricDifference; diff --git a/libs/events/node_modules/@types/lodash/fp/symmetricDifferenceBy.d.ts b/libs/events/node_modules/@types/lodash/fp/symmetricDifferenceBy.d.ts new file mode 100755 index 000000000..8e9316cf4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/symmetricDifferenceBy.d.ts @@ -0,0 +1,2 @@ +import { symmetricDifferenceBy } from "../fp"; +export = symmetricDifferenceBy; diff --git a/libs/events/node_modules/@types/lodash/fp/symmetricDifferenceWith.d.ts b/libs/events/node_modules/@types/lodash/fp/symmetricDifferenceWith.d.ts new file mode 100755 index 000000000..864ec01b5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/symmetricDifferenceWith.d.ts @@ -0,0 +1,2 @@ +import { symmetricDifferenceWith } from "../fp"; +export = symmetricDifferenceWith; diff --git a/libs/events/node_modules/@types/lodash/fp/tail.d.ts b/libs/events/node_modules/@types/lodash/fp/tail.d.ts new file mode 100755 index 000000000..df9bcdcd5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/tail.d.ts @@ -0,0 +1,2 @@ +import { tail } from "../fp"; +export = tail; diff --git a/libs/events/node_modules/@types/lodash/fp/take.d.ts b/libs/events/node_modules/@types/lodash/fp/take.d.ts new file mode 100755 index 000000000..ab46aca05 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/take.d.ts @@ -0,0 +1,2 @@ +import { take } from "../fp"; +export = take; diff --git a/libs/events/node_modules/@types/lodash/fp/takeLast.d.ts b/libs/events/node_modules/@types/lodash/fp/takeLast.d.ts new file mode 100755 index 000000000..027dcda5e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/takeLast.d.ts @@ -0,0 +1,2 @@ +import { takeLast } from "../fp"; +export = takeLast; diff --git a/libs/events/node_modules/@types/lodash/fp/takeLastWhile.d.ts b/libs/events/node_modules/@types/lodash/fp/takeLastWhile.d.ts new file mode 100755 index 000000000..c6729c352 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/takeLastWhile.d.ts @@ -0,0 +1,2 @@ +import { takeLastWhile } from "../fp"; +export = takeLastWhile; diff --git a/libs/events/node_modules/@types/lodash/fp/takeRight.d.ts b/libs/events/node_modules/@types/lodash/fp/takeRight.d.ts new file mode 100755 index 000000000..162c5166e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/takeRight.d.ts @@ -0,0 +1,2 @@ +import { takeRight } from "../fp"; +export = takeRight; diff --git a/libs/events/node_modules/@types/lodash/fp/takeRightWhile.d.ts b/libs/events/node_modules/@types/lodash/fp/takeRightWhile.d.ts new file mode 100755 index 000000000..b23f7a460 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/takeRightWhile.d.ts @@ -0,0 +1,2 @@ +import { takeRightWhile } from "../fp"; +export = takeRightWhile; diff --git a/libs/events/node_modules/@types/lodash/fp/takeWhile.d.ts b/libs/events/node_modules/@types/lodash/fp/takeWhile.d.ts new file mode 100755 index 000000000..b8cb51760 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/takeWhile.d.ts @@ -0,0 +1,2 @@ +import { takeWhile } from "../fp"; +export = takeWhile; diff --git a/libs/events/node_modules/@types/lodash/fp/tap.d.ts b/libs/events/node_modules/@types/lodash/fp/tap.d.ts new file mode 100755 index 000000000..8ffbbd7f2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/tap.d.ts @@ -0,0 +1,2 @@ +import { tap } from "../fp"; +export = tap; diff --git a/libs/events/node_modules/@types/lodash/fp/template.d.ts b/libs/events/node_modules/@types/lodash/fp/template.d.ts new file mode 100755 index 000000000..3a37ed1af --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/template.d.ts @@ -0,0 +1,2 @@ +import { template } from "../fp"; +export = template; diff --git a/libs/events/node_modules/@types/lodash/fp/throttle.d.ts b/libs/events/node_modules/@types/lodash/fp/throttle.d.ts new file mode 100755 index 000000000..24d8b7f4e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/throttle.d.ts @@ -0,0 +1,2 @@ +import { throttle } from "../fp"; +export = throttle; diff --git a/libs/events/node_modules/@types/lodash/fp/thru.d.ts b/libs/events/node_modules/@types/lodash/fp/thru.d.ts new file mode 100755 index 000000000..b9725820a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/thru.d.ts @@ -0,0 +1,2 @@ +import { thru } from "../fp"; +export = thru; diff --git a/libs/events/node_modules/@types/lodash/fp/times.d.ts b/libs/events/node_modules/@types/lodash/fp/times.d.ts new file mode 100755 index 000000000..3d9f0c607 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/times.d.ts @@ -0,0 +1,2 @@ +import { times } from "../fp"; +export = times; diff --git a/libs/events/node_modules/@types/lodash/fp/toArray.d.ts b/libs/events/node_modules/@types/lodash/fp/toArray.d.ts new file mode 100755 index 000000000..4b18ce6d5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toArray.d.ts @@ -0,0 +1,2 @@ +import { toArray } from "../fp"; +export = toArray; diff --git a/libs/events/node_modules/@types/lodash/fp/toFinite.d.ts b/libs/events/node_modules/@types/lodash/fp/toFinite.d.ts new file mode 100755 index 000000000..1d4199618 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toFinite.d.ts @@ -0,0 +1,2 @@ +import { toFinite } from "../fp"; +export = toFinite; diff --git a/libs/events/node_modules/@types/lodash/fp/toInteger.d.ts b/libs/events/node_modules/@types/lodash/fp/toInteger.d.ts new file mode 100755 index 000000000..46ccaf945 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toInteger.d.ts @@ -0,0 +1,2 @@ +import { toInteger } from "../fp"; +export = toInteger; diff --git a/libs/events/node_modules/@types/lodash/fp/toLength.d.ts b/libs/events/node_modules/@types/lodash/fp/toLength.d.ts new file mode 100755 index 000000000..bb6292431 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toLength.d.ts @@ -0,0 +1,2 @@ +import { toLength } from "../fp"; +export = toLength; diff --git a/libs/events/node_modules/@types/lodash/fp/toLower.d.ts b/libs/events/node_modules/@types/lodash/fp/toLower.d.ts new file mode 100755 index 000000000..64e6e364d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toLower.d.ts @@ -0,0 +1,2 @@ +import { toLower } from "../fp"; +export = toLower; diff --git a/libs/events/node_modules/@types/lodash/fp/toNumber.d.ts b/libs/events/node_modules/@types/lodash/fp/toNumber.d.ts new file mode 100755 index 000000000..262b91c52 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toNumber.d.ts @@ -0,0 +1,2 @@ +import { toNumber } from "../fp"; +export = toNumber; diff --git a/libs/events/node_modules/@types/lodash/fp/toPairs.d.ts b/libs/events/node_modules/@types/lodash/fp/toPairs.d.ts new file mode 100755 index 000000000..89334fcb5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toPairs.d.ts @@ -0,0 +1,2 @@ +import { toPairs } from "../fp"; +export = toPairs; diff --git a/libs/events/node_modules/@types/lodash/fp/toPairsIn.d.ts b/libs/events/node_modules/@types/lodash/fp/toPairsIn.d.ts new file mode 100755 index 000000000..278ff0b1d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toPairsIn.d.ts @@ -0,0 +1,2 @@ +import { toPairsIn } from "../fp"; +export = toPairsIn; diff --git a/libs/events/node_modules/@types/lodash/fp/toPath.d.ts b/libs/events/node_modules/@types/lodash/fp/toPath.d.ts new file mode 100755 index 000000000..9f2287cea --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toPath.d.ts @@ -0,0 +1,2 @@ +import { toPath } from "../fp"; +export = toPath; diff --git a/libs/events/node_modules/@types/lodash/fp/toPlainObject.d.ts b/libs/events/node_modules/@types/lodash/fp/toPlainObject.d.ts new file mode 100755 index 000000000..22fa07038 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toPlainObject.d.ts @@ -0,0 +1,2 @@ +import { toPlainObject } from "../fp"; +export = toPlainObject; diff --git a/libs/events/node_modules/@types/lodash/fp/toSafeInteger.d.ts b/libs/events/node_modules/@types/lodash/fp/toSafeInteger.d.ts new file mode 100755 index 000000000..2f85078fc --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toSafeInteger.d.ts @@ -0,0 +1,2 @@ +import { toSafeInteger } from "../fp"; +export = toSafeInteger; diff --git a/libs/events/node_modules/@types/lodash/fp/toString.d.ts b/libs/events/node_modules/@types/lodash/fp/toString.d.ts new file mode 100755 index 000000000..ee6703c06 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toString.d.ts @@ -0,0 +1,2 @@ +import { toString } from "../fp"; +export = toString; diff --git a/libs/events/node_modules/@types/lodash/fp/toUpper.d.ts b/libs/events/node_modules/@types/lodash/fp/toUpper.d.ts new file mode 100755 index 000000000..6bf21c1fc --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/toUpper.d.ts @@ -0,0 +1,2 @@ +import { toUpper } from "../fp"; +export = toUpper; diff --git a/libs/events/node_modules/@types/lodash/fp/transform.d.ts b/libs/events/node_modules/@types/lodash/fp/transform.d.ts new file mode 100755 index 000000000..ab0653cb7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/transform.d.ts @@ -0,0 +1,2 @@ +import { transform } from "../fp"; +export = transform; diff --git a/libs/events/node_modules/@types/lodash/fp/trim.d.ts b/libs/events/node_modules/@types/lodash/fp/trim.d.ts new file mode 100755 index 000000000..f0f9b905d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/trim.d.ts @@ -0,0 +1,2 @@ +import { trim } from "../fp"; +export = trim; diff --git a/libs/events/node_modules/@types/lodash/fp/trimChars.d.ts b/libs/events/node_modules/@types/lodash/fp/trimChars.d.ts new file mode 100755 index 000000000..929a49300 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/trimChars.d.ts @@ -0,0 +1,2 @@ +import { trimChars } from "../fp"; +export = trimChars; diff --git a/libs/events/node_modules/@types/lodash/fp/trimCharsEnd.d.ts b/libs/events/node_modules/@types/lodash/fp/trimCharsEnd.d.ts new file mode 100755 index 000000000..2f5609ae2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/trimCharsEnd.d.ts @@ -0,0 +1,2 @@ +import { trimCharsEnd } from "../fp"; +export = trimCharsEnd; diff --git a/libs/events/node_modules/@types/lodash/fp/trimCharsStart.d.ts b/libs/events/node_modules/@types/lodash/fp/trimCharsStart.d.ts new file mode 100755 index 000000000..fb998f7e5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/trimCharsStart.d.ts @@ -0,0 +1,2 @@ +import { trimCharsStart } from "../fp"; +export = trimCharsStart; diff --git a/libs/events/node_modules/@types/lodash/fp/trimEnd.d.ts b/libs/events/node_modules/@types/lodash/fp/trimEnd.d.ts new file mode 100755 index 000000000..b66649448 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/trimEnd.d.ts @@ -0,0 +1,2 @@ +import { trimEnd } from "../fp"; +export = trimEnd; diff --git a/libs/events/node_modules/@types/lodash/fp/trimStart.d.ts b/libs/events/node_modules/@types/lodash/fp/trimStart.d.ts new file mode 100755 index 000000000..988227ca7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/trimStart.d.ts @@ -0,0 +1,2 @@ +import { trimStart } from "../fp"; +export = trimStart; diff --git a/libs/events/node_modules/@types/lodash/fp/truncate.d.ts b/libs/events/node_modules/@types/lodash/fp/truncate.d.ts new file mode 100755 index 000000000..d38b7b18b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/truncate.d.ts @@ -0,0 +1,2 @@ +import { truncate } from "../fp"; +export = truncate; diff --git a/libs/events/node_modules/@types/lodash/fp/unapply.d.ts b/libs/events/node_modules/@types/lodash/fp/unapply.d.ts new file mode 100755 index 000000000..c59b6b2a1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/unapply.d.ts @@ -0,0 +1,2 @@ +import { unapply } from "../fp"; +export = unapply; diff --git a/libs/events/node_modules/@types/lodash/fp/unary.d.ts b/libs/events/node_modules/@types/lodash/fp/unary.d.ts new file mode 100755 index 000000000..02e319576 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/unary.d.ts @@ -0,0 +1,2 @@ +import { unary } from "../fp"; +export = unary; diff --git a/libs/events/node_modules/@types/lodash/fp/unescape.d.ts b/libs/events/node_modules/@types/lodash/fp/unescape.d.ts new file mode 100755 index 000000000..efcccf2a5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/unescape.d.ts @@ -0,0 +1,2 @@ +import { unescape } from "../fp"; +export = unescape; diff --git a/libs/events/node_modules/@types/lodash/fp/union.d.ts b/libs/events/node_modules/@types/lodash/fp/union.d.ts new file mode 100755 index 000000000..8e098ee7f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/union.d.ts @@ -0,0 +1,2 @@ +import { union } from "../fp"; +export = union; diff --git a/libs/events/node_modules/@types/lodash/fp/unionBy.d.ts b/libs/events/node_modules/@types/lodash/fp/unionBy.d.ts new file mode 100755 index 000000000..f3882c6b4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/unionBy.d.ts @@ -0,0 +1,2 @@ +import { unionBy } from "../fp"; +export = unionBy; diff --git a/libs/events/node_modules/@types/lodash/fp/unionWith.d.ts b/libs/events/node_modules/@types/lodash/fp/unionWith.d.ts new file mode 100755 index 000000000..46e19fd17 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/unionWith.d.ts @@ -0,0 +1,2 @@ +import { unionWith } from "../fp"; +export = unionWith; diff --git a/libs/events/node_modules/@types/lodash/fp/uniq.d.ts b/libs/events/node_modules/@types/lodash/fp/uniq.d.ts new file mode 100755 index 000000000..877d0d94d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/uniq.d.ts @@ -0,0 +1,2 @@ +import { uniq } from "../fp"; +export = uniq; diff --git a/libs/events/node_modules/@types/lodash/fp/uniqBy.d.ts b/libs/events/node_modules/@types/lodash/fp/uniqBy.d.ts new file mode 100755 index 000000000..0e6522d70 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/uniqBy.d.ts @@ -0,0 +1,2 @@ +import { uniqBy } from "../fp"; +export = uniqBy; diff --git a/libs/events/node_modules/@types/lodash/fp/uniqWith.d.ts b/libs/events/node_modules/@types/lodash/fp/uniqWith.d.ts new file mode 100755 index 000000000..165f45f1e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/uniqWith.d.ts @@ -0,0 +1,2 @@ +import { uniqWith } from "../fp"; +export = uniqWith; diff --git a/libs/events/node_modules/@types/lodash/fp/uniqueId.d.ts b/libs/events/node_modules/@types/lodash/fp/uniqueId.d.ts new file mode 100755 index 000000000..57736d9cc --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/uniqueId.d.ts @@ -0,0 +1,2 @@ +import { uniqueId } from "../fp"; +export = uniqueId; diff --git a/libs/events/node_modules/@types/lodash/fp/unnest.d.ts b/libs/events/node_modules/@types/lodash/fp/unnest.d.ts new file mode 100755 index 000000000..852e9a136 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/unnest.d.ts @@ -0,0 +1,2 @@ +import { unnest } from "../fp"; +export = unnest; diff --git a/libs/events/node_modules/@types/lodash/fp/unset.d.ts b/libs/events/node_modules/@types/lodash/fp/unset.d.ts new file mode 100755 index 000000000..3e9924771 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/unset.d.ts @@ -0,0 +1,2 @@ +import { unset } from "../fp"; +export = unset; diff --git a/libs/events/node_modules/@types/lodash/fp/unzip.d.ts b/libs/events/node_modules/@types/lodash/fp/unzip.d.ts new file mode 100755 index 000000000..ba9d4cd70 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/unzip.d.ts @@ -0,0 +1,2 @@ +import { unzip } from "../fp"; +export = unzip; diff --git a/libs/events/node_modules/@types/lodash/fp/unzipWith.d.ts b/libs/events/node_modules/@types/lodash/fp/unzipWith.d.ts new file mode 100755 index 000000000..599eadb35 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/unzipWith.d.ts @@ -0,0 +1,2 @@ +import { unzipWith } from "../fp"; +export = unzipWith; diff --git a/libs/events/node_modules/@types/lodash/fp/update.d.ts b/libs/events/node_modules/@types/lodash/fp/update.d.ts new file mode 100755 index 000000000..76dfe482f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/update.d.ts @@ -0,0 +1,2 @@ +import { update } from "../fp"; +export = update; diff --git a/libs/events/node_modules/@types/lodash/fp/updateWith.d.ts b/libs/events/node_modules/@types/lodash/fp/updateWith.d.ts new file mode 100755 index 000000000..6d6331d1b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/updateWith.d.ts @@ -0,0 +1,2 @@ +import { updateWith } from "../fp"; +export = updateWith; diff --git a/libs/events/node_modules/@types/lodash/fp/upperCase.d.ts b/libs/events/node_modules/@types/lodash/fp/upperCase.d.ts new file mode 100755 index 000000000..10aadb28e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/upperCase.d.ts @@ -0,0 +1,2 @@ +import { upperCase } from "../fp"; +export = upperCase; diff --git a/libs/events/node_modules/@types/lodash/fp/upperFirst.d.ts b/libs/events/node_modules/@types/lodash/fp/upperFirst.d.ts new file mode 100755 index 000000000..e2c9adfd5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/upperFirst.d.ts @@ -0,0 +1,2 @@ +import { upperFirst } from "../fp"; +export = upperFirst; diff --git a/libs/events/node_modules/@types/lodash/fp/useWith.d.ts b/libs/events/node_modules/@types/lodash/fp/useWith.d.ts new file mode 100755 index 000000000..991905a40 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/useWith.d.ts @@ -0,0 +1,2 @@ +import { useWith } from "../fp"; +export = useWith; diff --git a/libs/events/node_modules/@types/lodash/fp/values.d.ts b/libs/events/node_modules/@types/lodash/fp/values.d.ts new file mode 100755 index 000000000..75ec6fb4e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/values.d.ts @@ -0,0 +1,2 @@ +import { values } from "../fp"; +export = values; diff --git a/libs/events/node_modules/@types/lodash/fp/valuesIn.d.ts b/libs/events/node_modules/@types/lodash/fp/valuesIn.d.ts new file mode 100755 index 000000000..6f4f3b43b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/valuesIn.d.ts @@ -0,0 +1,2 @@ +import { valuesIn } from "../fp"; +export = valuesIn; diff --git a/libs/events/node_modules/@types/lodash/fp/where.d.ts b/libs/events/node_modules/@types/lodash/fp/where.d.ts new file mode 100755 index 000000000..41e21ec8a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/where.d.ts @@ -0,0 +1,2 @@ +import { where } from "../fp"; +export = where; diff --git a/libs/events/node_modules/@types/lodash/fp/whereEq.d.ts b/libs/events/node_modules/@types/lodash/fp/whereEq.d.ts new file mode 100755 index 000000000..893316d62 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/whereEq.d.ts @@ -0,0 +1,2 @@ +import { whereEq } from "../fp"; +export = whereEq; diff --git a/libs/events/node_modules/@types/lodash/fp/without.d.ts b/libs/events/node_modules/@types/lodash/fp/without.d.ts new file mode 100755 index 000000000..600890a40 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/without.d.ts @@ -0,0 +1,2 @@ +import { without } from "../fp"; +export = without; diff --git a/libs/events/node_modules/@types/lodash/fp/words.d.ts b/libs/events/node_modules/@types/lodash/fp/words.d.ts new file mode 100755 index 000000000..2b06b2636 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/words.d.ts @@ -0,0 +1,2 @@ +import { words } from "../fp"; +export = words; diff --git a/libs/events/node_modules/@types/lodash/fp/wrap.d.ts b/libs/events/node_modules/@types/lodash/fp/wrap.d.ts new file mode 100755 index 000000000..d9c2a283e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/wrap.d.ts @@ -0,0 +1,2 @@ +import { wrap } from "../fp"; +export = wrap; diff --git a/libs/events/node_modules/@types/lodash/fp/xor.d.ts b/libs/events/node_modules/@types/lodash/fp/xor.d.ts new file mode 100755 index 000000000..ac69bde23 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/xor.d.ts @@ -0,0 +1,2 @@ +import { xor } from "../fp"; +export = xor; diff --git a/libs/events/node_modules/@types/lodash/fp/xorBy.d.ts b/libs/events/node_modules/@types/lodash/fp/xorBy.d.ts new file mode 100755 index 000000000..123297232 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/xorBy.d.ts @@ -0,0 +1,2 @@ +import { xorBy } from "../fp"; +export = xorBy; diff --git a/libs/events/node_modules/@types/lodash/fp/xorWith.d.ts b/libs/events/node_modules/@types/lodash/fp/xorWith.d.ts new file mode 100755 index 000000000..ec93e40b3 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/xorWith.d.ts @@ -0,0 +1,2 @@ +import { xorWith } from "../fp"; +export = xorWith; diff --git a/libs/events/node_modules/@types/lodash/fp/zip.d.ts b/libs/events/node_modules/@types/lodash/fp/zip.d.ts new file mode 100755 index 000000000..2a83e733b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/zip.d.ts @@ -0,0 +1,2 @@ +import { zip } from "../fp"; +export = zip; diff --git a/libs/events/node_modules/@types/lodash/fp/zipAll.d.ts b/libs/events/node_modules/@types/lodash/fp/zipAll.d.ts new file mode 100755 index 000000000..af0b3ed3f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/zipAll.d.ts @@ -0,0 +1,2 @@ +import { zipAll } from "../fp"; +export = zipAll; diff --git a/libs/events/node_modules/@types/lodash/fp/zipObj.d.ts b/libs/events/node_modules/@types/lodash/fp/zipObj.d.ts new file mode 100755 index 000000000..4f4c19a87 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/zipObj.d.ts @@ -0,0 +1,2 @@ +import { zipObj } from "../fp"; +export = zipObj; diff --git a/libs/events/node_modules/@types/lodash/fp/zipObject.d.ts b/libs/events/node_modules/@types/lodash/fp/zipObject.d.ts new file mode 100755 index 000000000..f302d7b15 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/zipObject.d.ts @@ -0,0 +1,2 @@ +import { zipObject } from "../fp"; +export = zipObject; diff --git a/libs/events/node_modules/@types/lodash/fp/zipObjectDeep.d.ts b/libs/events/node_modules/@types/lodash/fp/zipObjectDeep.d.ts new file mode 100755 index 000000000..601063489 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/zipObjectDeep.d.ts @@ -0,0 +1,2 @@ +import { zipObjectDeep } from "../fp"; +export = zipObjectDeep; diff --git a/libs/events/node_modules/@types/lodash/fp/zipWith.d.ts b/libs/events/node_modules/@types/lodash/fp/zipWith.d.ts new file mode 100755 index 000000000..9faaf3c58 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fp/zipWith.d.ts @@ -0,0 +1,2 @@ +import { zipWith } from "../fp"; +export = zipWith; diff --git a/libs/events/node_modules/@types/lodash/fromPairs.d.ts b/libs/events/node_modules/@types/lodash/fromPairs.d.ts new file mode 100755 index 000000000..1c2006c63 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/fromPairs.d.ts @@ -0,0 +1,2 @@ +import { fromPairs } from "./index"; +export = fromPairs; diff --git a/libs/events/node_modules/@types/lodash/functions.d.ts b/libs/events/node_modules/@types/lodash/functions.d.ts new file mode 100755 index 000000000..86983361a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/functions.d.ts @@ -0,0 +1,2 @@ +import { functions } from "./index"; +export = functions; diff --git a/libs/events/node_modules/@types/lodash/functionsIn.d.ts b/libs/events/node_modules/@types/lodash/functionsIn.d.ts new file mode 100755 index 000000000..9f72a7838 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/functionsIn.d.ts @@ -0,0 +1,2 @@ +import { functionsIn } from "./index"; +export = functionsIn; diff --git a/libs/events/node_modules/@types/lodash/get.d.ts b/libs/events/node_modules/@types/lodash/get.d.ts new file mode 100755 index 000000000..5ea7a5a41 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/get.d.ts @@ -0,0 +1,2 @@ +import { get } from "./index"; +export = get; diff --git a/libs/events/node_modules/@types/lodash/groupBy.d.ts b/libs/events/node_modules/@types/lodash/groupBy.d.ts new file mode 100755 index 000000000..ef49718e5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/groupBy.d.ts @@ -0,0 +1,2 @@ +import { groupBy } from "./index"; +export = groupBy; diff --git a/libs/events/node_modules/@types/lodash/gt.d.ts b/libs/events/node_modules/@types/lodash/gt.d.ts new file mode 100755 index 000000000..860134fbe --- /dev/null +++ b/libs/events/node_modules/@types/lodash/gt.d.ts @@ -0,0 +1,2 @@ +import { gt } from "./index"; +export = gt; diff --git a/libs/events/node_modules/@types/lodash/gte.d.ts b/libs/events/node_modules/@types/lodash/gte.d.ts new file mode 100755 index 000000000..994e88264 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/gte.d.ts @@ -0,0 +1,2 @@ +import { gte } from "./index"; +export = gte; diff --git a/libs/events/node_modules/@types/lodash/has.d.ts b/libs/events/node_modules/@types/lodash/has.d.ts new file mode 100755 index 000000000..fff146869 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/has.d.ts @@ -0,0 +1,2 @@ +import { has } from "./index"; +export = has; diff --git a/libs/events/node_modules/@types/lodash/hasIn.d.ts b/libs/events/node_modules/@types/lodash/hasIn.d.ts new file mode 100755 index 000000000..a898071b1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/hasIn.d.ts @@ -0,0 +1,2 @@ +import { hasIn } from "./index"; +export = hasIn; diff --git a/libs/events/node_modules/@types/lodash/head.d.ts b/libs/events/node_modules/@types/lodash/head.d.ts new file mode 100755 index 000000000..0e16da171 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/head.d.ts @@ -0,0 +1,2 @@ +import { head } from "./index"; +export = head; diff --git a/libs/events/node_modules/@types/lodash/identity.d.ts b/libs/events/node_modules/@types/lodash/identity.d.ts new file mode 100755 index 000000000..6814a1653 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/identity.d.ts @@ -0,0 +1,2 @@ +import { identity } from "./index"; +export = identity; diff --git a/libs/events/node_modules/@types/lodash/inRange.d.ts b/libs/events/node_modules/@types/lodash/inRange.d.ts new file mode 100755 index 000000000..d9c57c0e8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/inRange.d.ts @@ -0,0 +1,2 @@ +import { inRange } from "./index"; +export = inRange; diff --git a/libs/events/node_modules/@types/lodash/includes.d.ts b/libs/events/node_modules/@types/lodash/includes.d.ts new file mode 100755 index 000000000..4edd22619 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/includes.d.ts @@ -0,0 +1,2 @@ +import { includes } from "./index"; +export = includes; diff --git a/libs/events/node_modules/@types/lodash/index.d.ts b/libs/events/node_modules/@types/lodash/index.d.ts new file mode 100755 index 000000000..0d4b05fa0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/index.d.ts @@ -0,0 +1,33 @@ +// Type definitions for Lo-Dash 4.14 +// Project: https://lodash.com +// Definitions by: Brian Zengel +// Ilya Mochalov +// AJ Richardson +// e-cloud +// Georgii Dolzhykov +// Jack Moore +// Dominique Rau +// William Chelman +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// + +export = _; +export as namespace _; + +declare const _: _.LoDashStatic; +declare namespace _ { + // tslint:disable-next-line no-empty-interface (This will be augmented) + interface LoDashStatic {} +} diff --git a/libs/events/node_modules/@types/lodash/indexOf.d.ts b/libs/events/node_modules/@types/lodash/indexOf.d.ts new file mode 100755 index 000000000..50b8f702c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/indexOf.d.ts @@ -0,0 +1,2 @@ +import { indexOf } from "./index"; +export = indexOf; diff --git a/libs/events/node_modules/@types/lodash/initial.d.ts b/libs/events/node_modules/@types/lodash/initial.d.ts new file mode 100755 index 000000000..3ce64ebc0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/initial.d.ts @@ -0,0 +1,2 @@ +import { initial } from "./index"; +export = initial; diff --git a/libs/events/node_modules/@types/lodash/intersection.d.ts b/libs/events/node_modules/@types/lodash/intersection.d.ts new file mode 100755 index 000000000..1fbe4e596 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/intersection.d.ts @@ -0,0 +1,2 @@ +import { intersection } from "./index"; +export = intersection; diff --git a/libs/events/node_modules/@types/lodash/intersectionBy.d.ts b/libs/events/node_modules/@types/lodash/intersectionBy.d.ts new file mode 100755 index 000000000..b4885da5e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/intersectionBy.d.ts @@ -0,0 +1,2 @@ +import { intersectionBy } from "./index"; +export = intersectionBy; diff --git a/libs/events/node_modules/@types/lodash/intersectionWith.d.ts b/libs/events/node_modules/@types/lodash/intersectionWith.d.ts new file mode 100755 index 000000000..bacccd045 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/intersectionWith.d.ts @@ -0,0 +1,2 @@ +import { intersectionWith } from "./index"; +export = intersectionWith; diff --git a/libs/events/node_modules/@types/lodash/invert.d.ts b/libs/events/node_modules/@types/lodash/invert.d.ts new file mode 100755 index 000000000..2287ea1f9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/invert.d.ts @@ -0,0 +1,2 @@ +import { invert } from "./index"; +export = invert; diff --git a/libs/events/node_modules/@types/lodash/invertBy.d.ts b/libs/events/node_modules/@types/lodash/invertBy.d.ts new file mode 100755 index 000000000..5951600e2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/invertBy.d.ts @@ -0,0 +1,2 @@ +import { invertBy } from "./index"; +export = invertBy; diff --git a/libs/events/node_modules/@types/lodash/invoke.d.ts b/libs/events/node_modules/@types/lodash/invoke.d.ts new file mode 100755 index 000000000..eea6b3888 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/invoke.d.ts @@ -0,0 +1,2 @@ +import { invoke } from "./index"; +export = invoke; diff --git a/libs/events/node_modules/@types/lodash/invokeMap.d.ts b/libs/events/node_modules/@types/lodash/invokeMap.d.ts new file mode 100755 index 000000000..814cf05fd --- /dev/null +++ b/libs/events/node_modules/@types/lodash/invokeMap.d.ts @@ -0,0 +1,2 @@ +import { invokeMap } from "./index"; +export = invokeMap; diff --git a/libs/events/node_modules/@types/lodash/isArguments.d.ts b/libs/events/node_modules/@types/lodash/isArguments.d.ts new file mode 100755 index 000000000..5b2257231 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isArguments.d.ts @@ -0,0 +1,2 @@ +import { isArguments } from "./index"; +export = isArguments; diff --git a/libs/events/node_modules/@types/lodash/isArray.d.ts b/libs/events/node_modules/@types/lodash/isArray.d.ts new file mode 100755 index 000000000..a35ab5a62 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isArray.d.ts @@ -0,0 +1,2 @@ +import { isArray } from "./index"; +export = isArray; diff --git a/libs/events/node_modules/@types/lodash/isArrayBuffer.d.ts b/libs/events/node_modules/@types/lodash/isArrayBuffer.d.ts new file mode 100755 index 000000000..ec7c68ce2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isArrayBuffer.d.ts @@ -0,0 +1,2 @@ +import { isArrayBuffer } from "./index"; +export = isArrayBuffer; diff --git a/libs/events/node_modules/@types/lodash/isArrayLike.d.ts b/libs/events/node_modules/@types/lodash/isArrayLike.d.ts new file mode 100755 index 000000000..aa95c7700 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isArrayLike.d.ts @@ -0,0 +1,2 @@ +import { isArrayLike } from "./index"; +export = isArrayLike; diff --git a/libs/events/node_modules/@types/lodash/isArrayLikeObject.d.ts b/libs/events/node_modules/@types/lodash/isArrayLikeObject.d.ts new file mode 100755 index 000000000..736c91db1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isArrayLikeObject.d.ts @@ -0,0 +1,2 @@ +import { isArrayLikeObject } from "./index"; +export = isArrayLikeObject; diff --git a/libs/events/node_modules/@types/lodash/isBoolean.d.ts b/libs/events/node_modules/@types/lodash/isBoolean.d.ts new file mode 100755 index 000000000..96c306d9c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isBoolean.d.ts @@ -0,0 +1,2 @@ +import { isBoolean } from "./index"; +export = isBoolean; diff --git a/libs/events/node_modules/@types/lodash/isBuffer.d.ts b/libs/events/node_modules/@types/lodash/isBuffer.d.ts new file mode 100755 index 000000000..b22d78244 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isBuffer.d.ts @@ -0,0 +1,2 @@ +import { isBuffer } from "./index"; +export = isBuffer; diff --git a/libs/events/node_modules/@types/lodash/isDate.d.ts b/libs/events/node_modules/@types/lodash/isDate.d.ts new file mode 100755 index 000000000..1269a69d4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isDate.d.ts @@ -0,0 +1,2 @@ +import { isDate } from "./index"; +export = isDate; diff --git a/libs/events/node_modules/@types/lodash/isElement.d.ts b/libs/events/node_modules/@types/lodash/isElement.d.ts new file mode 100755 index 000000000..e4510cd9c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isElement.d.ts @@ -0,0 +1,2 @@ +import { isElement } from "./index"; +export = isElement; diff --git a/libs/events/node_modules/@types/lodash/isEmpty.d.ts b/libs/events/node_modules/@types/lodash/isEmpty.d.ts new file mode 100755 index 000000000..9e71bfa96 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isEmpty.d.ts @@ -0,0 +1,2 @@ +import { isEmpty } from "./index"; +export = isEmpty; diff --git a/libs/events/node_modules/@types/lodash/isEqual.d.ts b/libs/events/node_modules/@types/lodash/isEqual.d.ts new file mode 100755 index 000000000..1e065fa83 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isEqual.d.ts @@ -0,0 +1,2 @@ +import { isEqual } from "./index"; +export = isEqual; diff --git a/libs/events/node_modules/@types/lodash/isEqualWith.d.ts b/libs/events/node_modules/@types/lodash/isEqualWith.d.ts new file mode 100755 index 000000000..e14d005c4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isEqualWith.d.ts @@ -0,0 +1,2 @@ +import { isEqualWith } from "./index"; +export = isEqualWith; diff --git a/libs/events/node_modules/@types/lodash/isError.d.ts b/libs/events/node_modules/@types/lodash/isError.d.ts new file mode 100755 index 000000000..d9d578577 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isError.d.ts @@ -0,0 +1,2 @@ +import { isError } from "./index"; +export = isError; diff --git a/libs/events/node_modules/@types/lodash/isFinite.d.ts b/libs/events/node_modules/@types/lodash/isFinite.d.ts new file mode 100755 index 000000000..7aba1dc6f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isFinite.d.ts @@ -0,0 +1,2 @@ +import { isFinite } from "./index"; +export = isFinite; diff --git a/libs/events/node_modules/@types/lodash/isFunction.d.ts b/libs/events/node_modules/@types/lodash/isFunction.d.ts new file mode 100755 index 000000000..0a22d6cc7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isFunction.d.ts @@ -0,0 +1,2 @@ +import { isFunction } from "./index"; +export = isFunction; diff --git a/libs/events/node_modules/@types/lodash/isInteger.d.ts b/libs/events/node_modules/@types/lodash/isInteger.d.ts new file mode 100755 index 000000000..40d33d39e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isInteger.d.ts @@ -0,0 +1,2 @@ +import { isInteger } from "./index"; +export = isInteger; diff --git a/libs/events/node_modules/@types/lodash/isLength.d.ts b/libs/events/node_modules/@types/lodash/isLength.d.ts new file mode 100755 index 000000000..ee5a93304 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isLength.d.ts @@ -0,0 +1,2 @@ +import { isLength } from "./index"; +export = isLength; diff --git a/libs/events/node_modules/@types/lodash/isMap.d.ts b/libs/events/node_modules/@types/lodash/isMap.d.ts new file mode 100755 index 000000000..441c5388c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isMap.d.ts @@ -0,0 +1,2 @@ +import { isMap } from "./index"; +export = isMap; diff --git a/libs/events/node_modules/@types/lodash/isMatch.d.ts b/libs/events/node_modules/@types/lodash/isMatch.d.ts new file mode 100755 index 000000000..69d194a28 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isMatch.d.ts @@ -0,0 +1,2 @@ +import { isMatch } from "./index"; +export = isMatch; diff --git a/libs/events/node_modules/@types/lodash/isMatchWith.d.ts b/libs/events/node_modules/@types/lodash/isMatchWith.d.ts new file mode 100755 index 000000000..932310af4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isMatchWith.d.ts @@ -0,0 +1,2 @@ +import { isMatchWith } from "./index"; +export = isMatchWith; diff --git a/libs/events/node_modules/@types/lodash/isNaN.d.ts b/libs/events/node_modules/@types/lodash/isNaN.d.ts new file mode 100755 index 000000000..970702b50 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isNaN.d.ts @@ -0,0 +1,2 @@ +import { isNaN } from "./index"; +export = isNaN; diff --git a/libs/events/node_modules/@types/lodash/isNative.d.ts b/libs/events/node_modules/@types/lodash/isNative.d.ts new file mode 100755 index 000000000..3174f8a8c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isNative.d.ts @@ -0,0 +1,2 @@ +import { isNative } from "./index"; +export = isNative; diff --git a/libs/events/node_modules/@types/lodash/isNil.d.ts b/libs/events/node_modules/@types/lodash/isNil.d.ts new file mode 100755 index 000000000..9e1581976 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isNil.d.ts @@ -0,0 +1,2 @@ +import { isNil } from "./index"; +export = isNil; diff --git a/libs/events/node_modules/@types/lodash/isNull.d.ts b/libs/events/node_modules/@types/lodash/isNull.d.ts new file mode 100755 index 000000000..e572c456e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isNull.d.ts @@ -0,0 +1,2 @@ +import { isNull } from "./index"; +export = isNull; diff --git a/libs/events/node_modules/@types/lodash/isNumber.d.ts b/libs/events/node_modules/@types/lodash/isNumber.d.ts new file mode 100755 index 000000000..91c83598c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isNumber.d.ts @@ -0,0 +1,2 @@ +import { isNumber } from "./index"; +export = isNumber; diff --git a/libs/events/node_modules/@types/lodash/isObject.d.ts b/libs/events/node_modules/@types/lodash/isObject.d.ts new file mode 100755 index 000000000..9a43544c2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isObject.d.ts @@ -0,0 +1,2 @@ +import { isObject } from "./index"; +export = isObject; diff --git a/libs/events/node_modules/@types/lodash/isObjectLike.d.ts b/libs/events/node_modules/@types/lodash/isObjectLike.d.ts new file mode 100755 index 000000000..a17d39c4e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isObjectLike.d.ts @@ -0,0 +1,2 @@ +import { isObjectLike } from "./index"; +export = isObjectLike; diff --git a/libs/events/node_modules/@types/lodash/isPlainObject.d.ts b/libs/events/node_modules/@types/lodash/isPlainObject.d.ts new file mode 100755 index 000000000..4df85e28b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isPlainObject.d.ts @@ -0,0 +1,2 @@ +import { isPlainObject } from "./index"; +export = isPlainObject; diff --git a/libs/events/node_modules/@types/lodash/isRegExp.d.ts b/libs/events/node_modules/@types/lodash/isRegExp.d.ts new file mode 100755 index 000000000..ed206d972 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isRegExp.d.ts @@ -0,0 +1,2 @@ +import { isRegExp } from "./index"; +export = isRegExp; diff --git a/libs/events/node_modules/@types/lodash/isSafeInteger.d.ts b/libs/events/node_modules/@types/lodash/isSafeInteger.d.ts new file mode 100755 index 000000000..6bc608331 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isSafeInteger.d.ts @@ -0,0 +1,2 @@ +import { isSafeInteger } from "./index"; +export = isSafeInteger; diff --git a/libs/events/node_modules/@types/lodash/isSet.d.ts b/libs/events/node_modules/@types/lodash/isSet.d.ts new file mode 100755 index 000000000..7967b50d2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isSet.d.ts @@ -0,0 +1,2 @@ +import { isSet } from "./index"; +export = isSet; diff --git a/libs/events/node_modules/@types/lodash/isString.d.ts b/libs/events/node_modules/@types/lodash/isString.d.ts new file mode 100755 index 000000000..757802e17 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isString.d.ts @@ -0,0 +1,2 @@ +import { isString } from "./index"; +export = isString; diff --git a/libs/events/node_modules/@types/lodash/isSymbol.d.ts b/libs/events/node_modules/@types/lodash/isSymbol.d.ts new file mode 100755 index 000000000..e28b2b0c7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isSymbol.d.ts @@ -0,0 +1,2 @@ +import { isSymbol } from "./index"; +export = isSymbol; diff --git a/libs/events/node_modules/@types/lodash/isTypedArray.d.ts b/libs/events/node_modules/@types/lodash/isTypedArray.d.ts new file mode 100755 index 000000000..7f3260122 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isTypedArray.d.ts @@ -0,0 +1,2 @@ +import { isTypedArray } from "./index"; +export = isTypedArray; diff --git a/libs/events/node_modules/@types/lodash/isUndefined.d.ts b/libs/events/node_modules/@types/lodash/isUndefined.d.ts new file mode 100755 index 000000000..7a5c64ff7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isUndefined.d.ts @@ -0,0 +1,2 @@ +import { isUndefined } from "./index"; +export = isUndefined; diff --git a/libs/events/node_modules/@types/lodash/isWeakMap.d.ts b/libs/events/node_modules/@types/lodash/isWeakMap.d.ts new file mode 100755 index 000000000..b0609daab --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isWeakMap.d.ts @@ -0,0 +1,2 @@ +import { isWeakMap } from "./index"; +export = isWeakMap; diff --git a/libs/events/node_modules/@types/lodash/isWeakSet.d.ts b/libs/events/node_modules/@types/lodash/isWeakSet.d.ts new file mode 100755 index 000000000..6beda3d0f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/isWeakSet.d.ts @@ -0,0 +1,2 @@ +import { isWeakSet } from "./index"; +export = isWeakSet; diff --git a/libs/events/node_modules/@types/lodash/iteratee.d.ts b/libs/events/node_modules/@types/lodash/iteratee.d.ts new file mode 100755 index 000000000..493b39c4b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/iteratee.d.ts @@ -0,0 +1,2 @@ +import { iteratee } from "./index"; +export = iteratee; diff --git a/libs/events/node_modules/@types/lodash/join.d.ts b/libs/events/node_modules/@types/lodash/join.d.ts new file mode 100755 index 000000000..b2c5fb401 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/join.d.ts @@ -0,0 +1,2 @@ +import { join } from "./index"; +export = join; diff --git a/libs/events/node_modules/@types/lodash/kebabCase.d.ts b/libs/events/node_modules/@types/lodash/kebabCase.d.ts new file mode 100755 index 000000000..c088ef7c2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/kebabCase.d.ts @@ -0,0 +1,2 @@ +import { kebabCase } from "./index"; +export = kebabCase; diff --git a/libs/events/node_modules/@types/lodash/keyBy.d.ts b/libs/events/node_modules/@types/lodash/keyBy.d.ts new file mode 100755 index 000000000..664a7229a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/keyBy.d.ts @@ -0,0 +1,2 @@ +import { keyBy } from "./index"; +export = keyBy; diff --git a/libs/events/node_modules/@types/lodash/keys.d.ts b/libs/events/node_modules/@types/lodash/keys.d.ts new file mode 100755 index 000000000..7eb29a0b9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/keys.d.ts @@ -0,0 +1,2 @@ +import { keys } from "./index"; +export = keys; diff --git a/libs/events/node_modules/@types/lodash/keysIn.d.ts b/libs/events/node_modules/@types/lodash/keysIn.d.ts new file mode 100755 index 000000000..c9eeee6c2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/keysIn.d.ts @@ -0,0 +1,2 @@ +import { keysIn } from "./index"; +export = keysIn; diff --git a/libs/events/node_modules/@types/lodash/last.d.ts b/libs/events/node_modules/@types/lodash/last.d.ts new file mode 100755 index 000000000..cfdeb757e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/last.d.ts @@ -0,0 +1,2 @@ +import { last } from "./index"; +export = last; diff --git a/libs/events/node_modules/@types/lodash/lastIndexOf.d.ts b/libs/events/node_modules/@types/lodash/lastIndexOf.d.ts new file mode 100755 index 000000000..979d80dd9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/lastIndexOf.d.ts @@ -0,0 +1,2 @@ +import { lastIndexOf } from "./index"; +export = lastIndexOf; diff --git a/libs/events/node_modules/@types/lodash/lowerCase.d.ts b/libs/events/node_modules/@types/lodash/lowerCase.d.ts new file mode 100755 index 000000000..475297d8c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/lowerCase.d.ts @@ -0,0 +1,2 @@ +import { lowerCase } from "./index"; +export = lowerCase; diff --git a/libs/events/node_modules/@types/lodash/lowerFirst.d.ts b/libs/events/node_modules/@types/lodash/lowerFirst.d.ts new file mode 100755 index 000000000..0836228fc --- /dev/null +++ b/libs/events/node_modules/@types/lodash/lowerFirst.d.ts @@ -0,0 +1,2 @@ +import { lowerFirst } from "./index"; +export = lowerFirst; diff --git a/libs/events/node_modules/@types/lodash/lt.d.ts b/libs/events/node_modules/@types/lodash/lt.d.ts new file mode 100755 index 000000000..92cd4e26f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/lt.d.ts @@ -0,0 +1,2 @@ +import { lt } from "./index"; +export = lt; diff --git a/libs/events/node_modules/@types/lodash/lte.d.ts b/libs/events/node_modules/@types/lodash/lte.d.ts new file mode 100755 index 000000000..7c80f37c0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/lte.d.ts @@ -0,0 +1,2 @@ +import { lte } from "./index"; +export = lte; diff --git a/libs/events/node_modules/@types/lodash/map.d.ts b/libs/events/node_modules/@types/lodash/map.d.ts new file mode 100755 index 000000000..2f783cb7f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/map.d.ts @@ -0,0 +1,2 @@ +import { map } from "./index"; +export = map; diff --git a/libs/events/node_modules/@types/lodash/mapKeys.d.ts b/libs/events/node_modules/@types/lodash/mapKeys.d.ts new file mode 100755 index 000000000..7c7e1b5ce --- /dev/null +++ b/libs/events/node_modules/@types/lodash/mapKeys.d.ts @@ -0,0 +1,2 @@ +import { mapKeys } from "./index"; +export = mapKeys; diff --git a/libs/events/node_modules/@types/lodash/mapValues.d.ts b/libs/events/node_modules/@types/lodash/mapValues.d.ts new file mode 100755 index 000000000..3e87ea61e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/mapValues.d.ts @@ -0,0 +1,2 @@ +import { mapValues } from "./index"; +export = mapValues; diff --git a/libs/events/node_modules/@types/lodash/matches.d.ts b/libs/events/node_modules/@types/lodash/matches.d.ts new file mode 100755 index 000000000..5bb3cc268 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/matches.d.ts @@ -0,0 +1,2 @@ +import { matches } from "./index"; +export = matches; diff --git a/libs/events/node_modules/@types/lodash/matchesProperty.d.ts b/libs/events/node_modules/@types/lodash/matchesProperty.d.ts new file mode 100755 index 000000000..737849853 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/matchesProperty.d.ts @@ -0,0 +1,2 @@ +import { matchesProperty } from "./index"; +export = matchesProperty; diff --git a/libs/events/node_modules/@types/lodash/max.d.ts b/libs/events/node_modules/@types/lodash/max.d.ts new file mode 100755 index 000000000..36d064613 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/max.d.ts @@ -0,0 +1,2 @@ +import { max } from "./index"; +export = max; diff --git a/libs/events/node_modules/@types/lodash/maxBy.d.ts b/libs/events/node_modules/@types/lodash/maxBy.d.ts new file mode 100755 index 000000000..d483d95f9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/maxBy.d.ts @@ -0,0 +1,2 @@ +import { maxBy } from "./index"; +export = maxBy; diff --git a/libs/events/node_modules/@types/lodash/mean.d.ts b/libs/events/node_modules/@types/lodash/mean.d.ts new file mode 100755 index 000000000..983ad7728 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/mean.d.ts @@ -0,0 +1,2 @@ +import { mean } from "./index"; +export = mean; diff --git a/libs/events/node_modules/@types/lodash/meanBy.d.ts b/libs/events/node_modules/@types/lodash/meanBy.d.ts new file mode 100755 index 000000000..67aebbbe8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/meanBy.d.ts @@ -0,0 +1,2 @@ +import { meanBy } from "./index"; +export = meanBy; diff --git a/libs/events/node_modules/@types/lodash/memoize.d.ts b/libs/events/node_modules/@types/lodash/memoize.d.ts new file mode 100755 index 000000000..6ff535b91 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/memoize.d.ts @@ -0,0 +1,2 @@ +import { memoize } from "./index"; +export = memoize; diff --git a/libs/events/node_modules/@types/lodash/merge.d.ts b/libs/events/node_modules/@types/lodash/merge.d.ts new file mode 100755 index 000000000..eb8bd95e8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/merge.d.ts @@ -0,0 +1,2 @@ +import { merge } from "./index"; +export = merge; diff --git a/libs/events/node_modules/@types/lodash/mergeWith.d.ts b/libs/events/node_modules/@types/lodash/mergeWith.d.ts new file mode 100755 index 000000000..a58dd908b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/mergeWith.d.ts @@ -0,0 +1,2 @@ +import { mergeWith } from "./index"; +export = mergeWith; diff --git a/libs/events/node_modules/@types/lodash/method.d.ts b/libs/events/node_modules/@types/lodash/method.d.ts new file mode 100755 index 000000000..cc3058870 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/method.d.ts @@ -0,0 +1,2 @@ +import { method } from "./index"; +export = method; diff --git a/libs/events/node_modules/@types/lodash/methodOf.d.ts b/libs/events/node_modules/@types/lodash/methodOf.d.ts new file mode 100755 index 000000000..af7f19aa6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/methodOf.d.ts @@ -0,0 +1,2 @@ +import { methodOf } from "./index"; +export = methodOf; diff --git a/libs/events/node_modules/@types/lodash/min.d.ts b/libs/events/node_modules/@types/lodash/min.d.ts new file mode 100755 index 000000000..e8ba597cd --- /dev/null +++ b/libs/events/node_modules/@types/lodash/min.d.ts @@ -0,0 +1,2 @@ +import { min } from "./index"; +export = min; diff --git a/libs/events/node_modules/@types/lodash/minBy.d.ts b/libs/events/node_modules/@types/lodash/minBy.d.ts new file mode 100755 index 000000000..74860f908 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/minBy.d.ts @@ -0,0 +1,2 @@ +import { minBy } from "./index"; +export = minBy; diff --git a/libs/events/node_modules/@types/lodash/mixin.d.ts b/libs/events/node_modules/@types/lodash/mixin.d.ts new file mode 100755 index 000000000..798424679 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/mixin.d.ts @@ -0,0 +1,2 @@ +import { mixin } from "./index"; +export = mixin; diff --git a/libs/events/node_modules/@types/lodash/multiply.d.ts b/libs/events/node_modules/@types/lodash/multiply.d.ts new file mode 100755 index 000000000..dea578686 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/multiply.d.ts @@ -0,0 +1,2 @@ +import { multiply } from './index'; +export = multiply; diff --git a/libs/events/node_modules/@types/lodash/negate.d.ts b/libs/events/node_modules/@types/lodash/negate.d.ts new file mode 100755 index 000000000..46d059644 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/negate.d.ts @@ -0,0 +1,2 @@ +import { negate } from "./index"; +export = negate; diff --git a/libs/events/node_modules/@types/lodash/noConflict.d.ts b/libs/events/node_modules/@types/lodash/noConflict.d.ts new file mode 100755 index 000000000..78b3c921b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/noConflict.d.ts @@ -0,0 +1,2 @@ +import { noConflict } from "./index"; +export = noConflict; diff --git a/libs/events/node_modules/@types/lodash/noop.d.ts b/libs/events/node_modules/@types/lodash/noop.d.ts new file mode 100755 index 000000000..bfaeb880d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/noop.d.ts @@ -0,0 +1,2 @@ +import { noop } from "./index"; +export = noop; diff --git a/libs/events/node_modules/@types/lodash/now.d.ts b/libs/events/node_modules/@types/lodash/now.d.ts new file mode 100755 index 000000000..00f807eb5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/now.d.ts @@ -0,0 +1,2 @@ +import { now } from "./index"; +export = now; diff --git a/libs/events/node_modules/@types/lodash/nth.d.ts b/libs/events/node_modules/@types/lodash/nth.d.ts new file mode 100755 index 000000000..ce1013f23 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/nth.d.ts @@ -0,0 +1,2 @@ +import { nth } from "./index"; +export = nth; diff --git a/libs/events/node_modules/@types/lodash/nthArg.d.ts b/libs/events/node_modules/@types/lodash/nthArg.d.ts new file mode 100755 index 000000000..2729d70e0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/nthArg.d.ts @@ -0,0 +1,2 @@ +import { nthArg } from "./index"; +export = nthArg; diff --git a/libs/events/node_modules/@types/lodash/omit.d.ts b/libs/events/node_modules/@types/lodash/omit.d.ts new file mode 100755 index 000000000..5868a07bf --- /dev/null +++ b/libs/events/node_modules/@types/lodash/omit.d.ts @@ -0,0 +1,2 @@ +import { omit } from "./index"; +export = omit; diff --git a/libs/events/node_modules/@types/lodash/omitBy.d.ts b/libs/events/node_modules/@types/lodash/omitBy.d.ts new file mode 100755 index 000000000..41bf6b48a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/omitBy.d.ts @@ -0,0 +1,2 @@ +import { omitBy } from "./index"; +export = omitBy; diff --git a/libs/events/node_modules/@types/lodash/once.d.ts b/libs/events/node_modules/@types/lodash/once.d.ts new file mode 100755 index 000000000..4340e8805 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/once.d.ts @@ -0,0 +1,2 @@ +import { once } from "./index"; +export = once; diff --git a/libs/events/node_modules/@types/lodash/orderBy.d.ts b/libs/events/node_modules/@types/lodash/orderBy.d.ts new file mode 100755 index 000000000..02320d506 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/orderBy.d.ts @@ -0,0 +1,2 @@ +import { orderBy } from "./index"; +export = orderBy; diff --git a/libs/events/node_modules/@types/lodash/over.d.ts b/libs/events/node_modules/@types/lodash/over.d.ts new file mode 100755 index 000000000..172c822bd --- /dev/null +++ b/libs/events/node_modules/@types/lodash/over.d.ts @@ -0,0 +1,2 @@ +import { over } from "./index"; +export = over; diff --git a/libs/events/node_modules/@types/lodash/overArgs.d.ts b/libs/events/node_modules/@types/lodash/overArgs.d.ts new file mode 100755 index 000000000..f8518f68d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/overArgs.d.ts @@ -0,0 +1,2 @@ +import { overArgs } from "./index"; +export = overArgs; diff --git a/libs/events/node_modules/@types/lodash/overEvery.d.ts b/libs/events/node_modules/@types/lodash/overEvery.d.ts new file mode 100755 index 000000000..b8328fb52 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/overEvery.d.ts @@ -0,0 +1,2 @@ +import { overEvery } from "./index"; +export = overEvery; diff --git a/libs/events/node_modules/@types/lodash/overSome.d.ts b/libs/events/node_modules/@types/lodash/overSome.d.ts new file mode 100755 index 000000000..2f172581c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/overSome.d.ts @@ -0,0 +1,2 @@ +import { overSome } from "./index"; +export = overSome; diff --git a/libs/events/node_modules/@types/lodash/package.json b/libs/events/node_modules/@types/lodash/package.json new file mode 100755 index 000000000..05a49bf0e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/package.json @@ -0,0 +1,60 @@ +{ + "name": "@types/lodash", + "version": "4.14.198", + "description": "TypeScript definitions for Lo-Dash", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/lodash", + "license": "MIT", + "contributors": [ + { + "name": "Brian Zengel", + "url": "https://github.com/bczengel", + "githubUsername": "bczengel" + }, + { + "name": "Ilya Mochalov", + "url": "https://github.com/chrootsu", + "githubUsername": "chrootsu" + }, + { + "name": "AJ Richardson", + "url": "https://github.com/aj-r", + "githubUsername": "aj-r" + }, + { + "name": "e-cloud", + "url": "https://github.com/e-cloud", + "githubUsername": "e-cloud" + }, + { + "name": "Georgii Dolzhykov", + "url": "https://github.com/thorn0", + "githubUsername": "thorn0" + }, + { + "name": "Jack Moore", + "url": "https://github.com/jtmthf", + "githubUsername": "jtmthf" + }, + { + "name": "Dominique Rau", + "url": "https://github.com/DomiR", + "githubUsername": "DomiR" + }, + { + "name": "William Chelman", + "url": "https://github.com/WilliamChelman", + "githubUsername": "WilliamChelman" + } + ], + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/lodash" + }, + "scripts": {}, + "dependencies": {}, + "typesPublisherContentHash": "f5a3d945b8f87ad615d40a020989b90134bb2412bc4d695240d131d65829c6bd", + "typeScriptVersion": "4.3" +} \ No newline at end of file diff --git a/libs/events/node_modules/@types/lodash/pad.d.ts b/libs/events/node_modules/@types/lodash/pad.d.ts new file mode 100755 index 000000000..552667ada --- /dev/null +++ b/libs/events/node_modules/@types/lodash/pad.d.ts @@ -0,0 +1,2 @@ +import { pad } from "./index"; +export = pad; diff --git a/libs/events/node_modules/@types/lodash/padEnd.d.ts b/libs/events/node_modules/@types/lodash/padEnd.d.ts new file mode 100755 index 000000000..c81a7b0e1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/padEnd.d.ts @@ -0,0 +1,2 @@ +import { padEnd } from "./index"; +export = padEnd; diff --git a/libs/events/node_modules/@types/lodash/padStart.d.ts b/libs/events/node_modules/@types/lodash/padStart.d.ts new file mode 100755 index 000000000..c119c3584 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/padStart.d.ts @@ -0,0 +1,2 @@ +import { padStart } from "./index"; +export = padStart; diff --git a/libs/events/node_modules/@types/lodash/parseInt.d.ts b/libs/events/node_modules/@types/lodash/parseInt.d.ts new file mode 100755 index 000000000..de59e7be9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/parseInt.d.ts @@ -0,0 +1,2 @@ +import { parseInt } from "./index"; +export = parseInt; diff --git a/libs/events/node_modules/@types/lodash/partial.d.ts b/libs/events/node_modules/@types/lodash/partial.d.ts new file mode 100755 index 000000000..d764f6e05 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/partial.d.ts @@ -0,0 +1,2 @@ +import { partial } from "./index"; +export = partial; diff --git a/libs/events/node_modules/@types/lodash/partialRight.d.ts b/libs/events/node_modules/@types/lodash/partialRight.d.ts new file mode 100755 index 000000000..ed60160c6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/partialRight.d.ts @@ -0,0 +1,2 @@ +import { partialRight } from "./index"; +export = partialRight; diff --git a/libs/events/node_modules/@types/lodash/partition.d.ts b/libs/events/node_modules/@types/lodash/partition.d.ts new file mode 100755 index 000000000..f26ab15a5 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/partition.d.ts @@ -0,0 +1,2 @@ +import { partition } from "./index"; +export = partition; diff --git a/libs/events/node_modules/@types/lodash/pick.d.ts b/libs/events/node_modules/@types/lodash/pick.d.ts new file mode 100755 index 000000000..6d346f8f6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/pick.d.ts @@ -0,0 +1,2 @@ +import { pick } from "./index"; +export = pick; diff --git a/libs/events/node_modules/@types/lodash/pickBy.d.ts b/libs/events/node_modules/@types/lodash/pickBy.d.ts new file mode 100755 index 000000000..5285ead8f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/pickBy.d.ts @@ -0,0 +1,2 @@ +import { pickBy } from "./index"; +export = pickBy; diff --git a/libs/events/node_modules/@types/lodash/property.d.ts b/libs/events/node_modules/@types/lodash/property.d.ts new file mode 100755 index 000000000..3ff96f0e1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/property.d.ts @@ -0,0 +1,2 @@ +import { property } from "./index"; +export = property; diff --git a/libs/events/node_modules/@types/lodash/propertyOf.d.ts b/libs/events/node_modules/@types/lodash/propertyOf.d.ts new file mode 100755 index 000000000..27c628fa9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/propertyOf.d.ts @@ -0,0 +1,2 @@ +import { propertyOf } from "./index"; +export = propertyOf; diff --git a/libs/events/node_modules/@types/lodash/pull.d.ts b/libs/events/node_modules/@types/lodash/pull.d.ts new file mode 100755 index 000000000..b496ebde8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/pull.d.ts @@ -0,0 +1,2 @@ +import { pull } from "./index"; +export = pull; diff --git a/libs/events/node_modules/@types/lodash/pullAll.d.ts b/libs/events/node_modules/@types/lodash/pullAll.d.ts new file mode 100755 index 000000000..22c81c48a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/pullAll.d.ts @@ -0,0 +1,2 @@ +import { pullAll } from "./index"; +export = pullAll; diff --git a/components/search/benthos/messages/committed_transactions.json b/libs/events/node_modules/@types/lodash/pullAllBy.d.ts old mode 100644 new mode 100755 similarity index 100% rename from components/search/benthos/messages/committed_transactions.json rename to libs/events/node_modules/@types/lodash/pullAllBy.d.ts diff --git a/libs/events/node_modules/@types/lodash/pullAllWith.d.ts b/libs/events/node_modules/@types/lodash/pullAllWith.d.ts new file mode 100755 index 000000000..d3ce82980 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/pullAllWith.d.ts @@ -0,0 +1,2 @@ +import { pullAllWith } from "./index"; +export = pullAllWith; diff --git a/libs/events/node_modules/@types/lodash/pullAt.d.ts b/libs/events/node_modules/@types/lodash/pullAt.d.ts new file mode 100755 index 000000000..47be38253 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/pullAt.d.ts @@ -0,0 +1,2 @@ +import { pullAt } from "./index"; +export = pullAt; diff --git a/libs/events/node_modules/@types/lodash/random.d.ts b/libs/events/node_modules/@types/lodash/random.d.ts new file mode 100755 index 000000000..a68cc2720 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/random.d.ts @@ -0,0 +1,2 @@ +import { random } from "./index"; +export = random; diff --git a/libs/events/node_modules/@types/lodash/range.d.ts b/libs/events/node_modules/@types/lodash/range.d.ts new file mode 100755 index 000000000..8f737ca5e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/range.d.ts @@ -0,0 +1,2 @@ +import { range } from "./index"; +export = range; diff --git a/libs/events/node_modules/@types/lodash/rangeRight.d.ts b/libs/events/node_modules/@types/lodash/rangeRight.d.ts new file mode 100755 index 000000000..cabd0ed7c --- /dev/null +++ b/libs/events/node_modules/@types/lodash/rangeRight.d.ts @@ -0,0 +1,2 @@ +import { rangeRight } from "./index"; +export = rangeRight; diff --git a/libs/events/node_modules/@types/lodash/rearg.d.ts b/libs/events/node_modules/@types/lodash/rearg.d.ts new file mode 100755 index 000000000..7684e867b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/rearg.d.ts @@ -0,0 +1,2 @@ +import { rearg } from "./index"; +export = rearg; diff --git a/libs/events/node_modules/@types/lodash/reduce.d.ts b/libs/events/node_modules/@types/lodash/reduce.d.ts new file mode 100755 index 000000000..4765fcd90 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/reduce.d.ts @@ -0,0 +1,2 @@ +import { reduce } from "./index"; +export = reduce; diff --git a/libs/events/node_modules/@types/lodash/reduceRight.d.ts b/libs/events/node_modules/@types/lodash/reduceRight.d.ts new file mode 100755 index 000000000..1cfdb5f80 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/reduceRight.d.ts @@ -0,0 +1,2 @@ +import { reduceRight } from "./index"; +export = reduceRight; diff --git a/libs/events/node_modules/@types/lodash/reject.d.ts b/libs/events/node_modules/@types/lodash/reject.d.ts new file mode 100755 index 000000000..aabc14131 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/reject.d.ts @@ -0,0 +1,2 @@ +import { reject } from "./index"; +export = reject; diff --git a/libs/events/node_modules/@types/lodash/remove.d.ts b/libs/events/node_modules/@types/lodash/remove.d.ts new file mode 100755 index 000000000..dca471886 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/remove.d.ts @@ -0,0 +1,2 @@ +import { remove } from "./index"; +export = remove; diff --git a/libs/events/node_modules/@types/lodash/repeat.d.ts b/libs/events/node_modules/@types/lodash/repeat.d.ts new file mode 100755 index 000000000..ca3c7fcb2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/repeat.d.ts @@ -0,0 +1,2 @@ +import { repeat } from "./index"; +export = repeat; diff --git a/libs/events/node_modules/@types/lodash/replace.d.ts b/libs/events/node_modules/@types/lodash/replace.d.ts new file mode 100755 index 000000000..701541126 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/replace.d.ts @@ -0,0 +1,2 @@ +import { replace } from "./index"; +export = replace; diff --git a/libs/events/node_modules/@types/lodash/rest.d.ts b/libs/events/node_modules/@types/lodash/rest.d.ts new file mode 100755 index 000000000..433a4fde7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/rest.d.ts @@ -0,0 +1,2 @@ +import { rest } from "./index"; +export = rest; diff --git a/libs/events/node_modules/@types/lodash/result.d.ts b/libs/events/node_modules/@types/lodash/result.d.ts new file mode 100755 index 000000000..65786428e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/result.d.ts @@ -0,0 +1,2 @@ +import { result } from "./index"; +export = result; diff --git a/libs/events/node_modules/@types/lodash/reverse.d.ts b/libs/events/node_modules/@types/lodash/reverse.d.ts new file mode 100755 index 000000000..ecef17389 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/reverse.d.ts @@ -0,0 +1,2 @@ +import { reverse } from "./index"; +export = reverse; diff --git a/libs/events/node_modules/@types/lodash/round.d.ts b/libs/events/node_modules/@types/lodash/round.d.ts new file mode 100755 index 000000000..ed2c17926 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/round.d.ts @@ -0,0 +1,2 @@ +import { round } from "./index"; +export = round; diff --git a/libs/events/node_modules/@types/lodash/runInContext.d.ts b/libs/events/node_modules/@types/lodash/runInContext.d.ts new file mode 100755 index 000000000..9ee01f324 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/runInContext.d.ts @@ -0,0 +1,2 @@ +import { runInContext } from "./index"; +export = runInContext; diff --git a/libs/events/node_modules/@types/lodash/sample.d.ts b/libs/events/node_modules/@types/lodash/sample.d.ts new file mode 100755 index 000000000..c22517869 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sample.d.ts @@ -0,0 +1,2 @@ +import { sample } from "./index"; +export = sample; diff --git a/libs/events/node_modules/@types/lodash/sampleSize.d.ts b/libs/events/node_modules/@types/lodash/sampleSize.d.ts new file mode 100755 index 000000000..0f1ed89ee --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sampleSize.d.ts @@ -0,0 +1,2 @@ +import { sampleSize } from "./index"; +export = sampleSize; diff --git a/libs/events/node_modules/@types/lodash/set.d.ts b/libs/events/node_modules/@types/lodash/set.d.ts new file mode 100755 index 000000000..09d0c2470 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/set.d.ts @@ -0,0 +1,2 @@ +import { set } from "./index"; +export = set; diff --git a/libs/events/node_modules/@types/lodash/setWith.d.ts b/libs/events/node_modules/@types/lodash/setWith.d.ts new file mode 100755 index 000000000..d4e319a05 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/setWith.d.ts @@ -0,0 +1,2 @@ +import { setWith } from "./index"; +export = setWith; diff --git a/libs/events/node_modules/@types/lodash/shuffle.d.ts b/libs/events/node_modules/@types/lodash/shuffle.d.ts new file mode 100755 index 000000000..ff96f884b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/shuffle.d.ts @@ -0,0 +1,2 @@ +import { shuffle } from "./index"; +export = shuffle; diff --git a/libs/events/node_modules/@types/lodash/size.d.ts b/libs/events/node_modules/@types/lodash/size.d.ts new file mode 100755 index 000000000..13d492f39 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/size.d.ts @@ -0,0 +1,2 @@ +import { size } from "./index"; +export = size; diff --git a/libs/events/node_modules/@types/lodash/slice.d.ts b/libs/events/node_modules/@types/lodash/slice.d.ts new file mode 100755 index 000000000..311d2fa5d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/slice.d.ts @@ -0,0 +1,2 @@ +import { slice } from "./index"; +export = slice; diff --git a/libs/events/node_modules/@types/lodash/snakeCase.d.ts b/libs/events/node_modules/@types/lodash/snakeCase.d.ts new file mode 100755 index 000000000..8245a7da1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/snakeCase.d.ts @@ -0,0 +1,2 @@ +import { snakeCase } from "./index"; +export = snakeCase; diff --git a/libs/events/node_modules/@types/lodash/some.d.ts b/libs/events/node_modules/@types/lodash/some.d.ts new file mode 100755 index 000000000..90ef478bb --- /dev/null +++ b/libs/events/node_modules/@types/lodash/some.d.ts @@ -0,0 +1,2 @@ +import { some } from "./index"; +export = some; diff --git a/libs/events/node_modules/@types/lodash/sortBy.d.ts b/libs/events/node_modules/@types/lodash/sortBy.d.ts new file mode 100755 index 000000000..5f3d4f2a7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sortBy.d.ts @@ -0,0 +1,2 @@ +import { sortBy } from "./index"; +export = sortBy; diff --git a/libs/events/node_modules/@types/lodash/sortedIndex.d.ts b/libs/events/node_modules/@types/lodash/sortedIndex.d.ts new file mode 100755 index 000000000..c9c79114d --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sortedIndex.d.ts @@ -0,0 +1,2 @@ +import { sortedIndex } from "./index"; +export = sortedIndex; diff --git a/libs/events/node_modules/@types/lodash/sortedIndexBy.d.ts b/libs/events/node_modules/@types/lodash/sortedIndexBy.d.ts new file mode 100755 index 000000000..fdbedac57 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sortedIndexBy.d.ts @@ -0,0 +1,2 @@ +import { sortedIndexBy } from "./index"; +export = sortedIndexBy; diff --git a/libs/events/node_modules/@types/lodash/sortedIndexOf.d.ts b/libs/events/node_modules/@types/lodash/sortedIndexOf.d.ts new file mode 100755 index 000000000..a076c4a40 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sortedIndexOf.d.ts @@ -0,0 +1,2 @@ +import { sortedIndexOf } from "./index"; +export = sortedIndexOf; diff --git a/libs/events/node_modules/@types/lodash/sortedLastIndex.d.ts b/libs/events/node_modules/@types/lodash/sortedLastIndex.d.ts new file mode 100755 index 000000000..808c2c0ff --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sortedLastIndex.d.ts @@ -0,0 +1,2 @@ +import { sortedLastIndex } from "./index"; +export = sortedLastIndex; diff --git a/libs/events/node_modules/@types/lodash/sortedLastIndexBy.d.ts b/libs/events/node_modules/@types/lodash/sortedLastIndexBy.d.ts new file mode 100755 index 000000000..9f23b9b83 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sortedLastIndexBy.d.ts @@ -0,0 +1,2 @@ +import { sortedLastIndexBy } from "./index"; +export = sortedLastIndexBy; diff --git a/libs/events/node_modules/@types/lodash/sortedLastIndexOf.d.ts b/libs/events/node_modules/@types/lodash/sortedLastIndexOf.d.ts new file mode 100755 index 000000000..abdeba024 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sortedLastIndexOf.d.ts @@ -0,0 +1,2 @@ +import { sortedLastIndexOf } from "./index"; +export = sortedLastIndexOf; diff --git a/libs/events/node_modules/@types/lodash/sortedUniq.d.ts b/libs/events/node_modules/@types/lodash/sortedUniq.d.ts new file mode 100755 index 000000000..257d35aea --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sortedUniq.d.ts @@ -0,0 +1,2 @@ +import { sortedUniq } from "./index"; +export = sortedUniq; diff --git a/libs/events/node_modules/@types/lodash/sortedUniqBy.d.ts b/libs/events/node_modules/@types/lodash/sortedUniqBy.d.ts new file mode 100755 index 000000000..316156ec2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sortedUniqBy.d.ts @@ -0,0 +1,2 @@ +import { sortedUniqBy } from "./index"; +export = sortedUniqBy; diff --git a/libs/events/node_modules/@types/lodash/split.d.ts b/libs/events/node_modules/@types/lodash/split.d.ts new file mode 100755 index 000000000..8879eb004 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/split.d.ts @@ -0,0 +1,2 @@ +import { split } from "./index"; +export = split; diff --git a/libs/events/node_modules/@types/lodash/spread.d.ts b/libs/events/node_modules/@types/lodash/spread.d.ts new file mode 100755 index 000000000..4f816b2ab --- /dev/null +++ b/libs/events/node_modules/@types/lodash/spread.d.ts @@ -0,0 +1,2 @@ +import { spread } from "./index"; +export = spread; diff --git a/libs/events/node_modules/@types/lodash/startCase.d.ts b/libs/events/node_modules/@types/lodash/startCase.d.ts new file mode 100755 index 000000000..c201a11c6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/startCase.d.ts @@ -0,0 +1,2 @@ +import { startCase } from "./index"; +export = startCase; diff --git a/libs/events/node_modules/@types/lodash/startsWith.d.ts b/libs/events/node_modules/@types/lodash/startsWith.d.ts new file mode 100755 index 000000000..a18b54f58 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/startsWith.d.ts @@ -0,0 +1,2 @@ +import { startsWith } from "./index"; +export = startsWith; diff --git a/libs/events/node_modules/@types/lodash/stubFalse.d.ts b/libs/events/node_modules/@types/lodash/stubFalse.d.ts new file mode 100755 index 000000000..fea47b716 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/stubFalse.d.ts @@ -0,0 +1,2 @@ +import { stubFalse } from "./index"; +export = stubFalse; diff --git a/libs/events/node_modules/@types/lodash/stubTrue.d.ts b/libs/events/node_modules/@types/lodash/stubTrue.d.ts new file mode 100755 index 000000000..f2d4cf099 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/stubTrue.d.ts @@ -0,0 +1,2 @@ +import { stubTrue } from "./index"; +export = stubTrue; diff --git a/libs/events/node_modules/@types/lodash/subtract.d.ts b/libs/events/node_modules/@types/lodash/subtract.d.ts new file mode 100755 index 000000000..6502fe2f4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/subtract.d.ts @@ -0,0 +1,2 @@ +import { subtract } from "./index"; +export = subtract; diff --git a/libs/events/node_modules/@types/lodash/sum.d.ts b/libs/events/node_modules/@types/lodash/sum.d.ts new file mode 100755 index 000000000..4e01cb4aa --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sum.d.ts @@ -0,0 +1,2 @@ +import { sum } from "./index"; +export = sum; diff --git a/libs/events/node_modules/@types/lodash/sumBy.d.ts b/libs/events/node_modules/@types/lodash/sumBy.d.ts new file mode 100755 index 000000000..92c4342aa --- /dev/null +++ b/libs/events/node_modules/@types/lodash/sumBy.d.ts @@ -0,0 +1,2 @@ +import { sumBy } from "./index"; +export = sumBy; diff --git a/libs/events/node_modules/@types/lodash/tail.d.ts b/libs/events/node_modules/@types/lodash/tail.d.ts new file mode 100755 index 000000000..2d80b444b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/tail.d.ts @@ -0,0 +1,2 @@ +import { tail } from "./index"; +export = tail; diff --git a/libs/events/node_modules/@types/lodash/take.d.ts b/libs/events/node_modules/@types/lodash/take.d.ts new file mode 100755 index 000000000..be9912245 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/take.d.ts @@ -0,0 +1,2 @@ +import { take } from "./index"; +export = take; diff --git a/libs/events/node_modules/@types/lodash/takeRight.d.ts b/libs/events/node_modules/@types/lodash/takeRight.d.ts new file mode 100755 index 000000000..9d7886647 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/takeRight.d.ts @@ -0,0 +1,2 @@ +import { takeRight } from "./index"; +export = takeRight; diff --git a/libs/events/node_modules/@types/lodash/takeRightWhile.d.ts b/libs/events/node_modules/@types/lodash/takeRightWhile.d.ts new file mode 100755 index 000000000..3b293de7a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/takeRightWhile.d.ts @@ -0,0 +1,2 @@ +import { takeRightWhile } from "./index"; +export = takeRightWhile; diff --git a/libs/events/node_modules/@types/lodash/takeWhile.d.ts b/libs/events/node_modules/@types/lodash/takeWhile.d.ts new file mode 100755 index 000000000..088234a8a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/takeWhile.d.ts @@ -0,0 +1,2 @@ +import { takeWhile } from "./index"; +export = takeWhile; diff --git a/libs/events/node_modules/@types/lodash/tap.d.ts b/libs/events/node_modules/@types/lodash/tap.d.ts new file mode 100755 index 000000000..e15a13cf4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/tap.d.ts @@ -0,0 +1,2 @@ +import { tap } from "./index"; +export = tap; diff --git a/libs/events/node_modules/@types/lodash/template.d.ts b/libs/events/node_modules/@types/lodash/template.d.ts new file mode 100755 index 000000000..854e7539b --- /dev/null +++ b/libs/events/node_modules/@types/lodash/template.d.ts @@ -0,0 +1,2 @@ +import { template } from "./index"; +export = template; diff --git a/libs/events/node_modules/@types/lodash/throttle.d.ts b/libs/events/node_modules/@types/lodash/throttle.d.ts new file mode 100755 index 000000000..2650896a0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/throttle.d.ts @@ -0,0 +1,2 @@ +import { throttle } from "./index"; +export = throttle; diff --git a/libs/events/node_modules/@types/lodash/thru.d.ts b/libs/events/node_modules/@types/lodash/thru.d.ts new file mode 100755 index 000000000..0447e1271 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/thru.d.ts @@ -0,0 +1,2 @@ +import { thru } from "./index"; +export = thru; diff --git a/libs/events/node_modules/@types/lodash/times.d.ts b/libs/events/node_modules/@types/lodash/times.d.ts new file mode 100755 index 000000000..7fda4de03 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/times.d.ts @@ -0,0 +1,2 @@ +import { times } from "./index"; +export = times; diff --git a/libs/events/node_modules/@types/lodash/toArray.d.ts b/libs/events/node_modules/@types/lodash/toArray.d.ts new file mode 100755 index 000000000..dd94c8a96 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toArray.d.ts @@ -0,0 +1,2 @@ +import { toArray } from "./index"; +export = toArray; diff --git a/libs/events/node_modules/@types/lodash/toFinite.d.ts b/libs/events/node_modules/@types/lodash/toFinite.d.ts new file mode 100755 index 000000000..c575b4784 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toFinite.d.ts @@ -0,0 +1,2 @@ +import { toFinite } from "./index"; +export = toFinite; diff --git a/libs/events/node_modules/@types/lodash/toInteger.d.ts b/libs/events/node_modules/@types/lodash/toInteger.d.ts new file mode 100755 index 000000000..021a9c089 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toInteger.d.ts @@ -0,0 +1,2 @@ +import { toInteger } from "./index"; +export = toInteger; diff --git a/libs/events/node_modules/@types/lodash/toLength.d.ts b/libs/events/node_modules/@types/lodash/toLength.d.ts new file mode 100755 index 000000000..41a4098c2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toLength.d.ts @@ -0,0 +1,2 @@ +import { toLength } from "./index"; +export = toLength; diff --git a/libs/events/node_modules/@types/lodash/toLower.d.ts b/libs/events/node_modules/@types/lodash/toLower.d.ts new file mode 100755 index 000000000..766c173ee --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toLower.d.ts @@ -0,0 +1,2 @@ +import { toLower } from "./index"; +export = toLower; diff --git a/libs/events/node_modules/@types/lodash/toNumber.d.ts b/libs/events/node_modules/@types/lodash/toNumber.d.ts new file mode 100755 index 000000000..a6c5e1fc0 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toNumber.d.ts @@ -0,0 +1,2 @@ +import { toNumber } from "./index"; +export = toNumber; diff --git a/libs/events/node_modules/@types/lodash/toPairs.d.ts b/libs/events/node_modules/@types/lodash/toPairs.d.ts new file mode 100755 index 000000000..4a7846ed2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toPairs.d.ts @@ -0,0 +1,2 @@ +import { toPairs } from "./index"; +export = toPairs; diff --git a/libs/events/node_modules/@types/lodash/toPairsIn.d.ts b/libs/events/node_modules/@types/lodash/toPairsIn.d.ts new file mode 100755 index 000000000..82d71b3f4 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toPairsIn.d.ts @@ -0,0 +1,2 @@ +import { toPairsIn } from "./index"; +export = toPairsIn; diff --git a/libs/events/node_modules/@types/lodash/toPath.d.ts b/libs/events/node_modules/@types/lodash/toPath.d.ts new file mode 100755 index 000000000..ff354e5d3 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toPath.d.ts @@ -0,0 +1,2 @@ +import { toPath } from "./index"; +export = toPath; diff --git a/libs/events/node_modules/@types/lodash/toPlainObject.d.ts b/libs/events/node_modules/@types/lodash/toPlainObject.d.ts new file mode 100755 index 000000000..0561ab6cd --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toPlainObject.d.ts @@ -0,0 +1,2 @@ +import { toPlainObject } from "./index"; +export = toPlainObject; diff --git a/libs/events/node_modules/@types/lodash/toSafeInteger.d.ts b/libs/events/node_modules/@types/lodash/toSafeInteger.d.ts new file mode 100755 index 000000000..6bb24d895 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toSafeInteger.d.ts @@ -0,0 +1,2 @@ +import { toSafeInteger } from "./index"; +export = toSafeInteger; diff --git a/libs/events/node_modules/@types/lodash/toString.d.ts b/libs/events/node_modules/@types/lodash/toString.d.ts new file mode 100755 index 000000000..7765d108a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toString.d.ts @@ -0,0 +1,2 @@ +import { toString } from "./index"; +export = toString; diff --git a/libs/events/node_modules/@types/lodash/toUpper.d.ts b/libs/events/node_modules/@types/lodash/toUpper.d.ts new file mode 100755 index 000000000..af4304122 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/toUpper.d.ts @@ -0,0 +1,2 @@ +import { toUpper } from "./index"; +export = toUpper; diff --git a/libs/events/node_modules/@types/lodash/transform.d.ts b/libs/events/node_modules/@types/lodash/transform.d.ts new file mode 100755 index 000000000..05e654341 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/transform.d.ts @@ -0,0 +1,2 @@ +import { transform } from "./index"; +export = transform; diff --git a/libs/events/node_modules/@types/lodash/trim.d.ts b/libs/events/node_modules/@types/lodash/trim.d.ts new file mode 100755 index 000000000..7d0bf90b7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/trim.d.ts @@ -0,0 +1,2 @@ +import { trim } from "./index"; +export = trim; diff --git a/libs/events/node_modules/@types/lodash/trimEnd.d.ts b/libs/events/node_modules/@types/lodash/trimEnd.d.ts new file mode 100755 index 000000000..b80c84481 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/trimEnd.d.ts @@ -0,0 +1,2 @@ +import { trimEnd } from "./index"; +export = trimEnd; diff --git a/libs/events/node_modules/@types/lodash/trimStart.d.ts b/libs/events/node_modules/@types/lodash/trimStart.d.ts new file mode 100755 index 000000000..a040712eb --- /dev/null +++ b/libs/events/node_modules/@types/lodash/trimStart.d.ts @@ -0,0 +1,2 @@ +import { trimStart } from "./index"; +export = trimStart; diff --git a/libs/events/node_modules/@types/lodash/truncate.d.ts b/libs/events/node_modules/@types/lodash/truncate.d.ts new file mode 100755 index 000000000..0ae065b30 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/truncate.d.ts @@ -0,0 +1,2 @@ +import { truncate } from "./index"; +export = truncate; diff --git a/libs/events/node_modules/@types/lodash/unary.d.ts b/libs/events/node_modules/@types/lodash/unary.d.ts new file mode 100755 index 000000000..44569978f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/unary.d.ts @@ -0,0 +1,2 @@ +import { unary } from "./index"; +export = unary; diff --git a/libs/events/node_modules/@types/lodash/unescape.d.ts b/libs/events/node_modules/@types/lodash/unescape.d.ts new file mode 100755 index 000000000..71ba85d89 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/unescape.d.ts @@ -0,0 +1,2 @@ +import { unescape } from "./index"; +export = unescape; diff --git a/libs/events/node_modules/@types/lodash/union.d.ts b/libs/events/node_modules/@types/lodash/union.d.ts new file mode 100755 index 000000000..7b12e92f6 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/union.d.ts @@ -0,0 +1,2 @@ +import { union } from "./index"; +export = union; diff --git a/libs/events/node_modules/@types/lodash/unionBy.d.ts b/libs/events/node_modules/@types/lodash/unionBy.d.ts new file mode 100755 index 000000000..0cb199245 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/unionBy.d.ts @@ -0,0 +1,2 @@ +import { unionBy } from "./index"; +export = unionBy; diff --git a/libs/events/node_modules/@types/lodash/unionWith.d.ts b/libs/events/node_modules/@types/lodash/unionWith.d.ts new file mode 100755 index 000000000..9888092f8 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/unionWith.d.ts @@ -0,0 +1,2 @@ +import { unionWith } from "./index"; +export = unionWith; diff --git a/libs/events/node_modules/@types/lodash/uniq.d.ts b/libs/events/node_modules/@types/lodash/uniq.d.ts new file mode 100755 index 000000000..6c105ac3e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/uniq.d.ts @@ -0,0 +1,2 @@ +import { uniq } from "./index"; +export = uniq; diff --git a/libs/events/node_modules/@types/lodash/uniqBy.d.ts b/libs/events/node_modules/@types/lodash/uniqBy.d.ts new file mode 100755 index 000000000..7101b0e30 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/uniqBy.d.ts @@ -0,0 +1,2 @@ +import { uniqBy } from "./index"; +export = uniqBy; diff --git a/libs/events/node_modules/@types/lodash/uniqWith.d.ts b/libs/events/node_modules/@types/lodash/uniqWith.d.ts new file mode 100755 index 000000000..72c3f8fc1 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/uniqWith.d.ts @@ -0,0 +1,2 @@ +import { uniqWith } from "./index"; +export = uniqWith; diff --git a/libs/events/node_modules/@types/lodash/uniqueId.d.ts b/libs/events/node_modules/@types/lodash/uniqueId.d.ts new file mode 100755 index 000000000..4ea55f92f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/uniqueId.d.ts @@ -0,0 +1,2 @@ +import { uniqueId } from "./index"; +export = uniqueId; diff --git a/libs/events/node_modules/@types/lodash/unset.d.ts b/libs/events/node_modules/@types/lodash/unset.d.ts new file mode 100755 index 000000000..1eac8ddb7 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/unset.d.ts @@ -0,0 +1,2 @@ +import { unset } from "./index"; +export = unset; diff --git a/libs/events/node_modules/@types/lodash/unzip.d.ts b/libs/events/node_modules/@types/lodash/unzip.d.ts new file mode 100755 index 000000000..7e320a27f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/unzip.d.ts @@ -0,0 +1,2 @@ +import { unzip } from "./index"; +export = unzip; diff --git a/libs/events/node_modules/@types/lodash/unzipWith.d.ts b/libs/events/node_modules/@types/lodash/unzipWith.d.ts new file mode 100755 index 000000000..2bf5394b2 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/unzipWith.d.ts @@ -0,0 +1,2 @@ +import { unzipWith } from "./index"; +export = unzipWith; diff --git a/libs/events/node_modules/@types/lodash/update.d.ts b/libs/events/node_modules/@types/lodash/update.d.ts new file mode 100755 index 000000000..d072c0fe9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/update.d.ts @@ -0,0 +1,2 @@ +import { update } from "./index"; +export = update; diff --git a/libs/events/node_modules/@types/lodash/updateWith.d.ts b/libs/events/node_modules/@types/lodash/updateWith.d.ts new file mode 100755 index 000000000..44175423e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/updateWith.d.ts @@ -0,0 +1,2 @@ +import { updateWith } from "./index"; +export = updateWith; diff --git a/libs/events/node_modules/@types/lodash/upperCase.d.ts b/libs/events/node_modules/@types/lodash/upperCase.d.ts new file mode 100755 index 000000000..c33598a93 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/upperCase.d.ts @@ -0,0 +1,2 @@ +import { upperCase } from "./index"; +export = upperCase; diff --git a/libs/events/node_modules/@types/lodash/upperFirst.d.ts b/libs/events/node_modules/@types/lodash/upperFirst.d.ts new file mode 100755 index 000000000..1f1b2a798 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/upperFirst.d.ts @@ -0,0 +1,2 @@ +import { upperFirst } from "./index"; +export = upperFirst; diff --git a/libs/events/node_modules/@types/lodash/values.d.ts b/libs/events/node_modules/@types/lodash/values.d.ts new file mode 100755 index 000000000..2015ebf8a --- /dev/null +++ b/libs/events/node_modules/@types/lodash/values.d.ts @@ -0,0 +1,2 @@ +import { values } from "./index"; +export = values; diff --git a/libs/events/node_modules/@types/lodash/valuesIn.d.ts b/libs/events/node_modules/@types/lodash/valuesIn.d.ts new file mode 100755 index 000000000..6f8d6a3ef --- /dev/null +++ b/libs/events/node_modules/@types/lodash/valuesIn.d.ts @@ -0,0 +1,2 @@ +import { valuesIn } from "./index"; +export = valuesIn; diff --git a/libs/events/node_modules/@types/lodash/without.d.ts b/libs/events/node_modules/@types/lodash/without.d.ts new file mode 100755 index 000000000..bbdfe163e --- /dev/null +++ b/libs/events/node_modules/@types/lodash/without.d.ts @@ -0,0 +1,2 @@ +import { without } from "./index"; +export = without; diff --git a/libs/events/node_modules/@types/lodash/words.d.ts b/libs/events/node_modules/@types/lodash/words.d.ts new file mode 100755 index 000000000..22da6cb94 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/words.d.ts @@ -0,0 +1,2 @@ +import { words } from "./index"; +export = words; diff --git a/libs/events/node_modules/@types/lodash/wrap.d.ts b/libs/events/node_modules/@types/lodash/wrap.d.ts new file mode 100755 index 000000000..3c20f28ed --- /dev/null +++ b/libs/events/node_modules/@types/lodash/wrap.d.ts @@ -0,0 +1,2 @@ +import { wrap } from "./index"; +export = wrap; diff --git a/libs/events/node_modules/@types/lodash/xor.d.ts b/libs/events/node_modules/@types/lodash/xor.d.ts new file mode 100755 index 000000000..894735c45 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/xor.d.ts @@ -0,0 +1,2 @@ +import { xor } from "./index"; +export = xor; diff --git a/libs/events/node_modules/@types/lodash/xorBy.d.ts b/libs/events/node_modules/@types/lodash/xorBy.d.ts new file mode 100755 index 000000000..6a08c6a87 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/xorBy.d.ts @@ -0,0 +1,2 @@ +import { xorBy } from "./index"; +export = xorBy; diff --git a/libs/events/node_modules/@types/lodash/xorWith.d.ts b/libs/events/node_modules/@types/lodash/xorWith.d.ts new file mode 100755 index 000000000..7cdcaf339 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/xorWith.d.ts @@ -0,0 +1,2 @@ +import { xorWith } from "./index"; +export = xorWith; diff --git a/libs/events/node_modules/@types/lodash/zip.d.ts b/libs/events/node_modules/@types/lodash/zip.d.ts new file mode 100755 index 000000000..e7467cdf9 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/zip.d.ts @@ -0,0 +1,2 @@ +import { zip } from "./index"; +export = zip; diff --git a/libs/events/node_modules/@types/lodash/zipObject.d.ts b/libs/events/node_modules/@types/lodash/zipObject.d.ts new file mode 100755 index 000000000..ad049fd15 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/zipObject.d.ts @@ -0,0 +1,2 @@ +import { zipObject } from "./index"; +export = zipObject; diff --git a/libs/events/node_modules/@types/lodash/zipObjectDeep.d.ts b/libs/events/node_modules/@types/lodash/zipObjectDeep.d.ts new file mode 100755 index 000000000..2a483e839 --- /dev/null +++ b/libs/events/node_modules/@types/lodash/zipObjectDeep.d.ts @@ -0,0 +1,2 @@ +import { zipObjectDeep } from "./index"; +export = zipObjectDeep; diff --git a/libs/events/node_modules/@types/lodash/zipWith.d.ts b/libs/events/node_modules/@types/lodash/zipWith.d.ts new file mode 100755 index 000000000..48693742f --- /dev/null +++ b/libs/events/node_modules/@types/lodash/zipWith.d.ts @@ -0,0 +1,2 @@ +import { zipWith } from "./index"; +export = zipWith; diff --git a/libs/events/node_modules/ajv-formats/LICENSE b/libs/events/node_modules/ajv-formats/LICENSE new file mode 100644 index 000000000..a3f8ba027 --- /dev/null +++ b/libs/events/node_modules/ajv-formats/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Evgeny Poberezkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/ajv-formats/README.md b/libs/events/node_modules/ajv-formats/README.md new file mode 100644 index 000000000..5b4706dc1 --- /dev/null +++ b/libs/events/node_modules/ajv-formats/README.md @@ -0,0 +1,123 @@ +# ajv-formats + +JSON Schema formats for Ajv + +[![Build Status](https://travis-ci.org/ajv-validator/ajv-formats.svg?branch=master)](https://travis-ci.org/ajv-validator/ajv-formats) +[![npm](https://img.shields.io/npm/v/ajv-formats.svg)](https://www.npmjs.com/package/ajv-formats) +[![Gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv) +[![GitHub Sponsors](https://img.shields.io/badge/$-sponsors-brightgreen)](https://github.com/sponsors/epoberezkin) + +## Usage + +```javascript +// ESM/TypeScript import +import Ajv from "ajv" +import addFormats from "ajv-formats" +// Node.js require: +const Ajv = require("ajv") +const addFormats = require("ajv-formats") + +const ajv = new Ajv() +addFormats(ajv) +``` + +## Formats + +The package defines these formats: + +- _date_: full-date according to [RFC3339](http://tools.ietf.org/html/rfc3339#section-5.6). +- _time_: time with optional time-zone. +- _date-time_: date-time from the same source (time-zone is mandatory). +- _duration_: duration from [RFC3339](https://tools.ietf.org/html/rfc3339#appendix-A) +- _uri_: full URI. +- _uri-reference_: URI reference, including full and relative URIs. +- _uri-template_: URI template according to [RFC6570](https://tools.ietf.org/html/rfc6570) +- _url_ (deprecated): [URL record](https://url.spec.whatwg.org/#concept-url). +- _email_: email address. +- _hostname_: host name according to [RFC1034](http://tools.ietf.org/html/rfc1034#section-3.5). +- _ipv4_: IP address v4. +- _ipv6_: IP address v6. +- _regex_: tests whether a string is a valid regular expression by passing it to RegExp constructor. +- _uuid_: Universally Unique IDentifier according to [RFC4122](http://tools.ietf.org/html/rfc4122). +- _json-pointer_: JSON-pointer according to [RFC6901](https://tools.ietf.org/html/rfc6901). +- _relative-json-pointer_: relative JSON-pointer according to [this draft](http://tools.ietf.org/html/draft-luff-relative-json-pointer-00). +- _byte_: base64 encoded data according to the [openApi 3.0.0 specification](https://spec.openapis.org/oas/v3.0.0#data-types) +- _int32_: signed 32 bits integer according to the [openApi 3.0.0 specification](https://spec.openapis.org/oas/v3.0.0#data-types) +- _int64_: signed 64 bits according to the [openApi 3.0.0 specification](https://spec.openapis.org/oas/v3.0.0#data-types) +- _float_: float according to the [openApi 3.0.0 specification](https://spec.openapis.org/oas/v3.0.0#data-types) +- _double_: double according to the [openApi 3.0.0 specification](https://spec.openapis.org/oas/v3.0.0#data-types) +- _password_: password string according to the [openApi 3.0.0 specification](https://spec.openapis.org/oas/v3.0.0#data-types) +- _binary_: binary string according to the [openApi 3.0.0 specification](https://spec.openapis.org/oas/v3.0.0#data-types) + +See regular expressions used for format validation and the sources that were used in [formats.ts](https://github.com/ajv-validator/ajv-formats/blob/master/src/formats.ts). + +**Please note**: JSON Schema draft-07 also defines formats `iri`, `iri-reference`, `idn-hostname` and `idn-email` for URLs, hostnames and emails with international characters. These formats are available in [ajv-formats-draft2019](https://github.com/luzlab/ajv-formats-draft2019) plugin. + +## Keywords to compare values: `formatMaximum` / `formatMinimum` and `formatExclusiveMaximum` / `formatExclusiveMinimum` + +These keywords allow to define minimum/maximum constraints when the format keyword defines ordering (`compare` function in format definition). + +These keywords are added to ajv instance when ajv-formats is used without options or with option `keywords: true`. + +These keywords apply only to strings. If the data is not a string, the validation succeeds. + +The value of keywords `formatMaximum`/`formatMinimum` and `formatExclusiveMaximum`/`formatExclusiveMinimum` should be a string or [\$data reference](https://github.com/ajv-validator/ajv/blob/master/docs/validation.md#data-reference). This value is the maximum (minimum) allowed value for the data to be valid as determined by `format` keyword. If `format` keyword is not present schema compilation will throw exception. + +When these keyword are added, they also add comparison functions to formats `"date"`, `"time"` and `"date-time"`. User-defined formats also can have comparison functions. See [addFormat](https://github.com/ajv-validator/ajv/blob/master/docs/api.md#api-addformat) method. + +```javascript +require("ajv-formats")(ajv) + +const schema = { + type: "string", + format: "date", + formatMinimum: "2016-02-06", + formatExclusiveMaximum: "2016-12-27", +} + +const validDataList = ["2016-02-06", "2016-12-26"] + +const invalidDataList = ["2016-02-05", "2016-12-27", "abc"] +``` + +## Options + +Options can be passed via the second parameter. Options value can be + +1. The list of format names that will be added to ajv instance: + +```javascript +addFormats(ajv, ["date", "time"]) +``` + +**Please note**: when ajv encounters an undefined format it throws exception (unless ajv instance was configured with `strict: false` option). To allow specific undefined formats they have to be passed to ajv instance via `formats` option with `true` value: + +```javascript +const ajv = new Ajv((formats: {date: true, time: true})) // to ignore "date" and "time" formats in schemas. +``` + +2. Format validation mode (default is `"full"`) with optional list of format names and `keywords` option to add additional format comparison keywords: + +```javascript +addFormats(ajv, {mode: "fast"}) +``` + +or + +```javascript +addFormats(ajv, {mode: "fast", formats: ["date", "time"], keywords: true}) +``` + +In `"fast"` mode the following formats are simplified: `"date"`, `"time"`, `"date-time"`, `"uri"`, `"uri-reference"`, `"email"`. For example `"date"`, `"time"` and `"date-time"` do not validate ranges in `"fast"` mode, only string structure, and other formats have simplified regular expressions. + +## Tests + +```bash +npm install +git submodule update --init +npm test +``` + +## License + +[MIT](https://github.com/ajv-validator/ajv-formats/blob/master/LICENSE) diff --git a/libs/events/node_modules/ajv-formats/package.json b/libs/events/node_modules/ajv-formats/package.json new file mode 100644 index 000000000..13e70a24a --- /dev/null +++ b/libs/events/node_modules/ajv-formats/package.json @@ -0,0 +1,74 @@ +{ + "name": "ajv-formats", + "version": "2.1.1", + "description": "Format validation for Ajv v7+", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "src/", + "dist/" + ], + "scripts": { + "build": "tsc", + "prettier:write": "prettier --write \"./**/*.{md,json,yaml,js,ts}\"", + "prettier:check": "prettier --list-different \"./**/*.{md,json,yaml,js,ts}\"", + "eslint": "eslint --ext .ts ./src/**/*", + "test-spec": "jest", + "test-cov": "jest --coverage", + "test": "npm run prettier:check && npm run build && npm run eslint && npm run test-cov", + "ci-test": "npm run test" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ajv-validator/ajv-formats.git" + }, + "keywords": [ + "Ajv", + "JSON-Schema", + "format", + "validation" + ], + "author": "Evgeny Poberezkin", + "license": "MIT", + "bugs": { + "url": "https://github.com/ajv-validator/ajv-formats/issues" + }, + "homepage": "https://github.com/ajv-validator/ajv-formats#readme", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + }, + "devDependencies": { + "@ajv-validator/config": "^0.3.0", + "@types/jest": "^26.0.5", + "@types/node": "^14.10.1", + "@typescript-eslint/eslint-plugin": "^3.7.0", + "@typescript-eslint/parser": "^3.7.0", + "ajv": "^8.0.0", + "eslint": "^7.5.0", + "eslint-config-prettier": "^6.11.0", + "husky": "^4.2.5", + "jest": "^26.1.0", + "json-schema-test": "^2.0.0", + "lint-staged": "^10.2.11", + "prettier": "^2.3.2", + "ts-jest": "^26.1.3", + "typescript": "^4.0.0" + }, + "prettier": "@ajv-validator/config/prettierrc.json", + "husky": { + "hooks": { + "pre-commit": "lint-staged && npm test" + } + }, + "lint-staged": { + "*.{md,json,yaml,js,ts}": "prettier --write" + } +} diff --git a/libs/events/node_modules/ajv-formats/src/formats.ts b/libs/events/node_modules/ajv-formats/src/formats.ts new file mode 100644 index 000000000..9e28226a0 --- /dev/null +++ b/libs/events/node_modules/ajv-formats/src/formats.ts @@ -0,0 +1,232 @@ +import type {Format, FormatDefinition} from "ajv" +import type {FormatValidator, FormatCompare} from "ajv/dist/types" + +export type FormatMode = "fast" | "full" + +export type FormatName = + | "date" + | "time" + | "date-time" + | "duration" + | "uri" + | "uri-reference" + | "uri-template" + | "url" + | "email" + | "hostname" + | "ipv4" + | "ipv6" + | "regex" + | "uuid" + | "json-pointer" + | "json-pointer-uri-fragment" + | "relative-json-pointer" + | "byte" + | "int32" + | "int64" + | "float" + | "double" + | "password" + | "binary" + +export type DefinedFormats = { + [key in FormatName]: Format +} + +function fmtDef( + validate: RegExp | FormatValidator, + compare: FormatCompare +): FormatDefinition { + return {validate, compare} +} + +export const fullFormats: DefinedFormats = { + // date: http://tools.ietf.org/html/rfc3339#section-5.6 + date: fmtDef(date, compareDate), + // date-time: http://tools.ietf.org/html/rfc3339#section-5.6 + time: fmtDef(time, compareTime), + "date-time": fmtDef(date_time, compareDateTime), + // duration: https://tools.ietf.org/html/rfc3339#appendix-A + duration: /^P(?!$)((\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?|(\d+W)?)$/, + uri, + "uri-reference": + /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i, + // uri-template: https://tools.ietf.org/html/rfc6570 + "uri-template": + /^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i, + // For the source: https://gist.github.com/dperini/729294 + // For test cases: https://mathiasbynens.be/demo/url-regex + url: /^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)(?:\.(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu, + email: + /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i, + hostname: + /^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i, + // optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html + ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/, + ipv6: /^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i, + regex, + // uuid: http://tools.ietf.org/html/rfc4122 + uuid: /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i, + // JSON-pointer: https://tools.ietf.org/html/rfc6901 + // uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A + "json-pointer": /^(?:\/(?:[^~/]|~0|~1)*)*$/, + "json-pointer-uri-fragment": /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i, + // relative JSON-pointer: http://tools.ietf.org/html/draft-luff-relative-json-pointer-00 + "relative-json-pointer": /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/, + // the following formats are used by the openapi specification: https://spec.openapis.org/oas/v3.0.0#data-types + // byte: https://github.com/miguelmota/is-base64 + byte, + // signed 32 bit integer + int32: {type: "number", validate: validateInt32}, + // signed 64 bit integer + int64: {type: "number", validate: validateInt64}, + // C-type float + float: {type: "number", validate: validateNumber}, + // C-type double + double: {type: "number", validate: validateNumber}, + // hint to the UI to hide input strings + password: true, + // unchecked string payload + binary: true, +} + +export const fastFormats: DefinedFormats = { + ...fullFormats, + date: fmtDef(/^\d\d\d\d-[0-1]\d-[0-3]\d$/, compareDate), + time: fmtDef( + /^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i, + compareTime + ), + "date-time": fmtDef( + /^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i, + compareDateTime + ), + // uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js + uri: /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/)?[^\s]*$/i, + "uri-reference": /^(?:(?:[a-z][a-z0-9+\-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i, + // email (sources from jsen validator): + // http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address#answer-8829363 + // http://www.w3.org/TR/html5/forms.html#valid-e-mail-address (search for 'wilful violation') + email: + /^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i, +} + +export const formatNames = Object.keys(fullFormats) as FormatName[] + +function isLeapYear(year: number): boolean { + // https://tools.ietf.org/html/rfc3339#appendix-C + return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) +} + +const DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ +const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + +function date(str: string): boolean { + // full-date from http://tools.ietf.org/html/rfc3339#section-5.6 + const matches: string[] | null = DATE.exec(str) + if (!matches) return false + const year: number = +matches[1] + const month: number = +matches[2] + const day: number = +matches[3] + return ( + month >= 1 && + month <= 12 && + day >= 1 && + day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]) + ) +} + +function compareDate(d1: string, d2: string): number | undefined { + if (!(d1 && d2)) return undefined + if (d1 > d2) return 1 + if (d1 < d2) return -1 + return 0 +} + +const TIME = /^(\d\d):(\d\d):(\d\d)(\.\d+)?(z|[+-]\d\d(?::?\d\d)?)?$/i + +function time(str: string, withTimeZone?: boolean): boolean { + const matches: string[] | null = TIME.exec(str) + if (!matches) return false + + const hour: number = +matches[1] + const minute: number = +matches[2] + const second: number = +matches[3] + const timeZone: string = matches[5] + return ( + ((hour <= 23 && minute <= 59 && second <= 59) || + (hour === 23 && minute === 59 && second === 60)) && + (!withTimeZone || timeZone !== "") + ) +} + +function compareTime(t1: string, t2: string): number | undefined { + if (!(t1 && t2)) return undefined + const a1 = TIME.exec(t1) + const a2 = TIME.exec(t2) + if (!(a1 && a2)) return undefined + t1 = a1[1] + a1[2] + a1[3] + (a1[4] || "") + t2 = a2[1] + a2[2] + a2[3] + (a2[4] || "") + if (t1 > t2) return 1 + if (t1 < t2) return -1 + return 0 +} + +const DATE_TIME_SEPARATOR = /t|\s/i +function date_time(str: string): boolean { + // http://tools.ietf.org/html/rfc3339#section-5.6 + const dateTime: string[] = str.split(DATE_TIME_SEPARATOR) + return dateTime.length === 2 && date(dateTime[0]) && time(dateTime[1], true) +} + +function compareDateTime(dt1: string, dt2: string): number | undefined { + if (!(dt1 && dt2)) return undefined + const [d1, t1] = dt1.split(DATE_TIME_SEPARATOR) + const [d2, t2] = dt2.split(DATE_TIME_SEPARATOR) + const res = compareDate(d1, d2) + if (res === undefined) return undefined + return res || compareTime(t1, t2) +} + +const NOT_URI_FRAGMENT = /\/|:/ +const URI = + /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i + +function uri(str: string): boolean { + // http://jmrware.com/articles/2009/uri_regexp/URI_regex.html + optional protocol + required "." + return NOT_URI_FRAGMENT.test(str) && URI.test(str) +} + +const BYTE = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm + +function byte(str: string): boolean { + BYTE.lastIndex = 0 + return BYTE.test(str) +} + +const MIN_INT32 = -(2 ** 31) +const MAX_INT32 = 2 ** 31 - 1 + +function validateInt32(value: number): boolean { + return Number.isInteger(value) && value <= MAX_INT32 && value >= MIN_INT32 +} + +function validateInt64(value: number): boolean { + // JSON and javascript max Int is 2**53, so any int that passes isInteger is valid for Int64 + return Number.isInteger(value) +} + +function validateNumber(): boolean { + return true +} + +const Z_ANCHOR = /[^\\]\\Z/ +function regex(str: string): boolean { + if (Z_ANCHOR.test(str)) return false + try { + new RegExp(str) + return true + } catch (e) { + return false + } +} diff --git a/libs/events/node_modules/ajv-formats/src/index.ts b/libs/events/node_modules/ajv-formats/src/index.ts new file mode 100644 index 000000000..8fd944a09 --- /dev/null +++ b/libs/events/node_modules/ajv-formats/src/index.ts @@ -0,0 +1,62 @@ +import { + DefinedFormats, + FormatMode, + FormatName, + formatNames, + fastFormats, + fullFormats, +} from "./formats" +import formatLimit from "./limit" +import type Ajv from "ajv" +import type {Plugin, Format} from "ajv" +import {_, Name} from "ajv/dist/compile/codegen" + +export {FormatMode, FormatName} from "./formats" +export {LimitFormatError} from "./limit" +export interface FormatOptions { + mode?: FormatMode + formats?: FormatName[] + keywords?: boolean +} + +export type FormatsPluginOptions = FormatName[] | FormatOptions + +export interface FormatsPlugin extends Plugin { + get: (format: FormatName, mode?: FormatMode) => Format +} + +const fullName = new Name("fullFormats") +const fastName = new Name("fastFormats") + +const formatsPlugin: FormatsPlugin = ( + ajv: Ajv, + opts: FormatsPluginOptions = {keywords: true} +): Ajv => { + if (Array.isArray(opts)) { + addFormats(ajv, opts, fullFormats, fullName) + return ajv + } + const [formats, exportName] = + opts.mode === "fast" ? [fastFormats, fastName] : [fullFormats, fullName] + const list = opts.formats || formatNames + addFormats(ajv, list, formats, exportName) + if (opts.keywords) formatLimit(ajv) + return ajv +} + +formatsPlugin.get = (name: FormatName, mode: FormatMode = "full"): Format => { + const formats = mode === "fast" ? fastFormats : fullFormats + const f = formats[name] + if (!f) throw new Error(`Unknown format "${name}"`) + return f +} + +function addFormats(ajv: Ajv, list: FormatName[], fs: DefinedFormats, exportName: Name): void { + ajv.opts.code.formats ??= _`require("ajv-formats/dist/formats").${exportName}` + for (const f of list) ajv.addFormat(f, fs[f]) +} + +module.exports = exports = formatsPlugin +Object.defineProperty(exports, "__esModule", {value: true}) + +export default formatsPlugin diff --git a/libs/events/node_modules/ajv-formats/src/limit.ts b/libs/events/node_modules/ajv-formats/src/limit.ts new file mode 100644 index 000000000..bf6a57cb9 --- /dev/null +++ b/libs/events/node_modules/ajv-formats/src/limit.ts @@ -0,0 +1,99 @@ +import type Ajv from "ajv" +import type { + Plugin, + CodeKeywordDefinition, + KeywordErrorDefinition, + Code, + Name, + ErrorObject, +} from "ajv" +import type {AddedFormat} from "ajv/dist/types" +import type {Rule} from "ajv/dist/compile/rules" +import {KeywordCxt} from "ajv" +import {_, str, or, getProperty, operators} from "ajv/dist/compile/codegen" + +type Kwd = "formatMaximum" | "formatMinimum" | "formatExclusiveMaximum" | "formatExclusiveMinimum" + +type Comparison = "<=" | ">=" | "<" | ">" + +const ops = operators + +const KWDs: {[K in Kwd]: {okStr: Comparison; ok: Code; fail: Code}} = { + formatMaximum: {okStr: "<=", ok: ops.LTE, fail: ops.GT}, + formatMinimum: {okStr: ">=", ok: ops.GTE, fail: ops.LT}, + formatExclusiveMaximum: {okStr: "<", ok: ops.LT, fail: ops.GTE}, + formatExclusiveMinimum: {okStr: ">", ok: ops.GT, fail: ops.LTE}, +} + +export type LimitFormatError = ErrorObject + +const error: KeywordErrorDefinition = { + message: ({keyword, schemaCode}) => str`should be ${KWDs[keyword as Kwd].okStr} ${schemaCode}`, + params: ({keyword, schemaCode}) => + _`{comparison: ${KWDs[keyword as Kwd].okStr}, limit: ${schemaCode}}`, +} + +export const formatLimitDefinition: CodeKeywordDefinition = { + keyword: Object.keys(KWDs), + type: "string", + schemaType: "string", + $data: true, + error, + code(cxt) { + const {gen, data, schemaCode, keyword, it} = cxt + const {opts, self} = it + if (!opts.validateFormats) return + + const fCxt = new KeywordCxt(it, (self.RULES.all.format as Rule).definition, "format") + if (fCxt.$data) validate$DataFormat() + else validateFormat() + + function validate$DataFormat(): void { + const fmts = gen.scopeValue("formats", { + ref: self.formats, + code: opts.code.formats, + }) + const fmt = gen.const("fmt", _`${fmts}[${fCxt.schemaCode}]`) + cxt.fail$data( + or( + _`typeof ${fmt} != "object"`, + _`${fmt} instanceof RegExp`, + _`typeof ${fmt}.compare != "function"`, + compareCode(fmt) + ) + ) + } + + function validateFormat(): void { + const format = fCxt.schema as string + const fmtDef: AddedFormat | undefined = self.formats[format] + if (!fmtDef || fmtDef === true) return + if ( + typeof fmtDef != "object" || + fmtDef instanceof RegExp || + typeof fmtDef.compare != "function" + ) { + throw new Error(`"${keyword}": format "${format}" does not define "compare" function`) + } + const fmt = gen.scopeValue("formats", { + key: format, + ref: fmtDef, + code: opts.code.formats ? _`${opts.code.formats}${getProperty(format)}` : undefined, + }) + + cxt.fail$data(compareCode(fmt)) + } + + function compareCode(fmt: Name): Code { + return _`${fmt}.compare(${data}, ${schemaCode}) ${KWDs[keyword as Kwd].fail} 0` + } + }, + dependencies: ["format"], +} + +const formatLimitPlugin: Plugin = (ajv: Ajv): Ajv => { + ajv.addKeyword(formatLimitDefinition) + return ajv +} + +export default formatLimitPlugin diff --git a/libs/events/node_modules/ajv/.runkit_example.js b/libs/events/node_modules/ajv/.runkit_example.js new file mode 100644 index 000000000..0d578d5d5 --- /dev/null +++ b/libs/events/node_modules/ajv/.runkit_example.js @@ -0,0 +1,23 @@ +const Ajv = require("ajv") +const ajv = new Ajv({allErrors: true}) + +const schema = { + type: "object", + properties: { + foo: {type: "string"}, + bar: {type: "number", maximum: 3}, + }, + required: ["foo", "bar"], + additionalProperties: false, +} + +const validate = ajv.compile(schema) + +test({foo: "abc", bar: 2}) +test({foo: 2, bar: 4}) + +function test(data) { + const valid = validate(data) + if (valid) console.log("Valid!") + else console.log("Invalid: " + ajv.errorsText(validate.errors)) +} diff --git a/libs/events/node_modules/ajv/LICENSE b/libs/events/node_modules/ajv/LICENSE new file mode 100644 index 000000000..139162ad2 --- /dev/null +++ b/libs/events/node_modules/ajv/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015-2021 Evgeny Poberezkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/libs/events/node_modules/ajv/README.md b/libs/events/node_modules/ajv/README.md new file mode 100644 index 000000000..ab3f774a1 --- /dev/null +++ b/libs/events/node_modules/ajv/README.md @@ -0,0 +1,207 @@ +Ajv logo + +  + +# Ajv JSON schema validator + +The fastest JSON validator for Node.js and browser. + +Supports JSON Schema draft-04/06/07/2019-09/2020-12 ([draft-04 support](https://ajv.js.org/json-schema.html#draft-04) requires ajv-draft-04 package) and JSON Type Definition [RFC8927](https://datatracker.ietf.org/doc/rfc8927/). + +[![build](https://github.com/ajv-validator/ajv/workflows/build/badge.svg)](https://github.com/ajv-validator/ajv/actions?query=workflow%3Abuild) +[![npm](https://img.shields.io/npm/v/ajv.svg)](https://www.npmjs.com/package/ajv) +[![npm downloads](https://img.shields.io/npm/dm/ajv.svg)](https://www.npmjs.com/package/ajv) +[![Coverage Status](https://coveralls.io/repos/github/ajv-validator/ajv/badge.svg?branch=master)](https://coveralls.io/github/ajv-validator/ajv?branch=master) +[![SimpleX](https://img.shields.io/badge/chat-on%20SimpleX-%2307b4b9)](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FV-6t4hoy_SsvKMi9KekdGX-VKQOhDeAe%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAm98gjwvrAEiiz_YgBoaQB9dtKTl5Om1pborUyevQwzg%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%22wYrTFafovkymjUtc2vUjCQ%3D%3D%22%7D) +[![Gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv) +[![GitHub Sponsors](https://img.shields.io/badge/$-sponsors-brightgreen)](https://github.com/sponsors/epoberezkin) + +## Ajv sponsors + +[Mozilla](https://www.mozilla.org)[](https://opencollective.com/ajv) + +[Microsoft](https://opensource.microsoft.com)[](https://opencollective.com/ajv)[](https://opencollective.com/ajv) + +[Retool](https://retool.com/?utm_source=sponsor&utm_campaign=ajv)[Tidelift](https://tidelift.com/subscription/pkg/npm-ajv?utm_source=npm-ajv&utm_medium=referral&utm_campaign=enterprise)[SimpleX](https://github.com/simplex-chat/simplex-chat)[](https://opencollective.com/ajv) + +## Contributing + +More than 100 people contributed to Ajv, and we would love to have you join the development. We welcome implementing new features that will benefit many users and ideas to improve our documentation. + +Please review [Contributing guidelines](./CONTRIBUTING.md) and [Code components](https://ajv.js.org/components.html). + +## Documentation + +All documentation is available on the [Ajv website](https://ajv.js.org). + +Some useful site links: + +- [Getting started](https://ajv.js.org/guide/getting-started.html) +- [JSON Schema vs JSON Type Definition](https://ajv.js.org/guide/schema-language.html) +- [API reference](https://ajv.js.org/api.html) +- [Strict mode](https://ajv.js.org/strict-mode.html) +- [Standalone validation code](https://ajv.js.org/standalone.html) +- [Security considerations](https://ajv.js.org/security.html) +- [Command line interface](https://ajv.js.org/packages/ajv-cli.html) +- [Frequently Asked Questions](https://ajv.js.org/faq.html) + +## Please [sponsor Ajv development](https://github.com/sponsors/epoberezkin) + +Since I asked to support Ajv development 40 people and 6 organizations contributed via GitHub and OpenCollective - this support helped receiving the MOSS grant! + +Your continuing support is very important - the funds will be used to develop and maintain Ajv once the next major version is released. + +Please sponsor Ajv via: + +- [GitHub sponsors page](https://github.com/sponsors/epoberezkin) (GitHub will match it) +- [Ajv Open Collective](https://opencollective.com/ajv) + +Thank you. + +#### Open Collective sponsors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Performance + +Ajv generates code to turn JSON Schemas into super-fast validation functions that are efficient for v8 optimization. + +Currently Ajv is the fastest and the most standard compliant validator according to these benchmarks: + +- [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark) - 50% faster than the second place +- [jsck benchmark](https://github.com/pandastrike/jsck#benchmarks) - 20-190% faster +- [z-schema benchmark](https://rawgit.com/zaggino/z-schema/master/benchmark/results.html) +- [themis benchmark](https://cdn.rawgit.com/playlyfe/themis/master/benchmark/results.html) + +Performance of different validators by [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark): + +[![performance](https://chart.googleapis.com/chart?chxt=x,y&cht=bhs&chco=76A4FB&chls=2.0&chbh=62,4,1&chs=600x416&chxl=-1:|ajv|@exodus/schemasafe|is-my-json-valid|djv|@cfworker/json-schema|jsonschema/=t:100,69.2,51.5,13.1,5.1,1.2)](https://github.com/ebdrup/json-schema-benchmark/blob/master/README.md#performance) + +## Features + +- Ajv implements JSON Schema [draft-06/07/2019-09/2020-12](http://json-schema.org/) standards (draft-04 is supported in v6): + - all validation keywords (see [JSON Schema validation keywords](https://ajv.js.org/json-schema.html)) + - [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md) extensions: + - NEW: keyword [discriminator](https://ajv.js.org/json-schema.html#discriminator). + - keyword [nullable](https://ajv.js.org/json-schema.html#nullable). + - full support of remote references (remote schemas have to be added with `addSchema` or compiled to be available) + - support of recursive references between schemas + - correct string lengths for strings with unicode pairs + - JSON Schema [formats](https://ajv.js.org/guide/formats.html) (with [ajv-formats](https://github.com/ajv-validator/ajv-formats) plugin). + - [validates schemas against meta-schema](https://ajv.js.org/api.html#api-validateschema) +- NEW: supports [JSON Type Definition](https://datatracker.ietf.org/doc/rfc8927/): + - all keywords (see [JSON Type Definition schema forms](https://ajv.js.org/json-type-definition.html)) + - meta-schema for JTD schemas + - "union" keyword and user-defined keywords (can be used inside "metadata" member of the schema) +- supports [browsers](https://ajv.js.org/guide/environments.html#browsers) and Node.js 10.x - current +- [asynchronous loading](https://ajv.js.org/guide/managing-schemas.html#asynchronous-schema-loading) of referenced schemas during compilation +- "All errors" validation mode with [option allErrors](https://ajv.js.org/options.html#allerrors) +- [error messages with parameters](https://ajv.js.org/api.html#validation-errors) describing error reasons to allow error message generation +- i18n error messages support with [ajv-i18n](https://github.com/ajv-validator/ajv-i18n) package +- [removing-additional-properties](https://ajv.js.org/guide/modifying-data.html#removing-additional-properties) +- [assigning defaults](https://ajv.js.org/guide/modifying-data.html#assigning-defaults) to missing properties and items +- [coercing data](https://ajv.js.org/guide/modifying-data.html#coercing-data-types) to the types specified in `type` keywords +- [user-defined keywords](https://ajv.js.org/guide/user-keywords.html) +- additional extension keywords with [ajv-keywords](https://github.com/ajv-validator/ajv-keywords) package +- [\$data reference](https://ajv.js.org/guide/combining-schemas.html#data-reference) to use values from the validated data as values for the schema keywords +- [asynchronous validation](https://ajv.js.org/guide/async-validation.html) of user-defined formats and keywords + +## Install + +To install version 8: + +``` +npm install ajv +``` + +## Getting started + +Try it in the Node.js REPL: https://runkit.com/npm/ajv + +In JavaScript: + +```javascript +// or ESM/TypeScript import +import Ajv from "ajv" +// Node.js require: +const Ajv = require("ajv") + +const ajv = new Ajv() // options can be passed, e.g. {allErrors: true} + +const schema = { + type: "object", + properties: { + foo: {type: "integer"}, + bar: {type: "string"}, + }, + required: ["foo"], + additionalProperties: false, +} + +const data = { + foo: 1, + bar: "abc", +} + +const validate = ajv.compile(schema) +const valid = validate(data) +if (!valid) console.log(validate.errors) +``` + +Learn how to use Ajv and see more examples in the [Guide: getting started](https://ajv.js.org/guide/getting-started.html) + +## Changes history + +See [https://github.com/ajv-validator/ajv/releases](https://github.com/ajv-validator/ajv/releases) + +**Please note**: [Changes in version 8.0.0](https://github.com/ajv-validator/ajv/releases/tag/v8.0.0) + +[Version 7.0.0](https://github.com/ajv-validator/ajv/releases/tag/v7.0.0) + +[Version 6.0.0](https://github.com/ajv-validator/ajv/releases/tag/v6.0.0). + +## Code of conduct + +Please review and follow the [Code of conduct](./CODE_OF_CONDUCT.md). + +Please report any unacceptable behaviour to ajv.validator@gmail.com - it will be reviewed by the project team. + +## Security contact + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. Please do NOT report security vulnerabilities via GitHub issues. + +## Open-source software support + +Ajv is a part of [Tidelift subscription](https://tidelift.com/subscription/pkg/npm-ajv?utm_source=npm-ajv&utm_medium=referral&utm_campaign=readme) - it provides a centralised support to open-source software users, in addition to the support provided by software maintainers. + +## License + +[MIT](./LICENSE) diff --git a/libs/events/node_modules/ajv/lib/2019.ts b/libs/events/node_modules/ajv/lib/2019.ts new file mode 100644 index 000000000..45a3fa535 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/2019.ts @@ -0,0 +1,80 @@ +import type {AnySchemaObject} from "./types" +import AjvCore, {Options} from "./core" + +import draft7Vocabularies from "./vocabularies/draft7" +import dynamicVocabulary from "./vocabularies/dynamic" +import nextVocabulary from "./vocabularies/next" +import unevaluatedVocabulary from "./vocabularies/unevaluated" +import discriminator from "./vocabularies/discriminator" +import addMetaSchema2019 from "./refs/json-schema-2019-09" + +const META_SCHEMA_ID = "https://json-schema.org/draft/2019-09/schema" + +class Ajv2019 extends AjvCore { + constructor(opts: Options = {}) { + super({ + ...opts, + dynamicRef: true, + next: true, + unevaluated: true, + }) + } + + _addVocabularies(): void { + super._addVocabularies() + this.addVocabulary(dynamicVocabulary) + draft7Vocabularies.forEach((v) => this.addVocabulary(v)) + this.addVocabulary(nextVocabulary) + this.addVocabulary(unevaluatedVocabulary) + if (this.opts.discriminator) this.addKeyword(discriminator) + } + + _addDefaultMetaSchema(): void { + super._addDefaultMetaSchema() + const {$data, meta} = this.opts + if (!meta) return + addMetaSchema2019.call(this, $data) + this.refs["http://json-schema.org/schema"] = META_SCHEMA_ID + } + + defaultMeta(): string | AnySchemaObject | undefined { + return (this.opts.defaultMeta = + super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : undefined)) + } +} + +module.exports = exports = Ajv2019 +Object.defineProperty(exports, "__esModule", {value: true}) + +export default Ajv2019 + +export { + Format, + FormatDefinition, + AsyncFormatDefinition, + KeywordDefinition, + KeywordErrorDefinition, + CodeKeywordDefinition, + MacroKeywordDefinition, + FuncKeywordDefinition, + Vocabulary, + Schema, + SchemaObject, + AnySchemaObject, + AsyncSchema, + AnySchema, + ValidateFunction, + AsyncValidateFunction, + ErrorObject, + ErrorNoParams, +} from "./types" + +export {Plugin, Options, CodeOptions, InstanceOptions, Logger, ErrorsTextOptions} from "./core" +export {SchemaCxt, SchemaObjCxt} from "./compile" +export {KeywordCxt} from "./compile/validate" +export {DefinedError} from "./vocabularies/errors" +export {JSONType} from "./compile/rules" +export {JSONSchemaType} from "./types/json-schema" +export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen" +export {default as ValidationError} from "./runtime/validation_error" +export {default as MissingRefError} from "./compile/ref_error" diff --git a/libs/events/node_modules/ajv/lib/2020.ts b/libs/events/node_modules/ajv/lib/2020.ts new file mode 100644 index 000000000..afbdda200 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/2020.ts @@ -0,0 +1,74 @@ +import type {AnySchemaObject} from "./types" +import AjvCore, {Options} from "./core" + +import draft2020Vocabularies from "./vocabularies/draft2020" +import discriminator from "./vocabularies/discriminator" +import addMetaSchema2020 from "./refs/json-schema-2020-12" + +const META_SCHEMA_ID = "https://json-schema.org/draft/2020-12/schema" + +class Ajv2020 extends AjvCore { + constructor(opts: Options = {}) { + super({ + ...opts, + dynamicRef: true, + next: true, + unevaluated: true, + }) + } + + _addVocabularies(): void { + super._addVocabularies() + draft2020Vocabularies.forEach((v) => this.addVocabulary(v)) + if (this.opts.discriminator) this.addKeyword(discriminator) + } + + _addDefaultMetaSchema(): void { + super._addDefaultMetaSchema() + const {$data, meta} = this.opts + if (!meta) return + addMetaSchema2020.call(this, $data) + this.refs["http://json-schema.org/schema"] = META_SCHEMA_ID + } + + defaultMeta(): string | AnySchemaObject | undefined { + return (this.opts.defaultMeta = + super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : undefined)) + } +} + +module.exports = exports = Ajv2020 +Object.defineProperty(exports, "__esModule", {value: true}) + +export default Ajv2020 + +export { + Format, + FormatDefinition, + AsyncFormatDefinition, + KeywordDefinition, + KeywordErrorDefinition, + CodeKeywordDefinition, + MacroKeywordDefinition, + FuncKeywordDefinition, + Vocabulary, + Schema, + SchemaObject, + AnySchemaObject, + AsyncSchema, + AnySchema, + ValidateFunction, + AsyncValidateFunction, + ErrorObject, + ErrorNoParams, +} from "./types" + +export {Plugin, Options, CodeOptions, InstanceOptions, Logger, ErrorsTextOptions} from "./core" +export {SchemaCxt, SchemaObjCxt} from "./compile" +export {KeywordCxt} from "./compile/validate" +export {DefinedError} from "./vocabularies/errors" +export {JSONType} from "./compile/rules" +export {JSONSchemaType} from "./types/json-schema" +export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen" +export {default as ValidationError} from "./runtime/validation_error" +export {default as MissingRefError} from "./compile/ref_error" diff --git a/libs/events/node_modules/ajv/lib/ajv.ts b/libs/events/node_modules/ajv/lib/ajv.ts new file mode 100644 index 000000000..7f87c8aea --- /dev/null +++ b/libs/events/node_modules/ajv/lib/ajv.ts @@ -0,0 +1,69 @@ +import type {AnySchemaObject} from "./types" +import AjvCore from "./core" +import draft7Vocabularies from "./vocabularies/draft7" +import discriminator from "./vocabularies/discriminator" +import * as draft7MetaSchema from "./refs/json-schema-draft-07.json" + +const META_SUPPORT_DATA = ["/properties"] + +const META_SCHEMA_ID = "http://json-schema.org/draft-07/schema" + +class Ajv extends AjvCore { + _addVocabularies(): void { + super._addVocabularies() + draft7Vocabularies.forEach((v) => this.addVocabulary(v)) + if (this.opts.discriminator) this.addKeyword(discriminator) + } + + _addDefaultMetaSchema(): void { + super._addDefaultMetaSchema() + if (!this.opts.meta) return + const metaSchema = this.opts.$data + ? this.$dataMetaSchema(draft7MetaSchema, META_SUPPORT_DATA) + : draft7MetaSchema + this.addMetaSchema(metaSchema, META_SCHEMA_ID, false) + this.refs["http://json-schema.org/schema"] = META_SCHEMA_ID + } + + defaultMeta(): string | AnySchemaObject | undefined { + return (this.opts.defaultMeta = + super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : undefined)) + } +} + +module.exports = exports = Ajv +Object.defineProperty(exports, "__esModule", {value: true}) + +export default Ajv + +export { + Format, + FormatDefinition, + AsyncFormatDefinition, + KeywordDefinition, + KeywordErrorDefinition, + CodeKeywordDefinition, + MacroKeywordDefinition, + FuncKeywordDefinition, + Vocabulary, + Schema, + SchemaObject, + AnySchemaObject, + AsyncSchema, + AnySchema, + ValidateFunction, + AsyncValidateFunction, + SchemaValidateFunction, + ErrorObject, + ErrorNoParams, +} from "./types" + +export {Plugin, Options, CodeOptions, InstanceOptions, Logger, ErrorsTextOptions} from "./core" +export {SchemaCxt, SchemaObjCxt} from "./compile" +export {KeywordCxt} from "./compile/validate" +export {DefinedError} from "./vocabularies/errors" +export {JSONType} from "./compile/rules" +export {JSONSchemaType} from "./types/json-schema" +export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen" +export {default as ValidationError} from "./runtime/validation_error" +export {default as MissingRefError} from "./compile/ref_error" diff --git a/libs/events/node_modules/ajv/lib/compile/codegen/code.ts b/libs/events/node_modules/ajv/lib/compile/codegen/code.ts new file mode 100644 index 000000000..b17701973 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/codegen/code.ts @@ -0,0 +1,168 @@ +export abstract class _CodeOrName { + abstract readonly str: string + abstract readonly names: UsedNames + abstract toString(): string + abstract emptyStr(): boolean +} + +export const IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i + +export class Name extends _CodeOrName { + readonly str: string + constructor(s: string) { + super() + if (!IDENTIFIER.test(s)) throw new Error("CodeGen: name must be a valid identifier") + this.str = s + } + + toString(): string { + return this.str + } + + emptyStr(): boolean { + return false + } + + get names(): UsedNames { + return {[this.str]: 1} + } +} + +export class _Code extends _CodeOrName { + readonly _items: readonly CodeItem[] + private _str?: string + private _names?: UsedNames + + constructor(code: string | readonly CodeItem[]) { + super() + this._items = typeof code === "string" ? [code] : code + } + + toString(): string { + return this.str + } + + emptyStr(): boolean { + if (this._items.length > 1) return false + const item = this._items[0] + return item === "" || item === '""' + } + + get str(): string { + return (this._str ??= this._items.reduce((s: string, c: CodeItem) => `${s}${c}`, "")) + } + + get names(): UsedNames { + return (this._names ??= this._items.reduce((names: UsedNames, c) => { + if (c instanceof Name) names[c.str] = (names[c.str] || 0) + 1 + return names + }, {})) + } +} + +export type CodeItem = Name | string | number | boolean | null + +export type UsedNames = Record + +export type Code = _Code | Name + +export type SafeExpr = Code | number | boolean | null + +export const nil = new _Code("") + +type CodeArg = SafeExpr | string | undefined + +export function _(strs: TemplateStringsArray, ...args: CodeArg[]): _Code { + const code: CodeItem[] = [strs[0]] + let i = 0 + while (i < args.length) { + addCodeArg(code, args[i]) + code.push(strs[++i]) + } + return new _Code(code) +} + +const plus = new _Code("+") + +export function str(strs: TemplateStringsArray, ...args: (CodeArg | string[])[]): _Code { + const expr: CodeItem[] = [safeStringify(strs[0])] + let i = 0 + while (i < args.length) { + expr.push(plus) + addCodeArg(expr, args[i]) + expr.push(plus, safeStringify(strs[++i])) + } + optimize(expr) + return new _Code(expr) +} + +export function addCodeArg(code: CodeItem[], arg: CodeArg | string[]): void { + if (arg instanceof _Code) code.push(...arg._items) + else if (arg instanceof Name) code.push(arg) + else code.push(interpolate(arg)) +} + +function optimize(expr: CodeItem[]): void { + let i = 1 + while (i < expr.length - 1) { + if (expr[i] === plus) { + const res = mergeExprItems(expr[i - 1], expr[i + 1]) + if (res !== undefined) { + expr.splice(i - 1, 3, res) + continue + } + expr[i++] = "+" + } + i++ + } +} + +function mergeExprItems(a: CodeItem, b: CodeItem): CodeItem | undefined { + if (b === '""') return a + if (a === '""') return b + if (typeof a == "string") { + if (b instanceof Name || a[a.length - 1] !== '"') return + if (typeof b != "string") return `${a.slice(0, -1)}${b}"` + if (b[0] === '"') return a.slice(0, -1) + b.slice(1) + return + } + if (typeof b == "string" && b[0] === '"' && !(a instanceof Name)) return `"${a}${b.slice(1)}` + return +} + +export function strConcat(c1: Code, c2: Code): Code { + return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str`${c1}${c2}` +} + +// TODO do not allow arrays here +function interpolate(x?: string | string[] | number | boolean | null): SafeExpr | string { + return typeof x == "number" || typeof x == "boolean" || x === null + ? x + : safeStringify(Array.isArray(x) ? x.join(",") : x) +} + +export function stringify(x: unknown): Code { + return new _Code(safeStringify(x)) +} + +export function safeStringify(x: unknown): string { + return JSON.stringify(x) + .replace(/\u2028/g, "\\u2028") + .replace(/\u2029/g, "\\u2029") +} + +export function getProperty(key: Code | string | number): Code { + return typeof key == "string" && IDENTIFIER.test(key) ? new _Code(`.${key}`) : _`[${key}]` +} + +//Does best effort to format the name properly +export function getEsmExportName(key: Code | string | number): Code { + if (typeof key == "string" && IDENTIFIER.test(key)) { + return new _Code(`${key}`) + } + throw new Error(`CodeGen: invalid export name: ${key}, use explicit $id name mapping`) +} + +export function regexpCode(rx: RegExp): Code { + return new _Code(rx.toString()) +} diff --git a/libs/events/node_modules/ajv/lib/compile/codegen/index.ts b/libs/events/node_modules/ajv/lib/compile/codegen/index.ts new file mode 100644 index 000000000..9d29055dc --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/codegen/index.ts @@ -0,0 +1,832 @@ +import type {ScopeValueSets, NameValue, ValueScope, ValueScopeName} from "./scope" +import {_, nil, _Code, Code, Name, UsedNames, CodeItem, addCodeArg, _CodeOrName} from "./code" +import {Scope, varKinds} from "./scope" + +export {_, str, strConcat, nil, getProperty, stringify, regexpCode, Name, Code} from "./code" +export {Scope, ScopeStore, ValueScope, ValueScopeName, ScopeValueSets, varKinds} from "./scope" + +// type for expressions that can be safely inserted in code without quotes +export type SafeExpr = Code | number | boolean | null + +// type that is either Code of function that adds code to CodeGen instance using its methods +export type Block = Code | (() => void) + +export const operators = { + GT: new _Code(">"), + GTE: new _Code(">="), + LT: new _Code("<"), + LTE: new _Code("<="), + EQ: new _Code("==="), + NEQ: new _Code("!=="), + NOT: new _Code("!"), + OR: new _Code("||"), + AND: new _Code("&&"), + ADD: new _Code("+"), +} + +abstract class Node { + abstract readonly names: UsedNames + + optimizeNodes(): this | ChildNode | ChildNode[] | undefined { + return this + } + + optimizeNames(_names: UsedNames, _constants: Constants): this | undefined { + return this + } + + // get count(): number { + // return 1 + // } +} + +class Def extends Node { + constructor(private readonly varKind: Name, private readonly name: Name, private rhs?: SafeExpr) { + super() + } + + render({es5, _n}: CGOptions): string { + const varKind = es5 ? varKinds.var : this.varKind + const rhs = this.rhs === undefined ? "" : ` = ${this.rhs}` + return `${varKind} ${this.name}${rhs};` + _n + } + + optimizeNames(names: UsedNames, constants: Constants): this | undefined { + if (!names[this.name.str]) return + if (this.rhs) this.rhs = optimizeExpr(this.rhs, names, constants) + return this + } + + get names(): UsedNames { + return this.rhs instanceof _CodeOrName ? this.rhs.names : {} + } +} + +class Assign extends Node { + constructor(readonly lhs: Code, public rhs: SafeExpr, private readonly sideEffects?: boolean) { + super() + } + + render({_n}: CGOptions): string { + return `${this.lhs} = ${this.rhs};` + _n + } + + optimizeNames(names: UsedNames, constants: Constants): this | undefined { + if (this.lhs instanceof Name && !names[this.lhs.str] && !this.sideEffects) return + this.rhs = optimizeExpr(this.rhs, names, constants) + return this + } + + get names(): UsedNames { + const names = this.lhs instanceof Name ? {} : {...this.lhs.names} + return addExprNames(names, this.rhs) + } +} + +class AssignOp extends Assign { + constructor(lhs: Code, private readonly op: Code, rhs: SafeExpr, sideEffects?: boolean) { + super(lhs, rhs, sideEffects) + } + + render({_n}: CGOptions): string { + return `${this.lhs} ${this.op}= ${this.rhs};` + _n + } +} + +class Label extends Node { + readonly names: UsedNames = {} + constructor(readonly label: Name) { + super() + } + + render({_n}: CGOptions): string { + return `${this.label}:` + _n + } +} + +class Break extends Node { + readonly names: UsedNames = {} + constructor(readonly label?: Code) { + super() + } + + render({_n}: CGOptions): string { + const label = this.label ? ` ${this.label}` : "" + return `break${label};` + _n + } +} + +class Throw extends Node { + constructor(readonly error: Code) { + super() + } + + render({_n}: CGOptions): string { + return `throw ${this.error};` + _n + } + + get names(): UsedNames { + return this.error.names + } +} + +class AnyCode extends Node { + constructor(private code: SafeExpr) { + super() + } + + render({_n}: CGOptions): string { + return `${this.code};` + _n + } + + optimizeNodes(): this | undefined { + return `${this.code}` ? this : undefined + } + + optimizeNames(names: UsedNames, constants: Constants): this { + this.code = optimizeExpr(this.code, names, constants) + return this + } + + get names(): UsedNames { + return this.code instanceof _CodeOrName ? this.code.names : {} + } +} + +abstract class ParentNode extends Node { + constructor(readonly nodes: ChildNode[] = []) { + super() + } + + render(opts: CGOptions): string { + return this.nodes.reduce((code, n) => code + n.render(opts), "") + } + + optimizeNodes(): this | ChildNode | ChildNode[] | undefined { + const {nodes} = this + let i = nodes.length + while (i--) { + const n = nodes[i].optimizeNodes() + if (Array.isArray(n)) nodes.splice(i, 1, ...n) + else if (n) nodes[i] = n + else nodes.splice(i, 1) + } + return nodes.length > 0 ? this : undefined + } + + optimizeNames(names: UsedNames, constants: Constants): this | undefined { + const {nodes} = this + let i = nodes.length + while (i--) { + // iterating backwards improves 1-pass optimization + const n = nodes[i] + if (n.optimizeNames(names, constants)) continue + subtractNames(names, n.names) + nodes.splice(i, 1) + } + return nodes.length > 0 ? this : undefined + } + + get names(): UsedNames { + return this.nodes.reduce((names: UsedNames, n) => addNames(names, n.names), {}) + } + + // get count(): number { + // return this.nodes.reduce((c, n) => c + n.count, 1) + // } +} + +abstract class BlockNode extends ParentNode { + render(opts: CGOptions): string { + return "{" + opts._n + super.render(opts) + "}" + opts._n + } +} + +class Root extends ParentNode {} + +class Else extends BlockNode { + static readonly kind = "else" +} + +class If extends BlockNode { + static readonly kind = "if" + else?: If | Else + constructor(private condition: Code | boolean, nodes?: ChildNode[]) { + super(nodes) + } + + render(opts: CGOptions): string { + let code = `if(${this.condition})` + super.render(opts) + if (this.else) code += "else " + this.else.render(opts) + return code + } + + optimizeNodes(): If | ChildNode[] | undefined { + super.optimizeNodes() + const cond = this.condition + if (cond === true) return this.nodes // else is ignored here + let e = this.else + if (e) { + const ns = e.optimizeNodes() + e = this.else = Array.isArray(ns) ? new Else(ns) : (ns as Else | undefined) + } + if (e) { + if (cond === false) return e instanceof If ? e : e.nodes + if (this.nodes.length) return this + return new If(not(cond), e instanceof If ? [e] : e.nodes) + } + if (cond === false || !this.nodes.length) return undefined + return this + } + + optimizeNames(names: UsedNames, constants: Constants): this | undefined { + this.else = this.else?.optimizeNames(names, constants) + if (!(super.optimizeNames(names, constants) || this.else)) return + this.condition = optimizeExpr(this.condition, names, constants) + return this + } + + get names(): UsedNames { + const names = super.names + addExprNames(names, this.condition) + if (this.else) addNames(names, this.else.names) + return names + } + + // get count(): number { + // return super.count + (this.else?.count || 0) + // } +} + +abstract class For extends BlockNode { + static readonly kind = "for" +} + +class ForLoop extends For { + constructor(private iteration: Code) { + super() + } + + render(opts: CGOptions): string { + return `for(${this.iteration})` + super.render(opts) + } + + optimizeNames(names: UsedNames, constants: Constants): this | undefined { + if (!super.optimizeNames(names, constants)) return + this.iteration = optimizeExpr(this.iteration, names, constants) + return this + } + + get names(): UsedNames { + return addNames(super.names, this.iteration.names) + } +} + +class ForRange extends For { + constructor( + private readonly varKind: Name, + private readonly name: Name, + private readonly from: SafeExpr, + private readonly to: SafeExpr + ) { + super() + } + + render(opts: CGOptions): string { + const varKind = opts.es5 ? varKinds.var : this.varKind + const {name, from, to} = this + return `for(${varKind} ${name}=${from}; ${name}<${to}; ${name}++)` + super.render(opts) + } + + get names(): UsedNames { + const names = addExprNames(super.names, this.from) + return addExprNames(names, this.to) + } +} + +class ForIter extends For { + constructor( + private readonly loop: "of" | "in", + private readonly varKind: Name, + private readonly name: Name, + private iterable: Code + ) { + super() + } + + render(opts: CGOptions): string { + return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts) + } + + optimizeNames(names: UsedNames, constants: Constants): this | undefined { + if (!super.optimizeNames(names, constants)) return + this.iterable = optimizeExpr(this.iterable, names, constants) + return this + } + + get names(): UsedNames { + return addNames(super.names, this.iterable.names) + } +} + +class Func extends BlockNode { + static readonly kind = "func" + constructor(public name: Name, public args: Code, public async?: boolean) { + super() + } + + render(opts: CGOptions): string { + const _async = this.async ? "async " : "" + return `${_async}function ${this.name}(${this.args})` + super.render(opts) + } +} + +class Return extends ParentNode { + static readonly kind = "return" + + render(opts: CGOptions): string { + return "return " + super.render(opts) + } +} + +class Try extends BlockNode { + catch?: Catch + finally?: Finally + + render(opts: CGOptions): string { + let code = "try" + super.render(opts) + if (this.catch) code += this.catch.render(opts) + if (this.finally) code += this.finally.render(opts) + return code + } + + optimizeNodes(): this { + super.optimizeNodes() + this.catch?.optimizeNodes() as Catch | undefined + this.finally?.optimizeNodes() as Finally | undefined + return this + } + + optimizeNames(names: UsedNames, constants: Constants): this { + super.optimizeNames(names, constants) + this.catch?.optimizeNames(names, constants) + this.finally?.optimizeNames(names, constants) + return this + } + + get names(): UsedNames { + const names = super.names + if (this.catch) addNames(names, this.catch.names) + if (this.finally) addNames(names, this.finally.names) + return names + } + + // get count(): number { + // return super.count + (this.catch?.count || 0) + (this.finally?.count || 0) + // } +} + +class Catch extends BlockNode { + static readonly kind = "catch" + constructor(readonly error: Name) { + super() + } + + render(opts: CGOptions): string { + return `catch(${this.error})` + super.render(opts) + } +} + +class Finally extends BlockNode { + static readonly kind = "finally" + render(opts: CGOptions): string { + return "finally" + super.render(opts) + } +} + +type StartBlockNode = If | For | Func | Return | Try + +type LeafNode = Def | Assign | Label | Break | Throw | AnyCode + +type ChildNode = StartBlockNode | LeafNode + +type EndBlockNodeType = + | typeof If + | typeof Else + | typeof For + | typeof Func + | typeof Return + | typeof Catch + | typeof Finally + +type Constants = Record + +export interface CodeGenOptions { + es5?: boolean + lines?: boolean + ownProperties?: boolean +} + +interface CGOptions extends CodeGenOptions { + _n: "\n" | "" +} + +export class CodeGen { + readonly _scope: Scope + readonly _extScope: ValueScope + readonly _values: ScopeValueSets = {} + private readonly _nodes: ParentNode[] + private readonly _blockStarts: number[] = [] + private readonly _constants: Constants = {} + private readonly opts: CGOptions + + constructor(extScope: ValueScope, opts: CodeGenOptions = {}) { + this.opts = {...opts, _n: opts.lines ? "\n" : ""} + this._extScope = extScope + this._scope = new Scope({parent: extScope}) + this._nodes = [new Root()] + } + + toString(): string { + return this._root.render(this.opts) + } + + // returns unique name in the internal scope + name(prefix: string): Name { + return this._scope.name(prefix) + } + + // reserves unique name in the external scope + scopeName(prefix: string): ValueScopeName { + return this._extScope.name(prefix) + } + + // reserves unique name in the external scope and assigns value to it + scopeValue(prefixOrName: ValueScopeName | string, value: NameValue): Name { + const name = this._extScope.value(prefixOrName, value) + const vs = this._values[name.prefix] || (this._values[name.prefix] = new Set()) + vs.add(name) + return name + } + + getScopeValue(prefix: string, keyOrRef: unknown): ValueScopeName | undefined { + return this._extScope.getValue(prefix, keyOrRef) + } + + // return code that assigns values in the external scope to the names that are used internally + // (same names that were returned by gen.scopeName or gen.scopeValue) + scopeRefs(scopeName: Name): Code { + return this._extScope.scopeRefs(scopeName, this._values) + } + + scopeCode(): Code { + return this._extScope.scopeCode(this._values) + } + + private _def( + varKind: Name, + nameOrPrefix: Name | string, + rhs?: SafeExpr, + constant?: boolean + ): Name { + const name = this._scope.toName(nameOrPrefix) + if (rhs !== undefined && constant) this._constants[name.str] = rhs + this._leafNode(new Def(varKind, name, rhs)) + return name + } + + // `const` declaration (`var` in es5 mode) + const(nameOrPrefix: Name | string, rhs: SafeExpr, _constant?: boolean): Name { + return this._def(varKinds.const, nameOrPrefix, rhs, _constant) + } + + // `let` declaration with optional assignment (`var` in es5 mode) + let(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean): Name { + return this._def(varKinds.let, nameOrPrefix, rhs, _constant) + } + + // `var` declaration with optional assignment + var(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean): Name { + return this._def(varKinds.var, nameOrPrefix, rhs, _constant) + } + + // assignment code + assign(lhs: Code, rhs: SafeExpr, sideEffects?: boolean): CodeGen { + return this._leafNode(new Assign(lhs, rhs, sideEffects)) + } + + // `+=` code + add(lhs: Code, rhs: SafeExpr): CodeGen { + return this._leafNode(new AssignOp(lhs, operators.ADD, rhs)) + } + + // appends passed SafeExpr to code or executes Block + code(c: Block | SafeExpr): CodeGen { + if (typeof c == "function") c() + else if (c !== nil) this._leafNode(new AnyCode(c)) + return this + } + + // returns code for object literal for the passed argument list of key-value pairs + object(...keyValues: [Name | string, SafeExpr | string][]): _Code { + const code: CodeItem[] = ["{"] + for (const [key, value] of keyValues) { + if (code.length > 1) code.push(",") + code.push(key) + if (key !== value || this.opts.es5) { + code.push(":") + addCodeArg(code, value) + } + } + code.push("}") + return new _Code(code) + } + + // `if` clause (or statement if `thenBody` and, optionally, `elseBody` are passed) + if(condition: Code | boolean, thenBody?: Block, elseBody?: Block): CodeGen { + this._blockNode(new If(condition)) + + if (thenBody && elseBody) { + this.code(thenBody).else().code(elseBody).endIf() + } else if (thenBody) { + this.code(thenBody).endIf() + } else if (elseBody) { + throw new Error('CodeGen: "else" body without "then" body') + } + return this + } + + // `else if` clause - invalid without `if` or after `else` clauses + elseIf(condition: Code | boolean): CodeGen { + return this._elseNode(new If(condition)) + } + + // `else` clause - only valid after `if` or `else if` clauses + else(): CodeGen { + return this._elseNode(new Else()) + } + + // end `if` statement (needed if gen.if was used only with condition) + endIf(): CodeGen { + return this._endBlockNode(If, Else) + } + + private _for(node: For, forBody?: Block): CodeGen { + this._blockNode(node) + if (forBody) this.code(forBody).endFor() + return this + } + + // a generic `for` clause (or statement if `forBody` is passed) + for(iteration: Code, forBody?: Block): CodeGen { + return this._for(new ForLoop(iteration), forBody) + } + + // `for` statement for a range of values + forRange( + nameOrPrefix: Name | string, + from: SafeExpr, + to: SafeExpr, + forBody: (index: Name) => void, + varKind: Code = this.opts.es5 ? varKinds.var : varKinds.let + ): CodeGen { + const name = this._scope.toName(nameOrPrefix) + return this._for(new ForRange(varKind, name, from, to), () => forBody(name)) + } + + // `for-of` statement (in es5 mode replace with a normal for loop) + forOf( + nameOrPrefix: Name | string, + iterable: Code, + forBody: (item: Name) => void, + varKind: Code = varKinds.const + ): CodeGen { + const name = this._scope.toName(nameOrPrefix) + if (this.opts.es5) { + const arr = iterable instanceof Name ? iterable : this.var("_arr", iterable) + return this.forRange("_i", 0, _`${arr}.length`, (i) => { + this.var(name, _`${arr}[${i}]`) + forBody(name) + }) + } + return this._for(new ForIter("of", varKind, name, iterable), () => forBody(name)) + } + + // `for-in` statement. + // With option `ownProperties` replaced with a `for-of` loop for object keys + forIn( + nameOrPrefix: Name | string, + obj: Code, + forBody: (item: Name) => void, + varKind: Code = this.opts.es5 ? varKinds.var : varKinds.const + ): CodeGen { + if (this.opts.ownProperties) { + return this.forOf(nameOrPrefix, _`Object.keys(${obj})`, forBody) + } + const name = this._scope.toName(nameOrPrefix) + return this._for(new ForIter("in", varKind, name, obj), () => forBody(name)) + } + + // end `for` loop + endFor(): CodeGen { + return this._endBlockNode(For) + } + + // `label` statement + label(label: Name): CodeGen { + return this._leafNode(new Label(label)) + } + + // `break` statement + break(label?: Code): CodeGen { + return this._leafNode(new Break(label)) + } + + // `return` statement + return(value: Block | SafeExpr): CodeGen { + const node = new Return() + this._blockNode(node) + this.code(value) + if (node.nodes.length !== 1) throw new Error('CodeGen: "return" should have one node') + return this._endBlockNode(Return) + } + + // `try` statement + try(tryBody: Block, catchCode?: (e: Name) => void, finallyCode?: Block): CodeGen { + if (!catchCode && !finallyCode) throw new Error('CodeGen: "try" without "catch" and "finally"') + const node = new Try() + this._blockNode(node) + this.code(tryBody) + if (catchCode) { + const error = this.name("e") + this._currNode = node.catch = new Catch(error) + catchCode(error) + } + if (finallyCode) { + this._currNode = node.finally = new Finally() + this.code(finallyCode) + } + return this._endBlockNode(Catch, Finally) + } + + // `throw` statement + throw(error: Code): CodeGen { + return this._leafNode(new Throw(error)) + } + + // start self-balancing block + block(body?: Block, nodeCount?: number): CodeGen { + this._blockStarts.push(this._nodes.length) + if (body) this.code(body).endBlock(nodeCount) + return this + } + + // end the current self-balancing block + endBlock(nodeCount?: number): CodeGen { + const len = this._blockStarts.pop() + if (len === undefined) throw new Error("CodeGen: not in self-balancing block") + const toClose = this._nodes.length - len + if (toClose < 0 || (nodeCount !== undefined && toClose !== nodeCount)) { + throw new Error(`CodeGen: wrong number of nodes: ${toClose} vs ${nodeCount} expected`) + } + this._nodes.length = len + return this + } + + // `function` heading (or definition if funcBody is passed) + func(name: Name, args: Code = nil, async?: boolean, funcBody?: Block): CodeGen { + this._blockNode(new Func(name, args, async)) + if (funcBody) this.code(funcBody).endFunc() + return this + } + + // end function definition + endFunc(): CodeGen { + return this._endBlockNode(Func) + } + + optimize(n = 1): void { + while (n-- > 0) { + this._root.optimizeNodes() + this._root.optimizeNames(this._root.names, this._constants) + } + } + + private _leafNode(node: LeafNode): CodeGen { + this._currNode.nodes.push(node) + return this + } + + private _blockNode(node: StartBlockNode): void { + this._currNode.nodes.push(node) + this._nodes.push(node) + } + + private _endBlockNode(N1: EndBlockNodeType, N2?: EndBlockNodeType): CodeGen { + const n = this._currNode + if (n instanceof N1 || (N2 && n instanceof N2)) { + this._nodes.pop() + return this + } + throw new Error(`CodeGen: not in block "${N2 ? `${N1.kind}/${N2.kind}` : N1.kind}"`) + } + + private _elseNode(node: If | Else): CodeGen { + const n = this._currNode + if (!(n instanceof If)) { + throw new Error('CodeGen: "else" without "if"') + } + this._currNode = n.else = node + return this + } + + private get _root(): Root { + return this._nodes[0] as Root + } + + private get _currNode(): ParentNode { + const ns = this._nodes + return ns[ns.length - 1] + } + + private set _currNode(node: ParentNode) { + const ns = this._nodes + ns[ns.length - 1] = node + } + + // get nodeCount(): number { + // return this._root.count + // } +} + +function addNames(names: UsedNames, from: UsedNames): UsedNames { + for (const n in from) names[n] = (names[n] || 0) + (from[n] || 0) + return names +} + +function addExprNames(names: UsedNames, from: SafeExpr): UsedNames { + return from instanceof _CodeOrName ? addNames(names, from.names) : names +} + +function optimizeExpr(expr: T, names: UsedNames, constants: Constants): T +function optimizeExpr(expr: SafeExpr, names: UsedNames, constants: Constants): SafeExpr { + if (expr instanceof Name) return replaceName(expr) + if (!canOptimize(expr)) return expr + return new _Code( + expr._items.reduce((items: CodeItem[], c: SafeExpr | string) => { + if (c instanceof Name) c = replaceName(c) + if (c instanceof _Code) items.push(...c._items) + else items.push(c) + return items + }, []) + ) + + function replaceName(n: Name): SafeExpr { + const c = constants[n.str] + if (c === undefined || names[n.str] !== 1) return n + delete names[n.str] + return c + } + + function canOptimize(e: SafeExpr): e is _Code { + return ( + e instanceof _Code && + e._items.some( + (c) => c instanceof Name && names[c.str] === 1 && constants[c.str] !== undefined + ) + ) + } +} + +function subtractNames(names: UsedNames, from: UsedNames): void { + for (const n in from) names[n] = (names[n] || 0) - (from[n] || 0) +} + +export function not(x: T): T +export function not(x: Code | SafeExpr): Code | SafeExpr { + return typeof x == "boolean" || typeof x == "number" || x === null ? !x : _`!${par(x)}` +} + +const andCode = mappend(operators.AND) + +// boolean AND (&&) expression with the passed arguments +export function and(...args: Code[]): Code { + return args.reduce(andCode) +} + +const orCode = mappend(operators.OR) + +// boolean OR (||) expression with the passed arguments +export function or(...args: Code[]): Code { + return args.reduce(orCode) +} + +type MAppend = (x: Code, y: Code) => Code + +function mappend(op: Code): MAppend { + return (x, y) => (x === nil ? y : y === nil ? x : _`${par(x)} ${op} ${par(y)}`) +} + +function par(x: Code): Code { + return x instanceof Name ? x : _`(${x})` +} diff --git a/libs/events/node_modules/ajv/lib/compile/codegen/scope.ts b/libs/events/node_modules/ajv/lib/compile/codegen/scope.ts new file mode 100644 index 000000000..511992297 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/codegen/scope.ts @@ -0,0 +1,215 @@ +import {_, nil, Code, Name} from "./code" + +interface NameGroup { + prefix: string + index: number +} + +export interface NameValue { + ref: ValueReference // this is the reference to any value that can be referred to from generated code via `globals` var in the closure + key?: unknown // any key to identify a global to avoid duplicates, if not passed ref is used + code?: Code // this is the code creating the value needed for standalone code wit_out closure - can be a primitive value, function or import (`require`) +} + +export type ValueReference = unknown // possibly make CodeGen parameterized type on this type + +class ValueError extends Error { + readonly value?: NameValue + constructor(name: ValueScopeName) { + super(`CodeGen: "code" for ${name} not defined`) + this.value = name.value + } +} + +interface ScopeOptions { + prefixes?: Set + parent?: Scope +} + +interface ValueScopeOptions extends ScopeOptions { + scope: ScopeStore + es5?: boolean + lines?: boolean +} + +export type ScopeStore = Record + +type ScopeValues = { + [Prefix in string]?: Map +} + +export type ScopeValueSets = { + [Prefix in string]?: Set +} + +export enum UsedValueState { + Started, + Completed, +} + +export type UsedScopeValues = { + [Prefix in string]?: Map +} + +export const varKinds = { + const: new Name("const"), + let: new Name("let"), + var: new Name("var"), +} + +export class Scope { + protected readonly _names: {[Prefix in string]?: NameGroup} = {} + protected readonly _prefixes?: Set + protected readonly _parent?: Scope + + constructor({prefixes, parent}: ScopeOptions = {}) { + this._prefixes = prefixes + this._parent = parent + } + + toName(nameOrPrefix: Name | string): Name { + return nameOrPrefix instanceof Name ? nameOrPrefix : this.name(nameOrPrefix) + } + + name(prefix: string): Name { + return new Name(this._newName(prefix)) + } + + protected _newName(prefix: string): string { + const ng = this._names[prefix] || this._nameGroup(prefix) + return `${prefix}${ng.index++}` + } + + private _nameGroup(prefix: string): NameGroup { + if (this._parent?._prefixes?.has(prefix) || (this._prefixes && !this._prefixes.has(prefix))) { + throw new Error(`CodeGen: prefix "${prefix}" is not allowed in this scope`) + } + return (this._names[prefix] = {prefix, index: 0}) + } +} + +interface ScopePath { + property: string + itemIndex: number +} + +export class ValueScopeName extends Name { + readonly prefix: string + value?: NameValue + scopePath?: Code + + constructor(prefix: string, nameStr: string) { + super(nameStr) + this.prefix = prefix + } + + setValue(value: NameValue, {property, itemIndex}: ScopePath): void { + this.value = value + this.scopePath = _`.${new Name(property)}[${itemIndex}]` + } +} + +interface VSOptions extends ValueScopeOptions { + _n: Code +} + +const line = _`\n` + +export class ValueScope extends Scope { + protected readonly _values: ScopeValues = {} + protected readonly _scope: ScopeStore + readonly opts: VSOptions + + constructor(opts: ValueScopeOptions) { + super(opts) + this._scope = opts.scope + this.opts = {...opts, _n: opts.lines ? line : nil} + } + + get(): ScopeStore { + return this._scope + } + + name(prefix: string): ValueScopeName { + return new ValueScopeName(prefix, this._newName(prefix)) + } + + value(nameOrPrefix: ValueScopeName | string, value: NameValue): ValueScopeName { + if (value.ref === undefined) throw new Error("CodeGen: ref must be passed in value") + const name = this.toName(nameOrPrefix) as ValueScopeName + const {prefix} = name + const valueKey = value.key ?? value.ref + let vs = this._values[prefix] + if (vs) { + const _name = vs.get(valueKey) + if (_name) return _name + } else { + vs = this._values[prefix] = new Map() + } + vs.set(valueKey, name) + + const s = this._scope[prefix] || (this._scope[prefix] = []) + const itemIndex = s.length + s[itemIndex] = value.ref + name.setValue(value, {property: prefix, itemIndex}) + return name + } + + getValue(prefix: string, keyOrRef: unknown): ValueScopeName | undefined { + const vs = this._values[prefix] + if (!vs) return + return vs.get(keyOrRef) + } + + scopeRefs(scopeName: Name, values: ScopeValues | ScopeValueSets = this._values): Code { + return this._reduceValues(values, (name: ValueScopeName) => { + if (name.scopePath === undefined) throw new Error(`CodeGen: name "${name}" has no value`) + return _`${scopeName}${name.scopePath}` + }) + } + + scopeCode( + values: ScopeValues | ScopeValueSets = this._values, + usedValues?: UsedScopeValues, + getCode?: (n: ValueScopeName) => Code | undefined + ): Code { + return this._reduceValues( + values, + (name: ValueScopeName) => { + if (name.value === undefined) throw new Error(`CodeGen: name "${name}" has no value`) + return name.value.code + }, + usedValues, + getCode + ) + } + + private _reduceValues( + values: ScopeValues | ScopeValueSets, + valueCode: (n: ValueScopeName) => Code | undefined, + usedValues: UsedScopeValues = {}, + getCode?: (n: ValueScopeName) => Code | undefined + ): Code { + let code: Code = nil + for (const prefix in values) { + const vs = values[prefix] + if (!vs) continue + const nameSet = (usedValues[prefix] = usedValues[prefix] || new Map()) + vs.forEach((name: ValueScopeName) => { + if (nameSet.has(name)) return + nameSet.set(name, UsedValueState.Started) + let c = valueCode(name) + if (c) { + const def = this.opts.es5 ? varKinds.var : varKinds.const + code = _`${code}${def} ${name} = ${c};${this.opts._n}` + } else if ((c = getCode?.(name))) { + code = _`${code}${c}${this.opts._n}` + } else { + throw new ValueError(name) + } + nameSet.set(name, UsedValueState.Completed) + }) + } + return code + } +} diff --git a/libs/events/node_modules/ajv/lib/compile/errors.ts b/libs/events/node_modules/ajv/lib/compile/errors.ts new file mode 100644 index 000000000..18424a0fc --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/errors.ts @@ -0,0 +1,184 @@ +import type {KeywordErrorCxt, KeywordErrorDefinition} from "../types" +import type {SchemaCxt} from "./index" +import {CodeGen, _, str, strConcat, Code, Name} from "./codegen" +import {SafeExpr} from "./codegen/code" +import {getErrorPath, Type} from "./util" +import N from "./names" + +export const keywordError: KeywordErrorDefinition = { + message: ({keyword}) => str`must pass "${keyword}" keyword validation`, +} + +export const keyword$DataError: KeywordErrorDefinition = { + message: ({keyword, schemaType}) => + schemaType + ? str`"${keyword}" keyword must be ${schemaType} ($data)` + : str`"${keyword}" keyword is invalid ($data)`, +} + +export interface ErrorPaths { + instancePath?: Code + schemaPath?: string + parentSchema?: boolean +} + +export function reportError( + cxt: KeywordErrorCxt, + error: KeywordErrorDefinition = keywordError, + errorPaths?: ErrorPaths, + overrideAllErrors?: boolean +): void { + const {it} = cxt + const {gen, compositeRule, allErrors} = it + const errObj = errorObjectCode(cxt, error, errorPaths) + if (overrideAllErrors ?? (compositeRule || allErrors)) { + addError(gen, errObj) + } else { + returnErrors(it, _`[${errObj}]`) + } +} + +export function reportExtraError( + cxt: KeywordErrorCxt, + error: KeywordErrorDefinition = keywordError, + errorPaths?: ErrorPaths +): void { + const {it} = cxt + const {gen, compositeRule, allErrors} = it + const errObj = errorObjectCode(cxt, error, errorPaths) + addError(gen, errObj) + if (!(compositeRule || allErrors)) { + returnErrors(it, N.vErrors) + } +} + +export function resetErrorsCount(gen: CodeGen, errsCount: Name): void { + gen.assign(N.errors, errsCount) + gen.if(_`${N.vErrors} !== null`, () => + gen.if( + errsCount, + () => gen.assign(_`${N.vErrors}.length`, errsCount), + () => gen.assign(N.vErrors, null) + ) + ) +} + +export function extendErrors({ + gen, + keyword, + schemaValue, + data, + errsCount, + it, +}: KeywordErrorCxt): void { + /* istanbul ignore if */ + if (errsCount === undefined) throw new Error("ajv implementation error") + const err = gen.name("err") + gen.forRange("i", errsCount, N.errors, (i) => { + gen.const(err, _`${N.vErrors}[${i}]`) + gen.if(_`${err}.instancePath === undefined`, () => + gen.assign(_`${err}.instancePath`, strConcat(N.instancePath, it.errorPath)) + ) + gen.assign(_`${err}.schemaPath`, str`${it.errSchemaPath}/${keyword}`) + if (it.opts.verbose) { + gen.assign(_`${err}.schema`, schemaValue) + gen.assign(_`${err}.data`, data) + } + }) +} + +function addError(gen: CodeGen, errObj: Code): void { + const err = gen.const("err", errObj) + gen.if( + _`${N.vErrors} === null`, + () => gen.assign(N.vErrors, _`[${err}]`), + _`${N.vErrors}.push(${err})` + ) + gen.code(_`${N.errors}++`) +} + +function returnErrors(it: SchemaCxt, errs: Code): void { + const {gen, validateName, schemaEnv} = it + if (schemaEnv.$async) { + gen.throw(_`new ${it.ValidationError as Name}(${errs})`) + } else { + gen.assign(_`${validateName}.errors`, errs) + gen.return(false) + } +} + +const E = { + keyword: new Name("keyword"), + schemaPath: new Name("schemaPath"), // also used in JTD errors + params: new Name("params"), + propertyName: new Name("propertyName"), + message: new Name("message"), + schema: new Name("schema"), + parentSchema: new Name("parentSchema"), +} + +function errorObjectCode( + cxt: KeywordErrorCxt, + error: KeywordErrorDefinition, + errorPaths?: ErrorPaths +): Code { + const {createErrors} = cxt.it + if (createErrors === false) return _`{}` + return errorObject(cxt, error, errorPaths) +} + +function errorObject( + cxt: KeywordErrorCxt, + error: KeywordErrorDefinition, + errorPaths: ErrorPaths = {} +): Code { + const {gen, it} = cxt + const keyValues: [Name, SafeExpr | string][] = [ + errorInstancePath(it, errorPaths), + errorSchemaPath(cxt, errorPaths), + ] + extraErrorProps(cxt, error, keyValues) + return gen.object(...keyValues) +} + +function errorInstancePath({errorPath}: SchemaCxt, {instancePath}: ErrorPaths): [Name, Code] { + const instPath = instancePath + ? str`${errorPath}${getErrorPath(instancePath, Type.Str)}` + : errorPath + return [N.instancePath, strConcat(N.instancePath, instPath)] +} + +function errorSchemaPath( + {keyword, it: {errSchemaPath}}: KeywordErrorCxt, + {schemaPath, parentSchema}: ErrorPaths +): [Name, string | Code] { + let schPath = parentSchema ? errSchemaPath : str`${errSchemaPath}/${keyword}` + if (schemaPath) { + schPath = str`${schPath}${getErrorPath(schemaPath, Type.Str)}` + } + return [E.schemaPath, schPath] +} + +function extraErrorProps( + cxt: KeywordErrorCxt, + {params, message}: KeywordErrorDefinition, + keyValues: [Name, SafeExpr | string][] +): void { + const {keyword, data, schemaValue, it} = cxt + const {opts, propertyName, topSchemaRef, schemaPath} = it + keyValues.push( + [E.keyword, keyword], + [E.params, typeof params == "function" ? params(cxt) : params || _`{}`] + ) + if (opts.messages) { + keyValues.push([E.message, typeof message == "function" ? message(cxt) : message]) + } + if (opts.verbose) { + keyValues.push( + [E.schema, schemaValue], + [E.parentSchema, _`${topSchemaRef}${schemaPath}`], + [N.data, data] + ) + } + if (propertyName) keyValues.push([E.propertyName, propertyName]) +} diff --git a/libs/events/node_modules/ajv/lib/compile/index.ts b/libs/events/node_modules/ajv/lib/compile/index.ts new file mode 100644 index 000000000..3dac2699b --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/index.ts @@ -0,0 +1,324 @@ +import type { + AnySchema, + AnySchemaObject, + AnyValidateFunction, + AsyncValidateFunction, + EvaluatedProperties, + EvaluatedItems, +} from "../types" +import type Ajv from "../core" +import type {InstanceOptions} from "../core" +import {CodeGen, _, nil, stringify, Name, Code, ValueScopeName} from "./codegen" +import ValidationError from "../runtime/validation_error" +import N from "./names" +import {LocalRefs, getFullPath, _getFullPath, inlineRef, normalizeId, resolveUrl} from "./resolve" +import {schemaHasRulesButRef, unescapeFragment} from "./util" +import {validateFunctionCode} from "./validate" +import * as URI from "uri-js" +import {JSONType} from "./rules" + +export type SchemaRefs = { + [Ref in string]?: SchemaEnv | AnySchema +} + +export interface SchemaCxt { + readonly gen: CodeGen + readonly allErrors?: boolean // validation mode - whether to collect all errors or break on error + readonly data: Name // Name with reference to the current part of data instance + readonly parentData: Name // should be used in keywords modifying data + readonly parentDataProperty: Code | number // should be used in keywords modifying data + readonly dataNames: Name[] + readonly dataPathArr: (Code | number)[] + readonly dataLevel: number // the level of the currently validated data, + // it can be used to access both the property names and the data on all levels from the top. + dataTypes: JSONType[] // data types applied to the current part of data instance + definedProperties: Set // set of properties to keep track of for required checks + readonly topSchemaRef: Code + readonly validateName: Name + evaluated?: Name + readonly ValidationError?: Name + readonly schema: AnySchema // current schema object - equal to parentSchema passed via KeywordCxt + readonly schemaEnv: SchemaEnv + readonly rootId: string + baseId: string // the current schema base URI that should be used as the base for resolving URIs in references (\$ref) + readonly schemaPath: Code // the run-time expression that evaluates to the property name of the current schema + readonly errSchemaPath: string // this is actual string, should not be changed to Code + readonly errorPath: Code + readonly propertyName?: Name + readonly compositeRule?: boolean // true indicates that the current schema is inside the compound keyword, + // where failing some rule doesn't mean validation failure (`anyOf`, `oneOf`, `not`, `if`). + // This flag is used to determine whether you can return validation result immediately after any error in case the option `allErrors` is not `true. + // You only need to use it if you have many steps in your keywords and potentially can define multiple errors. + props?: EvaluatedProperties | Name // properties evaluated by this schema - used by parent schema or assigned to validation function + items?: EvaluatedItems | Name // last item evaluated by this schema - used by parent schema or assigned to validation function + jtdDiscriminator?: string + jtdMetadata?: boolean + readonly createErrors?: boolean + readonly opts: InstanceOptions // Ajv instance option. + readonly self: Ajv // current Ajv instance +} + +export interface SchemaObjCxt extends SchemaCxt { + readonly schema: AnySchemaObject +} +interface SchemaEnvArgs { + readonly schema: AnySchema + readonly schemaId?: "$id" | "id" + readonly root?: SchemaEnv + readonly baseId?: string + readonly schemaPath?: string + readonly localRefs?: LocalRefs + readonly meta?: boolean +} + +export class SchemaEnv implements SchemaEnvArgs { + readonly schema: AnySchema + readonly schemaId?: "$id" | "id" + readonly root: SchemaEnv + baseId: string // TODO possibly, it should be readonly + schemaPath?: string + localRefs?: LocalRefs + readonly meta?: boolean + readonly $async?: boolean // true if the current schema is asynchronous. + readonly refs: SchemaRefs = {} + readonly dynamicAnchors: {[Ref in string]?: true} = {} + validate?: AnyValidateFunction + validateName?: ValueScopeName + serialize?: (data: unknown) => string + serializeName?: ValueScopeName + parse?: (data: string) => unknown + parseName?: ValueScopeName + + constructor(env: SchemaEnvArgs) { + let schema: AnySchemaObject | undefined + if (typeof env.schema == "object") schema = env.schema + this.schema = env.schema + this.schemaId = env.schemaId + this.root = env.root || this + this.baseId = env.baseId ?? normalizeId(schema?.[env.schemaId || "$id"]) + this.schemaPath = env.schemaPath + this.localRefs = env.localRefs + this.meta = env.meta + this.$async = schema?.$async + this.refs = {} + } +} + +// let codeSize = 0 +// let nodeCount = 0 + +// Compiles schema in SchemaEnv +export function compileSchema(this: Ajv, sch: SchemaEnv): SchemaEnv { + // TODO refactor - remove compilations + const _sch = getCompilingSchema.call(this, sch) + if (_sch) return _sch + const rootId = getFullPath(this.opts.uriResolver, sch.root.baseId) // TODO if getFullPath removed 1 tests fails + const {es5, lines} = this.opts.code + const {ownProperties} = this.opts + const gen = new CodeGen(this.scope, {es5, lines, ownProperties}) + let _ValidationError + if (sch.$async) { + _ValidationError = gen.scopeValue("Error", { + ref: ValidationError, + code: _`require("ajv/dist/runtime/validation_error").default`, + }) + } + + const validateName = gen.scopeName("validate") + sch.validateName = validateName + + const schemaCxt: SchemaCxt = { + gen, + allErrors: this.opts.allErrors, + data: N.data, + parentData: N.parentData, + parentDataProperty: N.parentDataProperty, + dataNames: [N.data], + dataPathArr: [nil], // TODO can its length be used as dataLevel if nil is removed? + dataLevel: 0, + dataTypes: [], + definedProperties: new Set(), + topSchemaRef: gen.scopeValue( + "schema", + this.opts.code.source === true + ? {ref: sch.schema, code: stringify(sch.schema)} + : {ref: sch.schema} + ), + validateName, + ValidationError: _ValidationError, + schema: sch.schema, + schemaEnv: sch, + rootId, + baseId: sch.baseId || rootId, + schemaPath: nil, + errSchemaPath: sch.schemaPath || (this.opts.jtd ? "" : "#"), + errorPath: _`""`, + opts: this.opts, + self: this, + } + + let sourceCode: string | undefined + try { + this._compilations.add(sch) + validateFunctionCode(schemaCxt) + gen.optimize(this.opts.code.optimize) + // gen.optimize(1) + const validateCode = gen.toString() + sourceCode = `${gen.scopeRefs(N.scope)}return ${validateCode}` + // console.log((codeSize += sourceCode.length), (nodeCount += gen.nodeCount)) + if (this.opts.code.process) sourceCode = this.opts.code.process(sourceCode, sch) + // console.log("\n\n\n *** \n", sourceCode) + const makeValidate = new Function(`${N.self}`, `${N.scope}`, sourceCode) + const validate: AnyValidateFunction = makeValidate(this, this.scope.get()) + this.scope.value(validateName, {ref: validate}) + + validate.errors = null + validate.schema = sch.schema + validate.schemaEnv = sch + if (sch.$async) (validate as AsyncValidateFunction).$async = true + if (this.opts.code.source === true) { + validate.source = {validateName, validateCode, scopeValues: gen._values} + } + if (this.opts.unevaluated) { + const {props, items} = schemaCxt + validate.evaluated = { + props: props instanceof Name ? undefined : props, + items: items instanceof Name ? undefined : items, + dynamicProps: props instanceof Name, + dynamicItems: items instanceof Name, + } + if (validate.source) validate.source.evaluated = stringify(validate.evaluated) + } + sch.validate = validate + return sch + } catch (e) { + delete sch.validate + delete sch.validateName + if (sourceCode) this.logger.error("Error compiling schema, function code:", sourceCode) + // console.log("\n\n\n *** \n", sourceCode, this.opts) + throw e + } finally { + this._compilations.delete(sch) + } +} + +export function resolveRef( + this: Ajv, + root: SchemaEnv, + baseId: string, + ref: string +): AnySchema | SchemaEnv | undefined { + ref = resolveUrl(this.opts.uriResolver, baseId, ref) + const schOrFunc = root.refs[ref] + if (schOrFunc) return schOrFunc + + let _sch = resolve.call(this, root, ref) + if (_sch === undefined) { + const schema = root.localRefs?.[ref] // TODO maybe localRefs should hold SchemaEnv + const {schemaId} = this.opts + if (schema) _sch = new SchemaEnv({schema, schemaId, root, baseId}) + } + + if (_sch === undefined) return + return (root.refs[ref] = inlineOrCompile.call(this, _sch)) +} + +function inlineOrCompile(this: Ajv, sch: SchemaEnv): AnySchema | SchemaEnv { + if (inlineRef(sch.schema, this.opts.inlineRefs)) return sch.schema + return sch.validate ? sch : compileSchema.call(this, sch) +} + +// Index of schema compilation in the currently compiled list +export function getCompilingSchema(this: Ajv, schEnv: SchemaEnv): SchemaEnv | void { + for (const sch of this._compilations) { + if (sameSchemaEnv(sch, schEnv)) return sch + } +} + +function sameSchemaEnv(s1: SchemaEnv, s2: SchemaEnv): boolean { + return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId +} + +// resolve and compile the references ($ref) +// TODO returns AnySchemaObject (if the schema can be inlined) or validation function +function resolve( + this: Ajv, + root: SchemaEnv, // information about the root schema for the current schema + ref: string // reference to resolve +): SchemaEnv | undefined { + let sch + while (typeof (sch = this.refs[ref]) == "string") ref = sch + return sch || this.schemas[ref] || resolveSchema.call(this, root, ref) +} + +// Resolve schema, its root and baseId +export function resolveSchema( + this: Ajv, + root: SchemaEnv, // root object with properties schema, refs TODO below SchemaEnv is assigned to it + ref: string // reference to resolve +): SchemaEnv | undefined { + const p = this.opts.uriResolver.parse(ref) + const refPath = _getFullPath(this.opts.uriResolver, p) + let baseId = getFullPath(this.opts.uriResolver, root.baseId, undefined) + // TODO `Object.keys(root.schema).length > 0` should not be needed - but removing breaks 2 tests + if (Object.keys(root.schema).length > 0 && refPath === baseId) { + return getJsonPointer.call(this, p, root) + } + + const id = normalizeId(refPath) + const schOrRef = this.refs[id] || this.schemas[id] + if (typeof schOrRef == "string") { + const sch = resolveSchema.call(this, root, schOrRef) + if (typeof sch?.schema !== "object") return + return getJsonPointer.call(this, p, sch) + } + + if (typeof schOrRef?.schema !== "object") return + if (!schOrRef.validate) compileSchema.call(this, schOrRef) + if (id === normalizeId(ref)) { + const {schema} = schOrRef + const {schemaId} = this.opts + const schId = schema[schemaId] + if (schId) baseId = resolveUrl(this.opts.uriResolver, baseId, schId) + return new SchemaEnv({schema, schemaId, root, baseId}) + } + return getJsonPointer.call(this, p, schOrRef) +} + +const PREVENT_SCOPE_CHANGE = new Set([ + "properties", + "patternProperties", + "enum", + "dependencies", + "definitions", +]) + +function getJsonPointer( + this: Ajv, + parsedRef: URI.URIComponents, + {baseId, schema, root}: SchemaEnv +): SchemaEnv | undefined { + if (parsedRef.fragment?.[0] !== "/") return + for (const part of parsedRef.fragment.slice(1).split("/")) { + if (typeof schema === "boolean") return + const partSchema = schema[unescapeFragment(part)] + if (partSchema === undefined) return + schema = partSchema + // TODO PREVENT_SCOPE_CHANGE could be defined in keyword def? + const schId = typeof schema === "object" && schema[this.opts.schemaId] + if (!PREVENT_SCOPE_CHANGE.has(part) && schId) { + baseId = resolveUrl(this.opts.uriResolver, baseId, schId) + } + } + let env: SchemaEnv | undefined + if (typeof schema != "boolean" && schema.$ref && !schemaHasRulesButRef(schema, this.RULES)) { + const $ref = resolveUrl(this.opts.uriResolver, baseId, schema.$ref) + env = resolveSchema.call(this, root, $ref) + } + // even though resolution failed we need to return SchemaEnv to throw exception + // so that compileAsync loads missing schema. + const {schemaId} = this.opts + env = env || new SchemaEnv({schema, schemaId, root, baseId}) + if (env.schema !== env.root.schema) return env + return undefined +} diff --git a/libs/events/node_modules/ajv/lib/compile/jtd/parse.ts b/libs/events/node_modules/ajv/lib/compile/jtd/parse.ts new file mode 100644 index 000000000..a0141c770 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/jtd/parse.ts @@ -0,0 +1,411 @@ +import type Ajv from "../../core" +import type {SchemaObject} from "../../types" +import {jtdForms, JTDForm, SchemaObjectMap} from "./types" +import {SchemaEnv, getCompilingSchema} from ".." +import {_, str, and, or, nil, not, CodeGen, Code, Name, SafeExpr} from "../codegen" +import MissingRefError from "../ref_error" +import N from "../names" +import {hasPropFunc} from "../../vocabularies/code" +import {hasRef} from "../../vocabularies/jtd/ref" +import {intRange, IntType} from "../../vocabularies/jtd/type" +import {parseJson, parseJsonNumber, parseJsonString} from "../../runtime/parseJson" +import {useFunc} from "../util" +import validTimestamp from "../../runtime/timestamp" + +type GenParse = (cxt: ParseCxt) => void + +const genParse: {[F in JTDForm]: GenParse} = { + elements: parseElements, + values: parseValues, + discriminator: parseDiscriminator, + properties: parseProperties, + optionalProperties: parseProperties, + enum: parseEnum, + type: parseType, + ref: parseRef, +} + +interface ParseCxt { + readonly gen: CodeGen + readonly self: Ajv // current Ajv instance + readonly schemaEnv: SchemaEnv + readonly definitions: SchemaObjectMap + schema: SchemaObject + data: Code + parseName: Name + char: Name +} + +export default function compileParser( + this: Ajv, + sch: SchemaEnv, + definitions: SchemaObjectMap +): SchemaEnv { + const _sch = getCompilingSchema.call(this, sch) + if (_sch) return _sch + const {es5, lines} = this.opts.code + const {ownProperties} = this.opts + const gen = new CodeGen(this.scope, {es5, lines, ownProperties}) + const parseName = gen.scopeName("parse") + const cxt: ParseCxt = { + self: this, + gen, + schema: sch.schema as SchemaObject, + schemaEnv: sch, + definitions, + data: N.data, + parseName, + char: gen.name("c"), + } + + let sourceCode: string | undefined + try { + this._compilations.add(sch) + sch.parseName = parseName + parserFunction(cxt) + gen.optimize(this.opts.code.optimize) + const parseFuncCode = gen.toString() + sourceCode = `${gen.scopeRefs(N.scope)}return ${parseFuncCode}` + const makeParse = new Function(`${N.scope}`, sourceCode) + const parse: (json: string) => unknown = makeParse(this.scope.get()) + this.scope.value(parseName, {ref: parse}) + sch.parse = parse + } catch (e) { + if (sourceCode) this.logger.error("Error compiling parser, function code:", sourceCode) + delete sch.parse + delete sch.parseName + throw e + } finally { + this._compilations.delete(sch) + } + return sch +} + +const undef = _`undefined` + +function parserFunction(cxt: ParseCxt): void { + const {gen, parseName, char} = cxt + gen.func(parseName, _`${N.json}, ${N.jsonPos}, ${N.jsonPart}`, false, () => { + gen.let(N.data) + gen.let(char) + gen.assign(_`${parseName}.message`, undef) + gen.assign(_`${parseName}.position`, undef) + gen.assign(N.jsonPos, _`${N.jsonPos} || 0`) + gen.const(N.jsonLen, _`${N.json}.length`) + parseCode(cxt) + skipWhitespace(cxt) + gen.if(N.jsonPart, () => { + gen.assign(_`${parseName}.position`, N.jsonPos) + gen.return(N.data) + }) + gen.if(_`${N.jsonPos} === ${N.jsonLen}`, () => gen.return(N.data)) + jsonSyntaxError(cxt) + }) +} + +function parseCode(cxt: ParseCxt): void { + let form: JTDForm | undefined + for (const key of jtdForms) { + if (key in cxt.schema) { + form = key + break + } + } + if (form) parseNullable(cxt, genParse[form]) + else parseEmpty(cxt) +} + +const parseBoolean = parseBooleanToken(true, parseBooleanToken(false, jsonSyntaxError)) + +function parseNullable(cxt: ParseCxt, parseForm: GenParse): void { + const {gen, schema, data} = cxt + if (!schema.nullable) return parseForm(cxt) + tryParseToken(cxt, "null", parseForm, () => gen.assign(data, null)) +} + +function parseElements(cxt: ParseCxt): void { + const {gen, schema, data} = cxt + parseToken(cxt, "[") + const ix = gen.let("i", 0) + gen.assign(data, _`[]`) + parseItems(cxt, "]", () => { + const el = gen.let("el") + parseCode({...cxt, schema: schema.elements, data: el}) + gen.assign(_`${data}[${ix}++]`, el) + }) +} + +function parseValues(cxt: ParseCxt): void { + const {gen, schema, data} = cxt + parseToken(cxt, "{") + gen.assign(data, _`{}`) + parseItems(cxt, "}", () => parseKeyValue(cxt, schema.values)) +} + +function parseItems(cxt: ParseCxt, endToken: string, block: () => void): void { + tryParseItems(cxt, endToken, block) + parseToken(cxt, endToken) +} + +function tryParseItems(cxt: ParseCxt, endToken: string, block: () => void): void { + const {gen} = cxt + gen.for(_`;${N.jsonPos}<${N.jsonLen} && ${jsonSlice(1)}!==${endToken};`, () => { + block() + tryParseToken(cxt, ",", () => gen.break(), hasItem) + }) + + function hasItem(): void { + tryParseToken(cxt, endToken, () => {}, jsonSyntaxError) + } +} + +function parseKeyValue(cxt: ParseCxt, schema: SchemaObject): void { + const {gen} = cxt + const key = gen.let("key") + parseString({...cxt, data: key}) + parseToken(cxt, ":") + parsePropertyValue(cxt, key, schema) +} + +function parseDiscriminator(cxt: ParseCxt): void { + const {gen, data, schema} = cxt + const {discriminator, mapping} = schema + parseToken(cxt, "{") + gen.assign(data, _`{}`) + const startPos = gen.const("pos", N.jsonPos) + const value = gen.let("value") + const tag = gen.let("tag") + tryParseItems(cxt, "}", () => { + const key = gen.let("key") + parseString({...cxt, data: key}) + parseToken(cxt, ":") + gen.if( + _`${key} === ${discriminator}`, + () => { + parseString({...cxt, data: tag}) + gen.assign(_`${data}[${key}]`, tag) + gen.break() + }, + () => parseEmpty({...cxt, data: value}) // can be discarded/skipped + ) + }) + gen.assign(N.jsonPos, startPos) + gen.if(_`${tag} === undefined`) + parsingError(cxt, str`discriminator tag not found`) + for (const tagValue in mapping) { + gen.elseIf(_`${tag} === ${tagValue}`) + parseSchemaProperties({...cxt, schema: mapping[tagValue]}, discriminator) + } + gen.else() + parsingError(cxt, str`discriminator value not in schema`) + gen.endIf() +} + +function parseProperties(cxt: ParseCxt): void { + const {gen, data} = cxt + parseToken(cxt, "{") + gen.assign(data, _`{}`) + parseSchemaProperties(cxt) +} + +function parseSchemaProperties(cxt: ParseCxt, discriminator?: string): void { + const {gen, schema, data} = cxt + const {properties, optionalProperties, additionalProperties} = schema + parseItems(cxt, "}", () => { + const key = gen.let("key") + parseString({...cxt, data: key}) + parseToken(cxt, ":") + gen.if(false) + parseDefinedProperty(cxt, key, properties) + parseDefinedProperty(cxt, key, optionalProperties) + if (discriminator) { + gen.elseIf(_`${key} === ${discriminator}`) + const tag = gen.let("tag") + parseString({...cxt, data: tag}) // can be discarded, it is already assigned + } + gen.else() + if (additionalProperties) { + parseEmpty({...cxt, data: _`${data}[${key}]`}) + } else { + parsingError(cxt, str`property ${key} not allowed`) + } + gen.endIf() + }) + if (properties) { + const hasProp = hasPropFunc(gen) + const allProps: Code = and( + ...Object.keys(properties).map((p): Code => _`${hasProp}.call(${data}, ${p})`) + ) + gen.if(not(allProps), () => parsingError(cxt, str`missing required properties`)) + } +} + +function parseDefinedProperty(cxt: ParseCxt, key: Name, schemas: SchemaObjectMap = {}): void { + const {gen} = cxt + for (const prop in schemas) { + gen.elseIf(_`${key} === ${prop}`) + parsePropertyValue(cxt, key, schemas[prop] as SchemaObject) + } +} + +function parsePropertyValue(cxt: ParseCxt, key: Name, schema: SchemaObject): void { + parseCode({...cxt, schema, data: _`${cxt.data}[${key}]`}) +} + +function parseType(cxt: ParseCxt): void { + const {gen, schema, data, self} = cxt + switch (schema.type) { + case "boolean": + parseBoolean(cxt) + break + case "string": + parseString(cxt) + break + case "timestamp": { + parseString(cxt) + const vts = useFunc(gen, validTimestamp) + const {allowDate, parseDate} = self.opts + const notValid = allowDate ? _`!${vts}(${data}, true)` : _`!${vts}(${data})` + const fail: Code = parseDate + ? or(notValid, _`(${data} = new Date(${data}), false)`, _`isNaN(${data}.valueOf())`) + : notValid + gen.if(fail, () => parsingError(cxt, str`invalid timestamp`)) + break + } + case "float32": + case "float64": + parseNumber(cxt) + break + default: { + const t = schema.type as IntType + if (!self.opts.int32range && (t === "int32" || t === "uint32")) { + parseNumber(cxt, 16) // 2 ** 53 - max safe integer + if (t === "uint32") { + gen.if(_`${data} < 0`, () => parsingError(cxt, str`integer out of range`)) + } + } else { + const [min, max, maxDigits] = intRange[t] + parseNumber(cxt, maxDigits) + gen.if(_`${data} < ${min} || ${data} > ${max}`, () => + parsingError(cxt, str`integer out of range`) + ) + } + } + } +} + +function parseString(cxt: ParseCxt): void { + parseToken(cxt, '"') + parseWith(cxt, parseJsonString) +} + +function parseEnum(cxt: ParseCxt): void { + const {gen, data, schema} = cxt + const enumSch = schema.enum + parseToken(cxt, '"') + // TODO loopEnum + gen.if(false) + for (const value of enumSch) { + const valueStr = JSON.stringify(value).slice(1) // remove starting quote + gen.elseIf(_`${jsonSlice(valueStr.length)} === ${valueStr}`) + gen.assign(data, str`${value}`) + gen.add(N.jsonPos, valueStr.length) + } + gen.else() + jsonSyntaxError(cxt) + gen.endIf() +} + +function parseNumber(cxt: ParseCxt, maxDigits?: number): void { + const {gen} = cxt + skipWhitespace(cxt) + gen.if( + _`"-0123456789".indexOf(${jsonSlice(1)}) < 0`, + () => jsonSyntaxError(cxt), + () => parseWith(cxt, parseJsonNumber, maxDigits) + ) +} + +function parseBooleanToken(bool: boolean, fail: GenParse): GenParse { + return (cxt) => { + const {gen, data} = cxt + tryParseToken( + cxt, + `${bool}`, + () => fail(cxt), + () => gen.assign(data, bool) + ) + } +} + +function parseRef(cxt: ParseCxt): void { + const {gen, self, definitions, schema, schemaEnv} = cxt + const {ref} = schema + const refSchema = definitions[ref] + if (!refSchema) throw new MissingRefError(self.opts.uriResolver, "", ref, `No definition ${ref}`) + if (!hasRef(refSchema)) return parseCode({...cxt, schema: refSchema}) + const {root} = schemaEnv + const sch = compileParser.call(self, new SchemaEnv({schema: refSchema, root}), definitions) + partialParse(cxt, getParser(gen, sch), true) +} + +function getParser(gen: CodeGen, sch: SchemaEnv): Code { + return sch.parse + ? gen.scopeValue("parse", {ref: sch.parse}) + : _`${gen.scopeValue("wrapper", {ref: sch})}.parse` +} + +function parseEmpty(cxt: ParseCxt): void { + parseWith(cxt, parseJson) +} + +function parseWith(cxt: ParseCxt, parseFunc: {code: string}, args?: SafeExpr): void { + partialParse(cxt, useFunc(cxt.gen, parseFunc), args) +} + +function partialParse(cxt: ParseCxt, parseFunc: Name, args?: SafeExpr): void { + const {gen, data} = cxt + gen.assign(data, _`${parseFunc}(${N.json}, ${N.jsonPos}${args ? _`, ${args}` : nil})`) + gen.assign(N.jsonPos, _`${parseFunc}.position`) + gen.if(_`${data} === undefined`, () => parsingError(cxt, _`${parseFunc}.message`)) +} + +function parseToken(cxt: ParseCxt, tok: string): void { + tryParseToken(cxt, tok, jsonSyntaxError) +} + +function tryParseToken(cxt: ParseCxt, tok: string, fail: GenParse, success?: GenParse): void { + const {gen} = cxt + const n = tok.length + skipWhitespace(cxt) + gen.if( + _`${jsonSlice(n)} === ${tok}`, + () => { + gen.add(N.jsonPos, n) + success?.(cxt) + }, + () => fail(cxt) + ) +} + +function skipWhitespace({gen, char: c}: ParseCxt): void { + gen.code( + _`while((${c}=${N.json}[${N.jsonPos}],${c}===" "||${c}==="\\n"||${c}==="\\r"||${c}==="\\t"))${N.jsonPos}++;` + ) +} + +function jsonSlice(len: number | Name): Code { + return len === 1 + ? _`${N.json}[${N.jsonPos}]` + : _`${N.json}.slice(${N.jsonPos}, ${N.jsonPos}+${len})` +} + +function jsonSyntaxError(cxt: ParseCxt): void { + parsingError(cxt, _`"unexpected token " + ${N.json}[${N.jsonPos}]`) +} + +function parsingError({gen, parseName}: ParseCxt, msg: Code): void { + gen.assign(_`${parseName}.message`, msg) + gen.assign(_`${parseName}.position`, N.jsonPos) + gen.return(undef) +} diff --git a/libs/events/node_modules/ajv/lib/compile/jtd/serialize.ts b/libs/events/node_modules/ajv/lib/compile/jtd/serialize.ts new file mode 100644 index 000000000..1d228826d --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/jtd/serialize.ts @@ -0,0 +1,266 @@ +import type Ajv from "../../core" +import type {SchemaObject} from "../../types" +import {jtdForms, JTDForm, SchemaObjectMap} from "./types" +import {SchemaEnv, getCompilingSchema} from ".." +import {_, str, and, getProperty, CodeGen, Code, Name} from "../codegen" +import MissingRefError from "../ref_error" +import N from "../names" +import {isOwnProperty} from "../../vocabularies/code" +import {hasRef} from "../../vocabularies/jtd/ref" +import {useFunc} from "../util" +import quote from "../../runtime/quote" + +const genSerialize: {[F in JTDForm]: (cxt: SerializeCxt) => void} = { + elements: serializeElements, + values: serializeValues, + discriminator: serializeDiscriminator, + properties: serializeProperties, + optionalProperties: serializeProperties, + enum: serializeString, + type: serializeType, + ref: serializeRef, +} + +interface SerializeCxt { + readonly gen: CodeGen + readonly self: Ajv // current Ajv instance + readonly schemaEnv: SchemaEnv + readonly definitions: SchemaObjectMap + schema: SchemaObject + data: Code +} + +export default function compileSerializer( + this: Ajv, + sch: SchemaEnv, + definitions: SchemaObjectMap +): SchemaEnv { + const _sch = getCompilingSchema.call(this, sch) + if (_sch) return _sch + const {es5, lines} = this.opts.code + const {ownProperties} = this.opts + const gen = new CodeGen(this.scope, {es5, lines, ownProperties}) + const serializeName = gen.scopeName("serialize") + const cxt: SerializeCxt = { + self: this, + gen, + schema: sch.schema as SchemaObject, + schemaEnv: sch, + definitions, + data: N.data, + } + + let sourceCode: string | undefined + try { + this._compilations.add(sch) + sch.serializeName = serializeName + gen.func(serializeName, N.data, false, () => { + gen.let(N.json, str``) + serializeCode(cxt) + gen.return(N.json) + }) + gen.optimize(this.opts.code.optimize) + const serializeFuncCode = gen.toString() + sourceCode = `${gen.scopeRefs(N.scope)}return ${serializeFuncCode}` + const makeSerialize = new Function(`${N.scope}`, sourceCode) + const serialize: (data: unknown) => string = makeSerialize(this.scope.get()) + this.scope.value(serializeName, {ref: serialize}) + sch.serialize = serialize + } catch (e) { + if (sourceCode) this.logger.error("Error compiling serializer, function code:", sourceCode) + delete sch.serialize + delete sch.serializeName + throw e + } finally { + this._compilations.delete(sch) + } + return sch +} + +function serializeCode(cxt: SerializeCxt): void { + let form: JTDForm | undefined + for (const key of jtdForms) { + if (key in cxt.schema) { + form = key + break + } + } + serializeNullable(cxt, form ? genSerialize[form] : serializeEmpty) +} + +function serializeNullable(cxt: SerializeCxt, serializeForm: (_cxt: SerializeCxt) => void): void { + const {gen, schema, data} = cxt + if (!schema.nullable) return serializeForm(cxt) + gen.if( + _`${data} === undefined || ${data} === null`, + () => gen.add(N.json, _`"null"`), + () => serializeForm(cxt) + ) +} + +function serializeElements(cxt: SerializeCxt): void { + const {gen, schema, data} = cxt + gen.add(N.json, str`[`) + const first = gen.let("first", true) + gen.forOf("el", data, (el) => { + addComma(cxt, first) + serializeCode({...cxt, schema: schema.elements, data: el}) + }) + gen.add(N.json, str`]`) +} + +function serializeValues(cxt: SerializeCxt): void { + const {gen, schema, data} = cxt + gen.add(N.json, str`{`) + const first = gen.let("first", true) + gen.forIn("key", data, (key) => serializeKeyValue(cxt, key, schema.values, first)) + gen.add(N.json, str`}`) +} + +function serializeKeyValue(cxt: SerializeCxt, key: Name, schema: SchemaObject, first?: Name): void { + const {gen, data} = cxt + addComma(cxt, first) + serializeString({...cxt, data: key}) + gen.add(N.json, str`:`) + const value = gen.const("value", _`${data}${getProperty(key)}`) + serializeCode({...cxt, schema, data: value}) +} + +function serializeDiscriminator(cxt: SerializeCxt): void { + const {gen, schema, data} = cxt + const {discriminator} = schema + gen.add(N.json, str`{${JSON.stringify(discriminator)}:`) + const tag = gen.const("tag", _`${data}${getProperty(discriminator)}`) + serializeString({...cxt, data: tag}) + gen.if(false) + for (const tagValue in schema.mapping) { + gen.elseIf(_`${tag} === ${tagValue}`) + const sch = schema.mapping[tagValue] + serializeSchemaProperties({...cxt, schema: sch}, discriminator) + } + gen.endIf() + gen.add(N.json, str`}`) +} + +function serializeProperties(cxt: SerializeCxt): void { + const {gen} = cxt + gen.add(N.json, str`{`) + serializeSchemaProperties(cxt) + gen.add(N.json, str`}`) +} + +function serializeSchemaProperties(cxt: SerializeCxt, discriminator?: string): void { + const {gen, schema, data} = cxt + const {properties, optionalProperties} = schema + const props = keys(properties) + const optProps = keys(optionalProperties) + const allProps = allProperties(props.concat(optProps)) + let first = !discriminator + let firstProp: Name | undefined + + for (const key of props) { + if (first) first = false + else gen.add(N.json, str`,`) + serializeProperty(key, properties[key], keyValue(key)) + } + if (first) firstProp = gen.let("first", true) + for (const key of optProps) { + const value = keyValue(key) + gen.if(and(_`${value} !== undefined`, isOwnProperty(gen, data, key)), () => { + addComma(cxt, firstProp) + serializeProperty(key, optionalProperties[key], value) + }) + } + if (schema.additionalProperties) { + gen.forIn("key", data, (key) => + gen.if(isAdditional(key, allProps), () => serializeKeyValue(cxt, key, {}, firstProp)) + ) + } + + function keys(ps?: SchemaObjectMap): string[] { + return ps ? Object.keys(ps) : [] + } + + function allProperties(ps: string[]): string[] { + if (discriminator) ps.push(discriminator) + if (new Set(ps).size !== ps.length) { + throw new Error("JTD: properties/optionalProperties/disciminator overlap") + } + return ps + } + + function keyValue(key: string): Name { + return gen.const("value", _`${data}${getProperty(key)}`) + } + + function serializeProperty(key: string, propSchema: SchemaObject, value: Name): void { + gen.add(N.json, str`${JSON.stringify(key)}:`) + serializeCode({...cxt, schema: propSchema, data: value}) + } + + function isAdditional(key: Name, ps: string[]): Code | true { + return ps.length ? and(...ps.map((p) => _`${key} !== ${p}`)) : true + } +} + +function serializeType(cxt: SerializeCxt): void { + const {gen, schema, data} = cxt + switch (schema.type) { + case "boolean": + gen.add(N.json, _`${data} ? "true" : "false"`) + break + case "string": + serializeString(cxt) + break + case "timestamp": + gen.if( + _`${data} instanceof Date`, + () => gen.add(N.json, _`'"' + ${data}.toISOString() + '"'`), + () => serializeString(cxt) + ) + break + default: + serializeNumber(cxt) + } +} + +function serializeString({gen, data}: SerializeCxt): void { + gen.add(N.json, _`${useFunc(gen, quote)}(${data})`) +} + +function serializeNumber({gen, data}: SerializeCxt): void { + gen.add(N.json, _`"" + ${data}`) +} + +function serializeRef(cxt: SerializeCxt): void { + const {gen, self, data, definitions, schema, schemaEnv} = cxt + const {ref} = schema + const refSchema = definitions[ref] + if (!refSchema) throw new MissingRefError(self.opts.uriResolver, "", ref, `No definition ${ref}`) + if (!hasRef(refSchema)) return serializeCode({...cxt, schema: refSchema}) + const {root} = schemaEnv + const sch = compileSerializer.call(self, new SchemaEnv({schema: refSchema, root}), definitions) + gen.add(N.json, _`${getSerialize(gen, sch)}(${data})`) +} + +function getSerialize(gen: CodeGen, sch: SchemaEnv): Code { + return sch.serialize + ? gen.scopeValue("serialize", {ref: sch.serialize}) + : _`${gen.scopeValue("wrapper", {ref: sch})}.serialize` +} + +function serializeEmpty({gen, data}: SerializeCxt): void { + gen.add(N.json, _`JSON.stringify(${data})`) +} + +function addComma({gen}: SerializeCxt, first?: Name): void { + if (first) { + gen.if( + first, + () => gen.assign(first, false), + () => gen.add(N.json, str`,`) + ) + } else { + gen.add(N.json, str`,`) + } +} diff --git a/libs/events/node_modules/ajv/lib/compile/jtd/types.ts b/libs/events/node_modules/ajv/lib/compile/jtd/types.ts new file mode 100644 index 000000000..7f3619576 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/jtd/types.ts @@ -0,0 +1,16 @@ +import type {SchemaObject} from "../../types" + +export type SchemaObjectMap = {[Ref in string]?: SchemaObject} + +export const jtdForms = [ + "elements", + "values", + "discriminator", + "properties", + "optionalProperties", + "enum", + "type", + "ref", +] as const + +export type JTDForm = typeof jtdForms[number] diff --git a/libs/events/node_modules/ajv/lib/compile/names.ts b/libs/events/node_modules/ajv/lib/compile/names.ts new file mode 100644 index 000000000..b4b242e17 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/names.ts @@ -0,0 +1,27 @@ +import {Name} from "./codegen" + +const names = { + // validation function arguments + data: new Name("data"), // data passed to validation function + // args passed from referencing schema + valCxt: new Name("valCxt"), // validation/data context - should not be used directly, it is destructured to the names below + instancePath: new Name("instancePath"), + parentData: new Name("parentData"), + parentDataProperty: new Name("parentDataProperty"), + rootData: new Name("rootData"), // root data - same as the data passed to the first/top validation function + dynamicAnchors: new Name("dynamicAnchors"), // used to support recursiveRef and dynamicRef + // function scoped variables + vErrors: new Name("vErrors"), // null or array of validation errors + errors: new Name("errors"), // counter of validation errors + this: new Name("this"), + // "globals" + self: new Name("self"), + scope: new Name("scope"), + // JTD serialize/parse name for JSON string and position + json: new Name("json"), + jsonPos: new Name("jsonPos"), + jsonLen: new Name("jsonLen"), + jsonPart: new Name("jsonPart"), +} + +export default names diff --git a/libs/events/node_modules/ajv/lib/compile/ref_error.ts b/libs/events/node_modules/ajv/lib/compile/ref_error.ts new file mode 100644 index 000000000..386bf0499 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/ref_error.ts @@ -0,0 +1,13 @@ +import {resolveUrl, normalizeId, getFullPath} from "./resolve" +import type {UriResolver} from "../types" + +export default class MissingRefError extends Error { + readonly missingRef: string + readonly missingSchema: string + + constructor(resolver: UriResolver, baseId: string, ref: string, msg?: string) { + super(msg || `can't resolve reference ${ref} from id ${baseId}`) + this.missingRef = resolveUrl(resolver, baseId, ref) + this.missingSchema = normalizeId(getFullPath(resolver, this.missingRef)) + } +} diff --git a/libs/events/node_modules/ajv/lib/compile/resolve.ts b/libs/events/node_modules/ajv/lib/compile/resolve.ts new file mode 100644 index 000000000..4360eab06 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/resolve.ts @@ -0,0 +1,149 @@ +import type {AnySchema, AnySchemaObject, UriResolver} from "../types" +import type Ajv from "../ajv" +import type {URIComponents} from "uri-js" +import {eachItem} from "./util" +import * as equal from "fast-deep-equal" +import * as traverse from "json-schema-traverse" + +// the hash of local references inside the schema (created by getSchemaRefs), used for inline resolution +export type LocalRefs = {[Ref in string]?: AnySchemaObject} + +// TODO refactor to use keyword definitions +const SIMPLE_INLINED = new Set([ + "type", + "format", + "pattern", + "maxLength", + "minLength", + "maxProperties", + "minProperties", + "maxItems", + "minItems", + "maximum", + "minimum", + "uniqueItems", + "multipleOf", + "required", + "enum", + "const", +]) + +export function inlineRef(schema: AnySchema, limit: boolean | number = true): boolean { + if (typeof schema == "boolean") return true + if (limit === true) return !hasRef(schema) + if (!limit) return false + return countKeys(schema) <= limit +} + +const REF_KEYWORDS = new Set([ + "$ref", + "$recursiveRef", + "$recursiveAnchor", + "$dynamicRef", + "$dynamicAnchor", +]) + +function hasRef(schema: AnySchemaObject): boolean { + for (const key in schema) { + if (REF_KEYWORDS.has(key)) return true + const sch = schema[key] + if (Array.isArray(sch) && sch.some(hasRef)) return true + if (typeof sch == "object" && hasRef(sch)) return true + } + return false +} + +function countKeys(schema: AnySchemaObject): number { + let count = 0 + for (const key in schema) { + if (key === "$ref") return Infinity + count++ + if (SIMPLE_INLINED.has(key)) continue + if (typeof schema[key] == "object") { + eachItem(schema[key], (sch) => (count += countKeys(sch))) + } + if (count === Infinity) return Infinity + } + return count +} + +export function getFullPath(resolver: UriResolver, id = "", normalize?: boolean): string { + if (normalize !== false) id = normalizeId(id) + const p = resolver.parse(id) + return _getFullPath(resolver, p) +} + +export function _getFullPath(resolver: UriResolver, p: URIComponents): string { + const serialized = resolver.serialize(p) + return serialized.split("#")[0] + "#" +} + +const TRAILING_SLASH_HASH = /#\/?$/ +export function normalizeId(id: string | undefined): string { + return id ? id.replace(TRAILING_SLASH_HASH, "") : "" +} + +export function resolveUrl(resolver: UriResolver, baseId: string, id: string): string { + id = normalizeId(id) + return resolver.resolve(baseId, id) +} + +const ANCHOR = /^[a-z_][-a-z0-9._]*$/i + +export function getSchemaRefs(this: Ajv, schema: AnySchema, baseId: string): LocalRefs { + if (typeof schema == "boolean") return {} + const {schemaId, uriResolver} = this.opts + const schId = normalizeId(schema[schemaId] || baseId) + const baseIds: {[JsonPtr in string]?: string} = {"": schId} + const pathPrefix = getFullPath(uriResolver, schId, false) + const localRefs: LocalRefs = {} + const schemaRefs: Set = new Set() + + traverse(schema, {allKeys: true}, (sch, jsonPtr, _, parentJsonPtr) => { + if (parentJsonPtr === undefined) return + const fullPath = pathPrefix + jsonPtr + let baseId = baseIds[parentJsonPtr] + if (typeof sch[schemaId] == "string") baseId = addRef.call(this, sch[schemaId]) + addAnchor.call(this, sch.$anchor) + addAnchor.call(this, sch.$dynamicAnchor) + baseIds[jsonPtr] = baseId + + function addRef(this: Ajv, ref: string): string { + // eslint-disable-next-line @typescript-eslint/unbound-method + const _resolve = this.opts.uriResolver.resolve + ref = normalizeId(baseId ? _resolve(baseId, ref) : ref) + if (schemaRefs.has(ref)) throw ambiguos(ref) + schemaRefs.add(ref) + let schOrRef = this.refs[ref] + if (typeof schOrRef == "string") schOrRef = this.refs[schOrRef] + if (typeof schOrRef == "object") { + checkAmbiguosRef(sch, schOrRef.schema, ref) + } else if (ref !== normalizeId(fullPath)) { + if (ref[0] === "#") { + checkAmbiguosRef(sch, localRefs[ref], ref) + localRefs[ref] = sch + } else { + this.refs[ref] = fullPath + } + } + return ref + } + + function addAnchor(this: Ajv, anchor: unknown): void { + if (typeof anchor == "string") { + if (!ANCHOR.test(anchor)) throw new Error(`invalid anchor "${anchor}"`) + addRef.call(this, `#${anchor}`) + } + } + }) + + return localRefs + + function checkAmbiguosRef(sch1: AnySchema, sch2: AnySchema | undefined, ref: string): void { + if (sch2 !== undefined && !equal(sch1, sch2)) throw ambiguos(ref) + } + + function ambiguos(ref: string): Error { + return new Error(`reference "${ref}" resolves to more than one schema`) + } +} diff --git a/libs/events/node_modules/ajv/lib/compile/rules.ts b/libs/events/node_modules/ajv/lib/compile/rules.ts new file mode 100644 index 000000000..ea65074f9 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/rules.ts @@ -0,0 +1,50 @@ +import type {AddedKeywordDefinition} from "../types" + +const _jsonTypes = ["string", "number", "integer", "boolean", "null", "object", "array"] as const + +export type JSONType = typeof _jsonTypes[number] + +const jsonTypes: Set = new Set(_jsonTypes) + +export function isJSONType(x: unknown): x is JSONType { + return typeof x == "string" && jsonTypes.has(x) +} + +type ValidationTypes = { + [K in JSONType]: boolean | RuleGroup | undefined +} + +export interface ValidationRules { + rules: RuleGroup[] + post: RuleGroup + all: {[Key in string]?: boolean | Rule} // rules that have to be validated + keywords: {[Key in string]?: boolean} // all known keywords (superset of "all") + types: ValidationTypes +} + +export interface RuleGroup { + type?: JSONType + rules: Rule[] +} + +// This interface wraps KeywordDefinition because definition can have multiple keywords +export interface Rule { + keyword: string + definition: AddedKeywordDefinition +} + +export function getRules(): ValidationRules { + const groups: Record<"number" | "string" | "array" | "object", RuleGroup> = { + number: {type: "number", rules: []}, + string: {type: "string", rules: []}, + array: {type: "array", rules: []}, + object: {type: "object", rules: []}, + } + return { + types: {...groups, integer: true, boolean: true, null: true}, + rules: [{rules: []}, groups.number, groups.string, groups.array, groups.object], + post: {rules: []}, + all: {}, + keywords: {}, + } +} diff --git a/libs/events/node_modules/ajv/lib/compile/util.ts b/libs/events/node_modules/ajv/lib/compile/util.ts new file mode 100644 index 000000000..cefae51c2 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/util.ts @@ -0,0 +1,213 @@ +import type {AnySchema, EvaluatedProperties, EvaluatedItems} from "../types" +import type {SchemaCxt, SchemaObjCxt} from "." +import {_, getProperty, Code, Name, CodeGen} from "./codegen" +import {_Code} from "./codegen/code" +import type {Rule, ValidationRules} from "./rules" + +// TODO refactor to use Set +export function toHash(arr: T[]): {[K in T]?: true} { + const hash: {[K in T]?: true} = {} + for (const item of arr) hash[item] = true + return hash +} + +export function alwaysValidSchema(it: SchemaCxt, schema: AnySchema): boolean | void { + if (typeof schema == "boolean") return schema + if (Object.keys(schema).length === 0) return true + checkUnknownRules(it, schema) + return !schemaHasRules(schema, it.self.RULES.all) +} + +export function checkUnknownRules(it: SchemaCxt, schema: AnySchema = it.schema): void { + const {opts, self} = it + if (!opts.strictSchema) return + if (typeof schema === "boolean") return + const rules = self.RULES.keywords + for (const key in schema) { + if (!rules[key]) checkStrictMode(it, `unknown keyword: "${key}"`) + } +} + +export function schemaHasRules( + schema: AnySchema, + rules: {[Key in string]?: boolean | Rule} +): boolean { + if (typeof schema == "boolean") return !schema + for (const key in schema) if (rules[key]) return true + return false +} + +export function schemaHasRulesButRef(schema: AnySchema, RULES: ValidationRules): boolean { + if (typeof schema == "boolean") return !schema + for (const key in schema) if (key !== "$ref" && RULES.all[key]) return true + return false +} + +export function schemaRefOrVal( + {topSchemaRef, schemaPath}: SchemaObjCxt, + schema: unknown, + keyword: string, + $data?: string | false +): Code | number | boolean { + if (!$data) { + if (typeof schema == "number" || typeof schema == "boolean") return schema + if (typeof schema == "string") return _`${schema}` + } + return _`${topSchemaRef}${schemaPath}${getProperty(keyword)}` +} + +export function unescapeFragment(str: string): string { + return unescapeJsonPointer(decodeURIComponent(str)) +} + +export function escapeFragment(str: string | number): string { + return encodeURIComponent(escapeJsonPointer(str)) +} + +export function escapeJsonPointer(str: string | number): string { + if (typeof str == "number") return `${str}` + return str.replace(/~/g, "~0").replace(/\//g, "~1") +} + +export function unescapeJsonPointer(str: string): string { + return str.replace(/~1/g, "/").replace(/~0/g, "~") +} + +export function eachItem(xs: T | T[], f: (x: T) => void): void { + if (Array.isArray(xs)) { + for (const x of xs) f(x) + } else { + f(xs) + } +} + +type SomeEvaluated = EvaluatedProperties | EvaluatedItems + +type MergeEvaluatedFunc = ( + gen: CodeGen, + from: Name | T, + to: Name | Exclude | undefined, + toName?: typeof Name +) => Name | T + +interface MakeMergeFuncArgs { + mergeNames: (gen: CodeGen, from: Name, to: Name) => void + mergeToName: (gen: CodeGen, from: T, to: Name) => void + mergeValues: (from: T, to: Exclude) => T + resultToName: (gen: CodeGen, res?: T) => Name +} + +function makeMergeEvaluated({ + mergeNames, + mergeToName, + mergeValues, + resultToName, +}: MakeMergeFuncArgs): MergeEvaluatedFunc { + return (gen, from, to, toName) => { + const res = + to === undefined + ? from + : to instanceof Name + ? (from instanceof Name ? mergeNames(gen, from, to) : mergeToName(gen, from, to), to) + : from instanceof Name + ? (mergeToName(gen, to, from), from) + : mergeValues(from, to) + return toName === Name && !(res instanceof Name) ? resultToName(gen, res) : res + } +} + +interface MergeEvaluated { + props: MergeEvaluatedFunc + items: MergeEvaluatedFunc +} + +export const mergeEvaluated: MergeEvaluated = { + props: makeMergeEvaluated({ + mergeNames: (gen, from, to) => + gen.if(_`${to} !== true && ${from} !== undefined`, () => { + gen.if( + _`${from} === true`, + () => gen.assign(to, true), + () => gen.assign(to, _`${to} || {}`).code(_`Object.assign(${to}, ${from})`) + ) + }), + mergeToName: (gen, from, to) => + gen.if(_`${to} !== true`, () => { + if (from === true) { + gen.assign(to, true) + } else { + gen.assign(to, _`${to} || {}`) + setEvaluated(gen, to, from) + } + }), + mergeValues: (from, to) => (from === true ? true : {...from, ...to}), + resultToName: evaluatedPropsToName, + }), + items: makeMergeEvaluated({ + mergeNames: (gen, from, to) => + gen.if(_`${to} !== true && ${from} !== undefined`, () => + gen.assign(to, _`${from} === true ? true : ${to} > ${from} ? ${to} : ${from}`) + ), + mergeToName: (gen, from, to) => + gen.if(_`${to} !== true`, () => + gen.assign(to, from === true ? true : _`${to} > ${from} ? ${to} : ${from}`) + ), + mergeValues: (from, to) => (from === true ? true : Math.max(from, to)), + resultToName: (gen, items) => gen.var("items", items), + }), +} + +export function evaluatedPropsToName(gen: CodeGen, ps?: EvaluatedProperties): Name { + if (ps === true) return gen.var("props", true) + const props = gen.var("props", _`{}`) + if (ps !== undefined) setEvaluated(gen, props, ps) + return props +} + +export function setEvaluated(gen: CodeGen, props: Name, ps: {[K in string]?: true}): void { + Object.keys(ps).forEach((p) => gen.assign(_`${props}${getProperty(p)}`, true)) +} + +const snippets: {[S in string]?: _Code} = {} + +export function useFunc(gen: CodeGen, f: {code: string}): Name { + return gen.scopeValue("func", { + ref: f, + code: snippets[f.code] || (snippets[f.code] = new _Code(f.code)), + }) +} + +export enum Type { + Num, + Str, +} + +export function getErrorPath( + dataProp: Name | string | number, + dataPropType?: Type, + jsPropertySyntax?: boolean +): Code | string { + // let path + if (dataProp instanceof Name) { + const isNumber = dataPropType === Type.Num + return jsPropertySyntax + ? isNumber + ? _`"[" + ${dataProp} + "]"` + : _`"['" + ${dataProp} + "']"` + : isNumber + ? _`"/" + ${dataProp}` + : _`"/" + ${dataProp}.replace(/~/g, "~0").replace(/\\//g, "~1")` // TODO maybe use global escapePointer + } + return jsPropertySyntax ? getProperty(dataProp).toString() : "/" + escapeJsonPointer(dataProp) +} + +export function checkStrictMode( + it: SchemaCxt, + msg: string, + mode: boolean | "log" = it.opts.strictSchema +): void { + if (!mode) return + msg = `strict mode: ${msg}` + if (mode === true) throw new Error(msg) + it.self.logger.warn(msg) +} diff --git a/libs/events/node_modules/ajv/lib/compile/validate/applicability.ts b/libs/events/node_modules/ajv/lib/compile/validate/applicability.ts new file mode 100644 index 000000000..478b704ac --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/validate/applicability.ts @@ -0,0 +1,22 @@ +import type {AnySchemaObject} from "../../types" +import type {SchemaObjCxt} from ".." +import type {JSONType, RuleGroup, Rule} from "../rules" + +export function schemaHasRulesForType( + {schema, self}: SchemaObjCxt, + type: JSONType +): boolean | undefined { + const group = self.RULES.types[type] + return group && group !== true && shouldUseGroup(schema, group) +} + +export function shouldUseGroup(schema: AnySchemaObject, group: RuleGroup): boolean { + return group.rules.some((rule) => shouldUseRule(schema, rule)) +} + +export function shouldUseRule(schema: AnySchemaObject, rule: Rule): boolean | undefined { + return ( + schema[rule.keyword] !== undefined || + rule.definition.implements?.some((kwd) => schema[kwd] !== undefined) + ) +} diff --git a/libs/events/node_modules/ajv/lib/compile/validate/boolSchema.ts b/libs/events/node_modules/ajv/lib/compile/validate/boolSchema.ts new file mode 100644 index 000000000..156355016 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/validate/boolSchema.ts @@ -0,0 +1,47 @@ +import type {KeywordErrorDefinition, KeywordErrorCxt} from "../../types" +import type {SchemaCxt} from ".." +import {reportError} from "../errors" +import {_, Name} from "../codegen" +import N from "../names" + +const boolError: KeywordErrorDefinition = { + message: "boolean schema is false", +} + +export function topBoolOrEmptySchema(it: SchemaCxt): void { + const {gen, schema, validateName} = it + if (schema === false) { + falseSchemaError(it, false) + } else if (typeof schema == "object" && schema.$async === true) { + gen.return(N.data) + } else { + gen.assign(_`${validateName}.errors`, null) + gen.return(true) + } +} + +export function boolOrEmptySchema(it: SchemaCxt, valid: Name): void { + const {gen, schema} = it + if (schema === false) { + gen.var(valid, false) // TODO var + falseSchemaError(it) + } else { + gen.var(valid, true) // TODO var + } +} + +function falseSchemaError(it: SchemaCxt, overrideAllErrors?: boolean): void { + const {gen, data} = it + // TODO maybe some other interface should be used for non-keyword validation errors... + const cxt: KeywordErrorCxt = { + gen, + keyword: "false schema", + data, + schema: false, + schemaCode: false, + schemaValue: false, + params: {}, + it, + } + reportError(cxt, boolError, undefined, overrideAllErrors) +} diff --git a/libs/events/node_modules/ajv/lib/compile/validate/dataType.ts b/libs/events/node_modules/ajv/lib/compile/validate/dataType.ts new file mode 100644 index 000000000..b315c2ce9 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/validate/dataType.ts @@ -0,0 +1,229 @@ +import type { + KeywordErrorDefinition, + KeywordErrorCxt, + ErrorObject, + AnySchemaObject, +} from "../../types" +import type {SchemaObjCxt} from ".." +import {isJSONType, JSONType} from "../rules" +import {schemaHasRulesForType} from "./applicability" +import {reportError} from "../errors" +import {_, nil, and, not, operators, Code, Name} from "../codegen" +import {toHash, schemaRefOrVal} from "../util" + +export enum DataType { + Correct, + Wrong, +} + +export function getSchemaTypes(schema: AnySchemaObject): JSONType[] { + const types = getJSONTypes(schema.type) + const hasNull = types.includes("null") + if (hasNull) { + if (schema.nullable === false) throw new Error("type: null contradicts nullable: false") + } else { + if (!types.length && schema.nullable !== undefined) { + throw new Error('"nullable" cannot be used without "type"') + } + if (schema.nullable === true) types.push("null") + } + return types +} + +export function getJSONTypes(ts: unknown | unknown[]): JSONType[] { + const types: unknown[] = Array.isArray(ts) ? ts : ts ? [ts] : [] + if (types.every(isJSONType)) return types + throw new Error("type must be JSONType or JSONType[]: " + types.join(",")) +} + +export function coerceAndCheckDataType(it: SchemaObjCxt, types: JSONType[]): boolean { + const {gen, data, opts} = it + const coerceTo = coerceToTypes(types, opts.coerceTypes) + const checkTypes = + types.length > 0 && + !(coerceTo.length === 0 && types.length === 1 && schemaHasRulesForType(it, types[0])) + if (checkTypes) { + const wrongType = checkDataTypes(types, data, opts.strictNumbers, DataType.Wrong) + gen.if(wrongType, () => { + if (coerceTo.length) coerceData(it, types, coerceTo) + else reportTypeError(it) + }) + } + return checkTypes +} + +const COERCIBLE: Set = new Set(["string", "number", "integer", "boolean", "null"]) +function coerceToTypes(types: JSONType[], coerceTypes?: boolean | "array"): JSONType[] { + return coerceTypes + ? types.filter((t) => COERCIBLE.has(t) || (coerceTypes === "array" && t === "array")) + : [] +} + +function coerceData(it: SchemaObjCxt, types: JSONType[], coerceTo: JSONType[]): void { + const {gen, data, opts} = it + const dataType = gen.let("dataType", _`typeof ${data}`) + const coerced = gen.let("coerced", _`undefined`) + if (opts.coerceTypes === "array") { + gen.if(_`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => + gen + .assign(data, _`${data}[0]`) + .assign(dataType, _`typeof ${data}`) + .if(checkDataTypes(types, data, opts.strictNumbers), () => gen.assign(coerced, data)) + ) + } + gen.if(_`${coerced} !== undefined`) + for (const t of coerceTo) { + if (COERCIBLE.has(t) || (t === "array" && opts.coerceTypes === "array")) { + coerceSpecificType(t) + } + } + gen.else() + reportTypeError(it) + gen.endIf() + + gen.if(_`${coerced} !== undefined`, () => { + gen.assign(data, coerced) + assignParentData(it, coerced) + }) + + function coerceSpecificType(t: string): void { + switch (t) { + case "string": + gen + .elseIf(_`${dataType} == "number" || ${dataType} == "boolean"`) + .assign(coerced, _`"" + ${data}`) + .elseIf(_`${data} === null`) + .assign(coerced, _`""`) + return + case "number": + gen + .elseIf( + _`${dataType} == "boolean" || ${data} === null + || (${dataType} == "string" && ${data} && ${data} == +${data})` + ) + .assign(coerced, _`+${data}`) + return + case "integer": + gen + .elseIf( + _`${dataType} === "boolean" || ${data} === null + || (${dataType} === "string" && ${data} && ${data} == +${data} && !(${data} % 1))` + ) + .assign(coerced, _`+${data}`) + return + case "boolean": + gen + .elseIf(_`${data} === "false" || ${data} === 0 || ${data} === null`) + .assign(coerced, false) + .elseIf(_`${data} === "true" || ${data} === 1`) + .assign(coerced, true) + return + case "null": + gen.elseIf(_`${data} === "" || ${data} === 0 || ${data} === false`) + gen.assign(coerced, null) + return + + case "array": + gen + .elseIf( + _`${dataType} === "string" || ${dataType} === "number" + || ${dataType} === "boolean" || ${data} === null` + ) + .assign(coerced, _`[${data}]`) + } + } +} + +function assignParentData({gen, parentData, parentDataProperty}: SchemaObjCxt, expr: Name): void { + // TODO use gen.property + gen.if(_`${parentData} !== undefined`, () => + gen.assign(_`${parentData}[${parentDataProperty}]`, expr) + ) +} + +export function checkDataType( + dataType: JSONType, + data: Name, + strictNums?: boolean | "log", + correct = DataType.Correct +): Code { + const EQ = correct === DataType.Correct ? operators.EQ : operators.NEQ + let cond: Code + switch (dataType) { + case "null": + return _`${data} ${EQ} null` + case "array": + cond = _`Array.isArray(${data})` + break + case "object": + cond = _`${data} && typeof ${data} == "object" && !Array.isArray(${data})` + break + case "integer": + cond = numCond(_`!(${data} % 1) && !isNaN(${data})`) + break + case "number": + cond = numCond() + break + default: + return _`typeof ${data} ${EQ} ${dataType}` + } + return correct === DataType.Correct ? cond : not(cond) + + function numCond(_cond: Code = nil): Code { + return and(_`typeof ${data} == "number"`, _cond, strictNums ? _`isFinite(${data})` : nil) + } +} + +export function checkDataTypes( + dataTypes: JSONType[], + data: Name, + strictNums?: boolean | "log", + correct?: DataType +): Code { + if (dataTypes.length === 1) { + return checkDataType(dataTypes[0], data, strictNums, correct) + } + let cond: Code + const types = toHash(dataTypes) + if (types.array && types.object) { + const notObj = _`typeof ${data} != "object"` + cond = types.null ? notObj : _`!${data} || ${notObj}` + delete types.null + delete types.array + delete types.object + } else { + cond = nil + } + if (types.number) delete types.integer + for (const t in types) cond = and(cond, checkDataType(t as JSONType, data, strictNums, correct)) + return cond +} + +export type TypeError = ErrorObject<"type", {type: string}> + +const typeError: KeywordErrorDefinition = { + message: ({schema}) => `must be ${schema}`, + params: ({schema, schemaValue}) => + typeof schema == "string" ? _`{type: ${schema}}` : _`{type: ${schemaValue}}`, +} + +export function reportTypeError(it: SchemaObjCxt): void { + const cxt = getTypeErrorContext(it) + reportError(cxt, typeError) +} + +function getTypeErrorContext(it: SchemaObjCxt): KeywordErrorCxt { + const {gen, data, schema} = it + const schemaCode = schemaRefOrVal(it, schema, "type") + return { + gen, + keyword: "type", + data, + schema: schema.type, + schemaCode, + schemaValue: schemaCode, + parentSchema: schema, + params: {}, + it, + } +} diff --git a/libs/events/node_modules/ajv/lib/compile/validate/defaults.ts b/libs/events/node_modules/ajv/lib/compile/validate/defaults.ts new file mode 100644 index 000000000..2ad3d4df8 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/validate/defaults.ts @@ -0,0 +1,32 @@ +import type {SchemaObjCxt} from ".." +import {_, getProperty, stringify} from "../codegen" +import {checkStrictMode} from "../util" + +export function assignDefaults(it: SchemaObjCxt, ty?: string): void { + const {properties, items} = it.schema + if (ty === "object" && properties) { + for (const key in properties) { + assignDefault(it, key, properties[key].default) + } + } else if (ty === "array" && Array.isArray(items)) { + items.forEach((sch, i: number) => assignDefault(it, i, sch.default)) + } +} + +function assignDefault(it: SchemaObjCxt, prop: string | number, defaultValue: unknown): void { + const {gen, compositeRule, data, opts} = it + if (defaultValue === undefined) return + const childData = _`${data}${getProperty(prop)}` + if (compositeRule) { + checkStrictMode(it, `default is ignored for: ${childData}`) + return + } + + let condition = _`${childData} === undefined` + if (opts.useDefaults === "empty") { + condition = _`${condition} || ${childData} === null || ${childData} === ""` + } + // `${childData} === undefined` + + // (opts.useDefaults === "empty" ? ` || ${childData} === null || ${childData} === ""` : "") + gen.if(condition, _`${childData} = ${stringify(defaultValue)}`) +} diff --git a/libs/events/node_modules/ajv/lib/compile/validate/index.ts b/libs/events/node_modules/ajv/lib/compile/validate/index.ts new file mode 100644 index 000000000..15ecabd85 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/validate/index.ts @@ -0,0 +1,582 @@ +import type { + AddedKeywordDefinition, + AnySchema, + AnySchemaObject, + KeywordErrorCxt, + KeywordCxtParams, +} from "../../types" +import type {SchemaCxt, SchemaObjCxt} from ".." +import type {InstanceOptions} from "../../core" +import {boolOrEmptySchema, topBoolOrEmptySchema} from "./boolSchema" +import {coerceAndCheckDataType, getSchemaTypes} from "./dataType" +import {shouldUseGroup, shouldUseRule} from "./applicability" +import {checkDataType, checkDataTypes, reportTypeError, DataType} from "./dataType" +import {assignDefaults} from "./defaults" +import {funcKeywordCode, macroKeywordCode, validateKeywordUsage, validSchemaType} from "./keyword" +import {getSubschema, extendSubschemaData, SubschemaArgs, extendSubschemaMode} from "./subschema" +import {_, nil, str, or, not, getProperty, Block, Code, Name, CodeGen} from "../codegen" +import N from "../names" +import {resolveUrl} from "../resolve" +import { + schemaRefOrVal, + schemaHasRulesButRef, + checkUnknownRules, + checkStrictMode, + unescapeJsonPointer, + mergeEvaluated, +} from "../util" +import type {JSONType, Rule, RuleGroup} from "../rules" +import { + ErrorPaths, + reportError, + reportExtraError, + resetErrorsCount, + keyword$DataError, +} from "../errors" + +// schema compilation - generates validation function, subschemaCode (below) is used for subschemas +export function validateFunctionCode(it: SchemaCxt): void { + if (isSchemaObj(it)) { + checkKeywords(it) + if (schemaCxtHasRules(it)) { + topSchemaObjCode(it) + return + } + } + validateFunction(it, () => topBoolOrEmptySchema(it)) +} + +function validateFunction( + {gen, validateName, schema, schemaEnv, opts}: SchemaCxt, + body: Block +): void { + if (opts.code.es5) { + gen.func(validateName, _`${N.data}, ${N.valCxt}`, schemaEnv.$async, () => { + gen.code(_`"use strict"; ${funcSourceUrl(schema, opts)}`) + destructureValCxtES5(gen, opts) + gen.code(body) + }) + } else { + gen.func(validateName, _`${N.data}, ${destructureValCxt(opts)}`, schemaEnv.$async, () => + gen.code(funcSourceUrl(schema, opts)).code(body) + ) + } +} + +function destructureValCxt(opts: InstanceOptions): Code { + return _`{${N.instancePath}="", ${N.parentData}, ${N.parentDataProperty}, ${N.rootData}=${ + N.data + }${opts.dynamicRef ? _`, ${N.dynamicAnchors}={}` : nil}}={}` +} + +function destructureValCxtES5(gen: CodeGen, opts: InstanceOptions): void { + gen.if( + N.valCxt, + () => { + gen.var(N.instancePath, _`${N.valCxt}.${N.instancePath}`) + gen.var(N.parentData, _`${N.valCxt}.${N.parentData}`) + gen.var(N.parentDataProperty, _`${N.valCxt}.${N.parentDataProperty}`) + gen.var(N.rootData, _`${N.valCxt}.${N.rootData}`) + if (opts.dynamicRef) gen.var(N.dynamicAnchors, _`${N.valCxt}.${N.dynamicAnchors}`) + }, + () => { + gen.var(N.instancePath, _`""`) + gen.var(N.parentData, _`undefined`) + gen.var(N.parentDataProperty, _`undefined`) + gen.var(N.rootData, N.data) + if (opts.dynamicRef) gen.var(N.dynamicAnchors, _`{}`) + } + ) +} + +function topSchemaObjCode(it: SchemaObjCxt): void { + const {schema, opts, gen} = it + validateFunction(it, () => { + if (opts.$comment && schema.$comment) commentKeyword(it) + checkNoDefault(it) + gen.let(N.vErrors, null) + gen.let(N.errors, 0) + if (opts.unevaluated) resetEvaluated(it) + typeAndKeywords(it) + returnResults(it) + }) + return +} + +function resetEvaluated(it: SchemaObjCxt): void { + // TODO maybe some hook to execute it in the end to check whether props/items are Name, as in assignEvaluated + const {gen, validateName} = it + it.evaluated = gen.const("evaluated", _`${validateName}.evaluated`) + gen.if(_`${it.evaluated}.dynamicProps`, () => gen.assign(_`${it.evaluated}.props`, _`undefined`)) + gen.if(_`${it.evaluated}.dynamicItems`, () => gen.assign(_`${it.evaluated}.items`, _`undefined`)) +} + +function funcSourceUrl(schema: AnySchema, opts: InstanceOptions): Code { + const schId = typeof schema == "object" && schema[opts.schemaId] + return schId && (opts.code.source || opts.code.process) ? _`/*# sourceURL=${schId} */` : nil +} + +// schema compilation - this function is used recursively to generate code for sub-schemas +function subschemaCode(it: SchemaCxt, valid: Name): void { + if (isSchemaObj(it)) { + checkKeywords(it) + if (schemaCxtHasRules(it)) { + subSchemaObjCode(it, valid) + return + } + } + boolOrEmptySchema(it, valid) +} + +function schemaCxtHasRules({schema, self}: SchemaCxt): boolean { + if (typeof schema == "boolean") return !schema + for (const key in schema) if (self.RULES.all[key]) return true + return false +} + +function isSchemaObj(it: SchemaCxt): it is SchemaObjCxt { + return typeof it.schema != "boolean" +} + +function subSchemaObjCode(it: SchemaObjCxt, valid: Name): void { + const {schema, gen, opts} = it + if (opts.$comment && schema.$comment) commentKeyword(it) + updateContext(it) + checkAsyncSchema(it) + const errsCount = gen.const("_errs", N.errors) + typeAndKeywords(it, errsCount) + // TODO var + gen.var(valid, _`${errsCount} === ${N.errors}`) +} + +function checkKeywords(it: SchemaObjCxt): void { + checkUnknownRules(it) + checkRefsAndKeywords(it) +} + +function typeAndKeywords(it: SchemaObjCxt, errsCount?: Name): void { + if (it.opts.jtd) return schemaKeywords(it, [], false, errsCount) + const types = getSchemaTypes(it.schema) + const checkedTypes = coerceAndCheckDataType(it, types) + schemaKeywords(it, types, !checkedTypes, errsCount) +} + +function checkRefsAndKeywords(it: SchemaObjCxt): void { + const {schema, errSchemaPath, opts, self} = it + if (schema.$ref && opts.ignoreKeywordsWithRef && schemaHasRulesButRef(schema, self.RULES)) { + self.logger.warn(`$ref: keywords ignored in schema at path "${errSchemaPath}"`) + } +} + +function checkNoDefault(it: SchemaObjCxt): void { + const {schema, opts} = it + if (schema.default !== undefined && opts.useDefaults && opts.strictSchema) { + checkStrictMode(it, "default is ignored in the schema root") + } +} + +function updateContext(it: SchemaObjCxt): void { + const schId = it.schema[it.opts.schemaId] + if (schId) it.baseId = resolveUrl(it.opts.uriResolver, it.baseId, schId) +} + +function checkAsyncSchema(it: SchemaObjCxt): void { + if (it.schema.$async && !it.schemaEnv.$async) throw new Error("async schema in sync schema") +} + +function commentKeyword({gen, schemaEnv, schema, errSchemaPath, opts}: SchemaObjCxt): void { + const msg = schema.$comment + if (opts.$comment === true) { + gen.code(_`${N.self}.logger.log(${msg})`) + } else if (typeof opts.$comment == "function") { + const schemaPath = str`${errSchemaPath}/$comment` + const rootName = gen.scopeValue("root", {ref: schemaEnv.root}) + gen.code(_`${N.self}.opts.$comment(${msg}, ${schemaPath}, ${rootName}.schema)`) + } +} + +function returnResults(it: SchemaCxt): void { + const {gen, schemaEnv, validateName, ValidationError, opts} = it + if (schemaEnv.$async) { + // TODO assign unevaluated + gen.if( + _`${N.errors} === 0`, + () => gen.return(N.data), + () => gen.throw(_`new ${ValidationError as Name}(${N.vErrors})`) + ) + } else { + gen.assign(_`${validateName}.errors`, N.vErrors) + if (opts.unevaluated) assignEvaluated(it) + gen.return(_`${N.errors} === 0`) + } +} + +function assignEvaluated({gen, evaluated, props, items}: SchemaCxt): void { + if (props instanceof Name) gen.assign(_`${evaluated}.props`, props) + if (items instanceof Name) gen.assign(_`${evaluated}.items`, items) +} + +function schemaKeywords( + it: SchemaObjCxt, + types: JSONType[], + typeErrors: boolean, + errsCount?: Name +): void { + const {gen, schema, data, allErrors, opts, self} = it + const {RULES} = self + if (schema.$ref && (opts.ignoreKeywordsWithRef || !schemaHasRulesButRef(schema, RULES))) { + gen.block(() => keywordCode(it, "$ref", (RULES.all.$ref as Rule).definition)) // TODO typecast + return + } + if (!opts.jtd) checkStrictTypes(it, types) + gen.block(() => { + for (const group of RULES.rules) groupKeywords(group) + groupKeywords(RULES.post) + }) + + function groupKeywords(group: RuleGroup): void { + if (!shouldUseGroup(schema, group)) return + if (group.type) { + gen.if(checkDataType(group.type, data, opts.strictNumbers)) + iterateKeywords(it, group) + if (types.length === 1 && types[0] === group.type && typeErrors) { + gen.else() + reportTypeError(it) + } + gen.endIf() + } else { + iterateKeywords(it, group) + } + // TODO make it "ok" call? + if (!allErrors) gen.if(_`${N.errors} === ${errsCount || 0}`) + } +} + +function iterateKeywords(it: SchemaObjCxt, group: RuleGroup): void { + const { + gen, + schema, + opts: {useDefaults}, + } = it + if (useDefaults) assignDefaults(it, group.type) + gen.block(() => { + for (const rule of group.rules) { + if (shouldUseRule(schema, rule)) { + keywordCode(it, rule.keyword, rule.definition, group.type) + } + } + }) +} + +function checkStrictTypes(it: SchemaObjCxt, types: JSONType[]): void { + if (it.schemaEnv.meta || !it.opts.strictTypes) return + checkContextTypes(it, types) + if (!it.opts.allowUnionTypes) checkMultipleTypes(it, types) + checkKeywordTypes(it, it.dataTypes) +} + +function checkContextTypes(it: SchemaObjCxt, types: JSONType[]): void { + if (!types.length) return + if (!it.dataTypes.length) { + it.dataTypes = types + return + } + types.forEach((t) => { + if (!includesType(it.dataTypes, t)) { + strictTypesError(it, `type "${t}" not allowed by context "${it.dataTypes.join(",")}"`) + } + }) + narrowSchemaTypes(it, types) +} + +function checkMultipleTypes(it: SchemaObjCxt, ts: JSONType[]): void { + if (ts.length > 1 && !(ts.length === 2 && ts.includes("null"))) { + strictTypesError(it, "use allowUnionTypes to allow union type keyword") + } +} + +function checkKeywordTypes(it: SchemaObjCxt, ts: JSONType[]): void { + const rules = it.self.RULES.all + for (const keyword in rules) { + const rule = rules[keyword] + if (typeof rule == "object" && shouldUseRule(it.schema, rule)) { + const {type} = rule.definition + if (type.length && !type.some((t) => hasApplicableType(ts, t))) { + strictTypesError(it, `missing type "${type.join(",")}" for keyword "${keyword}"`) + } + } + } +} + +function hasApplicableType(schTs: JSONType[], kwdT: JSONType): boolean { + return schTs.includes(kwdT) || (kwdT === "number" && schTs.includes("integer")) +} + +function includesType(ts: JSONType[], t: JSONType): boolean { + return ts.includes(t) || (t === "integer" && ts.includes("number")) +} + +function narrowSchemaTypes(it: SchemaObjCxt, withTypes: JSONType[]): void { + const ts: JSONType[] = [] + for (const t of it.dataTypes) { + if (includesType(withTypes, t)) ts.push(t) + else if (withTypes.includes("integer") && t === "number") ts.push("integer") + } + it.dataTypes = ts +} + +function strictTypesError(it: SchemaObjCxt, msg: string): void { + const schemaPath = it.schemaEnv.baseId + it.errSchemaPath + msg += ` at "${schemaPath}" (strictTypes)` + checkStrictMode(it, msg, it.opts.strictTypes) +} + +export class KeywordCxt implements KeywordErrorCxt { + readonly gen: CodeGen + readonly allErrors?: boolean + readonly keyword: string + readonly data: Name // Name referencing the current level of the data instance + readonly $data?: string | false + schema: any // keyword value in the schema + readonly schemaValue: Code | number | boolean // Code reference to keyword schema value or primitive value + readonly schemaCode: Code | number | boolean // Code reference to resolved schema value (different if schema is $data) + readonly schemaType: JSONType[] // allowed type(s) of keyword value in the schema + readonly parentSchema: AnySchemaObject + readonly errsCount?: Name // Name reference to the number of validation errors collected before this keyword, + // requires option trackErrors in keyword definition + params: KeywordCxtParams // object to pass parameters to error messages from keyword code + readonly it: SchemaObjCxt // schema compilation context (schema is guaranteed to be an object, not boolean) + readonly def: AddedKeywordDefinition + + constructor(it: SchemaObjCxt, def: AddedKeywordDefinition, keyword: string) { + validateKeywordUsage(it, def, keyword) + this.gen = it.gen + this.allErrors = it.allErrors + this.keyword = keyword + this.data = it.data + this.schema = it.schema[keyword] + this.$data = def.$data && it.opts.$data && this.schema && this.schema.$data + this.schemaValue = schemaRefOrVal(it, this.schema, keyword, this.$data) + this.schemaType = def.schemaType + this.parentSchema = it.schema + this.params = {} + this.it = it + this.def = def + + if (this.$data) { + this.schemaCode = it.gen.const("vSchema", getData(this.$data, it)) + } else { + this.schemaCode = this.schemaValue + if (!validSchemaType(this.schema, def.schemaType, def.allowUndefined)) { + throw new Error(`${keyword} value must be ${JSON.stringify(def.schemaType)}`) + } + } + + if ("code" in def ? def.trackErrors : def.errors !== false) { + this.errsCount = it.gen.const("_errs", N.errors) + } + } + + result(condition: Code, successAction?: () => void, failAction?: () => void): void { + this.failResult(not(condition), successAction, failAction) + } + + failResult(condition: Code, successAction?: () => void, failAction?: () => void): void { + this.gen.if(condition) + if (failAction) failAction() + else this.error() + if (successAction) { + this.gen.else() + successAction() + if (this.allErrors) this.gen.endIf() + } else { + if (this.allErrors) this.gen.endIf() + else this.gen.else() + } + } + + pass(condition: Code, failAction?: () => void): void { + this.failResult(not(condition), undefined, failAction) + } + + fail(condition?: Code): void { + if (condition === undefined) { + this.error() + if (!this.allErrors) this.gen.if(false) // this branch will be removed by gen.optimize + return + } + this.gen.if(condition) + this.error() + if (this.allErrors) this.gen.endIf() + else this.gen.else() + } + + fail$data(condition: Code): void { + if (!this.$data) return this.fail(condition) + const {schemaCode} = this + this.fail(_`${schemaCode} !== undefined && (${or(this.invalid$data(), condition)})`) + } + + error(append?: boolean, errorParams?: KeywordCxtParams, errorPaths?: ErrorPaths): void { + if (errorParams) { + this.setParams(errorParams) + this._error(append, errorPaths) + this.setParams({}) + return + } + this._error(append, errorPaths) + } + + private _error(append?: boolean, errorPaths?: ErrorPaths): void { + ;(append ? reportExtraError : reportError)(this, this.def.error, errorPaths) + } + + $dataError(): void { + reportError(this, this.def.$dataError || keyword$DataError) + } + + reset(): void { + if (this.errsCount === undefined) throw new Error('add "trackErrors" to keyword definition') + resetErrorsCount(this.gen, this.errsCount) + } + + ok(cond: Code | boolean): void { + if (!this.allErrors) this.gen.if(cond) + } + + setParams(obj: KeywordCxtParams, assign?: true): void { + if (assign) Object.assign(this.params, obj) + else this.params = obj + } + + block$data(valid: Name, codeBlock: () => void, $dataValid: Code = nil): void { + this.gen.block(() => { + this.check$data(valid, $dataValid) + codeBlock() + }) + } + + check$data(valid: Name = nil, $dataValid: Code = nil): void { + if (!this.$data) return + const {gen, schemaCode, schemaType, def} = this + gen.if(or(_`${schemaCode} === undefined`, $dataValid)) + if (valid !== nil) gen.assign(valid, true) + if (schemaType.length || def.validateSchema) { + gen.elseIf(this.invalid$data()) + this.$dataError() + if (valid !== nil) gen.assign(valid, false) + } + gen.else() + } + + invalid$data(): Code { + const {gen, schemaCode, schemaType, def, it} = this + return or(wrong$DataType(), invalid$DataSchema()) + + function wrong$DataType(): Code { + if (schemaType.length) { + /* istanbul ignore if */ + if (!(schemaCode instanceof Name)) throw new Error("ajv implementation error") + const st = Array.isArray(schemaType) ? schemaType : [schemaType] + return _`${checkDataTypes(st, schemaCode, it.opts.strictNumbers, DataType.Wrong)}` + } + return nil + } + + function invalid$DataSchema(): Code { + if (def.validateSchema) { + const validateSchemaRef = gen.scopeValue("validate$data", {ref: def.validateSchema}) // TODO value.code for standalone + return _`!${validateSchemaRef}(${schemaCode})` + } + return nil + } + } + + subschema(appl: SubschemaArgs, valid: Name): SchemaCxt { + const subschema = getSubschema(this.it, appl) + extendSubschemaData(subschema, this.it, appl) + extendSubschemaMode(subschema, appl) + const nextContext = {...this.it, ...subschema, items: undefined, props: undefined} + subschemaCode(nextContext, valid) + return nextContext + } + + mergeEvaluated(schemaCxt: SchemaCxt, toName?: typeof Name): void { + const {it, gen} = this + if (!it.opts.unevaluated) return + if (it.props !== true && schemaCxt.props !== undefined) { + it.props = mergeEvaluated.props(gen, schemaCxt.props, it.props, toName) + } + if (it.items !== true && schemaCxt.items !== undefined) { + it.items = mergeEvaluated.items(gen, schemaCxt.items, it.items, toName) + } + } + + mergeValidEvaluated(schemaCxt: SchemaCxt, valid: Name): boolean | void { + const {it, gen} = this + if (it.opts.unevaluated && (it.props !== true || it.items !== true)) { + gen.if(valid, () => this.mergeEvaluated(schemaCxt, Name)) + return true + } + } +} + +function keywordCode( + it: SchemaObjCxt, + keyword: string, + def: AddedKeywordDefinition, + ruleType?: JSONType +): void { + const cxt = new KeywordCxt(it, def, keyword) + if ("code" in def) { + def.code(cxt, ruleType) + } else if (cxt.$data && def.validate) { + funcKeywordCode(cxt, def) + } else if ("macro" in def) { + macroKeywordCode(cxt, def) + } else if (def.compile || def.validate) { + funcKeywordCode(cxt, def) + } +} + +const JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/ +const RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/ +export function getData( + $data: string, + {dataLevel, dataNames, dataPathArr}: SchemaCxt +): Code | number { + let jsonPointer + let data: Code + if ($data === "") return N.rootData + if ($data[0] === "/") { + if (!JSON_POINTER.test($data)) throw new Error(`Invalid JSON-pointer: ${$data}`) + jsonPointer = $data + data = N.rootData + } else { + const matches = RELATIVE_JSON_POINTER.exec($data) + if (!matches) throw new Error(`Invalid JSON-pointer: ${$data}`) + const up: number = +matches[1] + jsonPointer = matches[2] + if (jsonPointer === "#") { + if (up >= dataLevel) throw new Error(errorMsg("property/index", up)) + return dataPathArr[dataLevel - up] + } + if (up > dataLevel) throw new Error(errorMsg("data", up)) + data = dataNames[dataLevel - up] + if (!jsonPointer) return data + } + + let expr = data + const segments = jsonPointer.split("/") + for (const segment of segments) { + if (segment) { + data = _`${data}${getProperty(unescapeJsonPointer(segment))}` + expr = _`${expr} && ${data}` + } + } + return expr + + function errorMsg(pointerType: string, up: number): string { + return `Cannot access ${pointerType} ${up} levels up, current level is ${dataLevel}` + } +} diff --git a/libs/events/node_modules/ajv/lib/compile/validate/keyword.ts b/libs/events/node_modules/ajv/lib/compile/validate/keyword.ts new file mode 100644 index 000000000..f854aa710 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/validate/keyword.ts @@ -0,0 +1,171 @@ +import type {KeywordCxt} from "." +import type { + AnySchema, + SchemaValidateFunction, + AnyValidateFunction, + AddedKeywordDefinition, + MacroKeywordDefinition, + FuncKeywordDefinition, +} from "../../types" +import type {SchemaObjCxt} from ".." +import {_, nil, not, stringify, Code, Name, CodeGen} from "../codegen" +import N from "../names" +import type {JSONType} from "../rules" +import {callValidateCode} from "../../vocabularies/code" +import {extendErrors} from "../errors" + +type KeywordCompilationResult = AnySchema | SchemaValidateFunction | AnyValidateFunction + +export function macroKeywordCode(cxt: KeywordCxt, def: MacroKeywordDefinition): void { + const {gen, keyword, schema, parentSchema, it} = cxt + const macroSchema = def.macro.call(it.self, schema, parentSchema, it) + const schemaRef = useKeyword(gen, keyword, macroSchema) + if (it.opts.validateSchema !== false) it.self.validateSchema(macroSchema, true) + + const valid = gen.name("valid") + cxt.subschema( + { + schema: macroSchema, + schemaPath: nil, + errSchemaPath: `${it.errSchemaPath}/${keyword}`, + topSchemaRef: schemaRef, + compositeRule: true, + }, + valid + ) + cxt.pass(valid, () => cxt.error(true)) +} + +export function funcKeywordCode(cxt: KeywordCxt, def: FuncKeywordDefinition): void { + const {gen, keyword, schema, parentSchema, $data, it} = cxt + checkAsyncKeyword(it, def) + const validate = + !$data && def.compile ? def.compile.call(it.self, schema, parentSchema, it) : def.validate + const validateRef = useKeyword(gen, keyword, validate) + const valid = gen.let("valid") + cxt.block$data(valid, validateKeyword) + cxt.ok(def.valid ?? valid) + + function validateKeyword(): void { + if (def.errors === false) { + assignValid() + if (def.modifying) modifyData(cxt) + reportErrs(() => cxt.error()) + } else { + const ruleErrs = def.async ? validateAsync() : validateSync() + if (def.modifying) modifyData(cxt) + reportErrs(() => addErrs(cxt, ruleErrs)) + } + } + + function validateAsync(): Name { + const ruleErrs = gen.let("ruleErrs", null) + gen.try( + () => assignValid(_`await `), + (e) => + gen.assign(valid, false).if( + _`${e} instanceof ${it.ValidationError as Name}`, + () => gen.assign(ruleErrs, _`${e}.errors`), + () => gen.throw(e) + ) + ) + return ruleErrs + } + + function validateSync(): Code { + const validateErrs = _`${validateRef}.errors` + gen.assign(validateErrs, null) + assignValid(nil) + return validateErrs + } + + function assignValid(_await: Code = def.async ? _`await ` : nil): void { + const passCxt = it.opts.passContext ? N.this : N.self + const passSchema = !(("compile" in def && !$data) || def.schema === false) + gen.assign( + valid, + _`${_await}${callValidateCode(cxt, validateRef, passCxt, passSchema)}`, + def.modifying + ) + } + + function reportErrs(errors: () => void): void { + gen.if(not(def.valid ?? valid), errors) + } +} + +function modifyData(cxt: KeywordCxt): void { + const {gen, data, it} = cxt + gen.if(it.parentData, () => gen.assign(data, _`${it.parentData}[${it.parentDataProperty}]`)) +} + +function addErrs(cxt: KeywordCxt, errs: Code): void { + const {gen} = cxt + gen.if( + _`Array.isArray(${errs})`, + () => { + gen + .assign(N.vErrors, _`${N.vErrors} === null ? ${errs} : ${N.vErrors}.concat(${errs})`) + .assign(N.errors, _`${N.vErrors}.length`) + extendErrors(cxt) + }, + () => cxt.error() + ) +} + +function checkAsyncKeyword({schemaEnv}: SchemaObjCxt, def: FuncKeywordDefinition): void { + if (def.async && !schemaEnv.$async) throw new Error("async keyword in sync schema") +} + +function useKeyword(gen: CodeGen, keyword: string, result?: KeywordCompilationResult): Name { + if (result === undefined) throw new Error(`keyword "${keyword}" failed to compile`) + return gen.scopeValue( + "keyword", + typeof result == "function" ? {ref: result} : {ref: result, code: stringify(result)} + ) +} + +export function validSchemaType( + schema: unknown, + schemaType: JSONType[], + allowUndefined = false +): boolean { + // TODO add tests + return ( + !schemaType.length || + schemaType.some((st) => + st === "array" + ? Array.isArray(schema) + : st === "object" + ? schema && typeof schema == "object" && !Array.isArray(schema) + : typeof schema == st || (allowUndefined && typeof schema == "undefined") + ) + ) +} + +export function validateKeywordUsage( + {schema, opts, self, errSchemaPath}: SchemaObjCxt, + def: AddedKeywordDefinition, + keyword: string +): void { + /* istanbul ignore if */ + if (Array.isArray(def.keyword) ? !def.keyword.includes(keyword) : def.keyword !== keyword) { + throw new Error("ajv implementation error") + } + + const deps = def.dependencies + if (deps?.some((kwd) => !Object.prototype.hasOwnProperty.call(schema, kwd))) { + throw new Error(`parent schema must have dependencies of ${keyword}: ${deps.join(",")}`) + } + + if (def.validateSchema) { + const valid = def.validateSchema(schema[keyword]) + if (!valid) { + const msg = + `keyword "${keyword}" value is invalid at path "${errSchemaPath}": ` + + self.errorsText(def.validateSchema.errors) + if (opts.validateSchema === "log") self.logger.error(msg) + else throw new Error(msg) + } + } +} diff --git a/libs/events/node_modules/ajv/lib/compile/validate/subschema.ts b/libs/events/node_modules/ajv/lib/compile/validate/subschema.ts new file mode 100644 index 000000000..9072ed774 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/compile/validate/subschema.ts @@ -0,0 +1,135 @@ +import type {AnySchema} from "../../types" +import type {SchemaObjCxt} from ".." +import {_, str, getProperty, Code, Name} from "../codegen" +import {escapeFragment, getErrorPath, Type} from "../util" +import type {JSONType} from "../rules" + +export interface SubschemaContext { + // TODO use Optional? align with SchemCxt property types + schema: AnySchema + schemaPath: Code + errSchemaPath: string + topSchemaRef?: Code + errorPath?: Code + dataLevel?: number + dataTypes?: JSONType[] + data?: Name + parentData?: Name + parentDataProperty?: Code | number + dataNames?: Name[] + dataPathArr?: (Code | number)[] + propertyName?: Name + jtdDiscriminator?: string + jtdMetadata?: boolean + compositeRule?: true + createErrors?: boolean + allErrors?: boolean +} + +export type SubschemaArgs = Partial<{ + keyword: string + schemaProp: string | number + schema: AnySchema + schemaPath: Code + errSchemaPath: string + topSchemaRef: Code + data: Name | Code + dataProp: Code | string | number + dataTypes: JSONType[] + definedProperties: Set + propertyName: Name + dataPropType: Type + jtdDiscriminator: string + jtdMetadata: boolean + compositeRule: true + createErrors: boolean + allErrors: boolean +}> + +export function getSubschema( + it: SchemaObjCxt, + {keyword, schemaProp, schema, schemaPath, errSchemaPath, topSchemaRef}: SubschemaArgs +): SubschemaContext { + if (keyword !== undefined && schema !== undefined) { + throw new Error('both "keyword" and "schema" passed, only one allowed') + } + + if (keyword !== undefined) { + const sch = it.schema[keyword] + return schemaProp === undefined + ? { + schema: sch, + schemaPath: _`${it.schemaPath}${getProperty(keyword)}`, + errSchemaPath: `${it.errSchemaPath}/${keyword}`, + } + : { + schema: sch[schemaProp], + schemaPath: _`${it.schemaPath}${getProperty(keyword)}${getProperty(schemaProp)}`, + errSchemaPath: `${it.errSchemaPath}/${keyword}/${escapeFragment(schemaProp)}`, + } + } + + if (schema !== undefined) { + if (schemaPath === undefined || errSchemaPath === undefined || topSchemaRef === undefined) { + throw new Error('"schemaPath", "errSchemaPath" and "topSchemaRef" are required with "schema"') + } + return { + schema, + schemaPath, + topSchemaRef, + errSchemaPath, + } + } + + throw new Error('either "keyword" or "schema" must be passed') +} + +export function extendSubschemaData( + subschema: SubschemaContext, + it: SchemaObjCxt, + {dataProp, dataPropType: dpType, data, dataTypes, propertyName}: SubschemaArgs +): void { + if (data !== undefined && dataProp !== undefined) { + throw new Error('both "data" and "dataProp" passed, only one allowed') + } + + const {gen} = it + + if (dataProp !== undefined) { + const {errorPath, dataPathArr, opts} = it + const nextData = gen.let("data", _`${it.data}${getProperty(dataProp)}`, true) + dataContextProps(nextData) + subschema.errorPath = str`${errorPath}${getErrorPath(dataProp, dpType, opts.jsPropertySyntax)}` + subschema.parentDataProperty = _`${dataProp}` + subschema.dataPathArr = [...dataPathArr, subschema.parentDataProperty] + } + + if (data !== undefined) { + const nextData = data instanceof Name ? data : gen.let("data", data, true) // replaceable if used once? + dataContextProps(nextData) + if (propertyName !== undefined) subschema.propertyName = propertyName + // TODO something is possibly wrong here with not changing parentDataProperty and not appending dataPathArr + } + + if (dataTypes) subschema.dataTypes = dataTypes + + function dataContextProps(_nextData: Name): void { + subschema.data = _nextData + subschema.dataLevel = it.dataLevel + 1 + subschema.dataTypes = [] + it.definedProperties = new Set() + subschema.parentData = it.data + subschema.dataNames = [...it.dataNames, _nextData] + } +} + +export function extendSubschemaMode( + subschema: SubschemaContext, + {jtdDiscriminator, jtdMetadata, compositeRule, createErrors, allErrors}: SubschemaArgs +): void { + if (compositeRule !== undefined) subschema.compositeRule = compositeRule + if (createErrors !== undefined) subschema.createErrors = createErrors + if (allErrors !== undefined) subschema.allErrors = allErrors + subschema.jtdDiscriminator = jtdDiscriminator // not inherited + subschema.jtdMetadata = jtdMetadata // not inherited +} diff --git a/libs/events/node_modules/ajv/lib/core.ts b/libs/events/node_modules/ajv/lib/core.ts new file mode 100644 index 000000000..3686ffe76 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/core.ts @@ -0,0 +1,887 @@ +export { + Format, + FormatDefinition, + AsyncFormatDefinition, + KeywordDefinition, + KeywordErrorDefinition, + CodeKeywordDefinition, + MacroKeywordDefinition, + FuncKeywordDefinition, + Vocabulary, + Schema, + SchemaObject, + AnySchemaObject, + AsyncSchema, + AnySchema, + ValidateFunction, + AsyncValidateFunction, + AnyValidateFunction, + ErrorObject, + ErrorNoParams, +} from "./types" + +export {SchemaCxt, SchemaObjCxt} from "./compile" +export interface Plugin { + (ajv: Ajv, options?: Opts): Ajv + [prop: string]: any +} + +export {KeywordCxt} from "./compile/validate" +export {DefinedError} from "./vocabularies/errors" +export {JSONType} from "./compile/rules" +export {JSONSchemaType} from "./types/json-schema" +export {JTDSchemaType, SomeJTDSchemaType, JTDDataType} from "./types/jtd-schema" +export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen" + +import type { + Schema, + AnySchema, + AnySchemaObject, + SchemaObject, + AsyncSchema, + Vocabulary, + KeywordDefinition, + AddedKeywordDefinition, + AnyValidateFunction, + ValidateFunction, + AsyncValidateFunction, + ErrorObject, + Format, + AddedFormat, + RegExpEngine, + UriResolver, +} from "./types" +import type {JSONSchemaType} from "./types/json-schema" +import type {JTDSchemaType, SomeJTDSchemaType, JTDDataType} from "./types/jtd-schema" +import ValidationError from "./runtime/validation_error" +import MissingRefError from "./compile/ref_error" +import {getRules, ValidationRules, Rule, RuleGroup, JSONType} from "./compile/rules" +import {SchemaEnv, compileSchema, resolveSchema} from "./compile" +import {Code, ValueScope} from "./compile/codegen" +import {normalizeId, getSchemaRefs} from "./compile/resolve" +import {getJSONTypes} from "./compile/validate/dataType" +import {eachItem} from "./compile/util" +import * as $dataRefSchema from "./refs/data.json" + +import DefaultUriResolver from "./runtime/uri" + +const defaultRegExp: RegExpEngine = (str, flags) => new RegExp(str, flags) +defaultRegExp.code = "new RegExp" + +const META_IGNORE_OPTIONS: (keyof Options)[] = ["removeAdditional", "useDefaults", "coerceTypes"] +const EXT_SCOPE_NAMES = new Set([ + "validate", + "serialize", + "parse", + "wrapper", + "root", + "schema", + "keyword", + "pattern", + "formats", + "validate$data", + "func", + "obj", + "Error", +]) + +export type Options = CurrentOptions & DeprecatedOptions + +export interface CurrentOptions { + // strict mode options (NEW) + strict?: boolean | "log" + strictSchema?: boolean | "log" + strictNumbers?: boolean | "log" + strictTypes?: boolean | "log" + strictTuples?: boolean | "log" + strictRequired?: boolean | "log" + allowMatchingProperties?: boolean // disables a strict mode restriction + allowUnionTypes?: boolean + validateFormats?: boolean + // validation and reporting options: + $data?: boolean + allErrors?: boolean + verbose?: boolean + discriminator?: boolean + unicodeRegExp?: boolean + timestamp?: "string" | "date" // JTD only + parseDate?: boolean // JTD only + allowDate?: boolean // JTD only + $comment?: + | true + | ((comment: string, schemaPath?: string, rootSchema?: AnySchemaObject) => unknown) + formats?: {[Name in string]?: Format} + keywords?: Vocabulary + schemas?: AnySchema[] | {[Key in string]?: AnySchema} + logger?: Logger | false + loadSchema?: (uri: string) => Promise + // options to modify validated data: + removeAdditional?: boolean | "all" | "failing" + useDefaults?: boolean | "empty" + coerceTypes?: boolean | "array" + // advanced options: + next?: boolean // NEW + unevaluated?: boolean // NEW + dynamicRef?: boolean // NEW + schemaId?: "id" | "$id" + jtd?: boolean // NEW + meta?: SchemaObject | boolean + defaultMeta?: string | AnySchemaObject + validateSchema?: boolean | "log" + addUsedSchema?: boolean + inlineRefs?: boolean | number + passContext?: boolean + loopRequired?: number + loopEnum?: number // NEW + ownProperties?: boolean + multipleOfPrecision?: number + int32range?: boolean // JTD only + messages?: boolean + code?: CodeOptions // NEW + uriResolver?: UriResolver +} + +export interface CodeOptions { + es5?: boolean + esm?: boolean + lines?: boolean + optimize?: boolean | number + formats?: Code // code to require (or construct) map of available formats - for standalone code + source?: boolean + process?: (code: string, schema?: SchemaEnv) => string + regExp?: RegExpEngine +} + +interface InstanceCodeOptions extends CodeOptions { + regExp: RegExpEngine + optimize: number +} + +interface DeprecatedOptions { + /** @deprecated */ + ignoreKeywordsWithRef?: boolean + /** @deprecated */ + jsPropertySyntax?: boolean // added instead of jsonPointers + /** @deprecated */ + unicode?: boolean +} + +interface RemovedOptions { + format?: boolean + errorDataPath?: "object" | "property" + nullable?: boolean // "nullable" keyword is supported by default + jsonPointers?: boolean + extendRefs?: true | "ignore" | "fail" + missingRefs?: true | "ignore" | "fail" + processCode?: (code: string, schema?: SchemaEnv) => string + sourceCode?: boolean + strictDefaults?: boolean + strictKeywords?: boolean + uniqueItems?: boolean + unknownFormats?: true | string[] | "ignore" + cache?: any + serialize?: (schema: AnySchema) => unknown + ajvErrors?: boolean +} + +type OptionsInfo = { + [K in keyof T]-?: string | undefined +} + +const removedOptions: OptionsInfo = { + errorDataPath: "", + format: "`validateFormats: false` can be used instead.", + nullable: '"nullable" keyword is supported by default.', + jsonPointers: "Deprecated jsPropertySyntax can be used instead.", + extendRefs: "Deprecated ignoreKeywordsWithRef can be used instead.", + missingRefs: "Pass empty schema with $id that should be ignored to ajv.addSchema.", + processCode: "Use option `code: {process: (code, schemaEnv: object) => string}`", + sourceCode: "Use option `code: {source: true}`", + strictDefaults: "It is default now, see option `strict`.", + strictKeywords: "It is default now, see option `strict`.", + uniqueItems: '"uniqueItems" keyword is always validated.', + unknownFormats: "Disable strict mode or pass `true` to `ajv.addFormat` (or `formats` option).", + cache: "Map is used as cache, schema object as key.", + serialize: "Map is used as cache, schema object as key.", + ajvErrors: "It is default now.", +} + +const deprecatedOptions: OptionsInfo = { + ignoreKeywordsWithRef: "", + jsPropertySyntax: "", + unicode: '"minLength"/"maxLength" account for unicode characters by default.', +} + +type RequiredInstanceOptions = { + [K in + | "strictSchema" + | "strictNumbers" + | "strictTypes" + | "strictTuples" + | "strictRequired" + | "inlineRefs" + | "loopRequired" + | "loopEnum" + | "meta" + | "messages" + | "schemaId" + | "addUsedSchema" + | "validateSchema" + | "validateFormats" + | "int32range" + | "unicodeRegExp" + | "uriResolver"]: NonNullable +} & {code: InstanceCodeOptions} + +export type InstanceOptions = Options & RequiredInstanceOptions + +const MAX_EXPRESSION = 200 + +// eslint-disable-next-line complexity +function requiredOptions(o: Options): RequiredInstanceOptions { + const s = o.strict + const _optz = o.code?.optimize + const optimize = _optz === true || _optz === undefined ? 1 : _optz || 0 + const regExp = o.code?.regExp ?? defaultRegExp + const uriResolver = o.uriResolver ?? DefaultUriResolver + return { + strictSchema: o.strictSchema ?? s ?? true, + strictNumbers: o.strictNumbers ?? s ?? true, + strictTypes: o.strictTypes ?? s ?? "log", + strictTuples: o.strictTuples ?? s ?? "log", + strictRequired: o.strictRequired ?? s ?? false, + code: o.code ? {...o.code, optimize, regExp} : {optimize, regExp}, + loopRequired: o.loopRequired ?? MAX_EXPRESSION, + loopEnum: o.loopEnum ?? MAX_EXPRESSION, + meta: o.meta ?? true, + messages: o.messages ?? true, + inlineRefs: o.inlineRefs ?? true, + schemaId: o.schemaId ?? "$id", + addUsedSchema: o.addUsedSchema ?? true, + validateSchema: o.validateSchema ?? true, + validateFormats: o.validateFormats ?? true, + unicodeRegExp: o.unicodeRegExp ?? true, + int32range: o.int32range ?? true, + uriResolver: uriResolver, + } +} + +export interface Logger { + log(...args: unknown[]): unknown + warn(...args: unknown[]): unknown + error(...args: unknown[]): unknown +} + +export default class Ajv { + opts: InstanceOptions + errors?: ErrorObject[] | null // errors from the last validation + logger: Logger + // shared external scope values for compiled functions + readonly scope: ValueScope + readonly schemas: {[Key in string]?: SchemaEnv} = {} + readonly refs: {[Ref in string]?: SchemaEnv | string} = {} + readonly formats: {[Name in string]?: AddedFormat} = {} + readonly RULES: ValidationRules + readonly _compilations: Set = new Set() + private readonly _loading: {[Ref in string]?: Promise} = {} + private readonly _cache: Map = new Map() + private readonly _metaOpts: InstanceOptions + + static ValidationError = ValidationError + static MissingRefError = MissingRefError + + constructor(opts: Options = {}) { + opts = this.opts = {...opts, ...requiredOptions(opts)} + const {es5, lines} = this.opts.code + + this.scope = new ValueScope({scope: {}, prefixes: EXT_SCOPE_NAMES, es5, lines}) + this.logger = getLogger(opts.logger) + const formatOpt = opts.validateFormats + opts.validateFormats = false + + this.RULES = getRules() + checkOptions.call(this, removedOptions, opts, "NOT SUPPORTED") + checkOptions.call(this, deprecatedOptions, opts, "DEPRECATED", "warn") + this._metaOpts = getMetaSchemaOptions.call(this) + + if (opts.formats) addInitialFormats.call(this) + this._addVocabularies() + this._addDefaultMetaSchema() + if (opts.keywords) addInitialKeywords.call(this, opts.keywords) + if (typeof opts.meta == "object") this.addMetaSchema(opts.meta) + addInitialSchemas.call(this) + opts.validateFormats = formatOpt + } + + _addVocabularies(): void { + this.addKeyword("$async") + } + + _addDefaultMetaSchema(): void { + const {$data, meta, schemaId} = this.opts + let _dataRefSchema: SchemaObject = $dataRefSchema + if (schemaId === "id") { + _dataRefSchema = {...$dataRefSchema} + _dataRefSchema.id = _dataRefSchema.$id + delete _dataRefSchema.$id + } + if (meta && $data) this.addMetaSchema(_dataRefSchema, _dataRefSchema[schemaId], false) + } + + defaultMeta(): string | AnySchemaObject | undefined { + const {meta, schemaId} = this.opts + return (this.opts.defaultMeta = typeof meta == "object" ? meta[schemaId] || meta : undefined) + } + + // Validate data using schema + // AnySchema will be compiled and cached using schema itself as a key for Map + validate(schema: Schema | string, data: unknown): boolean + validate(schemaKeyRef: AnySchema | string, data: unknown): boolean | Promise + validate(schema: Schema | JSONSchemaType | string, data: unknown): data is T + // Separated for type inference to work + // eslint-disable-next-line @typescript-eslint/unified-signatures + validate(schema: JTDSchemaType, data: unknown): data is T + // This overload is only intended for typescript inference, the first + // argument prevents manual type annotation from matching this overload + validate( + schema: T, + data: unknown + ): data is JTDDataType + validate(schema: AsyncSchema, data: unknown | T): Promise + validate(schemaKeyRef: AnySchema | string, data: unknown): data is T | Promise + validate( + schemaKeyRef: AnySchema | string, // key, ref or schema object + data: unknown | T // to be validated + ): boolean | Promise { + let v: AnyValidateFunction | undefined + if (typeof schemaKeyRef == "string") { + v = this.getSchema(schemaKeyRef) + if (!v) throw new Error(`no schema with key or ref "${schemaKeyRef}"`) + } else { + v = this.compile(schemaKeyRef) + } + + const valid = v(data) + if (!("$async" in v)) this.errors = v.errors + return valid + } + + // Create validation function for passed schema + // _meta: true if schema is a meta-schema. Used internally to compile meta schemas of user-defined keywords. + compile(schema: Schema | JSONSchemaType, _meta?: boolean): ValidateFunction + // Separated for type inference to work + // eslint-disable-next-line @typescript-eslint/unified-signatures + compile(schema: JTDSchemaType, _meta?: boolean): ValidateFunction + // This overload is only intended for typescript inference, the first + // argument prevents manual type annotation from matching this overload + compile( + schema: T, + _meta?: boolean + ): ValidateFunction> + compile(schema: AsyncSchema, _meta?: boolean): AsyncValidateFunction + compile(schema: AnySchema, _meta?: boolean): AnyValidateFunction + compile(schema: AnySchema, _meta?: boolean): AnyValidateFunction { + const sch = this._addSchema(schema, _meta) + return (sch.validate || this._compileSchemaEnv(sch)) as AnyValidateFunction + } + + // Creates validating function for passed schema with asynchronous loading of missing schemas. + // `loadSchema` option should be a function that accepts schema uri and returns promise that resolves with the schema. + // TODO allow passing schema URI + // meta - optional true to compile meta-schema + compileAsync( + schema: SchemaObject | JSONSchemaType, + _meta?: boolean + ): Promise> + // Separated for type inference to work + // eslint-disable-next-line @typescript-eslint/unified-signatures + compileAsync(schema: JTDSchemaType, _meta?: boolean): Promise> + compileAsync(schema: AsyncSchema, meta?: boolean): Promise> + // eslint-disable-next-line @typescript-eslint/unified-signatures + compileAsync( + schema: AnySchemaObject, + meta?: boolean + ): Promise> + compileAsync( + schema: AnySchemaObject, + meta?: boolean + ): Promise> { + if (typeof this.opts.loadSchema != "function") { + throw new Error("options.loadSchema should be a function") + } + const {loadSchema} = this.opts + return runCompileAsync.call(this, schema, meta) + + async function runCompileAsync( + this: Ajv, + _schema: AnySchemaObject, + _meta?: boolean + ): Promise { + await loadMetaSchema.call(this, _schema.$schema) + const sch = this._addSchema(_schema, _meta) + return sch.validate || _compileAsync.call(this, sch) + } + + async function loadMetaSchema(this: Ajv, $ref?: string): Promise { + if ($ref && !this.getSchema($ref)) { + await runCompileAsync.call(this, {$ref}, true) + } + } + + async function _compileAsync(this: Ajv, sch: SchemaEnv): Promise { + try { + return this._compileSchemaEnv(sch) + } catch (e) { + if (!(e instanceof MissingRefError)) throw e + checkLoaded.call(this, e) + await loadMissingSchema.call(this, e.missingSchema) + return _compileAsync.call(this, sch) + } + } + + function checkLoaded(this: Ajv, {missingSchema: ref, missingRef}: MissingRefError): void { + if (this.refs[ref]) { + throw new Error(`AnySchema ${ref} is loaded but ${missingRef} cannot be resolved`) + } + } + + async function loadMissingSchema(this: Ajv, ref: string): Promise { + const _schema = await _loadSchema.call(this, ref) + if (!this.refs[ref]) await loadMetaSchema.call(this, _schema.$schema) + if (!this.refs[ref]) this.addSchema(_schema, ref, meta) + } + + async function _loadSchema(this: Ajv, ref: string): Promise { + const p = this._loading[ref] + if (p) return p + try { + return await (this._loading[ref] = loadSchema(ref)) + } finally { + delete this._loading[ref] + } + } + } + + // Adds schema to the instance + addSchema( + schema: AnySchema | AnySchema[], // If array is passed, `key` will be ignored + key?: string, // Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`. + _meta?: boolean, // true if schema is a meta-schema. Used internally, addMetaSchema should be used instead. + _validateSchema = this.opts.validateSchema // false to skip schema validation. Used internally, option validateSchema should be used instead. + ): Ajv { + if (Array.isArray(schema)) { + for (const sch of schema) this.addSchema(sch, undefined, _meta, _validateSchema) + return this + } + let id: string | undefined + if (typeof schema === "object") { + const {schemaId} = this.opts + id = schema[schemaId] + if (id !== undefined && typeof id != "string") { + throw new Error(`schema ${schemaId} must be string`) + } + } + key = normalizeId(key || id) + this._checkUnique(key) + this.schemas[key] = this._addSchema(schema, _meta, key, _validateSchema, true) + return this + } + + // Add schema that will be used to validate other schemas + // options in META_IGNORE_OPTIONS are alway set to false + addMetaSchema( + schema: AnySchemaObject, + key?: string, // schema key + _validateSchema = this.opts.validateSchema // false to skip schema validation, can be used to override validateSchema option for meta-schema + ): Ajv { + this.addSchema(schema, key, true, _validateSchema) + return this + } + + // Validate schema against its meta-schema + validateSchema(schema: AnySchema, throwOrLogError?: boolean): boolean | Promise { + if (typeof schema == "boolean") return true + let $schema: string | AnySchemaObject | undefined + $schema = schema.$schema + if ($schema !== undefined && typeof $schema != "string") { + throw new Error("$schema must be a string") + } + $schema = $schema || this.opts.defaultMeta || this.defaultMeta() + if (!$schema) { + this.logger.warn("meta-schema not available") + this.errors = null + return true + } + const valid = this.validate($schema, schema) + if (!valid && throwOrLogError) { + const message = "schema is invalid: " + this.errorsText() + if (this.opts.validateSchema === "log") this.logger.error(message) + else throw new Error(message) + } + return valid + } + + // Get compiled schema by `key` or `ref`. + // (`key` that was passed to `addSchema` or full schema reference - `schema.$id` or resolved id) + getSchema(keyRef: string): AnyValidateFunction | undefined { + let sch + while (typeof (sch = getSchEnv.call(this, keyRef)) == "string") keyRef = sch + if (sch === undefined) { + const {schemaId} = this.opts + const root = new SchemaEnv({schema: {}, schemaId}) + sch = resolveSchema.call(this, root, keyRef) + if (!sch) return + this.refs[keyRef] = sch + } + return (sch.validate || this._compileSchemaEnv(sch)) as AnyValidateFunction | undefined + } + + // Remove cached schema(s). + // If no parameter is passed all schemas but meta-schemas are removed. + // If RegExp is passed all schemas with key/id matching pattern but meta-schemas are removed. + // Even if schema is referenced by other schemas it still can be removed as other schemas have local references. + removeSchema(schemaKeyRef?: AnySchema | string | RegExp): Ajv { + if (schemaKeyRef instanceof RegExp) { + this._removeAllSchemas(this.schemas, schemaKeyRef) + this._removeAllSchemas(this.refs, schemaKeyRef) + return this + } + switch (typeof schemaKeyRef) { + case "undefined": + this._removeAllSchemas(this.schemas) + this._removeAllSchemas(this.refs) + this._cache.clear() + return this + case "string": { + const sch = getSchEnv.call(this, schemaKeyRef) + if (typeof sch == "object") this._cache.delete(sch.schema) + delete this.schemas[schemaKeyRef] + delete this.refs[schemaKeyRef] + return this + } + case "object": { + const cacheKey = schemaKeyRef + this._cache.delete(cacheKey) + let id = schemaKeyRef[this.opts.schemaId] + if (id) { + id = normalizeId(id) + delete this.schemas[id] + delete this.refs[id] + } + return this + } + default: + throw new Error("ajv.removeSchema: invalid parameter") + } + } + + // add "vocabulary" - a collection of keywords + addVocabulary(definitions: Vocabulary): Ajv { + for (const def of definitions) this.addKeyword(def) + return this + } + + addKeyword( + kwdOrDef: string | KeywordDefinition, + def?: KeywordDefinition // deprecated + ): Ajv { + let keyword: string | string[] + if (typeof kwdOrDef == "string") { + keyword = kwdOrDef + if (typeof def == "object") { + this.logger.warn("these parameters are deprecated, see docs for addKeyword") + def.keyword = keyword + } + } else if (typeof kwdOrDef == "object" && def === undefined) { + def = kwdOrDef + keyword = def.keyword + if (Array.isArray(keyword) && !keyword.length) { + throw new Error("addKeywords: keyword must be string or non-empty array") + } + } else { + throw new Error("invalid addKeywords parameters") + } + + checkKeyword.call(this, keyword, def) + if (!def) { + eachItem(keyword, (kwd) => addRule.call(this, kwd)) + return this + } + keywordMetaschema.call(this, def) + const definition: AddedKeywordDefinition = { + ...def, + type: getJSONTypes(def.type), + schemaType: getJSONTypes(def.schemaType), + } + eachItem( + keyword, + definition.type.length === 0 + ? (k) => addRule.call(this, k, definition) + : (k) => definition.type.forEach((t) => addRule.call(this, k, definition, t)) + ) + return this + } + + getKeyword(keyword: string): AddedKeywordDefinition | boolean { + const rule = this.RULES.all[keyword] + return typeof rule == "object" ? rule.definition : !!rule + } + + // Remove keyword + removeKeyword(keyword: string): Ajv { + // TODO return type should be Ajv + const {RULES} = this + delete RULES.keywords[keyword] + delete RULES.all[keyword] + for (const group of RULES.rules) { + const i = group.rules.findIndex((rule) => rule.keyword === keyword) + if (i >= 0) group.rules.splice(i, 1) + } + return this + } + + // Add format + addFormat(name: string, format: Format): Ajv { + if (typeof format == "string") format = new RegExp(format) + this.formats[name] = format + return this + } + + errorsText( + errors: ErrorObject[] | null | undefined = this.errors, // optional array of validation errors + {separator = ", ", dataVar = "data"}: ErrorsTextOptions = {} // optional options with properties `separator` and `dataVar` + ): string { + if (!errors || errors.length === 0) return "No errors" + return errors + .map((e) => `${dataVar}${e.instancePath} ${e.message}`) + .reduce((text, msg) => text + separator + msg) + } + + $dataMetaSchema(metaSchema: AnySchemaObject, keywordsJsonPointers: string[]): AnySchemaObject { + const rules = this.RULES.all + metaSchema = JSON.parse(JSON.stringify(metaSchema)) + for (const jsonPointer of keywordsJsonPointers) { + const segments = jsonPointer.split("/").slice(1) // first segment is an empty string + let keywords = metaSchema + for (const seg of segments) keywords = keywords[seg] as AnySchemaObject + + for (const key in rules) { + const rule = rules[key] + if (typeof rule != "object") continue + const {$data} = rule.definition + const schema = keywords[key] as AnySchemaObject | undefined + if ($data && schema) keywords[key] = schemaOrData(schema) + } + } + + return metaSchema + } + + private _removeAllSchemas(schemas: {[Ref in string]?: SchemaEnv | string}, regex?: RegExp): void { + for (const keyRef in schemas) { + const sch = schemas[keyRef] + if (!regex || regex.test(keyRef)) { + if (typeof sch == "string") { + delete schemas[keyRef] + } else if (sch && !sch.meta) { + this._cache.delete(sch.schema) + delete schemas[keyRef] + } + } + } + } + + _addSchema( + schema: AnySchema, + meta?: boolean, + baseId?: string, + validateSchema = this.opts.validateSchema, + addSchema = this.opts.addUsedSchema + ): SchemaEnv { + let id: string | undefined + const {schemaId} = this.opts + if (typeof schema == "object") { + id = schema[schemaId] + } else { + if (this.opts.jtd) throw new Error("schema must be object") + else if (typeof schema != "boolean") throw new Error("schema must be object or boolean") + } + let sch = this._cache.get(schema) + if (sch !== undefined) return sch + + baseId = normalizeId(id || baseId) + const localRefs = getSchemaRefs.call(this, schema, baseId) + sch = new SchemaEnv({schema, schemaId, meta, baseId, localRefs}) + this._cache.set(sch.schema, sch) + if (addSchema && !baseId.startsWith("#")) { + // TODO atm it is allowed to overwrite schemas without id (instead of not adding them) + if (baseId) this._checkUnique(baseId) + this.refs[baseId] = sch + } + if (validateSchema) this.validateSchema(schema, true) + return sch + } + + private _checkUnique(id: string): void { + if (this.schemas[id] || this.refs[id]) { + throw new Error(`schema with key or id "${id}" already exists`) + } + } + + private _compileSchemaEnv(sch: SchemaEnv): AnyValidateFunction { + if (sch.meta) this._compileMetaSchema(sch) + else compileSchema.call(this, sch) + + /* istanbul ignore if */ + if (!sch.validate) throw new Error("ajv implementation error") + return sch.validate + } + + private _compileMetaSchema(sch: SchemaEnv): void { + const currentOpts = this.opts + this.opts = this._metaOpts + try { + compileSchema.call(this, sch) + } finally { + this.opts = currentOpts + } + } +} + +export interface ErrorsTextOptions { + separator?: string + dataVar?: string +} + +function checkOptions( + this: Ajv, + checkOpts: OptionsInfo, + options: Options & RemovedOptions, + msg: string, + log: "warn" | "error" = "error" +): void { + for (const key in checkOpts) { + const opt = key as keyof typeof checkOpts + if (opt in options) this.logger[log](`${msg}: option ${key}. ${checkOpts[opt]}`) + } +} + +function getSchEnv(this: Ajv, keyRef: string): SchemaEnv | string | undefined { + keyRef = normalizeId(keyRef) // TODO tests fail without this line + return this.schemas[keyRef] || this.refs[keyRef] +} + +function addInitialSchemas(this: Ajv): void { + const optsSchemas = this.opts.schemas + if (!optsSchemas) return + if (Array.isArray(optsSchemas)) this.addSchema(optsSchemas) + else for (const key in optsSchemas) this.addSchema(optsSchemas[key] as AnySchema, key) +} + +function addInitialFormats(this: Ajv): void { + for (const name in this.opts.formats) { + const format = this.opts.formats[name] + if (format) this.addFormat(name, format) + } +} + +function addInitialKeywords( + this: Ajv, + defs: Vocabulary | {[K in string]?: KeywordDefinition} +): void { + if (Array.isArray(defs)) { + this.addVocabulary(defs) + return + } + this.logger.warn("keywords option as map is deprecated, pass array") + for (const keyword in defs) { + const def = defs[keyword] as KeywordDefinition + if (!def.keyword) def.keyword = keyword + this.addKeyword(def) + } +} + +function getMetaSchemaOptions(this: Ajv): InstanceOptions { + const metaOpts = {...this.opts} + for (const opt of META_IGNORE_OPTIONS) delete metaOpts[opt] + return metaOpts +} + +const noLogs = {log() {}, warn() {}, error() {}} + +function getLogger(logger?: Partial | false): Logger { + if (logger === false) return noLogs + if (logger === undefined) return console + if (logger.log && logger.warn && logger.error) return logger as Logger + throw new Error("logger must implement log, warn and error methods") +} + +const KEYWORD_NAME = /^[a-z_$][a-z0-9_$:-]*$/i + +function checkKeyword(this: Ajv, keyword: string | string[], def?: KeywordDefinition): void { + const {RULES} = this + eachItem(keyword, (kwd) => { + if (RULES.keywords[kwd]) throw new Error(`Keyword ${kwd} is already defined`) + if (!KEYWORD_NAME.test(kwd)) throw new Error(`Keyword ${kwd} has invalid name`) + }) + if (!def) return + if (def.$data && !("code" in def || "validate" in def)) { + throw new Error('$data keyword must have "code" or "validate" function') + } +} + +function addRule( + this: Ajv, + keyword: string, + definition?: AddedKeywordDefinition, + dataType?: JSONType +): void { + const post = definition?.post + if (dataType && post) throw new Error('keyword with "post" flag cannot have "type"') + const {RULES} = this + let ruleGroup = post ? RULES.post : RULES.rules.find(({type: t}) => t === dataType) + if (!ruleGroup) { + ruleGroup = {type: dataType, rules: []} + RULES.rules.push(ruleGroup) + } + RULES.keywords[keyword] = true + if (!definition) return + + const rule: Rule = { + keyword, + definition: { + ...definition, + type: getJSONTypes(definition.type), + schemaType: getJSONTypes(definition.schemaType), + }, + } + if (definition.before) addBeforeRule.call(this, ruleGroup, rule, definition.before) + else ruleGroup.rules.push(rule) + RULES.all[keyword] = rule + definition.implements?.forEach((kwd) => this.addKeyword(kwd)) +} + +function addBeforeRule(this: Ajv, ruleGroup: RuleGroup, rule: Rule, before: string): void { + const i = ruleGroup.rules.findIndex((_rule) => _rule.keyword === before) + if (i >= 0) { + ruleGroup.rules.splice(i, 0, rule) + } else { + ruleGroup.rules.push(rule) + this.logger.warn(`rule ${before} is not defined`) + } +} + +function keywordMetaschema(this: Ajv, def: KeywordDefinition): void { + let {metaSchema} = def + if (metaSchema === undefined) return + if (def.$data && this.opts.$data) metaSchema = schemaOrData(metaSchema) + def.validateSchema = this.compile(metaSchema, true) +} + +const $dataRef = { + $ref: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#", +} + +function schemaOrData(schema: AnySchema): AnySchemaObject { + return {anyOf: [schema, $dataRef]} +} diff --git a/libs/events/node_modules/ajv/lib/jtd.ts b/libs/events/node_modules/ajv/lib/jtd.ts new file mode 100644 index 000000000..96eb7b9dc --- /dev/null +++ b/libs/events/node_modules/ajv/lib/jtd.ts @@ -0,0 +1,131 @@ +import type {AnySchemaObject, SchemaObject, JTDParser} from "./types" +import type {JTDSchemaType, SomeJTDSchemaType, JTDDataType} from "./types/jtd-schema" +import AjvCore, {CurrentOptions} from "./core" +import jtdVocabulary from "./vocabularies/jtd" +import jtdMetaSchema from "./refs/jtd-schema" +import compileSerializer from "./compile/jtd/serialize" +import compileParser from "./compile/jtd/parse" +import {SchemaEnv} from "./compile" + +const META_SCHEMA_ID = "JTD-meta-schema" + +type JTDOptions = CurrentOptions & { + // strict mode options not supported with JTD: + strict?: never + allowMatchingProperties?: never + allowUnionTypes?: never + validateFormats?: never + // validation and reporting options not supported with JTD: + $data?: never + verbose?: boolean + $comment?: never + formats?: never + loadSchema?: never + // options to modify validated data: + useDefaults?: never + coerceTypes?: never + // advanced options: + next?: never + unevaluated?: never + dynamicRef?: never + meta?: boolean + defaultMeta?: never + inlineRefs?: boolean + loopRequired?: never + multipleOfPrecision?: never +} + +class Ajv extends AjvCore { + constructor(opts: JTDOptions = {}) { + super({ + ...opts, + jtd: true, + }) + } + + _addVocabularies(): void { + super._addVocabularies() + this.addVocabulary(jtdVocabulary) + } + + _addDefaultMetaSchema(): void { + super._addDefaultMetaSchema() + if (!this.opts.meta) return + this.addMetaSchema(jtdMetaSchema, META_SCHEMA_ID, false) + } + + defaultMeta(): string | AnySchemaObject | undefined { + return (this.opts.defaultMeta = + super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : undefined)) + } + + compileSerializer(schema: SchemaObject): (data: T) => string + // Separated for type inference to work + // eslint-disable-next-line @typescript-eslint/unified-signatures + compileSerializer(schema: JTDSchemaType): (data: T) => string + compileSerializer(schema: SchemaObject): (data: T) => string { + const sch = this._addSchema(schema) + return sch.serialize || this._compileSerializer(sch) + } + + compileParser(schema: SchemaObject): JTDParser + // Separated for type inference to work + // eslint-disable-next-line @typescript-eslint/unified-signatures + compileParser(schema: JTDSchemaType): JTDParser + compileParser(schema: SchemaObject): JTDParser { + const sch = this._addSchema(schema) + return (sch.parse || this._compileParser(sch)) as JTDParser + } + + private _compileSerializer(sch: SchemaEnv): (data: T) => string { + compileSerializer.call(this, sch, (sch.schema as AnySchemaObject).definitions || {}) + /* istanbul ignore if */ + if (!sch.serialize) throw new Error("ajv implementation error") + return sch.serialize + } + + private _compileParser(sch: SchemaEnv): JTDParser { + compileParser.call(this, sch, (sch.schema as AnySchemaObject).definitions || {}) + /* istanbul ignore if */ + if (!sch.parse) throw new Error("ajv implementation error") + return sch.parse + } +} + +module.exports = exports = Ajv +Object.defineProperty(exports, "__esModule", {value: true}) + +export default Ajv + +export { + Format, + FormatDefinition, + AsyncFormatDefinition, + KeywordDefinition, + KeywordErrorDefinition, + CodeKeywordDefinition, + MacroKeywordDefinition, + FuncKeywordDefinition, + Vocabulary, + Schema, + SchemaObject, + AnySchemaObject, + AsyncSchema, + AnySchema, + ValidateFunction, + AsyncValidateFunction, + ErrorObject, + ErrorNoParams, + JTDParser, +} from "./types" + +export {Plugin, Options, CodeOptions, InstanceOptions, Logger, ErrorsTextOptions} from "./core" +export {SchemaCxt, SchemaObjCxt} from "./compile" +export {KeywordCxt} from "./compile/validate" +export {JTDErrorObject} from "./vocabularies/jtd" +export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen" + +export {JTDSchemaType, SomeJTDSchemaType, JTDDataType} +export {JTDOptions} +export {default as ValidationError} from "./runtime/validation_error" +export {default as MissingRefError} from "./compile/ref_error" diff --git a/libs/events/node_modules/ajv/lib/refs/data.json b/libs/events/node_modules/ajv/lib/refs/data.json new file mode 100644 index 000000000..9ffc9f5ce --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/data.json @@ -0,0 +1,13 @@ +{ + "$id": "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#", + "description": "Meta-schema for $data reference (JSON AnySchema extension proposal)", + "type": "object", + "required": ["$data"], + "properties": { + "$data": { + "type": "string", + "anyOf": [{"format": "relative-json-pointer"}, {"format": "json-pointer"}] + } + }, + "additionalProperties": false +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/index.ts b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/index.ts new file mode 100644 index 000000000..b6ea7195f --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/index.ts @@ -0,0 +1,28 @@ +import type Ajv from "../../core" +import type {AnySchemaObject} from "../../types" +import * as metaSchema from "./schema.json" +import * as applicator from "./meta/applicator.json" +import * as content from "./meta/content.json" +import * as core from "./meta/core.json" +import * as format from "./meta/format.json" +import * as metadata from "./meta/meta-data.json" +import * as validation from "./meta/validation.json" + +const META_SUPPORT_DATA = ["/properties"] + +export default function addMetaSchema2019(this: Ajv, $data?: boolean): Ajv { + ;[ + metaSchema, + applicator, + content, + core, + with$data(this, format), + metadata, + with$data(this, validation), + ].forEach((sch) => this.addMetaSchema(sch, undefined, false)) + return this + + function with$data(ajv: Ajv, sch: AnySchemaObject): AnySchemaObject { + return $data ? ajv.$dataMetaSchema(sch, META_SUPPORT_DATA) : sch + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/applicator.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/applicator.json new file mode 100644 index 000000000..c5e91cf2a --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/applicator.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/applicator", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/applicator": true + }, + "$recursiveAnchor": true, + + "title": "Applicator vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "additionalItems": {"$recursiveRef": "#"}, + "unevaluatedItems": {"$recursiveRef": "#"}, + "items": { + "anyOf": [{"$recursiveRef": "#"}, {"$ref": "#/$defs/schemaArray"}] + }, + "contains": {"$recursiveRef": "#"}, + "additionalProperties": {"$recursiveRef": "#"}, + "unevaluatedProperties": {"$recursiveRef": "#"}, + "properties": { + "type": "object", + "additionalProperties": {"$recursiveRef": "#"}, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": {"$recursiveRef": "#"}, + "propertyNames": {"format": "regex"}, + "default": {} + }, + "dependentSchemas": { + "type": "object", + "additionalProperties": { + "$recursiveRef": "#" + } + }, + "propertyNames": {"$recursiveRef": "#"}, + "if": {"$recursiveRef": "#"}, + "then": {"$recursiveRef": "#"}, + "else": {"$recursiveRef": "#"}, + "allOf": {"$ref": "#/$defs/schemaArray"}, + "anyOf": {"$ref": "#/$defs/schemaArray"}, + "oneOf": {"$ref": "#/$defs/schemaArray"}, + "not": {"$recursiveRef": "#"} + }, + "$defs": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": {"$recursiveRef": "#"} + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/content.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/content.json new file mode 100644 index 000000000..b8f637343 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/content.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/content", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/content": true + }, + "$recursiveAnchor": true, + + "title": "Content vocabulary meta-schema", + + "type": ["object", "boolean"], + "properties": { + "contentMediaType": {"type": "string"}, + "contentEncoding": {"type": "string"}, + "contentSchema": {"$recursiveRef": "#"} + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/core.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/core.json new file mode 100644 index 000000000..f71adbff0 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/core.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/core", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/core": true + }, + "$recursiveAnchor": true, + + "title": "Core vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "$id": { + "type": "string", + "format": "uri-reference", + "$comment": "Non-empty fragments not allowed.", + "pattern": "^[^#]*#?$" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "$anchor": { + "type": "string", + "pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$" + }, + "$ref": { + "type": "string", + "format": "uri-reference" + }, + "$recursiveRef": { + "type": "string", + "format": "uri-reference" + }, + "$recursiveAnchor": { + "type": "boolean", + "default": false + }, + "$vocabulary": { + "type": "object", + "propertyNames": { + "type": "string", + "format": "uri" + }, + "additionalProperties": { + "type": "boolean" + } + }, + "$comment": { + "type": "string" + }, + "$defs": { + "type": "object", + "additionalProperties": {"$recursiveRef": "#"}, + "default": {} + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/format.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/format.json new file mode 100644 index 000000000..03ccfce26 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/format.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/format", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/format": true + }, + "$recursiveAnchor": true, + + "title": "Format vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "format": {"type": "string"} + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/meta-data.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/meta-data.json new file mode 100644 index 000000000..0e194326f --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/meta-data.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/meta-data", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/meta-data": true + }, + "$recursiveAnchor": true, + + "title": "Meta-data vocabulary meta-schema", + + "type": ["object", "boolean"], + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": true, + "deprecated": { + "type": "boolean", + "default": false + }, + "readOnly": { + "type": "boolean", + "default": false + }, + "writeOnly": { + "type": "boolean", + "default": false + }, + "examples": { + "type": "array", + "items": true + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/validation.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/validation.json new file mode 100644 index 000000000..7027a1279 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/meta/validation.json @@ -0,0 +1,90 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/validation", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/validation": true + }, + "$recursiveAnchor": true, + + "title": "Validation vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": {"$ref": "#/$defs/nonNegativeInteger"}, + "minLength": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, + "pattern": { + "type": "string", + "format": "regex" + }, + "maxItems": {"$ref": "#/$defs/nonNegativeInteger"}, + "minItems": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "maxContains": {"$ref": "#/$defs/nonNegativeInteger"}, + "minContains": { + "$ref": "#/$defs/nonNegativeInteger", + "default": 1 + }, + "maxProperties": {"$ref": "#/$defs/nonNegativeInteger"}, + "minProperties": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, + "required": {"$ref": "#/$defs/stringArray"}, + "dependentRequired": { + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/stringArray" + } + }, + "const": true, + "enum": { + "type": "array", + "items": true + }, + "type": { + "anyOf": [ + {"$ref": "#/$defs/simpleTypes"}, + { + "type": "array", + "items": {"$ref": "#/$defs/simpleTypes"}, + "minItems": 1, + "uniqueItems": true + } + ] + } + }, + "$defs": { + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "$ref": "#/$defs/nonNegativeInteger", + "default": 0 + }, + "simpleTypes": { + "enum": ["array", "boolean", "integer", "null", "number", "object", "string"] + }, + "stringArray": { + "type": "array", + "items": {"type": "string"}, + "uniqueItems": true, + "default": [] + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/schema.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/schema.json new file mode 100644 index 000000000..54eb7157a --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2019-09/schema.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/schema", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/core": true, + "https://json-schema.org/draft/2019-09/vocab/applicator": true, + "https://json-schema.org/draft/2019-09/vocab/validation": true, + "https://json-schema.org/draft/2019-09/vocab/meta-data": true, + "https://json-schema.org/draft/2019-09/vocab/format": false, + "https://json-schema.org/draft/2019-09/vocab/content": true + }, + "$recursiveAnchor": true, + + "title": "Core and Validation specifications meta-schema", + "allOf": [ + {"$ref": "meta/core"}, + {"$ref": "meta/applicator"}, + {"$ref": "meta/validation"}, + {"$ref": "meta/meta-data"}, + {"$ref": "meta/format"}, + {"$ref": "meta/content"} + ], + "type": ["object", "boolean"], + "properties": { + "definitions": { + "$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.", + "type": "object", + "additionalProperties": {"$recursiveRef": "#"}, + "default": {} + }, + "dependencies": { + "$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"", + "type": "object", + "additionalProperties": { + "anyOf": [{"$recursiveRef": "#"}, {"$ref": "meta/validation#/$defs/stringArray"}] + } + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/index.ts b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/index.ts new file mode 100644 index 000000000..8e850d08b --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/index.ts @@ -0,0 +1,30 @@ +import type Ajv from "../../core" +import type {AnySchemaObject} from "../../types" +import * as metaSchema from "./schema.json" +import * as applicator from "./meta/applicator.json" +import * as unevaluated from "./meta/unevaluated.json" +import * as content from "./meta/content.json" +import * as core from "./meta/core.json" +import * as format from "./meta/format-annotation.json" +import * as metadata from "./meta/meta-data.json" +import * as validation from "./meta/validation.json" + +const META_SUPPORT_DATA = ["/properties"] + +export default function addMetaSchema2020(this: Ajv, $data?: boolean): Ajv { + ;[ + metaSchema, + applicator, + unevaluated, + content, + core, + with$data(this, format), + metadata, + with$data(this, validation), + ].forEach((sch) => this.addMetaSchema(sch, undefined, false)) + return this + + function with$data(ajv: Ajv, sch: AnySchemaObject): AnySchemaObject { + return $data ? ajv.$dataMetaSchema(sch, META_SUPPORT_DATA) : sch + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/applicator.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/applicator.json new file mode 100644 index 000000000..674c913da --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/applicator.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/applicator", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/applicator": true + }, + "$dynamicAnchor": "meta", + + "title": "Applicator vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "prefixItems": {"$ref": "#/$defs/schemaArray"}, + "items": {"$dynamicRef": "#meta"}, + "contains": {"$dynamicRef": "#meta"}, + "additionalProperties": {"$dynamicRef": "#meta"}, + "properties": { + "type": "object", + "additionalProperties": {"$dynamicRef": "#meta"}, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": {"$dynamicRef": "#meta"}, + "propertyNames": {"format": "regex"}, + "default": {} + }, + "dependentSchemas": { + "type": "object", + "additionalProperties": {"$dynamicRef": "#meta"}, + "default": {} + }, + "propertyNames": {"$dynamicRef": "#meta"}, + "if": {"$dynamicRef": "#meta"}, + "then": {"$dynamicRef": "#meta"}, + "else": {"$dynamicRef": "#meta"}, + "allOf": {"$ref": "#/$defs/schemaArray"}, + "anyOf": {"$ref": "#/$defs/schemaArray"}, + "oneOf": {"$ref": "#/$defs/schemaArray"}, + "not": {"$dynamicRef": "#meta"} + }, + "$defs": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": {"$dynamicRef": "#meta"} + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/content.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/content.json new file mode 100644 index 000000000..2ae23ddb5 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/content.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/content", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/content": true + }, + "$dynamicAnchor": "meta", + + "title": "Content vocabulary meta-schema", + + "type": ["object", "boolean"], + "properties": { + "contentEncoding": {"type": "string"}, + "contentMediaType": {"type": "string"}, + "contentSchema": {"$dynamicRef": "#meta"} + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/core.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/core.json new file mode 100644 index 000000000..4c8e5cb61 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/core.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/core", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/core": true + }, + "$dynamicAnchor": "meta", + + "title": "Core vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "$id": { + "$ref": "#/$defs/uriReferenceString", + "$comment": "Non-empty fragments not allowed.", + "pattern": "^[^#]*#?$" + }, + "$schema": {"$ref": "#/$defs/uriString"}, + "$ref": {"$ref": "#/$defs/uriReferenceString"}, + "$anchor": {"$ref": "#/$defs/anchorString"}, + "$dynamicRef": {"$ref": "#/$defs/uriReferenceString"}, + "$dynamicAnchor": {"$ref": "#/$defs/anchorString"}, + "$vocabulary": { + "type": "object", + "propertyNames": {"$ref": "#/$defs/uriString"}, + "additionalProperties": { + "type": "boolean" + } + }, + "$comment": { + "type": "string" + }, + "$defs": { + "type": "object", + "additionalProperties": {"$dynamicRef": "#meta"} + } + }, + "$defs": { + "anchorString": { + "type": "string", + "pattern": "^[A-Za-z_][-A-Za-z0-9._]*$" + }, + "uriString": { + "type": "string", + "format": "uri" + }, + "uriReferenceString": { + "type": "string", + "format": "uri-reference" + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/format-annotation.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/format-annotation.json new file mode 100644 index 000000000..83c26e35f --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/format-annotation.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/format-annotation", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/format-annotation": true + }, + "$dynamicAnchor": "meta", + + "title": "Format vocabulary meta-schema for annotation results", + "type": ["object", "boolean"], + "properties": { + "format": {"type": "string"} + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/meta-data.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/meta-data.json new file mode 100644 index 000000000..11946fb50 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/meta-data.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/meta-data", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/meta-data": true + }, + "$dynamicAnchor": "meta", + + "title": "Meta-data vocabulary meta-schema", + + "type": ["object", "boolean"], + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": true, + "deprecated": { + "type": "boolean", + "default": false + }, + "readOnly": { + "type": "boolean", + "default": false + }, + "writeOnly": { + "type": "boolean", + "default": false + }, + "examples": { + "type": "array", + "items": true + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/unevaluated.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/unevaluated.json new file mode 100644 index 000000000..5e4b203b2 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/unevaluated.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/unevaluated", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/unevaluated": true + }, + "$dynamicAnchor": "meta", + + "title": "Unevaluated applicator vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "unevaluatedItems": {"$dynamicRef": "#meta"}, + "unevaluatedProperties": {"$dynamicRef": "#meta"} + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/validation.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/validation.json new file mode 100644 index 000000000..e0ae13d9d --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/meta/validation.json @@ -0,0 +1,90 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/validation", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/validation": true + }, + "$dynamicAnchor": "meta", + + "title": "Validation vocabulary meta-schema", + "type": ["object", "boolean"], + "properties": { + "type": { + "anyOf": [ + {"$ref": "#/$defs/simpleTypes"}, + { + "type": "array", + "items": {"$ref": "#/$defs/simpleTypes"}, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "const": true, + "enum": { + "type": "array", + "items": true + }, + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": {"$ref": "#/$defs/nonNegativeInteger"}, + "minLength": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, + "pattern": { + "type": "string", + "format": "regex" + }, + "maxItems": {"$ref": "#/$defs/nonNegativeInteger"}, + "minItems": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "maxContains": {"$ref": "#/$defs/nonNegativeInteger"}, + "minContains": { + "$ref": "#/$defs/nonNegativeInteger", + "default": 1 + }, + "maxProperties": {"$ref": "#/$defs/nonNegativeInteger"}, + "minProperties": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, + "required": {"$ref": "#/$defs/stringArray"}, + "dependentRequired": { + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/stringArray" + } + } + }, + "$defs": { + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "$ref": "#/$defs/nonNegativeInteger", + "default": 0 + }, + "simpleTypes": { + "enum": ["array", "boolean", "integer", "null", "number", "object", "string"] + }, + "stringArray": { + "type": "array", + "items": {"type": "string"}, + "uniqueItems": true, + "default": [] + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/schema.json b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/schema.json new file mode 100644 index 000000000..1c68270fd --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-2020-12/schema.json @@ -0,0 +1,55 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/schema", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/core": true, + "https://json-schema.org/draft/2020-12/vocab/applicator": true, + "https://json-schema.org/draft/2020-12/vocab/unevaluated": true, + "https://json-schema.org/draft/2020-12/vocab/validation": true, + "https://json-schema.org/draft/2020-12/vocab/meta-data": true, + "https://json-schema.org/draft/2020-12/vocab/format-annotation": true, + "https://json-schema.org/draft/2020-12/vocab/content": true + }, + "$dynamicAnchor": "meta", + + "title": "Core and Validation specifications meta-schema", + "allOf": [ + {"$ref": "meta/core"}, + {"$ref": "meta/applicator"}, + {"$ref": "meta/unevaluated"}, + {"$ref": "meta/validation"}, + {"$ref": "meta/meta-data"}, + {"$ref": "meta/format-annotation"}, + {"$ref": "meta/content"} + ], + "type": ["object", "boolean"], + "$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.", + "properties": { + "definitions": { + "$comment": "\"definitions\" has been replaced by \"$defs\".", + "type": "object", + "additionalProperties": {"$dynamicRef": "#meta"}, + "deprecated": true, + "default": {} + }, + "dependencies": { + "$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.", + "type": "object", + "additionalProperties": { + "anyOf": [{"$dynamicRef": "#meta"}, {"$ref": "meta/validation#/$defs/stringArray"}] + }, + "deprecated": true, + "default": {} + }, + "$recursiveAnchor": { + "$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".", + "$ref": "meta/core#/$defs/anchorString", + "deprecated": true + }, + "$recursiveRef": { + "$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".", + "$ref": "meta/core#/$defs/uriReferenceString", + "deprecated": true + } + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-draft-06.json b/libs/events/node_modules/ajv/lib/refs/json-schema-draft-06.json new file mode 100644 index 000000000..5410064ba --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-draft-06.json @@ -0,0 +1,137 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$id": "http://json-schema.org/draft-06/schema#", + "title": "Core schema meta-schema", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": {"$ref": "#"} + }, + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "allOf": [{"$ref": "#/definitions/nonNegativeInteger"}, {"default": 0}] + }, + "simpleTypes": { + "enum": ["array", "boolean", "integer", "null", "number", "object", "string"] + }, + "stringArray": { + "type": "array", + "items": {"type": "string"}, + "uniqueItems": true, + "default": [] + } + }, + "type": ["object", "boolean"], + "properties": { + "$id": { + "type": "string", + "format": "uri-reference" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "$ref": { + "type": "string", + "format": "uri-reference" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": {}, + "examples": { + "type": "array", + "items": {} + }, + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": {"$ref": "#/definitions/nonNegativeInteger"}, + "minLength": {"$ref": "#/definitions/nonNegativeIntegerDefault0"}, + "pattern": { + "type": "string", + "format": "regex" + }, + "additionalItems": {"$ref": "#"}, + "items": { + "anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/schemaArray"}], + "default": {} + }, + "maxItems": {"$ref": "#/definitions/nonNegativeInteger"}, + "minItems": {"$ref": "#/definitions/nonNegativeIntegerDefault0"}, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "contains": {"$ref": "#"}, + "maxProperties": {"$ref": "#/definitions/nonNegativeInteger"}, + "minProperties": {"$ref": "#/definitions/nonNegativeIntegerDefault0"}, + "required": {"$ref": "#/definitions/stringArray"}, + "additionalProperties": {"$ref": "#"}, + "definitions": { + "type": "object", + "additionalProperties": {"$ref": "#"}, + "default": {} + }, + "properties": { + "type": "object", + "additionalProperties": {"$ref": "#"}, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": {"$ref": "#"}, + "default": {} + }, + "dependencies": { + "type": "object", + "additionalProperties": { + "anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/stringArray"}] + } + }, + "propertyNames": {"$ref": "#"}, + "const": {}, + "enum": { + "type": "array", + "minItems": 1, + "uniqueItems": true + }, + "type": { + "anyOf": [ + {"$ref": "#/definitions/simpleTypes"}, + { + "type": "array", + "items": {"$ref": "#/definitions/simpleTypes"}, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "format": {"type": "string"}, + "allOf": {"$ref": "#/definitions/schemaArray"}, + "anyOf": {"$ref": "#/definitions/schemaArray"}, + "oneOf": {"$ref": "#/definitions/schemaArray"}, + "not": {"$ref": "#"} + }, + "default": {} +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-draft-07.json b/libs/events/node_modules/ajv/lib/refs/json-schema-draft-07.json new file mode 100644 index 000000000..6a7485104 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-draft-07.json @@ -0,0 +1,151 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://json-schema.org/draft-07/schema#", + "title": "Core schema meta-schema", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": {"$ref": "#"} + }, + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "allOf": [{"$ref": "#/definitions/nonNegativeInteger"}, {"default": 0}] + }, + "simpleTypes": { + "enum": ["array", "boolean", "integer", "null", "number", "object", "string"] + }, + "stringArray": { + "type": "array", + "items": {"type": "string"}, + "uniqueItems": true, + "default": [] + } + }, + "type": ["object", "boolean"], + "properties": { + "$id": { + "type": "string", + "format": "uri-reference" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "$ref": { + "type": "string", + "format": "uri-reference" + }, + "$comment": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": true, + "readOnly": { + "type": "boolean", + "default": false + }, + "examples": { + "type": "array", + "items": true + }, + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": {"$ref": "#/definitions/nonNegativeInteger"}, + "minLength": {"$ref": "#/definitions/nonNegativeIntegerDefault0"}, + "pattern": { + "type": "string", + "format": "regex" + }, + "additionalItems": {"$ref": "#"}, + "items": { + "anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/schemaArray"}], + "default": true + }, + "maxItems": {"$ref": "#/definitions/nonNegativeInteger"}, + "minItems": {"$ref": "#/definitions/nonNegativeIntegerDefault0"}, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "contains": {"$ref": "#"}, + "maxProperties": {"$ref": "#/definitions/nonNegativeInteger"}, + "minProperties": {"$ref": "#/definitions/nonNegativeIntegerDefault0"}, + "required": {"$ref": "#/definitions/stringArray"}, + "additionalProperties": {"$ref": "#"}, + "definitions": { + "type": "object", + "additionalProperties": {"$ref": "#"}, + "default": {} + }, + "properties": { + "type": "object", + "additionalProperties": {"$ref": "#"}, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": {"$ref": "#"}, + "propertyNames": {"format": "regex"}, + "default": {} + }, + "dependencies": { + "type": "object", + "additionalProperties": { + "anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/stringArray"}] + } + }, + "propertyNames": {"$ref": "#"}, + "const": true, + "enum": { + "type": "array", + "items": true, + "minItems": 1, + "uniqueItems": true + }, + "type": { + "anyOf": [ + {"$ref": "#/definitions/simpleTypes"}, + { + "type": "array", + "items": {"$ref": "#/definitions/simpleTypes"}, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "format": {"type": "string"}, + "contentMediaType": {"type": "string"}, + "contentEncoding": {"type": "string"}, + "if": {"$ref": "#"}, + "then": {"$ref": "#"}, + "else": {"$ref": "#"}, + "allOf": {"$ref": "#/definitions/schemaArray"}, + "anyOf": {"$ref": "#/definitions/schemaArray"}, + "oneOf": {"$ref": "#/definitions/schemaArray"}, + "not": {"$ref": "#"} + }, + "default": true +} diff --git a/libs/events/node_modules/ajv/lib/refs/json-schema-secure.json b/libs/events/node_modules/ajv/lib/refs/json-schema-secure.json new file mode 100644 index 000000000..3968abd5d --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/json-schema-secure.json @@ -0,0 +1,88 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/json-schema-secure.json#", + "title": "Meta-schema for the security assessment of JSON Schemas", + "description": "If a JSON AnySchema fails validation against this meta-schema, it may be unsafe to validate untrusted data", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": {"$ref": "#"} + } + }, + "dependencies": { + "patternProperties": { + "description": "prevent slow validation of large property names", + "required": ["propertyNames"], + "properties": { + "propertyNames": { + "required": ["maxLength"] + } + } + }, + "uniqueItems": { + "description": "prevent slow validation of large non-scalar arrays", + "if": { + "properties": { + "uniqueItems": {"const": true}, + "items": { + "properties": { + "type": { + "anyOf": [ + { + "enum": ["object", "array"] + }, + { + "type": "array", + "contains": {"enum": ["object", "array"]} + } + ] + } + } + } + } + }, + "then": { + "required": ["maxItems"] + } + }, + "pattern": { + "description": "prevent slow pattern matching of large strings", + "required": ["maxLength"] + }, + "format": { + "description": "prevent slow format validation of large strings", + "required": ["maxLength"] + } + }, + "properties": { + "additionalItems": {"$ref": "#"}, + "additionalProperties": {"$ref": "#"}, + "dependencies": { + "additionalProperties": { + "anyOf": [{"type": "array"}, {"$ref": "#"}] + } + }, + "items": { + "anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/schemaArray"}] + }, + "definitions": { + "additionalProperties": {"$ref": "#"} + }, + "patternProperties": { + "additionalProperties": {"$ref": "#"} + }, + "properties": { + "additionalProperties": {"$ref": "#"} + }, + "if": {"$ref": "#"}, + "then": {"$ref": "#"}, + "else": {"$ref": "#"}, + "allOf": {"$ref": "#/definitions/schemaArray"}, + "anyOf": {"$ref": "#/definitions/schemaArray"}, + "oneOf": {"$ref": "#/definitions/schemaArray"}, + "not": {"$ref": "#"}, + "contains": {"$ref": "#"}, + "propertyNames": {"$ref": "#"} + } +} diff --git a/libs/events/node_modules/ajv/lib/refs/jtd-schema.ts b/libs/events/node_modules/ajv/lib/refs/jtd-schema.ts new file mode 100644 index 000000000..c01981289 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/refs/jtd-schema.ts @@ -0,0 +1,130 @@ +import {SchemaObject} from "../types" + +type MetaSchema = (root: boolean) => SchemaObject + +const shared: MetaSchema = (root) => { + const sch: SchemaObject = { + nullable: {type: "boolean"}, + metadata: { + optionalProperties: { + union: {elements: {ref: "schema"}}, + }, + additionalProperties: true, + }, + } + if (root) sch.definitions = {values: {ref: "schema"}} + return sch +} + +const emptyForm: MetaSchema = (root) => ({ + optionalProperties: shared(root), +}) + +const refForm: MetaSchema = (root) => ({ + properties: { + ref: {type: "string"}, + }, + optionalProperties: shared(root), +}) + +const typeForm: MetaSchema = (root) => ({ + properties: { + type: { + enum: [ + "boolean", + "timestamp", + "string", + "float32", + "float64", + "int8", + "uint8", + "int16", + "uint16", + "int32", + "uint32", + ], + }, + }, + optionalProperties: shared(root), +}) + +const enumForm: MetaSchema = (root) => ({ + properties: { + enum: {elements: {type: "string"}}, + }, + optionalProperties: shared(root), +}) + +const elementsForm: MetaSchema = (root) => ({ + properties: { + elements: {ref: "schema"}, + }, + optionalProperties: shared(root), +}) + +const propertiesForm: MetaSchema = (root) => ({ + properties: { + properties: {values: {ref: "schema"}}, + }, + optionalProperties: { + optionalProperties: {values: {ref: "schema"}}, + additionalProperties: {type: "boolean"}, + ...shared(root), + }, +}) + +const optionalPropertiesForm: MetaSchema = (root) => ({ + properties: { + optionalProperties: {values: {ref: "schema"}}, + }, + optionalProperties: { + additionalProperties: {type: "boolean"}, + ...shared(root), + }, +}) + +const discriminatorForm: MetaSchema = (root) => ({ + properties: { + discriminator: {type: "string"}, + mapping: { + values: { + metadata: { + union: [propertiesForm(false), optionalPropertiesForm(false)], + }, + }, + }, + }, + optionalProperties: shared(root), +}) + +const valuesForm: MetaSchema = (root) => ({ + properties: { + values: {ref: "schema"}, + }, + optionalProperties: shared(root), +}) + +const schema: MetaSchema = (root) => ({ + metadata: { + union: [ + emptyForm, + refForm, + typeForm, + enumForm, + elementsForm, + propertiesForm, + optionalPropertiesForm, + discriminatorForm, + valuesForm, + ].map((s) => s(root)), + }, +}) + +const jtdMetaSchema: SchemaObject = { + definitions: { + schema: schema(false), + }, + ...schema(true), +} + +export default jtdMetaSchema diff --git a/libs/events/node_modules/ajv/lib/runtime/equal.ts b/libs/events/node_modules/ajv/lib/runtime/equal.ts new file mode 100644 index 000000000..3cb00631a --- /dev/null +++ b/libs/events/node_modules/ajv/lib/runtime/equal.ts @@ -0,0 +1,7 @@ +// https://github.com/ajv-validator/ajv/issues/889 +import * as equal from "fast-deep-equal" + +type Equal = typeof equal & {code: string} +;(equal as Equal).code = 'require("ajv/dist/runtime/equal").default' + +export default equal as Equal diff --git a/libs/events/node_modules/ajv/lib/runtime/parseJson.ts b/libs/events/node_modules/ajv/lib/runtime/parseJson.ts new file mode 100644 index 000000000..92579afeb --- /dev/null +++ b/libs/events/node_modules/ajv/lib/runtime/parseJson.ts @@ -0,0 +1,176 @@ +const rxParseJson = /position\s(\d+)$/ + +export function parseJson(s: string, pos: number): unknown { + let endPos: number | undefined + parseJson.message = undefined + let matches: RegExpExecArray | null + if (pos) s = s.slice(pos) + try { + parseJson.position = pos + s.length + return JSON.parse(s) + } catch (e) { + matches = rxParseJson.exec((e as Error).message) + if (!matches) { + parseJson.message = "unexpected end" + return undefined + } + endPos = +matches[1] + const c = s[endPos] + s = s.slice(0, endPos) + parseJson.position = pos + endPos + try { + return JSON.parse(s) + } catch (e1) { + parseJson.message = `unexpected token ${c}` + return undefined + } + } +} + +parseJson.message = undefined as string | undefined +parseJson.position = 0 as number +parseJson.code = 'require("ajv/dist/runtime/parseJson").parseJson' + +export function parseJsonNumber(s: string, pos: number, maxDigits?: number): number | undefined { + let numStr = "" + let c: string + parseJsonNumber.message = undefined + if (s[pos] === "-") { + numStr += "-" + pos++ + } + if (s[pos] === "0") { + numStr += "0" + pos++ + } else { + if (!parseDigits(maxDigits)) { + errorMessage() + return undefined + } + } + if (maxDigits) { + parseJsonNumber.position = pos + return +numStr + } + if (s[pos] === ".") { + numStr += "." + pos++ + if (!parseDigits()) { + errorMessage() + return undefined + } + } + if (((c = s[pos]), c === "e" || c === "E")) { + numStr += "e" + pos++ + if (((c = s[pos]), c === "+" || c === "-")) { + numStr += c + pos++ + } + if (!parseDigits()) { + errorMessage() + return undefined + } + } + parseJsonNumber.position = pos + return +numStr + + function parseDigits(maxLen?: number): boolean { + let digit = false + while (((c = s[pos]), c >= "0" && c <= "9" && (maxLen === undefined || maxLen-- > 0))) { + digit = true + numStr += c + pos++ + } + return digit + } + + function errorMessage(): void { + parseJsonNumber.position = pos + parseJsonNumber.message = pos < s.length ? `unexpected token ${s[pos]}` : "unexpected end" + } +} + +parseJsonNumber.message = undefined as string | undefined +parseJsonNumber.position = 0 as number +parseJsonNumber.code = 'require("ajv/dist/runtime/parseJson").parseJsonNumber' + +const escapedChars: {[X in string]?: string} = { + b: "\b", + f: "\f", + n: "\n", + r: "\r", + t: "\t", + '"': '"', + "/": "/", + "\\": "\\", +} + +const CODE_A: number = "a".charCodeAt(0) +const CODE_0: number = "0".charCodeAt(0) + +export function parseJsonString(s: string, pos: number): string | undefined { + let str = "" + let c: string | undefined + parseJsonString.message = undefined + // eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition + while (true) { + c = s[pos++] + if (c === '"') break + if (c === "\\") { + c = s[pos] + if (c in escapedChars) { + str += escapedChars[c] + pos++ + } else if (c === "u") { + pos++ + let count = 4 + let code = 0 + while (count--) { + code <<= 4 + c = s[pos] + if (c === undefined) { + errorMessage("unexpected end") + return undefined + } + c = c.toLowerCase() + if (c >= "a" && c <= "f") { + code += c.charCodeAt(0) - CODE_A + 10 + } else if (c >= "0" && c <= "9") { + code += c.charCodeAt(0) - CODE_0 + } else { + errorMessage(`unexpected token ${c}`) + return undefined + } + pos++ + } + str += String.fromCharCode(code) + } else { + errorMessage(`unexpected token ${c}`) + return undefined + } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + } else if (c === undefined) { + errorMessage("unexpected end") + return undefined + } else { + if (c.charCodeAt(0) >= 0x20) { + str += c + } else { + errorMessage(`unexpected token ${c}`) + return undefined + } + } + } + parseJsonString.position = pos + return str + + function errorMessage(msg: string): void { + parseJsonString.position = pos + parseJsonString.message = msg + } +} + +parseJsonString.message = undefined as string | undefined +parseJsonString.position = 0 as number +parseJsonString.code = 'require("ajv/dist/runtime/parseJson").parseJsonString' diff --git a/libs/events/node_modules/ajv/lib/runtime/quote.ts b/libs/events/node_modules/ajv/lib/runtime/quote.ts new file mode 100644 index 000000000..1160e6a23 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/runtime/quote.ts @@ -0,0 +1,31 @@ +const rxEscapable = + // eslint-disable-next-line no-control-regex, no-misleading-character-class + /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g + +const escaped: {[K in string]?: string} = { + "\b": "\\b", + "\t": "\\t", + "\n": "\\n", + "\f": "\\f", + "\r": "\\r", + '"': '\\"', + "\\": "\\\\", +} + +export default function quote(s: string): string { + rxEscapable.lastIndex = 0 + return ( + '"' + + (rxEscapable.test(s) + ? s.replace(rxEscapable, (a) => { + const c = escaped[a] + return typeof c === "string" + ? c + : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) + }) + : s) + + '"' + ) +} + +quote.code = 'require("ajv/dist/runtime/quote").default' diff --git a/libs/events/node_modules/ajv/lib/runtime/re2.ts b/libs/events/node_modules/ajv/lib/runtime/re2.ts new file mode 100644 index 000000000..0c769bc7a --- /dev/null +++ b/libs/events/node_modules/ajv/lib/runtime/re2.ts @@ -0,0 +1,6 @@ +import * as re2 from "re2" + +type Re2 = typeof re2 & {code: string} +;(re2 as Re2).code = 'require("ajv/dist/runtime/re2").default' + +export default re2 as Re2 diff --git a/libs/events/node_modules/ajv/lib/runtime/timestamp.ts b/libs/events/node_modules/ajv/lib/runtime/timestamp.ts new file mode 100644 index 000000000..1625f9a40 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/runtime/timestamp.ts @@ -0,0 +1,46 @@ +const DT_SEPARATOR = /t|\s/i +const DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ +const TIME = /^(\d\d):(\d\d):(\d\d)(?:\.\d+)?(?:z|([+-]\d\d)(?::?(\d\d))?)$/i +const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + +export default function validTimestamp(str: string, allowDate: boolean): boolean { + // http://tools.ietf.org/html/rfc3339#section-5.6 + const dt: string[] = str.split(DT_SEPARATOR) + return ( + (dt.length === 2 && validDate(dt[0]) && validTime(dt[1])) || + (allowDate && dt.length === 1 && validDate(dt[0])) + ) +} + +function validDate(str: string): boolean { + const matches: string[] | null = DATE.exec(str) + if (!matches) return false + const y: number = +matches[1] + const m: number = +matches[2] + const d: number = +matches[3] + return ( + m >= 1 && + m <= 12 && + d >= 1 && + (d <= DAYS[m] || + // leap year: https://tools.ietf.org/html/rfc3339#appendix-C + (m === 2 && d === 29 && (y % 100 === 0 ? y % 400 === 0 : y % 4 === 0))) + ) +} + +function validTime(str: string): boolean { + const matches: string[] | null = TIME.exec(str) + if (!matches) return false + const hr: number = +matches[1] + const min: number = +matches[2] + const sec: number = +matches[3] + const tzH: number = +(matches[4] || 0) + const tzM: number = +(matches[5] || 0) + return ( + (hr <= 23 && min <= 59 && sec <= 59) || + // leap second + (hr - tzH === 23 && min - tzM === 59 && sec === 60) + ) +} + +validTimestamp.code = 'require("ajv/dist/runtime/timestamp").default' diff --git a/libs/events/node_modules/ajv/lib/runtime/ucs2length.ts b/libs/events/node_modules/ajv/lib/runtime/ucs2length.ts new file mode 100644 index 000000000..47d8292b8 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/runtime/ucs2length.ts @@ -0,0 +1,20 @@ +// https://mathiasbynens.be/notes/javascript-encoding +// https://github.com/bestiejs/punycode.js - punycode.ucs2.decode +export default function ucs2length(str: string): number { + const len = str.length + let length = 0 + let pos = 0 + let value: number + while (pos < len) { + length++ + value = str.charCodeAt(pos++) + if (value >= 0xd800 && value <= 0xdbff && pos < len) { + // high surrogate, and there is a next character + value = str.charCodeAt(pos) + if ((value & 0xfc00) === 0xdc00) pos++ // low surrogate + } + } + return length +} + +ucs2length.code = 'require("ajv/dist/runtime/ucs2length").default' diff --git a/libs/events/node_modules/ajv/lib/runtime/uri.ts b/libs/events/node_modules/ajv/lib/runtime/uri.ts new file mode 100644 index 000000000..7dd35f9d1 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/runtime/uri.ts @@ -0,0 +1,6 @@ +import * as uri from "uri-js" + +type URI = typeof uri & {code: string} +;(uri as URI).code = 'require("ajv/dist/runtime/uri").default' + +export default uri as URI diff --git a/libs/events/node_modules/ajv/lib/runtime/validation_error.ts b/libs/events/node_modules/ajv/lib/runtime/validation_error.ts new file mode 100644 index 000000000..2d19a46a2 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/runtime/validation_error.ts @@ -0,0 +1,13 @@ +import type {ErrorObject} from "../types" + +export default class ValidationError extends Error { + readonly errors: Partial[] + readonly ajv: true + readonly validation: true + + constructor(errors: Partial[]) { + super("validation failed") + this.errors = errors + this.ajv = this.validation = true + } +} diff --git a/libs/events/node_modules/ajv/lib/standalone/index.ts b/libs/events/node_modules/ajv/lib/standalone/index.ts new file mode 100644 index 000000000..b6129ce9e --- /dev/null +++ b/libs/events/node_modules/ajv/lib/standalone/index.ts @@ -0,0 +1,100 @@ +import type AjvCore from "../core" +import type {AnyValidateFunction, SourceCode} from "../types" +import type {SchemaEnv} from "../compile" +import {UsedScopeValues, UsedValueState, ValueScopeName, varKinds} from "../compile/codegen/scope" +import {_, nil, _Code, Code, getProperty, getEsmExportName} from "../compile/codegen/code" + +function standaloneCode( + ajv: AjvCore, + refsOrFunc?: {[K in string]?: string} | AnyValidateFunction +): string { + if (!ajv.opts.code.source) { + throw new Error("moduleCode: ajv instance must have code.source option") + } + const {_n} = ajv.scope.opts + return typeof refsOrFunc == "function" + ? funcExportCode(refsOrFunc.source) + : refsOrFunc !== undefined + ? multiExportsCode(refsOrFunc, getValidate) + : multiExportsCode(ajv.schemas, (sch) => + sch.meta ? undefined : ajv.compile(sch.schema) + ) + + function getValidate(id: string): AnyValidateFunction { + const v = ajv.getSchema(id) + if (!v) throw new Error(`moduleCode: no schema with id ${id}`) + return v + } + + function funcExportCode(source?: SourceCode): string { + const usedValues: UsedScopeValues = {} + const n = source?.validateName + const vCode = validateCode(usedValues, source) + if (ajv.opts.code.esm) { + // Always do named export as `validate` rather than the variable `n` which is `validateXX` for known export value + return `"use strict";${_n}export const validate = ${n};${_n}export default ${n};${_n}${vCode}` + } + return `"use strict";${_n}module.exports = ${n};${_n}module.exports.default = ${n};${_n}${vCode}` + } + + function multiExportsCode( + schemas: {[K in string]?: T}, + getValidateFunc: (schOrId: T) => AnyValidateFunction | undefined + ): string { + const usedValues: UsedScopeValues = {} + let code = _`"use strict";` + for (const name in schemas) { + const v = getValidateFunc(schemas[name] as T) + if (v) { + const vCode = validateCode(usedValues, v.source) + const exportSyntax = ajv.opts.code.esm + ? _`export const ${getEsmExportName(name)}` + : _`exports${getProperty(name)}` + code = _`${code}${_n}${exportSyntax} = ${v.source?.validateName};${_n}${vCode}` + } + } + return `${code}` + } + + function validateCode(usedValues: UsedScopeValues, s?: SourceCode): Code { + if (!s) throw new Error('moduleCode: function does not have "source" property') + if (usedState(s.validateName) === UsedValueState.Completed) return nil + setUsedState(s.validateName, UsedValueState.Started) + + const scopeCode = ajv.scope.scopeCode(s.scopeValues, usedValues, refValidateCode) + const code = new _Code(`${scopeCode}${_n}${s.validateCode}`) + return s.evaluated ? _`${code}${s.validateName}.evaluated = ${s.evaluated};${_n}` : code + + function refValidateCode(n: ValueScopeName): Code | undefined { + const vRef = n.value?.ref + if (n.prefix === "validate" && typeof vRef == "function") { + const v = vRef as AnyValidateFunction + return validateCode(usedValues, v.source) + } else if ((n.prefix === "root" || n.prefix === "wrapper") && typeof vRef == "object") { + const {validate, validateName} = vRef as SchemaEnv + if (!validateName) throw new Error("ajv internal error") + const def = ajv.opts.code.es5 ? varKinds.var : varKinds.const + const wrapper = _`${def} ${n} = {validate: ${validateName}};` + if (usedState(validateName) === UsedValueState.Started) return wrapper + const vCode = validateCode(usedValues, validate?.source) + return _`${wrapper}${_n}${vCode}` + } + return undefined + } + + function usedState(name: ValueScopeName): UsedValueState | undefined { + return usedValues[name.prefix]?.get(name) + } + + function setUsedState(name: ValueScopeName, state: UsedValueState): void { + const {prefix} = name + const names = (usedValues[prefix] = usedValues[prefix] || new Map()) + names.set(name, state) + } + } +} + +module.exports = exports = standaloneCode +Object.defineProperty(exports, "__esModule", {value: true}) + +export default standaloneCode diff --git a/libs/events/node_modules/ajv/lib/standalone/instance.ts b/libs/events/node_modules/ajv/lib/standalone/instance.ts new file mode 100644 index 000000000..c4b2c30b5 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/standalone/instance.ts @@ -0,0 +1,36 @@ +import Ajv, {AnySchema, AnyValidateFunction, ErrorObject} from "../core" +import standaloneCode from "." +import * as requireFromString from "require-from-string" + +export default class AjvPack { + errors?: ErrorObject[] | null // errors from the last validation + constructor(readonly ajv: Ajv) {} + + validate(schemaKeyRef: AnySchema | string, data: unknown): boolean | Promise { + return Ajv.prototype.validate.call(this, schemaKeyRef, data) + } + + compile(schema: AnySchema, meta?: boolean): AnyValidateFunction { + return this.getStandalone(this.ajv.compile(schema, meta)) + } + + getSchema(keyRef: string): AnyValidateFunction | undefined { + const v = this.ajv.getSchema(keyRef) + if (!v) return undefined + return this.getStandalone(v) + } + + private getStandalone(v: AnyValidateFunction): AnyValidateFunction { + return requireFromString(standaloneCode(this.ajv, v)) as AnyValidateFunction + } + + addSchema(...args: Parameters): AjvPack { + this.ajv.addSchema.call(this.ajv, ...args) + return this + } + + addKeyword(...args: Parameters): AjvPack { + this.ajv.addKeyword.call(this.ajv, ...args) + return this + } +} diff --git a/libs/events/node_modules/ajv/lib/types/index.ts b/libs/events/node_modules/ajv/lib/types/index.ts new file mode 100644 index 000000000..123d9df16 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/types/index.ts @@ -0,0 +1,240 @@ +import * as URI from "uri-js" +import type {CodeGen, Code, Name, ScopeValueSets, ValueScopeName} from "../compile/codegen" +import type {SchemaEnv, SchemaCxt, SchemaObjCxt} from "../compile" +import type {JSONType} from "../compile/rules" +import type {KeywordCxt} from "../compile/validate" +import type Ajv from "../core" + +interface _SchemaObject { + id?: string + $id?: string + $schema?: string + [x: string]: any // TODO +} + +export interface SchemaObject extends _SchemaObject { + id?: string + $id?: string + $schema?: string + $async?: false + [x: string]: any // TODO +} + +export interface AsyncSchema extends _SchemaObject { + $async: true +} + +export type AnySchemaObject = SchemaObject | AsyncSchema + +export type Schema = SchemaObject | boolean + +export type AnySchema = Schema | AsyncSchema + +export type SchemaMap = {[Key in string]?: AnySchema} + +export interface SourceCode { + validateName: ValueScopeName + validateCode: string + scopeValues: ScopeValueSets + evaluated?: Code +} + +export interface DataValidationCxt { + instancePath: string + parentData: {[K in T]: any} // object or array + parentDataProperty: T // string or number + rootData: Record | any[] + dynamicAnchors: {[Ref in string]?: ValidateFunction} +} + +export interface ValidateFunction { + (this: Ajv | any, data: any, dataCxt?: DataValidationCxt): data is T + errors?: null | ErrorObject[] + evaluated?: Evaluated + schema: AnySchema + schemaEnv: SchemaEnv + source?: SourceCode +} + +export interface JTDParser { + (json: string): T | undefined + message?: string + position?: number +} + +export type EvaluatedProperties = {[K in string]?: true} | true + +export type EvaluatedItems = number | true + +export interface Evaluated { + // determined at compile time if staticProps/Items is true + props?: EvaluatedProperties + items?: EvaluatedItems + // whether props/items determined at compile time + dynamicProps: boolean + dynamicItems: boolean +} + +export interface AsyncValidateFunction extends ValidateFunction { + (...args: Parameters>): Promise + $async: true +} + +export type AnyValidateFunction = ValidateFunction | AsyncValidateFunction + +export interface ErrorObject, S = unknown> { + keyword: K + instancePath: string + schemaPath: string + params: P + // Added to validation errors of "propertyNames" keyword schema + propertyName?: string + // Excluded if option `messages` set to false. + message?: string + // These are added with the `verbose` option. + schema?: S + parentSchema?: AnySchemaObject + data?: unknown +} + +export type ErrorNoParams = ErrorObject, S> + +interface _KeywordDef { + keyword: string | string[] + type?: JSONType | JSONType[] // data types that keyword applies to + schemaType?: JSONType | JSONType[] // allowed type(s) of keyword value in the schema + allowUndefined?: boolean // used for keywords that can be invoked by other keywords, not being present in the schema + $data?: boolean // keyword supports [$data reference](../../docs/guide/combining-schemas.md#data-reference) + implements?: string[] // other schema keywords that this keyword implements + before?: string // keyword should be executed before this keyword (should be applicable to the same type) + post?: boolean // keyword should be executed after other keywords without post flag + metaSchema?: AnySchemaObject // meta-schema for keyword schema value - it is better to use schemaType where applicable + validateSchema?: AnyValidateFunction // compiled keyword metaSchema - should not be passed + dependencies?: string[] // keywords that must be present in the same schema + error?: KeywordErrorDefinition + $dataError?: KeywordErrorDefinition +} + +export interface CodeKeywordDefinition extends _KeywordDef { + code: (cxt: KeywordCxt, ruleType?: string) => void + trackErrors?: boolean +} + +export type MacroKeywordFunc = ( + schema: any, + parentSchema: AnySchemaObject, + it: SchemaCxt +) => AnySchema + +export type CompileKeywordFunc = ( + schema: any, + parentSchema: AnySchemaObject, + it: SchemaObjCxt +) => DataValidateFunction + +export interface DataValidateFunction { + (...args: Parameters): boolean | Promise + errors?: Partial[] +} + +export interface SchemaValidateFunction { + (schema: any, data: any, parentSchema?: AnySchemaObject, dataCxt?: DataValidationCxt): + | boolean + | Promise + errors?: Partial[] +} + +export interface FuncKeywordDefinition extends _KeywordDef { + validate?: SchemaValidateFunction | DataValidateFunction + compile?: CompileKeywordFunc + // schema: false makes validate not to expect schema (DataValidateFunction) + schema?: boolean // requires "validate" + modifying?: boolean + async?: boolean + valid?: boolean + errors?: boolean | "full" +} + +export interface MacroKeywordDefinition extends FuncKeywordDefinition { + macro: MacroKeywordFunc +} + +export type KeywordDefinition = + | CodeKeywordDefinition + | FuncKeywordDefinition + | MacroKeywordDefinition + +export type AddedKeywordDefinition = KeywordDefinition & { + type: JSONType[] + schemaType: JSONType[] +} + +export interface KeywordErrorDefinition { + message: string | Code | ((cxt: KeywordErrorCxt) => string | Code) + params?: Code | ((cxt: KeywordErrorCxt) => Code) +} + +export type Vocabulary = (KeywordDefinition | string)[] + +export interface KeywordErrorCxt { + gen: CodeGen + keyword: string + data: Name + $data?: string | false + schema: any // TODO + parentSchema?: AnySchemaObject + schemaCode: Code | number | boolean + schemaValue: Code | number | boolean + schemaType?: JSONType[] + errsCount?: Name + params: KeywordCxtParams + it: SchemaCxt +} + +export type KeywordCxtParams = {[P in string]?: Code | string | number} + +export type FormatValidator = (data: T) => boolean + +export type FormatCompare = (data1: T, data2: T) => number | undefined + +export type AsyncFormatValidator = (data: T) => Promise + +export interface FormatDefinition { + type?: T extends string ? "string" | undefined : "number" + validate: FormatValidator | (T extends string ? string | RegExp : never) + async?: false | undefined + compare?: FormatCompare +} + +export interface AsyncFormatDefinition { + type?: T extends string ? "string" | undefined : "number" + validate: AsyncFormatValidator + async: true + compare?: FormatCompare +} + +export type AddedFormat = + | true + | RegExp + | FormatValidator + | FormatDefinition + | FormatDefinition + | AsyncFormatDefinition + | AsyncFormatDefinition + +export type Format = AddedFormat | string + +export interface RegExpEngine { + (pattern: string, u: string): RegExpLike + code: string +} + +export interface RegExpLike { + test: (s: string) => boolean +} + +export interface UriResolver { + parse(uri: string): URI.URIComponents + resolve(base: string, path: string): string + serialize(component: URI.URIComponents): string +} diff --git a/libs/events/node_modules/ajv/lib/types/json-schema.ts b/libs/events/node_modules/ajv/lib/types/json-schema.ts new file mode 100644 index 000000000..281a38bdb --- /dev/null +++ b/libs/events/node_modules/ajv/lib/types/json-schema.ts @@ -0,0 +1,187 @@ +/* eslint-disable @typescript-eslint/no-empty-interface */ +type StrictNullChecksWrapper = undefined extends null + ? `strictNullChecks must be true in tsconfig to use ${Name}` + : Type + +type UnionToIntersection = (U extends any ? (_: U) => void : never) extends (_: infer I) => void + ? I + : never + +export type SomeJSONSchema = UncheckedJSONSchemaType + +type UncheckedPartialSchema = Partial> + +export type PartialSchema = StrictNullChecksWrapper<"PartialSchema", UncheckedPartialSchema> + +type JSONType = IsPartial extends true + ? T | undefined + : T + +interface NumberKeywords { + minimum?: number + maximum?: number + exclusiveMinimum?: number + exclusiveMaximum?: number + multipleOf?: number + format?: string +} + +interface StringKeywords { + minLength?: number + maxLength?: number + pattern?: string + format?: string +} + +type UncheckedJSONSchemaType = ( + | // these two unions allow arbitrary unions of types + { + anyOf: readonly UncheckedJSONSchemaType[] + } + | { + oneOf: readonly UncheckedJSONSchemaType[] + } + // this union allows for { type: (primitive)[] } style schemas + | ({ + type: readonly (T extends number + ? JSONType<"number" | "integer", IsPartial> + : T extends string + ? JSONType<"string", IsPartial> + : T extends boolean + ? JSONType<"boolean", IsPartial> + : never)[] + } & UnionToIntersection< + T extends number + ? NumberKeywords + : T extends string + ? StringKeywords + : T extends boolean + ? // eslint-disable-next-line @typescript-eslint/ban-types + {} + : never + >) + // this covers "normal" types; it's last so typescript looks to it first for errors + | ((T extends number + ? { + type: JSONType<"number" | "integer", IsPartial> + } & NumberKeywords + : T extends string + ? { + type: JSONType<"string", IsPartial> + } & StringKeywords + : T extends boolean + ? { + type: JSONType<"boolean", IsPartial> + } + : T extends readonly [any, ...any[]] + ? { + // JSON AnySchema for tuple + type: JSONType<"array", IsPartial> + items: { + readonly [K in keyof T]-?: UncheckedJSONSchemaType & Nullable + } & {length: T["length"]} + minItems: T["length"] + } & ({maxItems: T["length"]} | {additionalItems: false}) + : T extends readonly any[] + ? { + type: JSONType<"array", IsPartial> + items: UncheckedJSONSchemaType + contains?: UncheckedPartialSchema + minItems?: number + maxItems?: number + minContains?: number + maxContains?: number + uniqueItems?: true + additionalItems?: never + } + : T extends Record + ? { + // JSON AnySchema for records and dictionaries + // "required" is not optional because it is often forgotten + // "properties" are optional for more concise dictionary schemas + // "patternProperties" and can be only used with interfaces that have string index + type: JSONType<"object", IsPartial> + additionalProperties?: boolean | UncheckedJSONSchemaType + unevaluatedProperties?: boolean | UncheckedJSONSchemaType + properties?: IsPartial extends true + ? Partial> + : UncheckedPropertiesSchema + patternProperties?: Record> + propertyNames?: Omit, "type"> & {type?: "string"} + dependencies?: {[K in keyof T]?: Readonly<(keyof T)[]> | UncheckedPartialSchema} + dependentRequired?: {[K in keyof T]?: Readonly<(keyof T)[]>} + dependentSchemas?: {[K in keyof T]?: UncheckedPartialSchema} + minProperties?: number + maxProperties?: number + } & (IsPartial extends true // "required" is not necessary if it's a non-partial type with no required keys // are listed it only asserts that optional cannot be listed. // "required" type does not guarantee that all required properties + ? {required: Readonly<(keyof T)[]>} + : [UncheckedRequiredMembers] extends [never] + ? {required?: Readonly[]>} + : {required: Readonly[]>}) + : T extends null + ? { + type: JSONType<"null", IsPartial> + nullable: true + } + : never) & { + allOf?: Readonly[]> + anyOf?: Readonly[]> + oneOf?: Readonly[]> + if?: UncheckedPartialSchema + then?: UncheckedPartialSchema + else?: UncheckedPartialSchema + not?: UncheckedPartialSchema + }) +) & { + [keyword: string]: any + $id?: string + $ref?: string + $defs?: Record> + definitions?: Record> +} + +export type JSONSchemaType = StrictNullChecksWrapper< + "JSONSchemaType", + UncheckedJSONSchemaType +> + +type Known = + | {[key: string]: Known} + | [Known, ...Known[]] + | Known[] + | number + | string + | boolean + | null + +type UncheckedPropertiesSchema = { + [K in keyof T]-?: (UncheckedJSONSchemaType & Nullable) | {$ref: string} +} + +export type PropertiesSchema = StrictNullChecksWrapper< + "PropertiesSchema", + UncheckedPropertiesSchema +> + +type UncheckedRequiredMembers = { + [K in keyof T]-?: undefined extends T[K] ? never : K +}[keyof T] + +export type RequiredMembers = StrictNullChecksWrapper< + "RequiredMembers", + UncheckedRequiredMembers +> + +type Nullable = undefined extends T + ? { + nullable: true + const?: null // any non-null value would fail `const: null`, `null` would fail any other value in const + enum?: Readonly<(T | null)[]> // `null` must be explicitly included in "enum" for `null` to pass + default?: T | null + } + : { + nullable?: false + const?: T + enum?: Readonly + default?: T + } diff --git a/libs/events/node_modules/ajv/lib/types/jtd-schema.ts b/libs/events/node_modules/ajv/lib/types/jtd-schema.ts new file mode 100644 index 000000000..61b2bde81 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/types/jtd-schema.ts @@ -0,0 +1,273 @@ +/** numeric strings */ +type NumberType = "float32" | "float64" | "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" + +/** string strings */ +type StringType = "string" | "timestamp" + +/** Generic JTD Schema without inference of the represented type */ +export type SomeJTDSchemaType = ( + | // ref + {ref: string} + // primitives + | {type: NumberType | StringType | "boolean"} + // enum + | {enum: string[]} + // elements + | {elements: SomeJTDSchemaType} + // values + | {values: SomeJTDSchemaType} + // properties + | { + properties: Record + optionalProperties?: Record + additionalProperties?: boolean + } + | { + properties?: Record + optionalProperties: Record + additionalProperties?: boolean + } + // discriminator + | {discriminator: string; mapping: Record} + // empty + // NOTE see the end of + // https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492 + // eslint-disable-next-line @typescript-eslint/ban-types + | {} +) & { + nullable?: boolean + metadata?: Record + definitions?: Record +} + +/** required keys of an object, not undefined */ +type RequiredKeys = { + [K in keyof T]-?: undefined extends T[K] ? never : K +}[keyof T] + +/** optional or undifined-able keys of an object */ +type OptionalKeys = { + [K in keyof T]-?: undefined extends T[K] ? K : never +}[keyof T] + +/** type is true if T is a union type */ +type IsUnion_ = false extends ( + T extends unknown ? ([U] extends [T] ? false : true) : never +) + ? false + : true +type IsUnion = IsUnion_ + +/** type is true if T is identically E */ +type TypeEquality = [T] extends [E] ? ([E] extends [T] ? true : false) : false + +/** type is true if T or null is identically E or null*/ +type NullTypeEquality = TypeEquality + +/** gets only the string literals of a type or null if a type isn't a string literal */ +type EnumString = [T] extends [never] + ? null + : T extends string + ? string extends T + ? null + : T + : null + +/** true if type is a union of string literals */ +type IsEnum = null extends EnumString ? false : true + +/** true only if all types are array types (not tuples) */ +// NOTE relies on the fact that tuples don't have an index at 0.5, but arrays +// have an index at every number +type IsElements = false extends IsUnion + ? [T] extends [readonly unknown[]] + ? undefined extends T[0.5] + ? false + : true + : false + : false + +/** true if the the type is a values type */ +type IsValues = false extends IsUnion ? TypeEquality : false + +/** true if type is a properties type and Union is false, or type is a discriminator type and Union is true */ +type IsRecord = Union extends IsUnion + ? null extends EnumString + ? false + : true + : false + +/** true if type represents an empty record */ +type IsEmptyRecord = [T] extends [Record] + ? [T] extends [never] + ? false + : true + : false + +/** actual schema */ +export type JTDSchemaType = Record> = ( + | // refs - where null wasn't specified, must match exactly + (null extends EnumString + ? never + : + | ({[K in keyof D]: [T] extends [D[K]] ? {ref: K} : never}[keyof D] & {nullable?: false}) + // nulled refs - if ref is nullable and nullable is specified, then it can + // match either null or non-null definitions + | (null extends T + ? { + [K in keyof D]: [Exclude] extends [Exclude] + ? {ref: K} + : never + }[keyof D] & {nullable: true} + : never)) + // empty - empty schemas also treat nullable differently in that it's now fully ignored + | (unknown extends T ? {nullable?: boolean} : never) + // all other types // numbers - only accepts the type number + | ((true extends NullTypeEquality + ? {type: NumberType} + : // booleans - accepts the type boolean + true extends NullTypeEquality + ? {type: "boolean"} + : // strings - only accepts the type string + true extends NullTypeEquality + ? {type: StringType} + : // strings - only accepts the type Date + true extends NullTypeEquality + ? {type: "timestamp"} + : // enums - only accepts union of string literals + // TODO we can't actually check that everything in the union was specified + true extends IsEnum> + ? {enum: EnumString>[]} + : // arrays - only accepts arrays, could be array of unions to be resolved later + true extends IsElements> + ? T extends readonly (infer E)[] + ? { + elements: JTDSchemaType + } + : never + : // empty properties + true extends IsEmptyRecord> + ? + | {properties: Record; optionalProperties?: Record} + | {optionalProperties: Record} + : // values + true extends IsValues> + ? T extends Record + ? { + values: JTDSchemaType + } + : never + : // properties + true extends IsRecord, false> + ? ([RequiredKeys>] extends [never] + ? { + properties?: Record + } + : { + properties: {[K in RequiredKeys]: JTDSchemaType} + }) & + ([OptionalKeys>] extends [never] + ? { + optionalProperties?: Record + } + : { + optionalProperties: { + [K in OptionalKeys]: JTDSchemaType, D> + } + }) & { + additionalProperties?: boolean + } + : // discriminator + true extends IsRecord, true> + ? { + [K in keyof Exclude]-?: Exclude[K] extends string + ? { + discriminator: K + mapping: { + // TODO currently allows descriminator to be present in schema + [M in Exclude[K]]: JTDSchemaType< + Omit ? T : never, K>, + D + > + } + } + : never + }[keyof Exclude] + : never) & + (null extends T + ? { + nullable: true + } + : {nullable?: false})) +) & { + // extra properties + metadata?: Record + // TODO these should only be allowed at the top level + definitions?: {[K in keyof D]: JTDSchemaType} +} + +type JTDDataDef> = + | // ref + (S extends {ref: string} + ? D extends {[K in S["ref"]]: infer V} + ? JTDDataDef + : never + : // type + S extends {type: NumberType} + ? number + : S extends {type: "boolean"} + ? boolean + : S extends {type: "string"} + ? string + : S extends {type: "timestamp"} + ? string | Date + : // enum + S extends {enum: readonly (infer E)[]} + ? string extends E + ? never + : [E] extends [string] + ? E + : never + : // elements + S extends {elements: infer E} + ? JTDDataDef[] + : // properties + S extends { + properties: Record + optionalProperties?: Record + additionalProperties?: boolean + } + ? {-readonly [K in keyof S["properties"]]-?: JTDDataDef} & { + -readonly [K in keyof S["optionalProperties"]]+?: JTDDataDef< + S["optionalProperties"][K], + D + > + } & ([S["additionalProperties"]] extends [true] ? Record : unknown) + : S extends { + properties?: Record + optionalProperties: Record + additionalProperties?: boolean + } + ? {-readonly [K in keyof S["properties"]]-?: JTDDataDef} & { + -readonly [K in keyof S["optionalProperties"]]+?: JTDDataDef< + S["optionalProperties"][K], + D + > + } & ([S["additionalProperties"]] extends [true] ? Record : unknown) + : // values + S extends {values: infer V} + ? Record> + : // discriminator + S extends {discriminator: infer M; mapping: Record} + ? [M] extends [string] + ? { + [K in keyof S["mapping"]]: JTDDataDef & {[KM in M]: K} + }[keyof S["mapping"]] + : never + : // empty + unknown) + | (S extends {nullable: true} ? null : never) + +export type JTDDataType = S extends {definitions: Record} + ? JTDDataDef + : JTDDataDef> diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts new file mode 100644 index 000000000..755e5b3da --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts @@ -0,0 +1,56 @@ +import type { + CodeKeywordDefinition, + ErrorObject, + KeywordErrorDefinition, + AnySchema, +} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str, not, Name} from "../../compile/codegen" +import {alwaysValidSchema, checkStrictMode, Type} from "../../compile/util" + +export type AdditionalItemsError = ErrorObject<"additionalItems", {limit: number}, AnySchema> + +const error: KeywordErrorDefinition = { + message: ({params: {len}}) => str`must NOT have more than ${len} items`, + params: ({params: {len}}) => _`{limit: ${len}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "additionalItems" as const, + type: "array", + schemaType: ["boolean", "object"], + before: "uniqueItems", + error, + code(cxt: KeywordCxt) { + const {parentSchema, it} = cxt + const {items} = parentSchema + if (!Array.isArray(items)) { + checkStrictMode(it, '"additionalItems" is ignored when "items" is not an array of schemas') + return + } + validateAdditionalItems(cxt, items) + }, +} + +export function validateAdditionalItems(cxt: KeywordCxt, items: AnySchema[]): void { + const {gen, schema, data, keyword, it} = cxt + it.items = true + const len = gen.const("len", _`${data}.length`) + if (schema === false) { + cxt.setParams({len: items.length}) + cxt.pass(_`${len} <= ${items.length}`) + } else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) { + const valid = gen.var("valid", _`${len} <= ${items.length}`) // TODO var + gen.if(not(valid), () => validateItems(valid)) + cxt.ok(valid) + } + + function validateItems(valid: Name): void { + gen.forRange("i", items.length, len, (i) => { + cxt.subschema({keyword, dataProp: i, dataPropType: Type.Num}, valid) + if (!it.allErrors) gen.if(not(valid), () => gen.break()) + }) + } +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts new file mode 100644 index 000000000..bfb511ce5 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts @@ -0,0 +1,118 @@ +import type { + CodeKeywordDefinition, + AddedKeywordDefinition, + ErrorObject, + KeywordErrorDefinition, + AnySchema, +} from "../../types" +import {allSchemaProperties, usePattern, isOwnProperty} from "../code" +import {_, nil, or, not, Code, Name} from "../../compile/codegen" +import N from "../../compile/names" +import type {SubschemaArgs} from "../../compile/validate/subschema" +import {alwaysValidSchema, schemaRefOrVal, Type} from "../../compile/util" + +export type AdditionalPropertiesError = ErrorObject< + "additionalProperties", + {additionalProperty: string}, + AnySchema +> + +const error: KeywordErrorDefinition = { + message: "must NOT have additional properties", + params: ({params}) => _`{additionalProperty: ${params.additionalProperty}}`, +} + +const def: CodeKeywordDefinition & AddedKeywordDefinition = { + keyword: "additionalProperties", + type: ["object"], + schemaType: ["boolean", "object"], + allowUndefined: true, + trackErrors: true, + error, + code(cxt) { + const {gen, schema, parentSchema, data, errsCount, it} = cxt + /* istanbul ignore if */ + if (!errsCount) throw new Error("ajv implementation error") + const {allErrors, opts} = it + it.props = true + if (opts.removeAdditional !== "all" && alwaysValidSchema(it, schema)) return + const props = allSchemaProperties(parentSchema.properties) + const patProps = allSchemaProperties(parentSchema.patternProperties) + checkAdditionalProperties() + cxt.ok(_`${errsCount} === ${N.errors}`) + + function checkAdditionalProperties(): void { + gen.forIn("key", data, (key: Name) => { + if (!props.length && !patProps.length) additionalPropertyCode(key) + else gen.if(isAdditional(key), () => additionalPropertyCode(key)) + }) + } + + function isAdditional(key: Name): Code { + let definedProp: Code + if (props.length > 8) { + // TODO maybe an option instead of hard-coded 8? + const propsSchema = schemaRefOrVal(it, parentSchema.properties, "properties") + definedProp = isOwnProperty(gen, propsSchema as Code, key) + } else if (props.length) { + definedProp = or(...props.map((p) => _`${key} === ${p}`)) + } else { + definedProp = nil + } + if (patProps.length) { + definedProp = or(definedProp, ...patProps.map((p) => _`${usePattern(cxt, p)}.test(${key})`)) + } + return not(definedProp) + } + + function deleteAdditional(key: Name): void { + gen.code(_`delete ${data}[${key}]`) + } + + function additionalPropertyCode(key: Name): void { + if (opts.removeAdditional === "all" || (opts.removeAdditional && schema === false)) { + deleteAdditional(key) + return + } + + if (schema === false) { + cxt.setParams({additionalProperty: key}) + cxt.error() + if (!allErrors) gen.break() + return + } + + if (typeof schema == "object" && !alwaysValidSchema(it, schema)) { + const valid = gen.name("valid") + if (opts.removeAdditional === "failing") { + applyAdditionalSchema(key, valid, false) + gen.if(not(valid), () => { + cxt.reset() + deleteAdditional(key) + }) + } else { + applyAdditionalSchema(key, valid) + if (!allErrors) gen.if(not(valid), () => gen.break()) + } + } + } + + function applyAdditionalSchema(key: Name, valid: Name, errors?: false): void { + const subschema: SubschemaArgs = { + keyword: "additionalProperties", + dataProp: key, + dataPropType: Type.Str, + } + if (errors === false) { + Object.assign(subschema, { + compositeRule: true, + createErrors: false, + allErrors: false, + }) + } + cxt.subschema(subschema, valid) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/allOf.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/allOf.ts new file mode 100644 index 000000000..cdfa86ff4 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/allOf.ts @@ -0,0 +1,22 @@ +import type {CodeKeywordDefinition, AnySchema} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {alwaysValidSchema} from "../../compile/util" + +const def: CodeKeywordDefinition = { + keyword: "allOf", + schemaType: "array", + code(cxt: KeywordCxt) { + const {gen, schema, it} = cxt + /* istanbul ignore if */ + if (!Array.isArray(schema)) throw new Error("ajv implementation error") + const valid = gen.name("valid") + schema.forEach((sch: AnySchema, i: number) => { + if (alwaysValidSchema(it, sch)) return + const schCxt = cxt.subschema({keyword: "allOf", schemaProp: i}, valid) + cxt.ok(valid) + cxt.mergeEvaluated(schCxt) + }) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts new file mode 100644 index 000000000..bd331b5ae --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts @@ -0,0 +1,14 @@ +import type {CodeKeywordDefinition, ErrorNoParams, AnySchema} from "../../types" +import {validateUnion} from "../code" + +export type AnyOfError = ErrorNoParams<"anyOf", AnySchema[]> + +const def: CodeKeywordDefinition = { + keyword: "anyOf", + schemaType: "array", + trackErrors: true, + code: validateUnion, + error: {message: "must match a schema in anyOf"}, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/contains.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/contains.ts new file mode 100644 index 000000000..d88675c6c --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/contains.ts @@ -0,0 +1,109 @@ +import type { + CodeKeywordDefinition, + KeywordErrorDefinition, + ErrorObject, + AnySchema, +} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str, Name} from "../../compile/codegen" +import {alwaysValidSchema, checkStrictMode, Type} from "../../compile/util" + +export type ContainsError = ErrorObject< + "contains", + {minContains: number; maxContains?: number}, + AnySchema +> + +const error: KeywordErrorDefinition = { + message: ({params: {min, max}}) => + max === undefined + ? str`must contain at least ${min} valid item(s)` + : str`must contain at least ${min} and no more than ${max} valid item(s)`, + params: ({params: {min, max}}) => + max === undefined ? _`{minContains: ${min}}` : _`{minContains: ${min}, maxContains: ${max}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "contains", + type: "array", + schemaType: ["object", "boolean"], + before: "uniqueItems", + trackErrors: true, + error, + code(cxt: KeywordCxt) { + const {gen, schema, parentSchema, data, it} = cxt + let min: number + let max: number | undefined + const {minContains, maxContains} = parentSchema + if (it.opts.next) { + min = minContains === undefined ? 1 : minContains + max = maxContains + } else { + min = 1 + } + const len = gen.const("len", _`${data}.length`) + cxt.setParams({min, max}) + if (max === undefined && min === 0) { + checkStrictMode(it, `"minContains" == 0 without "maxContains": "contains" keyword ignored`) + return + } + if (max !== undefined && min > max) { + checkStrictMode(it, `"minContains" > "maxContains" is always invalid`) + cxt.fail() + return + } + if (alwaysValidSchema(it, schema)) { + let cond = _`${len} >= ${min}` + if (max !== undefined) cond = _`${cond} && ${len} <= ${max}` + cxt.pass(cond) + return + } + + it.items = true + const valid = gen.name("valid") + if (max === undefined && min === 1) { + validateItems(valid, () => gen.if(valid, () => gen.break())) + } else if (min === 0) { + gen.let(valid, true) + if (max !== undefined) gen.if(_`${data}.length > 0`, validateItemsWithCount) + } else { + gen.let(valid, false) + validateItemsWithCount() + } + cxt.result(valid, () => cxt.reset()) + + function validateItemsWithCount(): void { + const schValid = gen.name("_valid") + const count = gen.let("count", 0) + validateItems(schValid, () => gen.if(schValid, () => checkLimits(count))) + } + + function validateItems(_valid: Name, block: () => void): void { + gen.forRange("i", 0, len, (i) => { + cxt.subschema( + { + keyword: "contains", + dataProp: i, + dataPropType: Type.Num, + compositeRule: true, + }, + _valid + ) + block() + }) + } + + function checkLimits(count: Name): void { + gen.code(_`${count}++`) + if (max === undefined) { + gen.if(_`${count} >= ${min}`, () => gen.assign(valid, true).break()) + } else { + gen.if(_`${count} > ${max}`, () => gen.assign(valid, false).break()) + if (min === 1) gen.assign(valid, true) + else gen.if(_`${count} >= ${min}`, () => gen.assign(valid, true)) + } + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts new file mode 100644 index 000000000..f67611286 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts @@ -0,0 +1,112 @@ +import type { + CodeKeywordDefinition, + ErrorObject, + KeywordErrorDefinition, + SchemaMap, + AnySchema, +} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str} from "../../compile/codegen" +import {alwaysValidSchema} from "../../compile/util" +import {checkReportMissingProp, checkMissingProp, reportMissingProp, propertyInData} from "../code" + +export type PropertyDependencies = {[K in string]?: string[]} + +export interface DependenciesErrorParams { + property: string + missingProperty: string + depsCount: number + deps: string // TODO change to string[] +} + +type SchemaDependencies = SchemaMap + +export type DependenciesError = ErrorObject< + "dependencies", + DependenciesErrorParams, + {[K in string]?: string[] | AnySchema} +> + +export const error: KeywordErrorDefinition = { + message: ({params: {property, depsCount, deps}}) => { + const property_ies = depsCount === 1 ? "property" : "properties" + return str`must have ${property_ies} ${deps} when property ${property} is present` + }, + params: ({params: {property, depsCount, deps, missingProperty}}) => + _`{property: ${property}, + missingProperty: ${missingProperty}, + depsCount: ${depsCount}, + deps: ${deps}}`, // TODO change to reference +} + +const def: CodeKeywordDefinition = { + keyword: "dependencies", + type: "object", + schemaType: "object", + error, + code(cxt: KeywordCxt) { + const [propDeps, schDeps] = splitDependencies(cxt) + validatePropertyDeps(cxt, propDeps) + validateSchemaDeps(cxt, schDeps) + }, +} + +function splitDependencies({schema}: KeywordCxt): [PropertyDependencies, SchemaDependencies] { + const propertyDeps: PropertyDependencies = {} + const schemaDeps: SchemaDependencies = {} + for (const key in schema) { + if (key === "__proto__") continue + const deps = Array.isArray(schema[key]) ? propertyDeps : schemaDeps + deps[key] = schema[key] + } + return [propertyDeps, schemaDeps] +} + +export function validatePropertyDeps( + cxt: KeywordCxt, + propertyDeps: {[K in string]?: string[]} = cxt.schema +): void { + const {gen, data, it} = cxt + if (Object.keys(propertyDeps).length === 0) return + const missing = gen.let("missing") + for (const prop in propertyDeps) { + const deps = propertyDeps[prop] as string[] + if (deps.length === 0) continue + const hasProperty = propertyInData(gen, data, prop, it.opts.ownProperties) + cxt.setParams({ + property: prop, + depsCount: deps.length, + deps: deps.join(", "), + }) + if (it.allErrors) { + gen.if(hasProperty, () => { + for (const depProp of deps) { + checkReportMissingProp(cxt, depProp) + } + }) + } else { + gen.if(_`${hasProperty} && (${checkMissingProp(cxt, deps, missing)})`) + reportMissingProp(cxt, missing) + gen.else() + } + } +} + +export function validateSchemaDeps(cxt: KeywordCxt, schemaDeps: SchemaMap = cxt.schema): void { + const {gen, data, keyword, it} = cxt + const valid = gen.name("valid") + for (const prop in schemaDeps) { + if (alwaysValidSchema(it, schemaDeps[prop] as AnySchema)) continue + gen.if( + propertyInData(gen, data, prop, it.opts.ownProperties), + () => { + const schCxt = cxt.subschema({keyword, schemaProp: prop}, valid) + cxt.mergeValidEvaluated(schCxt, valid) + }, + () => gen.var(valid, true) // TODO var + ) + cxt.ok(valid) + } +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts new file mode 100644 index 000000000..dbd3ae45c --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts @@ -0,0 +1,11 @@ +import type {CodeKeywordDefinition} from "../../types" +import {validateSchemaDeps} from "./dependencies" + +const def: CodeKeywordDefinition = { + keyword: "dependentSchemas", + type: "object", + schemaType: "object", + code: (cxt) => validateSchemaDeps(cxt), +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/if.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/if.ts new file mode 100644 index 000000000..5a40d5e3a --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/if.ts @@ -0,0 +1,80 @@ +import type { + CodeKeywordDefinition, + ErrorObject, + KeywordErrorDefinition, + AnySchema, +} from "../../types" +import type {SchemaObjCxt} from "../../compile" +import type {KeywordCxt} from "../../compile/validate" +import {_, str, not, Name} from "../../compile/codegen" +import {alwaysValidSchema, checkStrictMode} from "../../compile/util" + +export type IfKeywordError = ErrorObject<"if", {failingKeyword: string}, AnySchema> + +const error: KeywordErrorDefinition = { + message: ({params}) => str`must match "${params.ifClause}" schema`, + params: ({params}) => _`{failingKeyword: ${params.ifClause}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "if", + schemaType: ["object", "boolean"], + trackErrors: true, + error, + code(cxt: KeywordCxt) { + const {gen, parentSchema, it} = cxt + if (parentSchema.then === undefined && parentSchema.else === undefined) { + checkStrictMode(it, '"if" without "then" and "else" is ignored') + } + const hasThen = hasSchema(it, "then") + const hasElse = hasSchema(it, "else") + if (!hasThen && !hasElse) return + + const valid = gen.let("valid", true) + const schValid = gen.name("_valid") + validateIf() + cxt.reset() + + if (hasThen && hasElse) { + const ifClause = gen.let("ifClause") + cxt.setParams({ifClause}) + gen.if(schValid, validateClause("then", ifClause), validateClause("else", ifClause)) + } else if (hasThen) { + gen.if(schValid, validateClause("then")) + } else { + gen.if(not(schValid), validateClause("else")) + } + + cxt.pass(valid, () => cxt.error(true)) + + function validateIf(): void { + const schCxt = cxt.subschema( + { + keyword: "if", + compositeRule: true, + createErrors: false, + allErrors: false, + }, + schValid + ) + cxt.mergeEvaluated(schCxt) + } + + function validateClause(keyword: string, ifClause?: Name): () => void { + return () => { + const schCxt = cxt.subschema({keyword}, schValid) + gen.assign(valid, schValid) + cxt.mergeValidEvaluated(schCxt, valid) + if (ifClause) gen.assign(ifClause, _`${keyword}`) + else cxt.setParams({ifClause: keyword}) + } + } + }, +} + +function hasSchema(it: SchemaObjCxt, keyword: string): boolean { + const schema = it.schema[keyword] + return schema !== undefined && !alwaysValidSchema(it, schema) +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/index.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/index.ts new file mode 100644 index 000000000..fc5271699 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/index.ts @@ -0,0 +1,53 @@ +import type {ErrorNoParams, Vocabulary} from "../../types" +import additionalItems, {AdditionalItemsError} from "./additionalItems" +import prefixItems from "./prefixItems" +import items from "./items" +import items2020, {ItemsError} from "./items2020" +import contains, {ContainsError} from "./contains" +import dependencies, {DependenciesError} from "./dependencies" +import propertyNames, {PropertyNamesError} from "./propertyNames" +import additionalProperties, {AdditionalPropertiesError} from "./additionalProperties" +import properties from "./properties" +import patternProperties from "./patternProperties" +import notKeyword, {NotKeywordError} from "./not" +import anyOf, {AnyOfError} from "./anyOf" +import oneOf, {OneOfError} from "./oneOf" +import allOf from "./allOf" +import ifKeyword, {IfKeywordError} from "./if" +import thenElse from "./thenElse" + +export default function getApplicator(draft2020 = false): Vocabulary { + const applicator = [ + // any + notKeyword, + anyOf, + oneOf, + allOf, + ifKeyword, + thenElse, + // object + propertyNames, + additionalProperties, + dependencies, + properties, + patternProperties, + ] + // array + if (draft2020) applicator.push(prefixItems, items2020) + else applicator.push(additionalItems, items) + applicator.push(contains) + return applicator +} + +export type ApplicatorKeywordError = + | ErrorNoParams<"false schema"> + | AdditionalItemsError + | ItemsError + | ContainsError + | AdditionalPropertiesError + | DependenciesError + | IfKeywordError + | AnyOfError + | OneOfError + | NotKeywordError + | PropertyNamesError diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/items.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/items.ts new file mode 100644 index 000000000..033cb3977 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/items.ts @@ -0,0 +1,59 @@ +import type {CodeKeywordDefinition, AnySchema, AnySchemaObject} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_} from "../../compile/codegen" +import {alwaysValidSchema, mergeEvaluated, checkStrictMode} from "../../compile/util" +import {validateArray} from "../code" + +const def: CodeKeywordDefinition = { + keyword: "items", + type: "array", + schemaType: ["object", "array", "boolean"], + before: "uniqueItems", + code(cxt: KeywordCxt) { + const {schema, it} = cxt + if (Array.isArray(schema)) return validateTuple(cxt, "additionalItems", schema) + it.items = true + if (alwaysValidSchema(it, schema)) return + cxt.ok(validateArray(cxt)) + }, +} + +export function validateTuple( + cxt: KeywordCxt, + extraItems: string, + schArr: AnySchema[] = cxt.schema +): void { + const {gen, parentSchema, data, keyword, it} = cxt + checkStrictTuple(parentSchema) + if (it.opts.unevaluated && schArr.length && it.items !== true) { + it.items = mergeEvaluated.items(gen, schArr.length, it.items) + } + const valid = gen.name("valid") + const len = gen.const("len", _`${data}.length`) + schArr.forEach((sch: AnySchema, i: number) => { + if (alwaysValidSchema(it, sch)) return + gen.if(_`${len} > ${i}`, () => + cxt.subschema( + { + keyword, + schemaProp: i, + dataProp: i, + }, + valid + ) + ) + cxt.ok(valid) + }) + + function checkStrictTuple(sch: AnySchemaObject): void { + const {opts, errSchemaPath} = it + const l = schArr.length + const fullTuple = l === sch.minItems && (l === sch.maxItems || sch[extraItems] === false) + if (opts.strictTuples && !fullTuple) { + const msg = `"${keyword}" is ${l}-tuple, but minItems or maxItems/${extraItems} are not specified or different at path "${errSchemaPath}"` + checkStrictMode(it, msg, opts.strictTuples) + } + } +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/items2020.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/items2020.ts new file mode 100644 index 000000000..2a99b08d5 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/items2020.ts @@ -0,0 +1,36 @@ +import type { + CodeKeywordDefinition, + KeywordErrorDefinition, + ErrorObject, + AnySchema, +} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str} from "../../compile/codegen" +import {alwaysValidSchema} from "../../compile/util" +import {validateArray} from "../code" +import {validateAdditionalItems} from "./additionalItems" + +export type ItemsError = ErrorObject<"items", {limit: number}, AnySchema> + +const error: KeywordErrorDefinition = { + message: ({params: {len}}) => str`must NOT have more than ${len} items`, + params: ({params: {len}}) => _`{limit: ${len}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "items", + type: "array", + schemaType: ["object", "boolean"], + before: "uniqueItems", + error, + code(cxt: KeywordCxt) { + const {schema, parentSchema, it} = cxt + const {prefixItems} = parentSchema + it.items = true + if (alwaysValidSchema(it, schema)) return + if (prefixItems) validateAdditionalItems(cxt, prefixItems) + else cxt.ok(validateArray(cxt)) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/not.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/not.ts new file mode 100644 index 000000000..8691db0bf --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/not.ts @@ -0,0 +1,38 @@ +import type {CodeKeywordDefinition, ErrorNoParams, AnySchema} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {alwaysValidSchema} from "../../compile/util" + +export type NotKeywordError = ErrorNoParams<"not", AnySchema> + +const def: CodeKeywordDefinition = { + keyword: "not", + schemaType: ["object", "boolean"], + trackErrors: true, + code(cxt: KeywordCxt) { + const {gen, schema, it} = cxt + if (alwaysValidSchema(it, schema)) { + cxt.fail() + return + } + + const valid = gen.name("valid") + cxt.subschema( + { + keyword: "not", + compositeRule: true, + createErrors: false, + allErrors: false, + }, + valid + ) + + cxt.failResult( + valid, + () => cxt.reset(), + () => cxt.error() + ) + }, + error: {message: "must NOT be valid"}, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts new file mode 100644 index 000000000..c25353ffd --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts @@ -0,0 +1,82 @@ +import type { + CodeKeywordDefinition, + ErrorObject, + KeywordErrorDefinition, + AnySchema, +} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, Name} from "../../compile/codegen" +import {alwaysValidSchema} from "../../compile/util" +import {SchemaCxt} from "../../compile" + +export type OneOfError = ErrorObject< + "oneOf", + {passingSchemas: [number, number] | null}, + AnySchema[] +> + +const error: KeywordErrorDefinition = { + message: "must match exactly one schema in oneOf", + params: ({params}) => _`{passingSchemas: ${params.passing}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "oneOf", + schemaType: "array", + trackErrors: true, + error, + code(cxt: KeywordCxt) { + const {gen, schema, parentSchema, it} = cxt + /* istanbul ignore if */ + if (!Array.isArray(schema)) throw new Error("ajv implementation error") + if (it.opts.discriminator && parentSchema.discriminator) return + const schArr: AnySchema[] = schema + const valid = gen.let("valid", false) + const passing = gen.let("passing", null) + const schValid = gen.name("_valid") + cxt.setParams({passing}) + // TODO possibly fail straight away (with warning or exception) if there are two empty always valid schemas + + gen.block(validateOneOf) + + cxt.result( + valid, + () => cxt.reset(), + () => cxt.error(true) + ) + + function validateOneOf(): void { + schArr.forEach((sch: AnySchema, i: number) => { + let schCxt: SchemaCxt | undefined + if (alwaysValidSchema(it, sch)) { + gen.var(schValid, true) + } else { + schCxt = cxt.subschema( + { + keyword: "oneOf", + schemaProp: i, + compositeRule: true, + }, + schValid + ) + } + + if (i > 0) { + gen + .if(_`${schValid} && ${valid}`) + .assign(valid, false) + .assign(passing, _`[${passing}, ${i}]`) + .else() + } + + gen.if(schValid, () => { + gen.assign(valid, true) + gen.assign(passing, i) + if (schCxt) cxt.mergeEvaluated(schCxt, Name) + }) + }) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts new file mode 100644 index 000000000..ea624e230 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts @@ -0,0 +1,91 @@ +import type {CodeKeywordDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {allSchemaProperties, usePattern} from "../code" +import {_, not, Name} from "../../compile/codegen" +import {alwaysValidSchema, checkStrictMode} from "../../compile/util" +import {evaluatedPropsToName, Type} from "../../compile/util" +import {AnySchema} from "../../types" + +const def: CodeKeywordDefinition = { + keyword: "patternProperties", + type: "object", + schemaType: "object", + code(cxt: KeywordCxt) { + const {gen, schema, data, parentSchema, it} = cxt + const {opts} = it + const patterns = allSchemaProperties(schema) + const alwaysValidPatterns = patterns.filter((p) => + alwaysValidSchema(it, schema[p] as AnySchema) + ) + + if ( + patterns.length === 0 || + (alwaysValidPatterns.length === patterns.length && + (!it.opts.unevaluated || it.props === true)) + ) { + return + } + + const checkProperties = + opts.strictSchema && !opts.allowMatchingProperties && parentSchema.properties + const valid = gen.name("valid") + if (it.props !== true && !(it.props instanceof Name)) { + it.props = evaluatedPropsToName(gen, it.props) + } + const {props} = it + validatePatternProperties() + + function validatePatternProperties(): void { + for (const pat of patterns) { + if (checkProperties) checkMatchingProperties(pat) + if (it.allErrors) { + validateProperties(pat) + } else { + gen.var(valid, true) // TODO var + validateProperties(pat) + gen.if(valid) + } + } + } + + function checkMatchingProperties(pat: string): void { + for (const prop in checkProperties) { + if (new RegExp(pat).test(prop)) { + checkStrictMode( + it, + `property ${prop} matches pattern ${pat} (use allowMatchingProperties)` + ) + } + } + } + + function validateProperties(pat: string): void { + gen.forIn("key", data, (key) => { + gen.if(_`${usePattern(cxt, pat)}.test(${key})`, () => { + const alwaysValid = alwaysValidPatterns.includes(pat) + if (!alwaysValid) { + cxt.subschema( + { + keyword: "patternProperties", + schemaProp: pat, + dataProp: key, + dataPropType: Type.Str, + }, + valid + ) + } + + if (it.opts.unevaluated && props !== true) { + gen.assign(_`${props}[${key}]`, true) + } else if (!alwaysValid && !it.allErrors) { + // can short-circuit if `unevaluatedProperties` is not supported (opts.next === false) + // or if all properties were evaluated (props === true) + gen.if(not(valid), () => gen.break()) + } + }) + }) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts new file mode 100644 index 000000000..008fb2db1 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts @@ -0,0 +1,12 @@ +import type {CodeKeywordDefinition} from "../../types" +import {validateTuple} from "./items" + +const def: CodeKeywordDefinition = { + keyword: "prefixItems", + type: "array", + schemaType: ["array"], + before: "uniqueItems", + code: (cxt) => validateTuple(cxt, "items"), +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/properties.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/properties.ts new file mode 100644 index 000000000..a55b19ce5 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/properties.ts @@ -0,0 +1,57 @@ +import type {CodeKeywordDefinition} from "../../types" +import {KeywordCxt} from "../../compile/validate" +import {propertyInData, allSchemaProperties} from "../code" +import {alwaysValidSchema, toHash, mergeEvaluated} from "../../compile/util" +import apDef from "./additionalProperties" + +const def: CodeKeywordDefinition = { + keyword: "properties", + type: "object", + schemaType: "object", + code(cxt: KeywordCxt) { + const {gen, schema, parentSchema, data, it} = cxt + if (it.opts.removeAdditional === "all" && parentSchema.additionalProperties === undefined) { + apDef.code(new KeywordCxt(it, apDef, "additionalProperties")) + } + const allProps = allSchemaProperties(schema) + for (const prop of allProps) { + it.definedProperties.add(prop) + } + if (it.opts.unevaluated && allProps.length && it.props !== true) { + it.props = mergeEvaluated.props(gen, toHash(allProps), it.props) + } + const properties = allProps.filter((p) => !alwaysValidSchema(it, schema[p])) + if (properties.length === 0) return + const valid = gen.name("valid") + + for (const prop of properties) { + if (hasDefault(prop)) { + applyPropertySchema(prop) + } else { + gen.if(propertyInData(gen, data, prop, it.opts.ownProperties)) + applyPropertySchema(prop) + if (!it.allErrors) gen.else().var(valid, true) + gen.endIf() + } + cxt.it.definedProperties.add(prop) + cxt.ok(valid) + } + + function hasDefault(prop: string): boolean | undefined { + return it.opts.useDefaults && !it.compositeRule && schema[prop].default !== undefined + } + + function applyPropertySchema(prop: string): void { + cxt.subschema( + { + keyword: "properties", + schemaProp: prop, + dataProp: prop, + }, + valid + ) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts new file mode 100644 index 000000000..1c54d6052 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts @@ -0,0 +1,50 @@ +import type { + CodeKeywordDefinition, + ErrorObject, + KeywordErrorDefinition, + AnySchema, +} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, not} from "../../compile/codegen" +import {alwaysValidSchema} from "../../compile/util" + +export type PropertyNamesError = ErrorObject<"propertyNames", {propertyName: string}, AnySchema> + +const error: KeywordErrorDefinition = { + message: "property name must be valid", + params: ({params}) => _`{propertyName: ${params.propertyName}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "propertyNames", + type: "object", + schemaType: ["object", "boolean"], + error, + code(cxt: KeywordCxt) { + const {gen, schema, data, it} = cxt + if (alwaysValidSchema(it, schema)) return + const valid = gen.name("valid") + + gen.forIn("key", data, (key) => { + cxt.setParams({propertyName: key}) + cxt.subschema( + { + keyword: "propertyNames", + data: key, + dataTypes: ["string"], + propertyName: key, + compositeRule: true, + }, + valid + ) + gen.if(not(valid), () => { + cxt.error(true) + if (!it.allErrors) gen.break() + }) + }) + + cxt.ok(valid) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts b/libs/events/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts new file mode 100644 index 000000000..5055182e8 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts @@ -0,0 +1,13 @@ +import type {CodeKeywordDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {checkStrictMode} from "../../compile/util" + +const def: CodeKeywordDefinition = { + keyword: ["then", "else"], + schemaType: ["object", "boolean"], + code({keyword, parentSchema, it}: KeywordCxt) { + if (parentSchema.if === undefined) checkStrictMode(it, `"${keyword}" without "if" is ignored`) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/code.ts b/libs/events/node_modules/ajv/lib/vocabularies/code.ts new file mode 100644 index 000000000..92cdd5b04 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/code.ts @@ -0,0 +1,168 @@ +import type {AnySchema, SchemaMap} from "../types" +import type {SchemaCxt} from "../compile" +import type {KeywordCxt} from "../compile/validate" +import {CodeGen, _, and, or, not, nil, strConcat, getProperty, Code, Name} from "../compile/codegen" +import {alwaysValidSchema, Type} from "../compile/util" +import N from "../compile/names" +import {useFunc} from "../compile/util" +export function checkReportMissingProp(cxt: KeywordCxt, prop: string): void { + const {gen, data, it} = cxt + gen.if(noPropertyInData(gen, data, prop, it.opts.ownProperties), () => { + cxt.setParams({missingProperty: _`${prop}`}, true) + cxt.error() + }) +} + +export function checkMissingProp( + {gen, data, it: {opts}}: KeywordCxt, + properties: string[], + missing: Name +): Code { + return or( + ...properties.map((prop) => + and(noPropertyInData(gen, data, prop, opts.ownProperties), _`${missing} = ${prop}`) + ) + ) +} + +export function reportMissingProp(cxt: KeywordCxt, missing: Name): void { + cxt.setParams({missingProperty: missing}, true) + cxt.error() +} + +export function hasPropFunc(gen: CodeGen): Name { + return gen.scopeValue("func", { + // eslint-disable-next-line @typescript-eslint/unbound-method + ref: Object.prototype.hasOwnProperty, + code: _`Object.prototype.hasOwnProperty`, + }) +} + +export function isOwnProperty(gen: CodeGen, data: Name, property: Name | string): Code { + return _`${hasPropFunc(gen)}.call(${data}, ${property})` +} + +export function propertyInData( + gen: CodeGen, + data: Name, + property: Name | string, + ownProperties?: boolean +): Code { + const cond = _`${data}${getProperty(property)} !== undefined` + return ownProperties ? _`${cond} && ${isOwnProperty(gen, data, property)}` : cond +} + +export function noPropertyInData( + gen: CodeGen, + data: Name, + property: Name | string, + ownProperties?: boolean +): Code { + const cond = _`${data}${getProperty(property)} === undefined` + return ownProperties ? or(cond, not(isOwnProperty(gen, data, property))) : cond +} + +export function allSchemaProperties(schemaMap?: SchemaMap): string[] { + return schemaMap ? Object.keys(schemaMap).filter((p) => p !== "__proto__") : [] +} + +export function schemaProperties(it: SchemaCxt, schemaMap: SchemaMap): string[] { + return allSchemaProperties(schemaMap).filter( + (p) => !alwaysValidSchema(it, schemaMap[p] as AnySchema) + ) +} + +export function callValidateCode( + {schemaCode, data, it: {gen, topSchemaRef, schemaPath, errorPath}, it}: KeywordCxt, + func: Code, + context: Code, + passSchema?: boolean +): Code { + const dataAndSchema = passSchema ? _`${schemaCode}, ${data}, ${topSchemaRef}${schemaPath}` : data + const valCxt: [Name, Code | number][] = [ + [N.instancePath, strConcat(N.instancePath, errorPath)], + [N.parentData, it.parentData], + [N.parentDataProperty, it.parentDataProperty], + [N.rootData, N.rootData], + ] + if (it.opts.dynamicRef) valCxt.push([N.dynamicAnchors, N.dynamicAnchors]) + const args = _`${dataAndSchema}, ${gen.object(...valCxt)}` + return context !== nil ? _`${func}.call(${context}, ${args})` : _`${func}(${args})` +} + +const newRegExp = _`new RegExp` + +export function usePattern({gen, it: {opts}}: KeywordCxt, pattern: string): Name { + const u = opts.unicodeRegExp ? "u" : "" + const {regExp} = opts.code + const rx = regExp(pattern, u) + + return gen.scopeValue("pattern", { + key: rx.toString(), + ref: rx, + code: _`${regExp.code === "new RegExp" ? newRegExp : useFunc(gen, regExp)}(${pattern}, ${u})`, + }) +} + +export function validateArray(cxt: KeywordCxt): Name { + const {gen, data, keyword, it} = cxt + const valid = gen.name("valid") + if (it.allErrors) { + const validArr = gen.let("valid", true) + validateItems(() => gen.assign(validArr, false)) + return validArr + } + gen.var(valid, true) + validateItems(() => gen.break()) + return valid + + function validateItems(notValid: () => void): void { + const len = gen.const("len", _`${data}.length`) + gen.forRange("i", 0, len, (i) => { + cxt.subschema( + { + keyword, + dataProp: i, + dataPropType: Type.Num, + }, + valid + ) + gen.if(not(valid), notValid) + }) + } +} + +export function validateUnion(cxt: KeywordCxt): void { + const {gen, schema, keyword, it} = cxt + /* istanbul ignore if */ + if (!Array.isArray(schema)) throw new Error("ajv implementation error") + const alwaysValid = schema.some((sch: AnySchema) => alwaysValidSchema(it, sch)) + if (alwaysValid && !it.opts.unevaluated) return + + const valid = gen.let("valid", false) + const schValid = gen.name("_valid") + + gen.block(() => + schema.forEach((_sch: AnySchema, i: number) => { + const schCxt = cxt.subschema( + { + keyword, + schemaProp: i, + compositeRule: true, + }, + schValid + ) + gen.assign(valid, _`${valid} || ${schValid}`) + const merged = cxt.mergeValidEvaluated(schCxt, schValid) + // can short-circuit if `unevaluatedProperties/Items` not supported (opts.unevaluated !== true) + // or if all properties and items were evaluated (it.props === true && it.items === true) + if (!merged) gen.if(not(valid)) + }) + ) + + cxt.result( + valid, + () => cxt.reset(), + () => cxt.error(true) + ) +} diff --git a/libs/events/node_modules/ajv/lib/vocabularies/core/id.ts b/libs/events/node_modules/ajv/lib/vocabularies/core/id.ts new file mode 100644 index 000000000..aa36c4bb2 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/core/id.ts @@ -0,0 +1,10 @@ +import type {CodeKeywordDefinition} from "../../types" + +const def: CodeKeywordDefinition = { + keyword: "id", + code() { + throw new Error('NOT SUPPORTED: keyword "id", use "$id" for schema ID') + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/core/index.ts b/libs/events/node_modules/ajv/lib/vocabularies/core/index.ts new file mode 100644 index 000000000..e63e2895d --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/core/index.ts @@ -0,0 +1,16 @@ +import type {Vocabulary} from "../../types" +import idKeyword from "./id" +import refKeyword from "./ref" + +const core: Vocabulary = [ + "$schema", + "$id", + "$defs", + "$vocabulary", + {keyword: "$comment"}, + "definitions", + idKeyword, + refKeyword, +] + +export default core diff --git a/libs/events/node_modules/ajv/lib/vocabularies/core/ref.ts b/libs/events/node_modules/ajv/lib/vocabularies/core/ref.ts new file mode 100644 index 000000000..5d59fbcb2 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/core/ref.ts @@ -0,0 +1,129 @@ +import type {CodeKeywordDefinition, AnySchema} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import MissingRefError from "../../compile/ref_error" +import {callValidateCode} from "../code" +import {_, nil, stringify, Code, Name} from "../../compile/codegen" +import N from "../../compile/names" +import {SchemaEnv, resolveRef} from "../../compile" +import {mergeEvaluated} from "../../compile/util" + +const def: CodeKeywordDefinition = { + keyword: "$ref", + schemaType: "string", + code(cxt: KeywordCxt): void { + const {gen, schema: $ref, it} = cxt + const {baseId, schemaEnv: env, validateName, opts, self} = it + const {root} = env + if (($ref === "#" || $ref === "#/") && baseId === root.baseId) return callRootRef() + const schOrEnv = resolveRef.call(self, root, baseId, $ref) + if (schOrEnv === undefined) throw new MissingRefError(it.opts.uriResolver, baseId, $ref) + if (schOrEnv instanceof SchemaEnv) return callValidate(schOrEnv) + return inlineRefSchema(schOrEnv) + + function callRootRef(): void { + if (env === root) return callRef(cxt, validateName, env, env.$async) + const rootName = gen.scopeValue("root", {ref: root}) + return callRef(cxt, _`${rootName}.validate`, root, root.$async) + } + + function callValidate(sch: SchemaEnv): void { + const v = getValidate(cxt, sch) + callRef(cxt, v, sch, sch.$async) + } + + function inlineRefSchema(sch: AnySchema): void { + const schName = gen.scopeValue( + "schema", + opts.code.source === true ? {ref: sch, code: stringify(sch)} : {ref: sch} + ) + const valid = gen.name("valid") + const schCxt = cxt.subschema( + { + schema: sch, + dataTypes: [], + schemaPath: nil, + topSchemaRef: schName, + errSchemaPath: $ref, + }, + valid + ) + cxt.mergeEvaluated(schCxt) + cxt.ok(valid) + } + }, +} + +export function getValidate(cxt: KeywordCxt, sch: SchemaEnv): Code { + const {gen} = cxt + return sch.validate + ? gen.scopeValue("validate", {ref: sch.validate}) + : _`${gen.scopeValue("wrapper", {ref: sch})}.validate` +} + +export function callRef(cxt: KeywordCxt, v: Code, sch?: SchemaEnv, $async?: boolean): void { + const {gen, it} = cxt + const {allErrors, schemaEnv: env, opts} = it + const passCxt = opts.passContext ? N.this : nil + if ($async) callAsyncRef() + else callSyncRef() + + function callAsyncRef(): void { + if (!env.$async) throw new Error("async schema referenced by sync schema") + const valid = gen.let("valid") + gen.try( + () => { + gen.code(_`await ${callValidateCode(cxt, v, passCxt)}`) + addEvaluatedFrom(v) // TODO will not work with async, it has to be returned with the result + if (!allErrors) gen.assign(valid, true) + }, + (e) => { + gen.if(_`!(${e} instanceof ${it.ValidationError as Name})`, () => gen.throw(e)) + addErrorsFrom(e) + if (!allErrors) gen.assign(valid, false) + } + ) + cxt.ok(valid) + } + + function callSyncRef(): void { + cxt.result( + callValidateCode(cxt, v, passCxt), + () => addEvaluatedFrom(v), + () => addErrorsFrom(v) + ) + } + + function addErrorsFrom(source: Code): void { + const errs = _`${source}.errors` + gen.assign(N.vErrors, _`${N.vErrors} === null ? ${errs} : ${N.vErrors}.concat(${errs})`) // TODO tagged + gen.assign(N.errors, _`${N.vErrors}.length`) + } + + function addEvaluatedFrom(source: Code): void { + if (!it.opts.unevaluated) return + const schEvaluated = sch?.validate?.evaluated + // TODO refactor + if (it.props !== true) { + if (schEvaluated && !schEvaluated.dynamicProps) { + if (schEvaluated.props !== undefined) { + it.props = mergeEvaluated.props(gen, schEvaluated.props, it.props) + } + } else { + const props = gen.var("props", _`${source}.evaluated.props`) + it.props = mergeEvaluated.props(gen, props, it.props, Name) + } + } + if (it.items !== true) { + if (schEvaluated && !schEvaluated.dynamicItems) { + if (schEvaluated.items !== undefined) { + it.items = mergeEvaluated.items(gen, schEvaluated.items, it.items) + } + } else { + const items = gen.var("items", _`${source}.evaluated.items`) + it.items = mergeEvaluated.items(gen, items, it.items, Name) + } + } + } +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/discriminator/index.ts b/libs/events/node_modules/ajv/lib/vocabularies/discriminator/index.ts new file mode 100644 index 000000000..98f0f8cfb --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/discriminator/index.ts @@ -0,0 +1,110 @@ +import type {CodeKeywordDefinition, AnySchemaObject, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, getProperty, Name} from "../../compile/codegen" +import {DiscrError, DiscrErrorObj} from "../discriminator/types" +import {resolveRef, SchemaEnv} from "../../compile" +import {schemaHasRulesButRef} from "../../compile/util" + +export type DiscriminatorError = DiscrErrorObj | DiscrErrorObj + +const error: KeywordErrorDefinition = { + message: ({params: {discrError, tagName}}) => + discrError === DiscrError.Tag + ? `tag "${tagName}" must be string` + : `value of tag "${tagName}" must be in oneOf`, + params: ({params: {discrError, tag, tagName}}) => + _`{error: ${discrError}, tag: ${tagName}, tagValue: ${tag}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "discriminator", + type: "object", + schemaType: "object", + error, + code(cxt: KeywordCxt) { + const {gen, data, schema, parentSchema, it} = cxt + const {oneOf} = parentSchema + if (!it.opts.discriminator) { + throw new Error("discriminator: requires discriminator option") + } + const tagName = schema.propertyName + if (typeof tagName != "string") throw new Error("discriminator: requires propertyName") + if (schema.mapping) throw new Error("discriminator: mapping is not supported") + if (!oneOf) throw new Error("discriminator: requires oneOf keyword") + const valid = gen.let("valid", false) + const tag = gen.const("tag", _`${data}${getProperty(tagName)}`) + gen.if( + _`typeof ${tag} == "string"`, + () => validateMapping(), + () => cxt.error(false, {discrError: DiscrError.Tag, tag, tagName}) + ) + cxt.ok(valid) + + function validateMapping(): void { + const mapping = getMapping() + gen.if(false) + for (const tagValue in mapping) { + gen.elseIf(_`${tag} === ${tagValue}`) + gen.assign(valid, applyTagSchema(mapping[tagValue])) + } + gen.else() + cxt.error(false, {discrError: DiscrError.Mapping, tag, tagName}) + gen.endIf() + } + + function applyTagSchema(schemaProp?: number): Name { + const _valid = gen.name("valid") + const schCxt = cxt.subschema({keyword: "oneOf", schemaProp}, _valid) + cxt.mergeEvaluated(schCxt, Name) + return _valid + } + + function getMapping(): {[T in string]?: number} { + const oneOfMapping: {[T in string]?: number} = {} + const topRequired = hasRequired(parentSchema) + let tagRequired = true + for (let i = 0; i < oneOf.length; i++) { + let sch = oneOf[i] + if (sch?.$ref && !schemaHasRulesButRef(sch, it.self.RULES)) { + sch = resolveRef.call(it.self, it.schemaEnv.root, it.baseId, sch?.$ref) + if (sch instanceof SchemaEnv) sch = sch.schema + } + const propSch = sch?.properties?.[tagName] + if (typeof propSch != "object") { + throw new Error( + `discriminator: oneOf subschemas (or referenced schemas) must have "properties/${tagName}"` + ) + } + tagRequired = tagRequired && (topRequired || hasRequired(sch)) + addMappings(propSch, i) + } + if (!tagRequired) throw new Error(`discriminator: "${tagName}" must be required`) + return oneOfMapping + + function hasRequired({required}: AnySchemaObject): boolean { + return Array.isArray(required) && required.includes(tagName) + } + + function addMappings(sch: AnySchemaObject, i: number): void { + if (sch.const) { + addMapping(sch.const, i) + } else if (sch.enum) { + for (const tagValue of sch.enum) { + addMapping(tagValue, i) + } + } else { + throw new Error(`discriminator: "properties/${tagName}" must have "const" or "enum"`) + } + } + + function addMapping(tagValue: unknown, i: number): void { + if (typeof tagValue != "string" || tagValue in oneOfMapping) { + throw new Error(`discriminator: "${tagName}" values must be unique strings`) + } + oneOfMapping[tagValue] = i + } + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/discriminator/types.ts b/libs/events/node_modules/ajv/lib/vocabularies/discriminator/types.ts new file mode 100644 index 000000000..bee5a2785 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/discriminator/types.ts @@ -0,0 +1,12 @@ +import type {ErrorObject} from "../../types" + +export enum DiscrError { + Tag = "tag", + Mapping = "mapping", +} + +export type DiscrErrorObj = ErrorObject< + "discriminator", + {error: E; tag: string; tagValue: unknown}, + string +> diff --git a/libs/events/node_modules/ajv/lib/vocabularies/draft2020.ts b/libs/events/node_modules/ajv/lib/vocabularies/draft2020.ts new file mode 100644 index 000000000..47fbf0ee6 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/draft2020.ts @@ -0,0 +1,23 @@ +import type {Vocabulary} from "../types" +import coreVocabulary from "./core" +import validationVocabulary from "./validation" +import getApplicatorVocabulary from "./applicator" +import dynamicVocabulary from "./dynamic" +import nextVocabulary from "./next" +import unevaluatedVocabulary from "./unevaluated" +import formatVocabulary from "./format" +import {metadataVocabulary, contentVocabulary} from "./metadata" + +const draft2020Vocabularies: Vocabulary[] = [ + dynamicVocabulary, + coreVocabulary, + validationVocabulary, + getApplicatorVocabulary(true), + formatVocabulary, + metadataVocabulary, + contentVocabulary, + nextVocabulary, + unevaluatedVocabulary, +] + +export default draft2020Vocabularies diff --git a/libs/events/node_modules/ajv/lib/vocabularies/draft7.ts b/libs/events/node_modules/ajv/lib/vocabularies/draft7.ts new file mode 100644 index 000000000..226a644aa --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/draft7.ts @@ -0,0 +1,17 @@ +import type {Vocabulary} from "../types" +import coreVocabulary from "./core" +import validationVocabulary from "./validation" +import getApplicatorVocabulary from "./applicator" +import formatVocabulary from "./format" +import {metadataVocabulary, contentVocabulary} from "./metadata" + +const draft7Vocabularies: Vocabulary[] = [ + coreVocabulary, + validationVocabulary, + getApplicatorVocabulary(), + formatVocabulary, + metadataVocabulary, + contentVocabulary, +] + +export default draft7Vocabularies diff --git a/libs/events/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts new file mode 100644 index 000000000..ca1adb912 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts @@ -0,0 +1,31 @@ +import type {CodeKeywordDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, getProperty, Code} from "../../compile/codegen" +import N from "../../compile/names" +import {SchemaEnv, compileSchema} from "../../compile" +import {getValidate} from "../core/ref" + +const def: CodeKeywordDefinition = { + keyword: "$dynamicAnchor", + schemaType: "string", + code: (cxt) => dynamicAnchor(cxt, cxt.schema), +} + +export function dynamicAnchor(cxt: KeywordCxt, anchor: string): void { + const {gen, it} = cxt + it.schemaEnv.root.dynamicAnchors[anchor] = true + const v = _`${N.dynamicAnchors}${getProperty(anchor)}` + const validate = it.errSchemaPath === "#" ? it.validateName : _getValidate(cxt) + gen.if(_`!${v}`, () => gen.assign(v, validate)) +} + +function _getValidate(cxt: KeywordCxt): Code { + const {schemaEnv, schema, self} = cxt.it + const {root, baseId, localRefs, meta} = schemaEnv.root + const {schemaId} = self.opts + const sch = new SchemaEnv({schema, schemaId, root, baseId, localRefs, meta}) + compileSchema.call(self, sch) + return getValidate(cxt, sch) +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts new file mode 100644 index 000000000..6a573f330 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts @@ -0,0 +1,51 @@ +import type {CodeKeywordDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, getProperty, Code, Name} from "../../compile/codegen" +import N from "../../compile/names" +import {callRef} from "../core/ref" + +const def: CodeKeywordDefinition = { + keyword: "$dynamicRef", + schemaType: "string", + code: (cxt) => dynamicRef(cxt, cxt.schema), +} + +export function dynamicRef(cxt: KeywordCxt, ref: string): void { + const {gen, keyword, it} = cxt + if (ref[0] !== "#") throw new Error(`"${keyword}" only supports hash fragment reference`) + const anchor = ref.slice(1) + if (it.allErrors) { + _dynamicRef() + } else { + const valid = gen.let("valid", false) + _dynamicRef(valid) + cxt.ok(valid) + } + + function _dynamicRef(valid?: Name): void { + // TODO the assumption here is that `recursiveRef: #` always points to the root + // of the schema object, which is not correct, because there may be $id that + // makes # point to it, and the target schema may not contain dynamic/recursiveAnchor. + // Because of that 2 tests in recursiveRef.json fail. + // This is a similar problem to #815 (`$id` doesn't alter resolution scope for `{ "$ref": "#" }`). + // (This problem is not tested in JSON-Schema-Test-Suite) + if (it.schemaEnv.root.dynamicAnchors[anchor]) { + const v = gen.let("_v", _`${N.dynamicAnchors}${getProperty(anchor)}`) + gen.if(v, _callRef(v, valid), _callRef(it.validateName, valid)) + } else { + _callRef(it.validateName, valid)() + } + } + + function _callRef(validate: Code, valid?: Name): () => void { + return valid + ? () => + gen.block(() => { + callRef(cxt, validate) + gen.let(valid, true) + }) + : () => callRef(cxt, validate) + } +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/dynamic/index.ts b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/index.ts new file mode 100644 index 000000000..6d521db66 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/index.ts @@ -0,0 +1,9 @@ +import type {Vocabulary} from "../../types" +import dynamicAnchor from "./dynamicAnchor" +import dynamicRef from "./dynamicRef" +import recursiveAnchor from "./recursiveAnchor" +import recursiveRef from "./recursiveRef" + +const dynamic: Vocabulary = [dynamicAnchor, dynamicRef, recursiveAnchor, recursiveRef] + +export default dynamic diff --git a/libs/events/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts new file mode 100644 index 000000000..25f3db96b --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts @@ -0,0 +1,14 @@ +import type {CodeKeywordDefinition} from "../../types" +import {dynamicAnchor} from "./dynamicAnchor" +import {checkStrictMode} from "../../compile/util" + +const def: CodeKeywordDefinition = { + keyword: "$recursiveAnchor", + schemaType: "boolean", + code(cxt) { + if (cxt.schema) dynamicAnchor(cxt, "") + else checkStrictMode(cxt.it, "$recursiveAnchor: false is ignored") + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts new file mode 100644 index 000000000..c84af0f05 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts @@ -0,0 +1,10 @@ +import type {CodeKeywordDefinition} from "../../types" +import {dynamicRef} from "./dynamicRef" + +const def: CodeKeywordDefinition = { + keyword: "$recursiveRef", + schemaType: "string", + code: (cxt) => dynamicRef(cxt, cxt.schema), +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/errors.ts b/libs/events/node_modules/ajv/lib/vocabularies/errors.ts new file mode 100644 index 000000000..c9ca3f02f --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/errors.ts @@ -0,0 +1,18 @@ +import type {TypeError} from "../compile/validate/dataType" +import type {ApplicatorKeywordError} from "./applicator" +import type {ValidationKeywordError} from "./validation" +import type {FormatError} from "./format/format" +import type {UnevaluatedPropertiesError} from "./unevaluated/unevaluatedProperties" +import type {UnevaluatedItemsError} from "./unevaluated/unevaluatedItems" +import type {DependentRequiredError} from "./validation/dependentRequired" +import type {DiscriminatorError} from "./discriminator" + +export type DefinedError = + | TypeError + | ApplicatorKeywordError + | ValidationKeywordError + | FormatError + | UnevaluatedPropertiesError + | UnevaluatedItemsError + | DependentRequiredError + | DiscriminatorError diff --git a/libs/events/node_modules/ajv/lib/vocabularies/format/format.ts b/libs/events/node_modules/ajv/lib/vocabularies/format/format.ts new file mode 100644 index 000000000..4b1c13e76 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/format/format.ts @@ -0,0 +1,120 @@ +import type { + AddedFormat, + FormatValidator, + AsyncFormatValidator, + CodeKeywordDefinition, + KeywordErrorDefinition, + ErrorObject, +} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str, nil, or, Code, getProperty, regexpCode} from "../../compile/codegen" + +type FormatValidate = + | FormatValidator + | FormatValidator + | AsyncFormatValidator + | AsyncFormatValidator + | RegExp + | string + | true + +export type FormatError = ErrorObject<"format", {format: string}, string | {$data: string}> + +const error: KeywordErrorDefinition = { + message: ({schemaCode}) => str`must match format "${schemaCode}"`, + params: ({schemaCode}) => _`{format: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "format", + type: ["number", "string"], + schemaType: "string", + $data: true, + error, + code(cxt: KeywordCxt, ruleType?: string) { + const {gen, data, $data, schema, schemaCode, it} = cxt + const {opts, errSchemaPath, schemaEnv, self} = it + if (!opts.validateFormats) return + + if ($data) validate$DataFormat() + else validateFormat() + + function validate$DataFormat(): void { + const fmts = gen.scopeValue("formats", { + ref: self.formats, + code: opts.code.formats, + }) + const fDef = gen.const("fDef", _`${fmts}[${schemaCode}]`) + const fType = gen.let("fType") + const format = gen.let("format") + // TODO simplify + gen.if( + _`typeof ${fDef} == "object" && !(${fDef} instanceof RegExp)`, + () => gen.assign(fType, _`${fDef}.type || "string"`).assign(format, _`${fDef}.validate`), + () => gen.assign(fType, _`"string"`).assign(format, fDef) + ) + cxt.fail$data(or(unknownFmt(), invalidFmt())) + + function unknownFmt(): Code { + if (opts.strictSchema === false) return nil + return _`${schemaCode} && !${format}` + } + + function invalidFmt(): Code { + const callFormat = schemaEnv.$async + ? _`(${fDef}.async ? await ${format}(${data}) : ${format}(${data}))` + : _`${format}(${data})` + const validData = _`(typeof ${format} == "function" ? ${callFormat} : ${format}.test(${data}))` + return _`${format} && ${format} !== true && ${fType} === ${ruleType} && !${validData}` + } + } + + function validateFormat(): void { + const formatDef: AddedFormat | undefined = self.formats[schema] + if (!formatDef) { + unknownFormat() + return + } + if (formatDef === true) return + const [fmtType, format, fmtRef] = getFormat(formatDef) + if (fmtType === ruleType) cxt.pass(validCondition()) + + function unknownFormat(): void { + if (opts.strictSchema === false) { + self.logger.warn(unknownMsg()) + return + } + throw new Error(unknownMsg()) + + function unknownMsg(): string { + return `unknown format "${schema as string}" ignored in schema at path "${errSchemaPath}"` + } + } + + function getFormat(fmtDef: AddedFormat): [string, FormatValidate, Code] { + const code = + fmtDef instanceof RegExp + ? regexpCode(fmtDef) + : opts.code.formats + ? _`${opts.code.formats}${getProperty(schema)}` + : undefined + const fmt = gen.scopeValue("formats", {key: schema, ref: fmtDef, code}) + if (typeof fmtDef == "object" && !(fmtDef instanceof RegExp)) { + return [fmtDef.type || "string", fmtDef.validate, _`${fmt}.validate`] + } + + return ["string", fmtDef, fmt] + } + + function validCondition(): Code { + if (typeof formatDef == "object" && !(formatDef instanceof RegExp) && formatDef.async) { + if (!schemaEnv.$async) throw new Error("async format in sync schema") + return _`await ${fmtRef}(${data})` + } + return typeof format == "function" ? _`${fmtRef}(${data})` : _`${fmtRef}.test(${data})` + } + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/format/index.ts b/libs/events/node_modules/ajv/lib/vocabularies/format/index.ts new file mode 100644 index 000000000..bca2f5b3d --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/format/index.ts @@ -0,0 +1,6 @@ +import type {Vocabulary} from "../../types" +import formatKeyword from "./format" + +const format: Vocabulary = [formatKeyword] + +export default format diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts new file mode 100644 index 000000000..f487c97f8 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts @@ -0,0 +1,89 @@ +import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, not, getProperty, Name} from "../../compile/codegen" +import {checkMetadata} from "./metadata" +import {checkNullableObject} from "./nullable" +import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error" +import {DiscrError, DiscrErrorObj} from "../discriminator/types" + +export type JTDDiscriminatorError = + | _JTDTypeError<"discriminator", "object", string> + | DiscrErrorObj + | DiscrErrorObj + +const error: KeywordErrorDefinition = { + message: (cxt) => { + const {schema, params} = cxt + return params.discrError + ? params.discrError === DiscrError.Tag + ? `tag "${schema}" must be string` + : `value of tag "${schema}" must be in mapping` + : typeErrorMessage(cxt, "object") + }, + params: (cxt) => { + const {schema, params} = cxt + return params.discrError + ? _`{error: ${params.discrError}, tag: ${schema}, tagValue: ${params.tag}}` + : typeErrorParams(cxt, "object") + }, +} + +const def: CodeKeywordDefinition = { + keyword: "discriminator", + schemaType: "string", + implements: ["mapping"], + error, + code(cxt: KeywordCxt) { + checkMetadata(cxt) + const {gen, data, schema, parentSchema} = cxt + const [valid, cond] = checkNullableObject(cxt, data) + + gen.if(cond) + validateDiscriminator() + gen.elseIf(not(valid)) + cxt.error() + gen.endIf() + cxt.ok(valid) + + function validateDiscriminator(): void { + const tag = gen.const("tag", _`${data}${getProperty(schema)}`) + gen.if(_`${tag} === undefined`) + cxt.error(false, {discrError: DiscrError.Tag, tag}) + gen.elseIf(_`typeof ${tag} == "string"`) + validateMapping(tag) + gen.else() + cxt.error(false, {discrError: DiscrError.Tag, tag}, {instancePath: schema}) + gen.endIf() + } + + function validateMapping(tag: Name): void { + gen.if(false) + for (const tagValue in parentSchema.mapping) { + gen.elseIf(_`${tag} === ${tagValue}`) + gen.assign(valid, applyTagSchema(tagValue)) + } + gen.else() + cxt.error( + false, + {discrError: DiscrError.Mapping, tag}, + {instancePath: schema, schemaPath: "mapping", parentSchema: true} + ) + gen.endIf() + } + + function applyTagSchema(schemaProp: string): Name { + const _valid = gen.name("valid") + cxt.subschema( + { + keyword: "mapping", + schemaProp, + jtdDiscriminator: schema, + }, + _valid + ) + return _valid + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/elements.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/elements.ts new file mode 100644 index 000000000..983af7c02 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/elements.ts @@ -0,0 +1,32 @@ +import type {CodeKeywordDefinition, SchemaObject} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {alwaysValidSchema} from "../../compile/util" +import {validateArray} from "../code" +import {_, not} from "../../compile/codegen" +import {checkMetadata} from "./metadata" +import {checkNullable} from "./nullable" +import {typeError, _JTDTypeError} from "./error" + +export type JTDElementsError = _JTDTypeError<"elements", "array", SchemaObject> + +const def: CodeKeywordDefinition = { + keyword: "elements", + schemaType: "object", + error: typeError("array"), + code(cxt: KeywordCxt) { + checkMetadata(cxt) + const {gen, data, schema, it} = cxt + if (alwaysValidSchema(it, schema)) return + const [valid] = checkNullable(cxt) + gen.if(not(valid), () => + gen.if( + _`Array.isArray(${data})`, + () => gen.assign(valid, validateArray(cxt)), + () => cxt.error() + ) + ) + cxt.ok(valid) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/enum.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/enum.ts new file mode 100644 index 000000000..75464ff8e --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/enum.ts @@ -0,0 +1,45 @@ +import type {CodeKeywordDefinition, KeywordErrorDefinition, ErrorObject} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, or, and, Code} from "../../compile/codegen" +import {checkMetadata} from "./metadata" +import {checkNullable} from "./nullable" + +export type JTDEnumError = ErrorObject<"enum", {allowedValues: string[]}, string[]> + +const error: KeywordErrorDefinition = { + message: "must be equal to one of the allowed values", + params: ({schemaCode}) => _`{allowedValues: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "enum", + schemaType: "array", + error, + code(cxt: KeywordCxt) { + checkMetadata(cxt) + const {gen, data, schema, schemaValue, parentSchema, it} = cxt + if (schema.length === 0) throw new Error("enum must have non-empty array") + if (schema.length !== new Set(schema).size) throw new Error("enum items must be unique") + let valid: Code + const isString = _`typeof ${data} == "string"` + if (schema.length >= it.opts.loopEnum) { + let cond: Code + ;[valid, cond] = checkNullable(cxt, isString) + gen.if(cond, loopEnum) + } else { + /* istanbul ignore if */ + if (!Array.isArray(schema)) throw new Error("ajv implementation error") + valid = and(isString, or(...schema.map((value: string) => _`${data} === ${value}`))) + if (parentSchema.nullable) valid = or(_`${data} === null`, valid) + } + cxt.pass(valid) + + function loopEnum(): void { + gen.forOf("v", schemaValue as Code, (v) => + gen.if(_`${valid} = ${data} === ${v}`, () => gen.break()) + ) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/error.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/error.ts new file mode 100644 index 000000000..506932258 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/error.ts @@ -0,0 +1,23 @@ +import type {KeywordErrorDefinition, KeywordErrorCxt, ErrorObject} from "../../types" +import {_, Code} from "../../compile/codegen" + +export type _JTDTypeError = ErrorObject< + K, + {type: T; nullable: boolean}, + S +> + +export function typeError(t: string): KeywordErrorDefinition { + return { + message: (cxt) => typeErrorMessage(cxt, t), + params: (cxt) => typeErrorParams(cxt, t), + } +} + +export function typeErrorMessage({parentSchema}: KeywordErrorCxt, t: string): string { + return parentSchema?.nullable ? `must be ${t} or null` : `must be ${t}` +} + +export function typeErrorParams({parentSchema}: KeywordErrorCxt, t: string): Code { + return _`{type: ${t}, nullable: ${!!parentSchema?.nullable}}` +} diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/index.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/index.ts new file mode 100644 index 000000000..f7baebc30 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/index.ts @@ -0,0 +1,37 @@ +import type {Vocabulary} from "../../types" +import refKeyword from "./ref" +import typeKeyword, {JTDTypeError} from "./type" +import enumKeyword, {JTDEnumError} from "./enum" +import elements, {JTDElementsError} from "./elements" +import properties, {JTDPropertiesError} from "./properties" +import optionalProperties from "./optionalProperties" +import discriminator, {JTDDiscriminatorError} from "./discriminator" +import values, {JTDValuesError} from "./values" +import union from "./union" +import metadata from "./metadata" + +const jtdVocabulary: Vocabulary = [ + "definitions", + refKeyword, + typeKeyword, + enumKeyword, + elements, + properties, + optionalProperties, + discriminator, + values, + union, + metadata, + {keyword: "additionalProperties", schemaType: "boolean"}, + {keyword: "nullable", schemaType: "boolean"}, +] + +export default jtdVocabulary + +export type JTDErrorObject = + | JTDTypeError + | JTDEnumError + | JTDElementsError + | JTDPropertiesError + | JTDDiscriminatorError + | JTDValuesError diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/metadata.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/metadata.ts new file mode 100644 index 000000000..19eeb8c7d --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/metadata.ts @@ -0,0 +1,24 @@ +import {KeywordCxt} from "../../ajv" +import type {CodeKeywordDefinition} from "../../types" +import {alwaysValidSchema} from "../../compile/util" + +const def: CodeKeywordDefinition = { + keyword: "metadata", + schemaType: "object", + code(cxt: KeywordCxt) { + checkMetadata(cxt) + const {gen, schema, it} = cxt + if (alwaysValidSchema(it, schema)) return + const valid = gen.name("valid") + cxt.subschema({keyword: "metadata", jtdMetadata: true}, valid) + cxt.ok(valid) + }, +} + +export function checkMetadata({it, keyword}: KeywordCxt, metadata?: boolean): void { + if (it.jtdMetadata !== metadata) { + throw new Error(`JTD: "${keyword}" cannot be used in this schema location`) + } +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/nullable.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/nullable.ts new file mode 100644 index 000000000..c74b05da7 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/nullable.ts @@ -0,0 +1,21 @@ +import type {KeywordCxt} from "../../compile/validate" +import {_, not, nil, Code, Name} from "../../compile/codegen" + +export function checkNullable( + {gen, data, parentSchema}: KeywordCxt, + cond: Code = nil +): [Name, Code] { + const valid = gen.name("valid") + if (parentSchema.nullable) { + gen.let(valid, _`${data} === null`) + cond = not(valid) + } else { + gen.let(valid, false) + } + return [valid, cond] +} + +export function checkNullableObject(cxt: KeywordCxt, cond: Code): [Name, Code] { + const [valid, cond_] = checkNullable(cxt, cond) + return [valid, _`${cond_} && typeof ${cxt.data} == "object" && !Array.isArray(${cxt.data})`] +} diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts new file mode 100644 index 000000000..8e91c8d91 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts @@ -0,0 +1,15 @@ +import type {CodeKeywordDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {validateProperties, error} from "./properties" + +const def: CodeKeywordDefinition = { + keyword: "optionalProperties", + schemaType: "object", + error, + code(cxt: KeywordCxt) { + if (cxt.parentSchema.properties) return + validateProperties(cxt) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/properties.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/properties.ts new file mode 100644 index 000000000..9dd24c5cd --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/properties.ts @@ -0,0 +1,184 @@ +import type { + CodeKeywordDefinition, + ErrorObject, + KeywordErrorDefinition, + SchemaObject, +} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {propertyInData, allSchemaProperties, isOwnProperty} from "../code" +import {alwaysValidSchema, schemaRefOrVal} from "../../compile/util" +import {_, and, not, Code, Name} from "../../compile/codegen" +import {checkMetadata} from "./metadata" +import {checkNullableObject} from "./nullable" +import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error" + +enum PropError { + Additional = "additional", + Missing = "missing", +} + +type PropKeyword = "properties" | "optionalProperties" + +type PropSchema = {[P in string]?: SchemaObject} + +export type JTDPropertiesError = + | _JTDTypeError + | ErrorObject + | ErrorObject + +export const error: KeywordErrorDefinition = { + message: (cxt) => { + const {params} = cxt + return params.propError + ? params.propError === PropError.Additional + ? "must NOT have additional properties" + : `must have property '${params.missingProperty}'` + : typeErrorMessage(cxt, "object") + }, + params: (cxt) => { + const {params} = cxt + return params.propError + ? params.propError === PropError.Additional + ? _`{error: ${params.propError}, additionalProperty: ${params.additionalProperty}}` + : _`{error: ${params.propError}, missingProperty: ${params.missingProperty}}` + : typeErrorParams(cxt, "object") + }, +} + +const def: CodeKeywordDefinition = { + keyword: "properties", + schemaType: "object", + error, + code: validateProperties, +} + +// const error: KeywordErrorDefinition = { +// message: "should NOT have additional properties", +// params: ({params}) => _`{additionalProperty: ${params.additionalProperty}}`, +// } + +export function validateProperties(cxt: KeywordCxt): void { + checkMetadata(cxt) + const {gen, data, parentSchema, it} = cxt + const {additionalProperties, nullable} = parentSchema + if (it.jtdDiscriminator && nullable) throw new Error("JTD: nullable inside discriminator mapping") + if (commonProperties()) { + throw new Error("JTD: properties and optionalProperties have common members") + } + const [allProps, properties] = schemaProperties("properties") + const [allOptProps, optProperties] = schemaProperties("optionalProperties") + if (properties.length === 0 && optProperties.length === 0 && additionalProperties) { + return + } + + const [valid, cond] = + it.jtdDiscriminator === undefined + ? checkNullableObject(cxt, data) + : [gen.let("valid", false), true] + gen.if(cond, () => + gen.assign(valid, true).block(() => { + validateProps(properties, "properties", true) + validateProps(optProperties, "optionalProperties") + if (!additionalProperties) validateAdditional() + }) + ) + cxt.pass(valid) + + function commonProperties(): boolean { + const props = parentSchema.properties as Record | undefined + const optProps = parentSchema.optionalProperties as Record | undefined + if (!(props && optProps)) return false + for (const p in props) { + if (Object.prototype.hasOwnProperty.call(optProps, p)) return true + } + return false + } + + function schemaProperties(keyword: string): [string[], string[]] { + const schema = parentSchema[keyword] + const allPs = schema ? allSchemaProperties(schema) : [] + if (it.jtdDiscriminator && allPs.some((p) => p === it.jtdDiscriminator)) { + throw new Error(`JTD: discriminator tag used in ${keyword}`) + } + const ps = allPs.filter((p) => !alwaysValidSchema(it, schema[p])) + return [allPs, ps] + } + + function validateProps(props: string[], keyword: string, required?: boolean): void { + const _valid = gen.var("valid") + for (const prop of props) { + gen.if( + propertyInData(gen, data, prop, it.opts.ownProperties), + () => applyPropertySchema(prop, keyword, _valid), + () => missingProperty(prop) + ) + cxt.ok(_valid) + } + + function missingProperty(prop: string): void { + if (required) { + gen.assign(_valid, false) + cxt.error(false, {propError: PropError.Missing, missingProperty: prop}, {schemaPath: prop}) + } else { + gen.assign(_valid, true) + } + } + } + + function applyPropertySchema(prop: string, keyword: string, _valid: Name): void { + cxt.subschema( + { + keyword, + schemaProp: prop, + dataProp: prop, + }, + _valid + ) + } + + function validateAdditional(): void { + gen.forIn("key", data, (key: Name) => { + const addProp = isAdditional(key, allProps, "properties", it.jtdDiscriminator) + const addOptProp = isAdditional(key, allOptProps, "optionalProperties") + const extra = + addProp === true ? addOptProp : addOptProp === true ? addProp : and(addProp, addOptProp) + gen.if(extra, () => { + if (it.opts.removeAdditional) { + gen.code(_`delete ${data}[${key}]`) + } else { + cxt.error( + false, + {propError: PropError.Additional, additionalProperty: key}, + {instancePath: key, parentSchema: true} + ) + if (!it.opts.allErrors) gen.break() + } + }) + }) + } + + function isAdditional( + key: Name, + props: string[], + keyword: string, + jtdDiscriminator?: string + ): Code | true { + let additional: Code | boolean + if (props.length > 8) { + // TODO maybe an option instead of hard-coded 8? + const propsSchema = schemaRefOrVal(it, parentSchema[keyword], keyword) + additional = not(isOwnProperty(gen, propsSchema as Code, key)) + if (jtdDiscriminator !== undefined) { + additional = and(additional, _`${key} !== ${jtdDiscriminator}`) + } + } else if (props.length || jtdDiscriminator !== undefined) { + const ps = jtdDiscriminator === undefined ? props : [jtdDiscriminator].concat(props) + additional = and(...ps.map((p) => _`${key} !== ${p}`)) + } else { + additional = true + } + return additional + } +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/ref.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/ref.ts new file mode 100644 index 000000000..97646ee1b --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/ref.ts @@ -0,0 +1,76 @@ +import type {CodeKeywordDefinition, AnySchemaObject} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {compileSchema, SchemaEnv} from "../../compile" +import {_, not, nil, stringify} from "../../compile/codegen" +import MissingRefError from "../../compile/ref_error" +import N from "../../compile/names" +import {getValidate, callRef} from "../core/ref" +import {checkMetadata} from "./metadata" + +const def: CodeKeywordDefinition = { + keyword: "ref", + schemaType: "string", + code(cxt: KeywordCxt) { + checkMetadata(cxt) + const {gen, data, schema: ref, parentSchema, it} = cxt + const { + schemaEnv: {root}, + } = it + const valid = gen.name("valid") + if (parentSchema.nullable) { + gen.var(valid, _`${data} === null`) + gen.if(not(valid), validateJtdRef) + } else { + gen.var(valid, false) + validateJtdRef() + } + cxt.ok(valid) + + function validateJtdRef(): void { + const refSchema = (root.schema as AnySchemaObject).definitions?.[ref] + if (!refSchema) { + throw new MissingRefError(it.opts.uriResolver, "", ref, `No definition ${ref}`) + } + if (hasRef(refSchema) || !it.opts.inlineRefs) callValidate(refSchema) + else inlineRefSchema(refSchema) + } + + function callValidate(schema: AnySchemaObject): void { + const sch = compileSchema.call( + it.self, + new SchemaEnv({schema, root, schemaPath: `/definitions/${ref}`}) + ) + const v = getValidate(cxt, sch) + const errsCount = gen.const("_errs", N.errors) + callRef(cxt, v, sch, sch.$async) + gen.assign(valid, _`${errsCount} === ${N.errors}`) + } + + function inlineRefSchema(schema: AnySchemaObject): void { + const schName = gen.scopeValue( + "schema", + it.opts.code.source === true ? {ref: schema, code: stringify(schema)} : {ref: schema} + ) + cxt.subschema( + { + schema, + dataTypes: [], + schemaPath: nil, + topSchemaRef: schName, + errSchemaPath: `/definitions/${ref}`, + }, + valid + ) + } + }, +} + +export function hasRef(schema: AnySchemaObject): boolean { + for (const key in schema) { + let sch: AnySchemaObject + if (key === "ref" || (typeof (sch = schema[key]) == "object" && hasRef(sch))) return true + } + return false +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/type.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/type.ts new file mode 100644 index 000000000..17274300b --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/type.ts @@ -0,0 +1,75 @@ +import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, nil, or, Code} from "../../compile/codegen" +import validTimestamp from "../../runtime/timestamp" +import {useFunc} from "../../compile/util" +import {checkMetadata} from "./metadata" +import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error" + +export type JTDTypeError = _JTDTypeError<"type", JTDType, JTDType> + +export type IntType = "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" + +export const intRange: {[T in IntType]: [number, number, number]} = { + int8: [-128, 127, 3], + uint8: [0, 255, 3], + int16: [-32768, 32767, 5], + uint16: [0, 65535, 5], + int32: [-2147483648, 2147483647, 10], + uint32: [0, 4294967295, 10], +} + +export type JTDType = "boolean" | "string" | "timestamp" | "float32" | "float64" | IntType + +const error: KeywordErrorDefinition = { + message: (cxt) => typeErrorMessage(cxt, cxt.schema), + params: (cxt) => typeErrorParams(cxt, cxt.schema), +} + +function timestampCode(cxt: KeywordCxt): Code { + const {gen, data, it} = cxt + const {timestamp, allowDate} = it.opts + if (timestamp === "date") return _`${data} instanceof Date ` + const vts = useFunc(gen, validTimestamp) + const allowDateArg = allowDate ? _`, true` : nil + const validString = _`typeof ${data} == "string" && ${vts}(${data}${allowDateArg})` + return timestamp === "string" ? validString : or(_`${data} instanceof Date`, validString) +} + +const def: CodeKeywordDefinition = { + keyword: "type", + schemaType: "string", + error, + code(cxt: KeywordCxt) { + checkMetadata(cxt) + const {data, schema, parentSchema, it} = cxt + let cond: Code + switch (schema) { + case "boolean": + case "string": + cond = _`typeof ${data} == ${schema}` + break + case "timestamp": { + cond = timestampCode(cxt) + break + } + case "float32": + case "float64": + cond = _`typeof ${data} == "number"` + break + default: { + const sch = schema as IntType + cond = _`typeof ${data} == "number" && isFinite(${data}) && !(${data} % 1)` + if (!it.opts.int32range && (sch === "int32" || sch === "uint32")) { + if (sch === "uint32") cond = _`${cond} && ${data} >= 0` + } else { + const [min, max] = intRange[sch] + cond = _`${cond} && ${data} >= ${min} && ${data} <= ${max}` + } + } + } + cxt.pass(parentSchema.nullable ? or(_`${data} === null`, cond) : cond) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/union.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/union.ts new file mode 100644 index 000000000..588f07ab4 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/union.ts @@ -0,0 +1,12 @@ +import type {CodeKeywordDefinition} from "../../types" +import {validateUnion} from "../code" + +const def: CodeKeywordDefinition = { + keyword: "union", + schemaType: "array", + trackErrors: true, + code: validateUnion, + error: {message: "must match a schema in union"}, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/jtd/values.ts b/libs/events/node_modules/ajv/lib/vocabularies/jtd/values.ts new file mode 100644 index 000000000..e64945077 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/jtd/values.ts @@ -0,0 +1,58 @@ +import type {CodeKeywordDefinition, SchemaObject} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {alwaysValidSchema, Type} from "../../compile/util" +import {not, or, Name} from "../../compile/codegen" +import {checkMetadata} from "./metadata" +import {checkNullableObject} from "./nullable" +import {typeError, _JTDTypeError} from "./error" + +export type JTDValuesError = _JTDTypeError<"values", "object", SchemaObject> + +const def: CodeKeywordDefinition = { + keyword: "values", + schemaType: "object", + error: typeError("object"), + code(cxt: KeywordCxt) { + checkMetadata(cxt) + const {gen, data, schema, it} = cxt + const [valid, cond] = checkNullableObject(cxt, data) + if (alwaysValidSchema(it, schema)) { + gen.if(not(or(cond, valid)), () => cxt.error()) + } else { + gen.if(cond) + gen.assign(valid, validateMap()) + gen.elseIf(not(valid)) + cxt.error() + gen.endIf() + } + cxt.ok(valid) + + function validateMap(): Name | boolean { + const _valid = gen.name("valid") + if (it.allErrors) { + const validMap = gen.let("valid", true) + validateValues(() => gen.assign(validMap, false)) + return validMap + } + gen.var(_valid, true) + validateValues(() => gen.break()) + return _valid + + function validateValues(notValid: () => void): void { + gen.forIn("key", data, (key) => { + cxt.subschema( + { + keyword: "values", + dataProp: key, + dataPropType: Type.Str, + }, + _valid + ) + gen.if(not(_valid), notValid) + }) + } + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/metadata.ts b/libs/events/node_modules/ajv/lib/vocabularies/metadata.ts new file mode 100644 index 000000000..b9d5af85f --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/metadata.ts @@ -0,0 +1,17 @@ +import type {Vocabulary} from "../types" + +export const metadataVocabulary: Vocabulary = [ + "title", + "description", + "default", + "deprecated", + "readOnly", + "writeOnly", + "examples", +] + +export const contentVocabulary: Vocabulary = [ + "contentMediaType", + "contentEncoding", + "contentSchema", +] diff --git a/libs/events/node_modules/ajv/lib/vocabularies/next.ts b/libs/events/node_modules/ajv/lib/vocabularies/next.ts new file mode 100644 index 000000000..1e987ad21 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/next.ts @@ -0,0 +1,8 @@ +import type {Vocabulary} from "../types" +import dependentRequired from "./validation/dependentRequired" +import dependentSchemas from "./applicator/dependentSchemas" +import limitContains from "./validation/limitContains" + +const next: Vocabulary = [dependentRequired, dependentSchemas, limitContains] + +export default next diff --git a/libs/events/node_modules/ajv/lib/vocabularies/unevaluated/index.ts b/libs/events/node_modules/ajv/lib/vocabularies/unevaluated/index.ts new file mode 100644 index 000000000..f7f0815db --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/unevaluated/index.ts @@ -0,0 +1,7 @@ +import type {Vocabulary} from "../../types" +import unevaluatedProperties from "./unevaluatedProperties" +import unevaluatedItems from "./unevaluatedItems" + +const unevaluated: Vocabulary = [unevaluatedProperties, unevaluatedItems] + +export default unevaluated diff --git a/libs/events/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts b/libs/events/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts new file mode 100644 index 000000000..50bf0e7c1 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts @@ -0,0 +1,47 @@ +import type { + CodeKeywordDefinition, + ErrorObject, + KeywordErrorDefinition, + AnySchema, +} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str, not, Name} from "../../compile/codegen" +import {alwaysValidSchema, Type} from "../../compile/util" + +export type UnevaluatedItemsError = ErrorObject<"unevaluatedItems", {limit: number}, AnySchema> + +const error: KeywordErrorDefinition = { + message: ({params: {len}}) => str`must NOT have more than ${len} items`, + params: ({params: {len}}) => _`{limit: ${len}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "unevaluatedItems", + type: "array", + schemaType: ["boolean", "object"], + error, + code(cxt: KeywordCxt) { + const {gen, schema, data, it} = cxt + const items = it.items || 0 + if (items === true) return + const len = gen.const("len", _`${data}.length`) + if (schema === false) { + cxt.setParams({len: items}) + cxt.fail(_`${len} > ${items}`) + } else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) { + const valid = gen.var("valid", _`${len} <= ${items}`) + gen.if(not(valid), () => validateItems(valid, items)) + cxt.ok(valid) + } + it.items = true + + function validateItems(valid: Name, from: Name | number): void { + gen.forRange("i", from, len, (i) => { + cxt.subschema({keyword: "unevaluatedItems", dataProp: i, dataPropType: Type.Num}, valid) + if (!it.allErrors) gen.if(not(valid), () => gen.break()) + }) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts b/libs/events/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts new file mode 100644 index 000000000..0e6868fa3 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts @@ -0,0 +1,85 @@ +import type { + CodeKeywordDefinition, + KeywordErrorDefinition, + ErrorObject, + AnySchema, +} from "../../types" +import {_, not, and, Name, Code} from "../../compile/codegen" +import {alwaysValidSchema, Type} from "../../compile/util" +import N from "../../compile/names" + +export type UnevaluatedPropertiesError = ErrorObject< + "unevaluatedProperties", + {unevaluatedProperty: string}, + AnySchema +> + +const error: KeywordErrorDefinition = { + message: "must NOT have unevaluated properties", + params: ({params}) => _`{unevaluatedProperty: ${params.unevaluatedProperty}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "unevaluatedProperties", + type: "object", + schemaType: ["boolean", "object"], + trackErrors: true, + error, + code(cxt) { + const {gen, schema, data, errsCount, it} = cxt + /* istanbul ignore if */ + if (!errsCount) throw new Error("ajv implementation error") + const {allErrors, props} = it + if (props instanceof Name) { + gen.if(_`${props} !== true`, () => + gen.forIn("key", data, (key: Name) => + gen.if(unevaluatedDynamic(props, key), () => unevaluatedPropCode(key)) + ) + ) + } else if (props !== true) { + gen.forIn("key", data, (key: Name) => + props === undefined + ? unevaluatedPropCode(key) + : gen.if(unevaluatedStatic(props, key), () => unevaluatedPropCode(key)) + ) + } + it.props = true + cxt.ok(_`${errsCount} === ${N.errors}`) + + function unevaluatedPropCode(key: Name): void { + if (schema === false) { + cxt.setParams({unevaluatedProperty: key}) + cxt.error() + if (!allErrors) gen.break() + return + } + + if (!alwaysValidSchema(it, schema)) { + const valid = gen.name("valid") + cxt.subschema( + { + keyword: "unevaluatedProperties", + dataProp: key, + dataPropType: Type.Str, + }, + valid + ) + if (!allErrors) gen.if(not(valid), () => gen.break()) + } + } + + function unevaluatedDynamic(evaluatedProps: Name, key: Name): Code { + return _`!${evaluatedProps} || !${evaluatedProps}[${key}]` + } + + function unevaluatedStatic(evaluatedProps: {[K in string]?: true}, key: Name): Code { + const ps: Code[] = [] + for (const p in evaluatedProps) { + if (evaluatedProps[p] === true) ps.push(_`${key} !== ${p}`) + } + return and(...ps) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/const.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/const.ts new file mode 100644 index 000000000..a3b94a5dc --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/const.ts @@ -0,0 +1,28 @@ +import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_} from "../../compile/codegen" +import {useFunc} from "../../compile/util" +import equal from "../../runtime/equal" + +export type ConstError = ErrorObject<"const", {allowedValue: any}> + +const error: KeywordErrorDefinition = { + message: "must be equal to constant", + params: ({schemaCode}) => _`{allowedValue: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "const", + $data: true, + error, + code(cxt: KeywordCxt) { + const {gen, data, $data, schemaCode, schema} = cxt + if ($data || (schema && typeof schema == "object")) { + cxt.fail$data(_`!${useFunc(gen, equal)}(${data}, ${schemaCode})`) + } else { + cxt.fail(_`${schema} !== ${data}`) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts new file mode 100644 index 000000000..4c616cfa9 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts @@ -0,0 +1,23 @@ +import type {CodeKeywordDefinition, ErrorObject} from "../../types" +import { + validatePropertyDeps, + error, + DependenciesErrorParams, + PropertyDependencies, +} from "../applicator/dependencies" + +export type DependentRequiredError = ErrorObject< + "dependentRequired", + DependenciesErrorParams, + PropertyDependencies +> + +const def: CodeKeywordDefinition = { + keyword: "dependentRequired", + type: "object", + schemaType: "object", + error, + code: (cxt) => validatePropertyDeps(cxt), +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/enum.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/enum.ts new file mode 100644 index 000000000..76377fb02 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/enum.ts @@ -0,0 +1,54 @@ +import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, or, Name, Code} from "../../compile/codegen" +import {useFunc} from "../../compile/util" +import equal from "../../runtime/equal" + +export type EnumError = ErrorObject<"enum", {allowedValues: any[]}, any[] | {$data: string}> + +const error: KeywordErrorDefinition = { + message: "must be equal to one of the allowed values", + params: ({schemaCode}) => _`{allowedValues: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "enum", + schemaType: "array", + $data: true, + error, + code(cxt: KeywordCxt) { + const {gen, data, $data, schema, schemaCode, it} = cxt + if (!$data && schema.length === 0) throw new Error("enum must have non-empty array") + const useLoop = schema.length >= it.opts.loopEnum + let eql: Name | undefined + const getEql = (): Name => (eql ??= useFunc(gen, equal)) + + let valid: Code + if (useLoop || $data) { + valid = gen.let("valid") + cxt.block$data(valid, loopEnum) + } else { + /* istanbul ignore if */ + if (!Array.isArray(schema)) throw new Error("ajv implementation error") + const vSchema = gen.const("vSchema", schemaCode) + valid = or(...schema.map((_x: unknown, i: number) => equalCode(vSchema, i))) + } + cxt.pass(valid) + + function loopEnum(): void { + gen.assign(valid, false) + gen.forOf("v", schemaCode as Code, (v) => + gen.if(_`${getEql()}(${data}, ${v})`, () => gen.assign(valid, true).break()) + ) + } + + function equalCode(vSchema: Name, i: number): Code { + const sch = schema[i] + return typeof sch === "object" && sch !== null + ? _`${getEql()}(${data}, ${vSchema}[${i}])` + : _`${data} === ${sch}` + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/index.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/index.ts new file mode 100644 index 000000000..3531b1962 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/index.ts @@ -0,0 +1,49 @@ +import type {ErrorObject, Vocabulary} from "../../types" +import limitNumber, {LimitNumberError} from "./limitNumber" +import multipleOf, {MultipleOfError} from "./multipleOf" +import limitLength from "./limitLength" +import pattern, {PatternError} from "./pattern" +import limitProperties from "./limitProperties" +import required, {RequiredError} from "./required" +import limitItems from "./limitItems" +import uniqueItems, {UniqueItemsError} from "./uniqueItems" +import constKeyword, {ConstError} from "./const" +import enumKeyword, {EnumError} from "./enum" + +const validation: Vocabulary = [ + // number + limitNumber, + multipleOf, + // string + limitLength, + pattern, + // object + limitProperties, + required, + // array + limitItems, + uniqueItems, + // any + {keyword: "type", schemaType: ["string", "array"]}, + {keyword: "nullable", schemaType: "boolean"}, + constKeyword, + enumKeyword, +] + +export default validation + +type LimitError = ErrorObject< + "maxItems" | "minItems" | "minProperties" | "maxProperties" | "minLength" | "maxLength", + {limit: number}, + number | {$data: string} +> + +export type ValidationKeywordError = + | LimitError + | LimitNumberError + | MultipleOfError + | PatternError + | RequiredError + | UniqueItemsError + | ConstError + | EnumError diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/limitContains.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitContains.ts new file mode 100644 index 000000000..8bb43c1a4 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitContains.ts @@ -0,0 +1,16 @@ +import type {CodeKeywordDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {checkStrictMode} from "../../compile/util" + +const def: CodeKeywordDefinition = { + keyword: ["maxContains", "minContains"], + type: "array", + schemaType: "number", + code({keyword, parentSchema, it}: KeywordCxt) { + if (parentSchema.contains === undefined) { + checkStrictMode(it, `"${keyword}" without "contains" is ignored`) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/limitItems.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitItems.ts new file mode 100644 index 000000000..566de8588 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitItems.ts @@ -0,0 +1,26 @@ +import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str, operators} from "../../compile/codegen" + +const error: KeywordErrorDefinition = { + message({keyword, schemaCode}) { + const comp = keyword === "maxItems" ? "more" : "fewer" + return str`must NOT have ${comp} than ${schemaCode} items` + }, + params: ({schemaCode}) => _`{limit: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: ["maxItems", "minItems"], + type: "array", + schemaType: "number", + $data: true, + error, + code(cxt: KeywordCxt) { + const {keyword, data, schemaCode} = cxt + const op = keyword === "maxItems" ? operators.GT : operators.LT + cxt.fail$data(_`${data}.length ${op} ${schemaCode}`) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/limitLength.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitLength.ts new file mode 100644 index 000000000..f4f947259 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitLength.ts @@ -0,0 +1,30 @@ +import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str, operators} from "../../compile/codegen" +import {useFunc} from "../../compile/util" +import ucs2length from "../../runtime/ucs2length" + +const error: KeywordErrorDefinition = { + message({keyword, schemaCode}) { + const comp = keyword === "maxLength" ? "more" : "fewer" + return str`must NOT have ${comp} than ${schemaCode} characters` + }, + params: ({schemaCode}) => _`{limit: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: ["maxLength", "minLength"], + type: "string", + schemaType: "number", + $data: true, + error, + code(cxt: KeywordCxt) { + const {keyword, data, schemaCode, it} = cxt + const op = keyword === "maxLength" ? operators.GT : operators.LT + const len = + it.opts.unicode === false ? _`${data}.length` : _`${useFunc(cxt.gen, ucs2length)}(${data})` + cxt.fail$data(_`${len} ${op} ${schemaCode}`) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts new file mode 100644 index 000000000..5499202ef --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts @@ -0,0 +1,42 @@ +import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str, operators, Code} from "../../compile/codegen" + +const ops = operators + +type Kwd = "maximum" | "minimum" | "exclusiveMaximum" | "exclusiveMinimum" + +type Comparison = "<=" | ">=" | "<" | ">" + +const KWDs: {[K in Kwd]: {okStr: Comparison; ok: Code; fail: Code}} = { + maximum: {okStr: "<=", ok: ops.LTE, fail: ops.GT}, + minimum: {okStr: ">=", ok: ops.GTE, fail: ops.LT}, + exclusiveMaximum: {okStr: "<", ok: ops.LT, fail: ops.GTE}, + exclusiveMinimum: {okStr: ">", ok: ops.GT, fail: ops.LTE}, +} + +export type LimitNumberError = ErrorObject< + Kwd, + {limit: number; comparison: Comparison}, + number | {$data: string} +> + +const error: KeywordErrorDefinition = { + message: ({keyword, schemaCode}) => str`must be ${KWDs[keyword as Kwd].okStr} ${schemaCode}`, + params: ({keyword, schemaCode}) => + _`{comparison: ${KWDs[keyword as Kwd].okStr}, limit: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: Object.keys(KWDs), + type: "number", + schemaType: "number", + $data: true, + error, + code(cxt: KeywordCxt) { + const {keyword, data, schemaCode} = cxt + cxt.fail$data(_`${data} ${KWDs[keyword as Kwd].fail} ${schemaCode} || isNaN(${data})`) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts new file mode 100644 index 000000000..07fffa8b3 --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts @@ -0,0 +1,26 @@ +import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str, operators} from "../../compile/codegen" + +const error: KeywordErrorDefinition = { + message({keyword, schemaCode}) { + const comp = keyword === "maxProperties" ? "more" : "fewer" + return str`must NOT have ${comp} than ${schemaCode} properties` + }, + params: ({schemaCode}) => _`{limit: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: ["maxProperties", "minProperties"], + type: "object", + schemaType: "number", + $data: true, + error, + code(cxt: KeywordCxt) { + const {keyword, data, schemaCode} = cxt + const op = keyword === "maxProperties" ? operators.GT : operators.LT + cxt.fail$data(_`Object.keys(${data}).length ${op} ${schemaCode}`) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts new file mode 100644 index 000000000..1fd79abbd --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts @@ -0,0 +1,34 @@ +import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {_, str} from "../../compile/codegen" + +export type MultipleOfError = ErrorObject< + "multipleOf", + {multipleOf: number}, + number | {$data: string} +> + +const error: KeywordErrorDefinition = { + message: ({schemaCode}) => str`must be multiple of ${schemaCode}`, + params: ({schemaCode}) => _`{multipleOf: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "multipleOf", + type: "number", + schemaType: "number", + $data: true, + error, + code(cxt: KeywordCxt) { + const {gen, data, schemaCode, it} = cxt + // const bdt = bad$DataType(schemaCode, def.schemaType, $data) + const prec = it.opts.multipleOfPrecision + const res = gen.let("res") + const invalid = prec + ? _`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}` + : _`${res} !== parseInt(${res})` + cxt.fail$data(_`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid}))`) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/pattern.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/pattern.ts new file mode 100644 index 000000000..7b27b7d3c --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/pattern.ts @@ -0,0 +1,28 @@ +import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {usePattern} from "../code" +import {_, str} from "../../compile/codegen" + +export type PatternError = ErrorObject<"pattern", {pattern: string}, string | {$data: string}> + +const error: KeywordErrorDefinition = { + message: ({schemaCode}) => str`must match pattern "${schemaCode}"`, + params: ({schemaCode}) => _`{pattern: ${schemaCode}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "pattern", + type: "string", + schemaType: "string", + $data: true, + error, + code(cxt: KeywordCxt) { + const {data, $data, schema, schemaCode, it} = cxt + // TODO regexp should be wrapped in try/catchs + const u = it.opts.unicodeRegExp ? "u" : "" + const regExp = $data ? _`(new RegExp(${schemaCode}, ${u}))` : usePattern(cxt, schema) + cxt.fail$data(_`!${regExp}.test(${data})`) + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/required.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/required.ts new file mode 100644 index 000000000..fea7367ed --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/required.ts @@ -0,0 +1,98 @@ +import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import { + checkReportMissingProp, + checkMissingProp, + reportMissingProp, + propertyInData, + noPropertyInData, +} from "../code" +import {_, str, nil, not, Name, Code} from "../../compile/codegen" +import {checkStrictMode} from "../../compile/util" + +export type RequiredError = ErrorObject< + "required", + {missingProperty: string}, + string[] | {$data: string} +> + +const error: KeywordErrorDefinition = { + message: ({params: {missingProperty}}) => str`must have required property '${missingProperty}'`, + params: ({params: {missingProperty}}) => _`{missingProperty: ${missingProperty}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "required", + type: "object", + schemaType: "array", + $data: true, + error, + code(cxt: KeywordCxt) { + const {gen, schema, schemaCode, data, $data, it} = cxt + const {opts} = it + if (!$data && schema.length === 0) return + const useLoop = schema.length >= opts.loopRequired + if (it.allErrors) allErrorsMode() + else exitOnErrorMode() + + if (opts.strictRequired) { + const props = cxt.parentSchema.properties + const {definedProperties} = cxt.it + for (const requiredKey of schema) { + if (props?.[requiredKey] === undefined && !definedProperties.has(requiredKey)) { + const schemaPath = it.schemaEnv.baseId + it.errSchemaPath + const msg = `required property "${requiredKey}" is not defined at "${schemaPath}" (strictRequired)` + checkStrictMode(it, msg, it.opts.strictRequired) + } + } + } + + function allErrorsMode(): void { + if (useLoop || $data) { + cxt.block$data(nil, loopAllRequired) + } else { + for (const prop of schema) { + checkReportMissingProp(cxt, prop) + } + } + } + + function exitOnErrorMode(): void { + const missing = gen.let("missing") + if (useLoop || $data) { + const valid = gen.let("valid", true) + cxt.block$data(valid, () => loopUntilMissing(missing, valid)) + cxt.ok(valid) + } else { + gen.if(checkMissingProp(cxt, schema, missing)) + reportMissingProp(cxt, missing) + gen.else() + } + } + + function loopAllRequired(): void { + gen.forOf("prop", schemaCode as Code, (prop) => { + cxt.setParams({missingProperty: prop}) + gen.if(noPropertyInData(gen, data, prop, opts.ownProperties), () => cxt.error()) + }) + } + + function loopUntilMissing(missing: Name, valid: Name): void { + cxt.setParams({missingProperty: missing}) + gen.forOf( + missing, + schemaCode as Code, + () => { + gen.assign(valid, propertyInData(gen, data, missing, opts.ownProperties)) + gen.if(not(valid), () => { + cxt.error() + gen.break() + }) + }, + nil + ) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts b/libs/events/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts new file mode 100644 index 000000000..765c4d04f --- /dev/null +++ b/libs/events/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts @@ -0,0 +1,79 @@ +import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types" +import type {KeywordCxt} from "../../compile/validate" +import {checkDataTypes, getSchemaTypes, DataType} from "../../compile/validate/dataType" +import {_, str, Name} from "../../compile/codegen" +import {useFunc} from "../../compile/util" +import equal from "../../runtime/equal" + +export type UniqueItemsError = ErrorObject< + "uniqueItems", + {i: number; j: number}, + boolean | {$data: string} +> + +const error: KeywordErrorDefinition = { + message: ({params: {i, j}}) => + str`must NOT have duplicate items (items ## ${j} and ${i} are identical)`, + params: ({params: {i, j}}) => _`{i: ${i}, j: ${j}}`, +} + +const def: CodeKeywordDefinition = { + keyword: "uniqueItems", + type: "array", + schemaType: "boolean", + $data: true, + error, + code(cxt: KeywordCxt) { + const {gen, data, $data, schema, parentSchema, schemaCode, it} = cxt + if (!$data && !schema) return + const valid = gen.let("valid") + const itemTypes = parentSchema.items ? getSchemaTypes(parentSchema.items) : [] + cxt.block$data(valid, validateUniqueItems, _`${schemaCode} === false`) + cxt.ok(valid) + + function validateUniqueItems(): void { + const i = gen.let("i", _`${data}.length`) + const j = gen.let("j") + cxt.setParams({i, j}) + gen.assign(valid, true) + gen.if(_`${i} > 1`, () => (canOptimize() ? loopN : loopN2)(i, j)) + } + + function canOptimize(): boolean { + return itemTypes.length > 0 && !itemTypes.some((t) => t === "object" || t === "array") + } + + function loopN(i: Name, j: Name): void { + const item = gen.name("item") + const wrongType = checkDataTypes(itemTypes, item, it.opts.strictNumbers, DataType.Wrong) + const indices = gen.const("indices", _`{}`) + gen.for(_`;${i}--;`, () => { + gen.let(item, _`${data}[${i}]`) + gen.if(wrongType, _`continue`) + if (itemTypes.length > 1) gen.if(_`typeof ${item} == "string"`, _`${item} += "_"`) + gen + .if(_`typeof ${indices}[${item}] == "number"`, () => { + gen.assign(j, _`${indices}[${item}]`) + cxt.error() + gen.assign(valid, false).break() + }) + .code(_`${indices}[${item}] = ${i}`) + }) + } + + function loopN2(i: Name, j: Name): void { + const eql = useFunc(gen, equal) + const outer = gen.name("outer") + gen.label(outer).for(_`;${i}--;`, () => + gen.for(_`${j} = ${i}; ${j}--;`, () => + gen.if(_`${eql}(${data}[${i}], ${data}[${j}])`, () => { + cxt.error() + gen.assign(valid, false).break(outer) + }) + ) + ) + } + }, +} + +export default def diff --git a/libs/events/node_modules/ajv/package.json b/libs/events/node_modules/ajv/package.json new file mode 100644 index 000000000..61ae2b999 --- /dev/null +++ b/libs/events/node_modules/ajv/package.json @@ -0,0 +1,126 @@ +{ + "name": "ajv", + "version": "8.12.0", + "description": "Another JSON Schema Validator", + "main": "dist/ajv.js", + "types": "dist/ajv.d.ts", + "files": [ + "lib/", + "dist/", + ".runkit_example.js" + ], + "scripts": { + "eslint": "eslint \"lib/**/*.ts\" \"spec/**/*.*s\" --ignore-pattern spec/JSON-Schema-Test-Suite", + "prettier:write": "prettier --write \"./**/*.{json,yaml,js,ts}\"", + "prettier:check": "prettier --list-different \"./**/*.{json,yaml,js,ts}\"", + "test-spec": "cross-env TS_NODE_PROJECT=spec/tsconfig.json mocha -r ts-node/register \"spec/**/*.spec.{ts,js}\" -R dot", + "test-codegen": "nyc cross-env TS_NODE_PROJECT=spec/tsconfig.json mocha -r ts-node/register 'spec/codegen.spec.ts' -R spec", + "test-debug": "npm run test-spec -- --inspect-brk", + "test-cov": "nyc npm run test-spec", + "rollup": "rm -rf bundle && rollup -c", + "bundle": "rm -rf bundle && node ./scripts/bundle.js ajv ajv7 ajv7 && node ./scripts/bundle.js 2019 ajv2019 ajv2019 && node ./scripts/bundle.js 2020 ajv2020 ajv2020 && node ./scripts/bundle.js jtd ajvJTD ajvJTD", + "build": "rm -rf dist && tsc && cp -r lib/refs dist && rm dist/refs/json-schema-2019-09/index.ts && rm dist/refs/json-schema-2020-12/index.ts && rm dist/refs/jtd-schema.ts", + "json-tests": "rm -rf spec/_json/*.js && node scripts/jsontests", + "test-karma": "karma start", + "test-browser": "rm -rf .browser && npm run bundle && scripts/prepare-tests && karma start", + "test-all": "npm run test-cov && if-node-version 12 npm run test-browser", + "test": "npm run json-tests && npm run prettier:check && npm run eslint && npm link && npm link --legacy-peer-deps ajv && npm run test-cov", + "test-ci": "AJV_FULL_TEST=true npm test", + "prepublish": "npm run build", + "benchmark": "npm i && npm run build && npm link && cd ./benchmark && npm link --legacy-peer-deps ajv && npm i && node ./jtd", + "docs:dev": "./scripts/prepare-site && vuepress dev docs", + "docs:build": "./scripts/prepare-site && vuepress build docs" + }, + "nyc": { + "exclude": [ + "**/spec/**", + "node_modules" + ], + "reporter": [ + "lcov", + "text-summary" + ] + }, + "repository": "ajv-validator/ajv", + "keywords": [ + "JSON", + "schema", + "validator", + "validation", + "jsonschema", + "json-schema", + "json-schema-validator", + "json-schema-validation" + ], + "author": "Evgeny Poberezkin", + "license": "MIT", + "bugs": "https://github.com/ajv-validator/ajv/issues", + "homepage": "https://ajv.js.org", + "runkitExampleFilename": ".runkit_example.js", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "devDependencies": { + "@ajv-validator/config": "^0.3.0", + "@rollup/plugin-commonjs": "^24.0.0", + "@rollup/plugin-json": "^6.0.0", + "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-typescript": "^10.0.1", + "@types/chai": "^4.2.12", + "@types/mocha": "^10.0.0", + "@types/node": "^18.11.9", + "@types/require-from-string": "^1.2.0", + "@typescript-eslint/eslint-plugin": "^3.8.0", + "@typescript-eslint/parser": "^3.8.0", + "ajv-formats": "^3.0.0-rc.0", + "browserify": "^17.0.0", + "chai": "^4.0.1", + "cross-env": "^7.0.2", + "dayjs": "^1.10.4", + "dayjs-plugin-utc": "^0.1.2", + "eslint": "^7.8.1", + "eslint-config-prettier": "^7.0.0", + "fast-uri": "^2.1.0", + "glob": "^8.0.2", + "husky": "^8.0.2", + "if-node-version": "^1.0.0", + "jimp": "^0.16.1", + "js-beautify": "^1.7.3", + "json-schema-test": "^2.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-mocha": "^2.0.0", + "lint-staged": "^13.0.3", + "mocha": "^10.0.0", + "module-from-string": "^3.1.3", + "node-fetch": "^3.0.0", + "nyc": "^15.0.0", + "prettier": "^2.3.1", + "re2": "^1.16.0", + "rollup": "^2.44.0", + "rollup-plugin-terser": "^7.0.2", + "ts-node": "^10.0.0", + "tsify": "^5.0.2", + "typescript": "^4.8.0" + }, + "collective": { + "type": "opencollective", + "url": "https://opencollective.com/ajv" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + }, + "prettier": "@ajv-validator/config/prettierrc.json", + "husky": { + "hooks": { + "pre-commit": "lint-staged && npm test" + } + }, + "lint-staged": { + "*.{json,yaml,js,ts}": "prettier --write" + } +} diff --git a/libs/events/node_modules/argparse/CHANGELOG.md b/libs/events/node_modules/argparse/CHANGELOG.md new file mode 100644 index 000000000..dc39ed695 --- /dev/null +++ b/libs/events/node_modules/argparse/CHANGELOG.md @@ -0,0 +1,216 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [2.0.1] - 2020-08-29 +### Fixed +- Fix issue with `process.argv` when used with interpreters (`coffee`, `ts-node`, etc.), #150. + + +## [2.0.0] - 2020-08-14 +### Changed +- Full rewrite. Now port from python 3.9.0 & more precise following. + See [doc](./doc) for difference and migration info. +- node.js 10+ required +- Removed most of local docs in favour of original ones. + + +## [1.0.10] - 2018-02-15 +### Fixed +- Use .concat instead of + for arrays, #122. + + +## [1.0.9] - 2016-09-29 +### Changed +- Rerelease after 1.0.8 - deps cleanup. + + +## [1.0.8] - 2016-09-29 +### Changed +- Maintenance (deps bump, fix node 6.5+ tests, coverage report). + + +## [1.0.7] - 2016-03-17 +### Changed +- Teach `addArgument` to accept string arg names. #97, @tomxtobin. + + +## [1.0.6] - 2016-02-06 +### Changed +- Maintenance: moved to eslint & updated CS. + + +## [1.0.5] - 2016-02-05 +### Changed +- Removed lodash dependency to significantly reduce install size. + Thanks to @mourner. + + +## [1.0.4] - 2016-01-17 +### Changed +- Maintenance: lodash update to 4.0.0. + + +## [1.0.3] - 2015-10-27 +### Fixed +- Fix parse `=` in args: `--examplepath="C:\myfolder\env=x64"`. #84, @CatWithApple. + + +## [1.0.2] - 2015-03-22 +### Changed +- Relaxed lodash version dependency. + + +## [1.0.1] - 2015-02-20 +### Changed +- Changed dependencies to be compatible with ancient nodejs. + + +## [1.0.0] - 2015-02-19 +### Changed +- Maintenance release. +- Replaced `underscore` with `lodash`. +- Bumped version to 1.0.0 to better reflect semver meaning. +- HISTORY.md -> CHANGELOG.md + + +## [0.1.16] - 2013-12-01 +### Changed +- Maintenance release. Updated dependencies and docs. + + +## [0.1.15] - 2013-05-13 +### Fixed +- Fixed #55, @trebor89 + + +## [0.1.14] - 2013-05-12 +### Fixed +- Fixed #62, @maxtaco + + +## [0.1.13] - 2013-04-08 +### Changed +- Added `.npmignore` to reduce package size + + +## [0.1.12] - 2013-02-10 +### Fixed +- Fixed conflictHandler (#46), @hpaulj + + +## [0.1.11] - 2013-02-07 +### Added +- Added 70+ tests (ported from python), @hpaulj +- Added conflictHandler, @applepicke +- Added fromfilePrefixChar, @hpaulj + +### Fixed +- Multiple bugfixes, @hpaulj + + +## [0.1.10] - 2012-12-30 +### Added +- Added [mutual exclusion](http://docs.python.org/dev/library/argparse.html#mutual-exclusion) + support, thanks to @hpaulj + +### Fixed +- Fixed options check for `storeConst` & `appendConst` actions, thanks to @hpaulj + + +## [0.1.9] - 2012-12-27 +### Fixed +- Fixed option dest interferens with other options (issue #23), thanks to @hpaulj +- Fixed default value behavior with `*` positionals, thanks to @hpaulj +- Improve `getDefault()` behavior, thanks to @hpaulj +- Improve negative argument parsing, thanks to @hpaulj + + +## [0.1.8] - 2012-12-01 +### Fixed +- Fixed parser parents (issue #19), thanks to @hpaulj +- Fixed negative argument parse (issue #20), thanks to @hpaulj + + +## [0.1.7] - 2012-10-14 +### Fixed +- Fixed 'choices' argument parse (issue #16) +- Fixed stderr output (issue #15) + + +## [0.1.6] - 2012-09-09 +### Fixed +- Fixed check for conflict of options (thanks to @tomxtobin) + + +## [0.1.5] - 2012-09-03 +### Fixed +- Fix parser #setDefaults method (thanks to @tomxtobin) + + +## [0.1.4] - 2012-07-30 +### Fixed +- Fixed pseudo-argument support (thanks to @CGamesPlay) +- Fixed addHelp default (should be true), if not set (thanks to @benblank) + + +## [0.1.3] - 2012-06-27 +### Fixed +- Fixed formatter api name: Formatter -> HelpFormatter + + +## [0.1.2] - 2012-05-29 +### Fixed +- Removed excess whitespace in help +- Fixed error reporting, when parcer with subcommands + called with empty arguments + +### Added +- Added basic tests + + +## [0.1.1] - 2012-05-23 +### Fixed +- Fixed line wrapping in help formatter +- Added better error reporting on invalid arguments + + +## [0.1.0] - 2012-05-16 +### Added +- First release. + + +[2.0.1]: https://github.com/nodeca/argparse/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/nodeca/argparse/compare/1.0.10...2.0.0 +[1.0.10]: https://github.com/nodeca/argparse/compare/1.0.9...1.0.10 +[1.0.9]: https://github.com/nodeca/argparse/compare/1.0.8...1.0.9 +[1.0.8]: https://github.com/nodeca/argparse/compare/1.0.7...1.0.8 +[1.0.7]: https://github.com/nodeca/argparse/compare/1.0.6...1.0.7 +[1.0.6]: https://github.com/nodeca/argparse/compare/1.0.5...1.0.6 +[1.0.5]: https://github.com/nodeca/argparse/compare/1.0.4...1.0.5 +[1.0.4]: https://github.com/nodeca/argparse/compare/1.0.3...1.0.4 +[1.0.3]: https://github.com/nodeca/argparse/compare/1.0.2...1.0.3 +[1.0.2]: https://github.com/nodeca/argparse/compare/1.0.1...1.0.2 +[1.0.1]: https://github.com/nodeca/argparse/compare/1.0.0...1.0.1 +[1.0.0]: https://github.com/nodeca/argparse/compare/0.1.16...1.0.0 +[0.1.16]: https://github.com/nodeca/argparse/compare/0.1.15...0.1.16 +[0.1.15]: https://github.com/nodeca/argparse/compare/0.1.14...0.1.15 +[0.1.14]: https://github.com/nodeca/argparse/compare/0.1.13...0.1.14 +[0.1.13]: https://github.com/nodeca/argparse/compare/0.1.12...0.1.13 +[0.1.12]: https://github.com/nodeca/argparse/compare/0.1.11...0.1.12 +[0.1.11]: https://github.com/nodeca/argparse/compare/0.1.10...0.1.11 +[0.1.10]: https://github.com/nodeca/argparse/compare/0.1.9...0.1.10 +[0.1.9]: https://github.com/nodeca/argparse/compare/0.1.8...0.1.9 +[0.1.8]: https://github.com/nodeca/argparse/compare/0.1.7...0.1.8 +[0.1.7]: https://github.com/nodeca/argparse/compare/0.1.6...0.1.7 +[0.1.6]: https://github.com/nodeca/argparse/compare/0.1.5...0.1.6 +[0.1.5]: https://github.com/nodeca/argparse/compare/0.1.4...0.1.5 +[0.1.4]: https://github.com/nodeca/argparse/compare/0.1.3...0.1.4 +[0.1.3]: https://github.com/nodeca/argparse/compare/0.1.2...0.1.3 +[0.1.2]: https://github.com/nodeca/argparse/compare/0.1.1...0.1.2 +[0.1.1]: https://github.com/nodeca/argparse/compare/0.1.0...0.1.1 +[0.1.0]: https://github.com/nodeca/argparse/releases/tag/0.1.0 diff --git a/libs/events/node_modules/argparse/LICENSE b/libs/events/node_modules/argparse/LICENSE new file mode 100644 index 000000000..66a3ac80d --- /dev/null +++ b/libs/events/node_modules/argparse/LICENSE @@ -0,0 +1,254 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations, which became +Zope Corporation. In 2001, the Python Software Foundation (PSF, see +https://www.python.org/psf/) was formed, a non-profit organization +created specifically to own Python-related Intellectual Property. +Zope Corporation was a sponsoring member of the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2 and above 2.1.1 2001-now PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Python Software Foundation; +All Rights Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the Internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the Internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/libs/events/node_modules/argparse/README.md b/libs/events/node_modules/argparse/README.md new file mode 100644 index 000000000..550b5c9b7 --- /dev/null +++ b/libs/events/node_modules/argparse/README.md @@ -0,0 +1,84 @@ +argparse +======== + +[![Build Status](https://secure.travis-ci.org/nodeca/argparse.svg?branch=master)](http://travis-ci.org/nodeca/argparse) +[![NPM version](https://img.shields.io/npm/v/argparse.svg)](https://www.npmjs.org/package/argparse) + +CLI arguments parser for node.js, with [sub-commands](https://docs.python.org/3.9/library/argparse.html#sub-commands) support. Port of python's [argparse](http://docs.python.org/dev/library/argparse.html) (version [3.9.0](https://github.com/python/cpython/blob/v3.9.0rc1/Lib/argparse.py)). + +**Difference with original.** + +- JS has no keyword arguments support. + - Pass options instead: `new ArgumentParser({ description: 'example', add_help: true })`. +- JS has no python's types `int`, `float`, ... + - Use string-typed names: `.add_argument('-b', { type: 'int', help: 'help' })`. +- `%r` format specifier uses `require('util').inspect()`. + +More details in [doc](./doc). + + +Example +------- + +`test.js` file: + +```javascript +#!/usr/bin/env node +'use strict'; + +const { ArgumentParser } = require('argparse'); +const { version } = require('./package.json'); + +const parser = new ArgumentParser({ + description: 'Argparse example' +}); + +parser.add_argument('-v', '--version', { action: 'version', version }); +parser.add_argument('-f', '--foo', { help: 'foo bar' }); +parser.add_argument('-b', '--bar', { help: 'bar foo' }); +parser.add_argument('--baz', { help: 'baz bar' }); + +console.dir(parser.parse_args()); +``` + +Display help: + +``` +$ ./test.js -h +usage: test.js [-h] [-v] [-f FOO] [-b BAR] [--baz BAZ] + +Argparse example + +optional arguments: + -h, --help show this help message and exit + -v, --version show program's version number and exit + -f FOO, --foo FOO foo bar + -b BAR, --bar BAR bar foo + --baz BAZ baz bar +``` + +Parse arguments: + +``` +$ ./test.js -f=3 --bar=4 --baz 5 +{ foo: '3', bar: '4', baz: '5' } +``` + + +API docs +-------- + +Since this is a port with minimal divergence, there's no separate documentation. +Use original one instead, with notes about difference. + +1. [Original doc](https://docs.python.org/3.9/library/argparse.html). +2. [Original tutorial](https://docs.python.org/3.9/howto/argparse.html). +3. [Difference with python](./doc). + + +argparse for enterprise +----------------------- + +Available as part of the Tidelift Subscription + +The maintainers of argparse and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-argparse?utm_source=npm-argparse&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) diff --git a/libs/events/node_modules/argparse/argparse.js b/libs/events/node_modules/argparse/argparse.js new file mode 100644 index 000000000..2b8c8c631 --- /dev/null +++ b/libs/events/node_modules/argparse/argparse.js @@ -0,0 +1,3707 @@ +// Port of python's argparse module, version 3.9.0: +// https://github.com/python/cpython/blob/v3.9.0rc1/Lib/argparse.py + +'use strict' + +// Copyright (C) 2010-2020 Python Software Foundation. +// Copyright (C) 2020 argparse.js authors + +/* + * Command-line parsing library + * + * This module is an optparse-inspired command-line parsing library that: + * + * - handles both optional and positional arguments + * - produces highly informative usage messages + * - supports parsers that dispatch to sub-parsers + * + * The following is a simple usage example that sums integers from the + * command-line and writes the result to a file:: + * + * parser = argparse.ArgumentParser( + * description='sum the integers at the command line') + * parser.add_argument( + * 'integers', metavar='int', nargs='+', type=int, + * help='an integer to be summed') + * parser.add_argument( + * '--log', default=sys.stdout, type=argparse.FileType('w'), + * help='the file where the sum should be written') + * args = parser.parse_args() + * args.log.write('%s' % sum(args.integers)) + * args.log.close() + * + * The module contains the following public classes: + * + * - ArgumentParser -- The main entry point for command-line parsing. As the + * example above shows, the add_argument() method is used to populate + * the parser with actions for optional and positional arguments. Then + * the parse_args() method is invoked to convert the args at the + * command-line into an object with attributes. + * + * - ArgumentError -- The exception raised by ArgumentParser objects when + * there are errors with the parser's actions. Errors raised while + * parsing the command-line are caught by ArgumentParser and emitted + * as command-line messages. + * + * - FileType -- A factory for defining types of files to be created. As the + * example above shows, instances of FileType are typically passed as + * the type= argument of add_argument() calls. + * + * - Action -- The base class for parser actions. Typically actions are + * selected by passing strings like 'store_true' or 'append_const' to + * the action= argument of add_argument(). However, for greater + * customization of ArgumentParser actions, subclasses of Action may + * be defined and passed as the action= argument. + * + * - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter, + * ArgumentDefaultsHelpFormatter -- Formatter classes which + * may be passed as the formatter_class= argument to the + * ArgumentParser constructor. HelpFormatter is the default, + * RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser + * not to change the formatting for help text, and + * ArgumentDefaultsHelpFormatter adds information about argument defaults + * to the help. + * + * All other classes in this module are considered implementation details. + * (Also note that HelpFormatter and RawDescriptionHelpFormatter are only + * considered public as object names -- the API of the formatter objects is + * still considered an implementation detail.) + */ + +const SUPPRESS = '==SUPPRESS==' + +const OPTIONAL = '?' +const ZERO_OR_MORE = '*' +const ONE_OR_MORE = '+' +const PARSER = 'A...' +const REMAINDER = '...' +const _UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args' + + +// ================================== +// Utility functions used for porting +// ================================== +const assert = require('assert') +const util = require('util') +const fs = require('fs') +const sub = require('./lib/sub') +const path = require('path') +const repr = util.inspect + +function get_argv() { + // omit first argument (which is assumed to be interpreter - `node`, `coffee`, `ts-node`, etc.) + return process.argv.slice(1) +} + +function get_terminal_size() { + return { + columns: +process.env.COLUMNS || process.stdout.columns || 80 + } +} + +function hasattr(object, name) { + return Object.prototype.hasOwnProperty.call(object, name) +} + +function getattr(object, name, value) { + return hasattr(object, name) ? object[name] : value +} + +function setattr(object, name, value) { + object[name] = value +} + +function setdefault(object, name, value) { + if (!hasattr(object, name)) object[name] = value + return object[name] +} + +function delattr(object, name) { + delete object[name] +} + +function range(from, to, step=1) { + // range(10) is equivalent to range(0, 10) + if (arguments.length === 1) [ to, from ] = [ from, 0 ] + if (typeof from !== 'number' || typeof to !== 'number' || typeof step !== 'number') { + throw new TypeError('argument cannot be interpreted as an integer') + } + if (step === 0) throw new TypeError('range() arg 3 must not be zero') + + let result = [] + if (step > 0) { + for (let i = from; i < to; i += step) result.push(i) + } else { + for (let i = from; i > to; i += step) result.push(i) + } + return result +} + +function splitlines(str, keepends = false) { + let result + if (!keepends) { + result = str.split(/\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029]/) + } else { + result = [] + let parts = str.split(/(\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029])/) + for (let i = 0; i < parts.length; i += 2) { + result.push(parts[i] + (i + 1 < parts.length ? parts[i + 1] : '')) + } + } + if (!result[result.length - 1]) result.pop() + return result +} + +function _string_lstrip(string, prefix_chars) { + let idx = 0 + while (idx < string.length && prefix_chars.includes(string[idx])) idx++ + return idx ? string.slice(idx) : string +} + +function _string_split(string, sep, maxsplit) { + let result = string.split(sep) + if (result.length > maxsplit) { + result = result.slice(0, maxsplit).concat([ result.slice(maxsplit).join(sep) ]) + } + return result +} + +function _array_equal(array1, array2) { + if (array1.length !== array2.length) return false + for (let i = 0; i < array1.length; i++) { + if (array1[i] !== array2[i]) return false + } + return true +} + +function _array_remove(array, item) { + let idx = array.indexOf(item) + if (idx === -1) throw new TypeError(sub('%r not in list', item)) + array.splice(idx, 1) +} + +// normalize choices to array; +// this isn't required in python because `in` and `map` operators work with anything, +// but in js dealing with multiple types here is too clunky +function _choices_to_array(choices) { + if (choices === undefined) { + return [] + } else if (Array.isArray(choices)) { + return choices + } else if (choices !== null && typeof choices[Symbol.iterator] === 'function') { + return Array.from(choices) + } else if (typeof choices === 'object' && choices !== null) { + return Object.keys(choices) + } else { + throw new Error(sub('invalid choices value: %r', choices)) + } +} + +// decorator that allows a class to be called without new +function _callable(cls) { + let result = { // object is needed for inferred class name + [cls.name]: function (...args) { + let this_class = new.target === result || !new.target + return Reflect.construct(cls, args, this_class ? cls : new.target) + } + } + result[cls.name].prototype = cls.prototype + // fix default tag for toString, e.g. [object Action] instead of [object Object] + cls.prototype[Symbol.toStringTag] = cls.name + return result[cls.name] +} + +function _alias(object, from, to) { + try { + let name = object.constructor.name + Object.defineProperty(object, from, { + value: util.deprecate(object[to], sub('%s.%s() is renamed to %s.%s()', + name, from, name, to)), + enumerable: false + }) + } catch {} +} + +// decorator that allows snake_case class methods to be called with camelCase and vice versa +function _camelcase_alias(_class) { + for (let name of Object.getOwnPropertyNames(_class.prototype)) { + let camelcase = name.replace(/\w_[a-z]/g, s => s[0] + s[2].toUpperCase()) + if (camelcase !== name) _alias(_class.prototype, camelcase, name) + } + return _class +} + +function _to_legacy_name(key) { + key = key.replace(/\w_[a-z]/g, s => s[0] + s[2].toUpperCase()) + if (key === 'default') key = 'defaultValue' + if (key === 'const') key = 'constant' + return key +} + +function _to_new_name(key) { + if (key === 'defaultValue') key = 'default' + if (key === 'constant') key = 'const' + key = key.replace(/[A-Z]/g, c => '_' + c.toLowerCase()) + return key +} + +// parse options +let no_default = Symbol('no_default_value') +function _parse_opts(args, descriptor) { + function get_name() { + let stack = new Error().stack.split('\n') + .map(x => x.match(/^ at (.*) \(.*\)$/)) + .filter(Boolean) + .map(m => m[1]) + .map(fn => fn.match(/[^ .]*$/)[0]) + + if (stack.length && stack[0] === get_name.name) stack.shift() + if (stack.length && stack[0] === _parse_opts.name) stack.shift() + return stack.length ? stack[0] : '' + } + + args = Array.from(args) + let kwargs = {} + let result = [] + let last_opt = args.length && args[args.length - 1] + + if (typeof last_opt === 'object' && last_opt !== null && !Array.isArray(last_opt) && + (!last_opt.constructor || last_opt.constructor.name === 'Object')) { + kwargs = Object.assign({}, args.pop()) + } + + // LEGACY (v1 compatibility): camelcase + let renames = [] + for (let key of Object.keys(descriptor)) { + let old_name = _to_legacy_name(key) + if (old_name !== key && (old_name in kwargs)) { + if (key in kwargs) { + // default and defaultValue specified at the same time, happens often in old tests + //throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), key)) + } else { + kwargs[key] = kwargs[old_name] + } + renames.push([ old_name, key ]) + delete kwargs[old_name] + } + } + if (renames.length) { + let name = get_name() + deprecate('camelcase_' + name, sub('%s(): following options are renamed: %s', + name, renames.map(([ a, b ]) => sub('%r -> %r', a, b)))) + } + // end + + let missing_positionals = [] + let positional_count = args.length + + for (let [ key, def ] of Object.entries(descriptor)) { + if (key[0] === '*') { + if (key.length > 0 && key[1] === '*') { + // LEGACY (v1 compatibility): camelcase + let renames = [] + for (let key of Object.keys(kwargs)) { + let new_name = _to_new_name(key) + if (new_name !== key && (key in kwargs)) { + if (new_name in kwargs) { + // default and defaultValue specified at the same time, happens often in old tests + //throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), new_name)) + } else { + kwargs[new_name] = kwargs[key] + } + renames.push([ key, new_name ]) + delete kwargs[key] + } + } + if (renames.length) { + let name = get_name() + deprecate('camelcase_' + name, sub('%s(): following options are renamed: %s', + name, renames.map(([ a, b ]) => sub('%r -> %r', a, b)))) + } + // end + result.push(kwargs) + kwargs = {} + } else { + result.push(args) + args = [] + } + } else if (key in kwargs && args.length > 0) { + throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), key)) + } else if (key in kwargs) { + result.push(kwargs[key]) + delete kwargs[key] + } else if (args.length > 0) { + result.push(args.shift()) + } else if (def !== no_default) { + result.push(def) + } else { + missing_positionals.push(key) + } + } + + if (Object.keys(kwargs).length) { + throw new TypeError(sub('%s() got an unexpected keyword argument %r', + get_name(), Object.keys(kwargs)[0])) + } + + if (args.length) { + let from = Object.entries(descriptor).filter(([ k, v ]) => k[0] !== '*' && v !== no_default).length + let to = Object.entries(descriptor).filter(([ k ]) => k[0] !== '*').length + throw new TypeError(sub('%s() takes %s positional argument%s but %s %s given', + get_name(), + from === to ? sub('from %s to %s', from, to) : to, + from === to && to === 1 ? '' : 's', + positional_count, + positional_count === 1 ? 'was' : 'were')) + } + + if (missing_positionals.length) { + let strs = missing_positionals.map(repr) + if (strs.length > 1) strs[strs.length - 1] = 'and ' + strs[strs.length - 1] + let str_joined = strs.join(strs.length === 2 ? '' : ', ') + throw new TypeError(sub('%s() missing %i required positional argument%s: %s', + get_name(), strs.length, strs.length === 1 ? '' : 's', str_joined)) + } + + return result +} + +let _deprecations = {} +function deprecate(id, string) { + _deprecations[id] = _deprecations[id] || util.deprecate(() => {}, string) + _deprecations[id]() +} + + +// ============================= +// Utility functions and classes +// ============================= +function _AttributeHolder(cls = Object) { + /* + * Abstract base class that provides __repr__. + * + * The __repr__ method returns a string in the format:: + * ClassName(attr=name, attr=name, ...) + * The attributes are determined either by a class-level attribute, + * '_kwarg_names', or by inspecting the instance __dict__. + */ + + return class _AttributeHolder extends cls { + [util.inspect.custom]() { + let type_name = this.constructor.name + let arg_strings = [] + let star_args = {} + for (let arg of this._get_args()) { + arg_strings.push(repr(arg)) + } + for (let [ name, value ] of this._get_kwargs()) { + if (/^[a-z_][a-z0-9_$]*$/i.test(name)) { + arg_strings.push(sub('%s=%r', name, value)) + } else { + star_args[name] = value + } + } + if (Object.keys(star_args).length) { + arg_strings.push(sub('**%s', repr(star_args))) + } + return sub('%s(%s)', type_name, arg_strings.join(', ')) + } + + toString() { + return this[util.inspect.custom]() + } + + _get_kwargs() { + return Object.entries(this) + } + + _get_args() { + return [] + } + } +} + + +function _copy_items(items) { + if (items === undefined) { + return [] + } + return items.slice(0) +} + + +// =============== +// Formatting Help +// =============== +const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter { + /* + * Formatter for generating usage messages and argument help strings. + * + * Only the name of this class is considered a public API. All the methods + * provided by the class are considered an implementation detail. + */ + + constructor() { + let [ + prog, + indent_increment, + max_help_position, + width + ] = _parse_opts(arguments, { + prog: no_default, + indent_increment: 2, + max_help_position: 24, + width: undefined + }) + + // default setting for width + if (width === undefined) { + width = get_terminal_size().columns + width -= 2 + } + + this._prog = prog + this._indent_increment = indent_increment + this._max_help_position = Math.min(max_help_position, + Math.max(width - 20, indent_increment * 2)) + this._width = width + + this._current_indent = 0 + this._level = 0 + this._action_max_length = 0 + + this._root_section = this._Section(this, undefined) + this._current_section = this._root_section + + this._whitespace_matcher = /[ \t\n\r\f\v]+/g // equivalent to python /\s+/ with ASCII flag + this._long_break_matcher = /\n\n\n+/g + } + + // =============================== + // Section and indentation methods + // =============================== + _indent() { + this._current_indent += this._indent_increment + this._level += 1 + } + + _dedent() { + this._current_indent -= this._indent_increment + assert(this._current_indent >= 0, 'Indent decreased below 0.') + this._level -= 1 + } + + _add_item(func, args) { + this._current_section.items.push([ func, args ]) + } + + // ======================== + // Message building methods + // ======================== + start_section(heading) { + this._indent() + let section = this._Section(this, this._current_section, heading) + this._add_item(section.format_help.bind(section), []) + this._current_section = section + } + + end_section() { + this._current_section = this._current_section.parent + this._dedent() + } + + add_text(text) { + if (text !== SUPPRESS && text !== undefined) { + this._add_item(this._format_text.bind(this), [text]) + } + } + + add_usage(usage, actions, groups, prefix = undefined) { + if (usage !== SUPPRESS) { + let args = [ usage, actions, groups, prefix ] + this._add_item(this._format_usage.bind(this), args) + } + } + + add_argument(action) { + if (action.help !== SUPPRESS) { + + // find all invocations + let invocations = [this._format_action_invocation(action)] + for (let subaction of this._iter_indented_subactions(action)) { + invocations.push(this._format_action_invocation(subaction)) + } + + // update the maximum item length + let invocation_length = Math.max(...invocations.map(invocation => invocation.length)) + let action_length = invocation_length + this._current_indent + this._action_max_length = Math.max(this._action_max_length, + action_length) + + // add the item to the list + this._add_item(this._format_action.bind(this), [action]) + } + } + + add_arguments(actions) { + for (let action of actions) { + this.add_argument(action) + } + } + + // ======================= + // Help-formatting methods + // ======================= + format_help() { + let help = this._root_section.format_help() + if (help) { + help = help.replace(this._long_break_matcher, '\n\n') + help = help.replace(/^\n+|\n+$/g, '') + '\n' + } + return help + } + + _join_parts(part_strings) { + return part_strings.filter(part => part && part !== SUPPRESS).join('') + } + + _format_usage(usage, actions, groups, prefix) { + if (prefix === undefined) { + prefix = 'usage: ' + } + + // if usage is specified, use that + if (usage !== undefined) { + usage = sub(usage, { prog: this._prog }) + + // if no optionals or positionals are available, usage is just prog + } else if (usage === undefined && !actions.length) { + usage = sub('%(prog)s', { prog: this._prog }) + + // if optionals and positionals are available, calculate usage + } else if (usage === undefined) { + let prog = sub('%(prog)s', { prog: this._prog }) + + // split optionals from positionals + let optionals = [] + let positionals = [] + for (let action of actions) { + if (action.option_strings.length) { + optionals.push(action) + } else { + positionals.push(action) + } + } + + // build full usage string + let action_usage = this._format_actions_usage([].concat(optionals).concat(positionals), groups) + usage = [ prog, action_usage ].map(String).join(' ') + + // wrap the usage parts if it's too long + let text_width = this._width - this._current_indent + if (prefix.length + usage.length > text_width) { + + // break usage into wrappable parts + let part_regexp = /\(.*?\)+(?=\s|$)|\[.*?\]+(?=\s|$)|\S+/g + let opt_usage = this._format_actions_usage(optionals, groups) + let pos_usage = this._format_actions_usage(positionals, groups) + let opt_parts = opt_usage.match(part_regexp) || [] + let pos_parts = pos_usage.match(part_regexp) || [] + assert(opt_parts.join(' ') === opt_usage) + assert(pos_parts.join(' ') === pos_usage) + + // helper for wrapping lines + let get_lines = (parts, indent, prefix = undefined) => { + let lines = [] + let line = [] + let line_len + if (prefix !== undefined) { + line_len = prefix.length - 1 + } else { + line_len = indent.length - 1 + } + for (let part of parts) { + if (line_len + 1 + part.length > text_width && line) { + lines.push(indent + line.join(' ')) + line = [] + line_len = indent.length - 1 + } + line.push(part) + line_len += part.length + 1 + } + if (line.length) { + lines.push(indent + line.join(' ')) + } + if (prefix !== undefined) { + lines[0] = lines[0].slice(indent.length) + } + return lines + } + + let lines + + // if prog is short, follow it with optionals or positionals + if (prefix.length + prog.length <= 0.75 * text_width) { + let indent = ' '.repeat(prefix.length + prog.length + 1) + if (opt_parts.length) { + lines = get_lines([prog].concat(opt_parts), indent, prefix) + lines = lines.concat(get_lines(pos_parts, indent)) + } else if (pos_parts.length) { + lines = get_lines([prog].concat(pos_parts), indent, prefix) + } else { + lines = [prog] + } + + // if prog is long, put it on its own line + } else { + let indent = ' '.repeat(prefix.length) + let parts = [].concat(opt_parts).concat(pos_parts) + lines = get_lines(parts, indent) + if (lines.length > 1) { + lines = [] + lines = lines.concat(get_lines(opt_parts, indent)) + lines = lines.concat(get_lines(pos_parts, indent)) + } + lines = [prog].concat(lines) + } + + // join lines into usage + usage = lines.join('\n') + } + } + + // prefix with 'usage:' + return sub('%s%s\n\n', prefix, usage) + } + + _format_actions_usage(actions, groups) { + // find group indices and identify actions in groups + let group_actions = new Set() + let inserts = {} + for (let group of groups) { + let start = actions.indexOf(group._group_actions[0]) + if (start === -1) { + continue + } else { + let end = start + group._group_actions.length + if (_array_equal(actions.slice(start, end), group._group_actions)) { + for (let action of group._group_actions) { + group_actions.add(action) + } + if (!group.required) { + if (start in inserts) { + inserts[start] += ' [' + } else { + inserts[start] = '[' + } + if (end in inserts) { + inserts[end] += ']' + } else { + inserts[end] = ']' + } + } else { + if (start in inserts) { + inserts[start] += ' (' + } else { + inserts[start] = '(' + } + if (end in inserts) { + inserts[end] += ')' + } else { + inserts[end] = ')' + } + } + for (let i of range(start + 1, end)) { + inserts[i] = '|' + } + } + } + } + + // collect all actions format strings + let parts = [] + for (let [ i, action ] of Object.entries(actions)) { + + // suppressed arguments are marked with None + // remove | separators for suppressed arguments + if (action.help === SUPPRESS) { + parts.push(undefined) + if (inserts[+i] === '|') { + delete inserts[+i] + } else if (inserts[+i + 1] === '|') { + delete inserts[+i + 1] + } + + // produce all arg strings + } else if (!action.option_strings.length) { + let default_value = this._get_default_metavar_for_positional(action) + let part = this._format_args(action, default_value) + + // if it's in a group, strip the outer [] + if (group_actions.has(action)) { + if (part[0] === '[' && part[part.length - 1] === ']') { + part = part.slice(1, -1) + } + } + + // add the action string to the list + parts.push(part) + + // produce the first way to invoke the option in brackets + } else { + let option_string = action.option_strings[0] + let part + + // if the Optional doesn't take a value, format is: + // -s or --long + if (action.nargs === 0) { + part = action.format_usage() + + // if the Optional takes a value, format is: + // -s ARGS or --long ARGS + } else { + let default_value = this._get_default_metavar_for_optional(action) + let args_string = this._format_args(action, default_value) + part = sub('%s %s', option_string, args_string) + } + + // make it look optional if it's not required or in a group + if (!action.required && !group_actions.has(action)) { + part = sub('[%s]', part) + } + + // add the action string to the list + parts.push(part) + } + } + + // insert things at the necessary indices + for (let i of Object.keys(inserts).map(Number).sort((a, b) => b - a)) { + parts.splice(+i, 0, inserts[+i]) + } + + // join all the action items with spaces + let text = parts.filter(Boolean).join(' ') + + // clean up separators for mutually exclusive groups + text = text.replace(/([\[(]) /g, '$1') + text = text.replace(/ ([\])])/g, '$1') + text = text.replace(/[\[(] *[\])]/g, '') + text = text.replace(/\(([^|]*)\)/g, '$1', text) + text = text.trim() + + // return the text + return text + } + + _format_text(text) { + if (text.includes('%(prog)')) { + text = sub(text, { prog: this._prog }) + } + let text_width = Math.max(this._width - this._current_indent, 11) + let indent = ' '.repeat(this._current_indent) + return this._fill_text(text, text_width, indent) + '\n\n' + } + + _format_action(action) { + // determine the required width and the entry label + let help_position = Math.min(this._action_max_length + 2, + this._max_help_position) + let help_width = Math.max(this._width - help_position, 11) + let action_width = help_position - this._current_indent - 2 + let action_header = this._format_action_invocation(action) + let indent_first + + // no help; start on same line and add a final newline + if (!action.help) { + let tup = [ this._current_indent, '', action_header ] + action_header = sub('%*s%s\n', ...tup) + + // short action name; start on the same line and pad two spaces + } else if (action_header.length <= action_width) { + let tup = [ this._current_indent, '', action_width, action_header ] + action_header = sub('%*s%-*s ', ...tup) + indent_first = 0 + + // long action name; start on the next line + } else { + let tup = [ this._current_indent, '', action_header ] + action_header = sub('%*s%s\n', ...tup) + indent_first = help_position + } + + // collect the pieces of the action help + let parts = [action_header] + + // if there was help for the action, add lines of help text + if (action.help) { + let help_text = this._expand_help(action) + let help_lines = this._split_lines(help_text, help_width) + parts.push(sub('%*s%s\n', indent_first, '', help_lines[0])) + for (let line of help_lines.slice(1)) { + parts.push(sub('%*s%s\n', help_position, '', line)) + } + + // or add a newline if the description doesn't end with one + } else if (!action_header.endsWith('\n')) { + parts.push('\n') + } + + // if there are any sub-actions, add their help as well + for (let subaction of this._iter_indented_subactions(action)) { + parts.push(this._format_action(subaction)) + } + + // return a single string + return this._join_parts(parts) + } + + _format_action_invocation(action) { + if (!action.option_strings.length) { + let default_value = this._get_default_metavar_for_positional(action) + let metavar = this._metavar_formatter(action, default_value)(1)[0] + return metavar + + } else { + let parts = [] + + // if the Optional doesn't take a value, format is: + // -s, --long + if (action.nargs === 0) { + parts = parts.concat(action.option_strings) + + // if the Optional takes a value, format is: + // -s ARGS, --long ARGS + } else { + let default_value = this._get_default_metavar_for_optional(action) + let args_string = this._format_args(action, default_value) + for (let option_string of action.option_strings) { + parts.push(sub('%s %s', option_string, args_string)) + } + } + + return parts.join(', ') + } + } + + _metavar_formatter(action, default_metavar) { + let result + if (action.metavar !== undefined) { + result = action.metavar + } else if (action.choices !== undefined) { + let choice_strs = _choices_to_array(action.choices).map(String) + result = sub('{%s}', choice_strs.join(',')) + } else { + result = default_metavar + } + + function format(tuple_size) { + if (Array.isArray(result)) { + return result + } else { + return Array(tuple_size).fill(result) + } + } + return format + } + + _format_args(action, default_metavar) { + let get_metavar = this._metavar_formatter(action, default_metavar) + let result + if (action.nargs === undefined) { + result = sub('%s', ...get_metavar(1)) + } else if (action.nargs === OPTIONAL) { + result = sub('[%s]', ...get_metavar(1)) + } else if (action.nargs === ZERO_OR_MORE) { + let metavar = get_metavar(1) + if (metavar.length === 2) { + result = sub('[%s [%s ...]]', ...metavar) + } else { + result = sub('[%s ...]', ...metavar) + } + } else if (action.nargs === ONE_OR_MORE) { + result = sub('%s [%s ...]', ...get_metavar(2)) + } else if (action.nargs === REMAINDER) { + result = '...' + } else if (action.nargs === PARSER) { + result = sub('%s ...', ...get_metavar(1)) + } else if (action.nargs === SUPPRESS) { + result = '' + } else { + let formats + try { + formats = range(action.nargs).map(() => '%s') + } catch (err) { + throw new TypeError('invalid nargs value') + } + result = sub(formats.join(' '), ...get_metavar(action.nargs)) + } + return result + } + + _expand_help(action) { + let params = Object.assign({ prog: this._prog }, action) + for (let name of Object.keys(params)) { + if (params[name] === SUPPRESS) { + delete params[name] + } + } + for (let name of Object.keys(params)) { + if (params[name] && params[name].name) { + params[name] = params[name].name + } + } + if (params.choices !== undefined) { + let choices_str = _choices_to_array(params.choices).map(String).join(', ') + params.choices = choices_str + } + // LEGACY (v1 compatibility): camelcase + for (let key of Object.keys(params)) { + let old_name = _to_legacy_name(key) + if (old_name !== key) { + params[old_name] = params[key] + } + } + // end + return sub(this._get_help_string(action), params) + } + + * _iter_indented_subactions(action) { + if (typeof action._get_subactions === 'function') { + this._indent() + yield* action._get_subactions() + this._dedent() + } + } + + _split_lines(text, width) { + text = text.replace(this._whitespace_matcher, ' ').trim() + // The textwrap module is used only for formatting help. + // Delay its import for speeding up the common usage of argparse. + let textwrap = require('./lib/textwrap') + return textwrap.wrap(text, { width }) + } + + _fill_text(text, width, indent) { + text = text.replace(this._whitespace_matcher, ' ').trim() + let textwrap = require('./lib/textwrap') + return textwrap.fill(text, { width, + initial_indent: indent, + subsequent_indent: indent }) + } + + _get_help_string(action) { + return action.help + } + + _get_default_metavar_for_optional(action) { + return action.dest.toUpperCase() + } + + _get_default_metavar_for_positional(action) { + return action.dest + } +})) + +HelpFormatter.prototype._Section = _callable(class _Section { + + constructor(formatter, parent, heading = undefined) { + this.formatter = formatter + this.parent = parent + this.heading = heading + this.items = [] + } + + format_help() { + // format the indented section + if (this.parent !== undefined) { + this.formatter._indent() + } + let item_help = this.formatter._join_parts(this.items.map(([ func, args ]) => func.apply(null, args))) + if (this.parent !== undefined) { + this.formatter._dedent() + } + + // return nothing if the section was empty + if (!item_help) { + return '' + } + + // add the heading if the section was non-empty + let heading + if (this.heading !== SUPPRESS && this.heading !== undefined) { + let current_indent = this.formatter._current_indent + heading = sub('%*s%s:\n', current_indent, '', this.heading) + } else { + heading = '' + } + + // join the section-initial newline, the heading and the help + return this.formatter._join_parts(['\n', heading, item_help, '\n']) + } +}) + + +const RawDescriptionHelpFormatter = _camelcase_alias(_callable(class RawDescriptionHelpFormatter extends HelpFormatter { + /* + * Help message formatter which retains any formatting in descriptions. + * + * Only the name of this class is considered a public API. All the methods + * provided by the class are considered an implementation detail. + */ + + _fill_text(text, width, indent) { + return splitlines(text, true).map(line => indent + line).join('') + } +})) + + +const RawTextHelpFormatter = _camelcase_alias(_callable(class RawTextHelpFormatter extends RawDescriptionHelpFormatter { + /* + * Help message formatter which retains formatting of all help text. + * + * Only the name of this class is considered a public API. All the methods + * provided by the class are considered an implementation detail. + */ + + _split_lines(text/*, width*/) { + return splitlines(text) + } +})) + + +const ArgumentDefaultsHelpFormatter = _camelcase_alias(_callable(class ArgumentDefaultsHelpFormatter extends HelpFormatter { + /* + * Help message formatter which adds default values to argument help. + * + * Only the name of this class is considered a public API. All the methods + * provided by the class are considered an implementation detail. + */ + + _get_help_string(action) { + let help = action.help + // LEGACY (v1 compatibility): additional check for defaultValue needed + if (!action.help.includes('%(default)') && !action.help.includes('%(defaultValue)')) { + if (action.default !== SUPPRESS) { + let defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] + if (action.option_strings.length || defaulting_nargs.includes(action.nargs)) { + help += ' (default: %(default)s)' + } + } + } + return help + } +})) + + +const MetavarTypeHelpFormatter = _camelcase_alias(_callable(class MetavarTypeHelpFormatter extends HelpFormatter { + /* + * Help message formatter which uses the argument 'type' as the default + * metavar value (instead of the argument 'dest') + * + * Only the name of this class is considered a public API. All the methods + * provided by the class are considered an implementation detail. + */ + + _get_default_metavar_for_optional(action) { + return typeof action.type === 'function' ? action.type.name : action.type + } + + _get_default_metavar_for_positional(action) { + return typeof action.type === 'function' ? action.type.name : action.type + } +})) + + +// ===================== +// Options and Arguments +// ===================== +function _get_action_name(argument) { + if (argument === undefined) { + return undefined + } else if (argument.option_strings.length) { + return argument.option_strings.join('/') + } else if (![ undefined, SUPPRESS ].includes(argument.metavar)) { + return argument.metavar + } else if (![ undefined, SUPPRESS ].includes(argument.dest)) { + return argument.dest + } else { + return undefined + } +} + + +const ArgumentError = _callable(class ArgumentError extends Error { + /* + * An error from creating or using an argument (optional or positional). + * + * The string value of this exception is the message, augmented with + * information about the argument that caused it. + */ + + constructor(argument, message) { + super() + this.name = 'ArgumentError' + this._argument_name = _get_action_name(argument) + this._message = message + this.message = this.str() + } + + str() { + let format + if (this._argument_name === undefined) { + format = '%(message)s' + } else { + format = 'argument %(argument_name)s: %(message)s' + } + return sub(format, { message: this._message, + argument_name: this._argument_name }) + } +}) + + +const ArgumentTypeError = _callable(class ArgumentTypeError extends Error { + /* + * An error from trying to convert a command line string to a type. + */ + + constructor(message) { + super(message) + this.name = 'ArgumentTypeError' + } +}) + + +// ============== +// Action classes +// ============== +const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(Function) { + /* + * Information about how to convert command line strings to Python objects. + * + * Action objects are used by an ArgumentParser to represent the information + * needed to parse a single argument from one or more strings from the + * command line. The keyword arguments to the Action constructor are also + * all attributes of Action instances. + * + * Keyword Arguments: + * + * - option_strings -- A list of command-line option strings which + * should be associated with this action. + * + * - dest -- The name of the attribute to hold the created object(s) + * + * - nargs -- The number of command-line arguments that should be + * consumed. By default, one argument will be consumed and a single + * value will be produced. Other values include: + * - N (an integer) consumes N arguments (and produces a list) + * - '?' consumes zero or one arguments + * - '*' consumes zero or more arguments (and produces a list) + * - '+' consumes one or more arguments (and produces a list) + * Note that the difference between the default and nargs=1 is that + * with the default, a single value will be produced, while with + * nargs=1, a list containing a single value will be produced. + * + * - const -- The value to be produced if the option is specified and the + * option uses an action that takes no values. + * + * - default -- The value to be produced if the option is not specified. + * + * - type -- A callable that accepts a single string argument, and + * returns the converted value. The standard Python types str, int, + * float, and complex are useful examples of such callables. If None, + * str is used. + * + * - choices -- A container of values that should be allowed. If not None, + * after a command-line argument has been converted to the appropriate + * type, an exception will be raised if it is not a member of this + * collection. + * + * - required -- True if the action must always be specified at the + * command line. This is only meaningful for optional command-line + * arguments. + * + * - help -- The help string describing the argument. + * + * - metavar -- The name to be used for the option's argument with the + * help string. If None, the 'dest' value will be used as the name. + */ + + constructor() { + let [ + option_strings, + dest, + nargs, + const_value, + default_value, + type, + choices, + required, + help, + metavar + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: no_default, + nargs: undefined, + const: undefined, + default: undefined, + type: undefined, + choices: undefined, + required: false, + help: undefined, + metavar: undefined + }) + + // when this class is called as a function, redirect it to .call() method of itself + super('return arguments.callee.call.apply(arguments.callee, arguments)') + + this.option_strings = option_strings + this.dest = dest + this.nargs = nargs + this.const = const_value + this.default = default_value + this.type = type + this.choices = choices + this.required = required + this.help = help + this.metavar = metavar + } + + _get_kwargs() { + let names = [ + 'option_strings', + 'dest', + 'nargs', + 'const', + 'default', + 'type', + 'choices', + 'help', + 'metavar' + ] + return names.map(name => [ name, getattr(this, name) ]) + } + + format_usage() { + return this.option_strings[0] + } + + call(/*parser, namespace, values, option_string = undefined*/) { + throw new Error('.call() not defined') + } +})) + + +const BooleanOptionalAction = _camelcase_alias(_callable(class BooleanOptionalAction extends Action { + + constructor() { + let [ + option_strings, + dest, + default_value, + type, + choices, + required, + help, + metavar + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: no_default, + default: undefined, + type: undefined, + choices: undefined, + required: false, + help: undefined, + metavar: undefined + }) + + let _option_strings = [] + for (let option_string of option_strings) { + _option_strings.push(option_string) + + if (option_string.startsWith('--')) { + option_string = '--no-' + option_string.slice(2) + _option_strings.push(option_string) + } + } + + if (help !== undefined && default_value !== undefined) { + help += ` (default: ${default_value})` + } + + super({ + option_strings: _option_strings, + dest, + nargs: 0, + default: default_value, + type, + choices, + required, + help, + metavar + }) + } + + call(parser, namespace, values, option_string = undefined) { + if (this.option_strings.includes(option_string)) { + setattr(namespace, this.dest, !option_string.startsWith('--no-')) + } + } + + format_usage() { + return this.option_strings.join(' | ') + } +})) + + +const _StoreAction = _callable(class _StoreAction extends Action { + + constructor() { + let [ + option_strings, + dest, + nargs, + const_value, + default_value, + type, + choices, + required, + help, + metavar + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: no_default, + nargs: undefined, + const: undefined, + default: undefined, + type: undefined, + choices: undefined, + required: false, + help: undefined, + metavar: undefined + }) + + if (nargs === 0) { + throw new TypeError('nargs for store actions must be != 0; if you ' + + 'have nothing to store, actions such as store ' + + 'true or store const may be more appropriate') + } + if (const_value !== undefined && nargs !== OPTIONAL) { + throw new TypeError(sub('nargs must be %r to supply const', OPTIONAL)) + } + super({ + option_strings, + dest, + nargs, + const: const_value, + default: default_value, + type, + choices, + required, + help, + metavar + }) + } + + call(parser, namespace, values/*, option_string = undefined*/) { + setattr(namespace, this.dest, values) + } +}) + + +const _StoreConstAction = _callable(class _StoreConstAction extends Action { + + constructor() { + let [ + option_strings, + dest, + const_value, + default_value, + required, + help + //, metavar + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: no_default, + const: no_default, + default: undefined, + required: false, + help: undefined, + metavar: undefined + }) + + super({ + option_strings, + dest, + nargs: 0, + const: const_value, + default: default_value, + required, + help + }) + } + + call(parser, namespace/*, values, option_string = undefined*/) { + setattr(namespace, this.dest, this.const) + } +}) + + +const _StoreTrueAction = _callable(class _StoreTrueAction extends _StoreConstAction { + + constructor() { + let [ + option_strings, + dest, + default_value, + required, + help + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: no_default, + default: false, + required: false, + help: undefined + }) + + super({ + option_strings, + dest, + const: true, + default: default_value, + required, + help + }) + } +}) + + +const _StoreFalseAction = _callable(class _StoreFalseAction extends _StoreConstAction { + + constructor() { + let [ + option_strings, + dest, + default_value, + required, + help + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: no_default, + default: true, + required: false, + help: undefined + }) + + super({ + option_strings, + dest, + const: false, + default: default_value, + required, + help + }) + } +}) + + +const _AppendAction = _callable(class _AppendAction extends Action { + + constructor() { + let [ + option_strings, + dest, + nargs, + const_value, + default_value, + type, + choices, + required, + help, + metavar + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: no_default, + nargs: undefined, + const: undefined, + default: undefined, + type: undefined, + choices: undefined, + required: false, + help: undefined, + metavar: undefined + }) + + if (nargs === 0) { + throw new TypeError('nargs for append actions must be != 0; if arg ' + + 'strings are not supplying the value to append, ' + + 'the append const action may be more appropriate') + } + if (const_value !== undefined && nargs !== OPTIONAL) { + throw new TypeError(sub('nargs must be %r to supply const', OPTIONAL)) + } + super({ + option_strings, + dest, + nargs, + const: const_value, + default: default_value, + type, + choices, + required, + help, + metavar + }) + } + + call(parser, namespace, values/*, option_string = undefined*/) { + let items = getattr(namespace, this.dest, undefined) + items = _copy_items(items) + items.push(values) + setattr(namespace, this.dest, items) + } +}) + + +const _AppendConstAction = _callable(class _AppendConstAction extends Action { + + constructor() { + let [ + option_strings, + dest, + const_value, + default_value, + required, + help, + metavar + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: no_default, + const: no_default, + default: undefined, + required: false, + help: undefined, + metavar: undefined + }) + + super({ + option_strings, + dest, + nargs: 0, + const: const_value, + default: default_value, + required, + help, + metavar + }) + } + + call(parser, namespace/*, values, option_string = undefined*/) { + let items = getattr(namespace, this.dest, undefined) + items = _copy_items(items) + items.push(this.const) + setattr(namespace, this.dest, items) + } +}) + + +const _CountAction = _callable(class _CountAction extends Action { + + constructor() { + let [ + option_strings, + dest, + default_value, + required, + help + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: no_default, + default: undefined, + required: false, + help: undefined + }) + + super({ + option_strings, + dest, + nargs: 0, + default: default_value, + required, + help + }) + } + + call(parser, namespace/*, values, option_string = undefined*/) { + let count = getattr(namespace, this.dest, undefined) + if (count === undefined) { + count = 0 + } + setattr(namespace, this.dest, count + 1) + } +}) + + +const _HelpAction = _callable(class _HelpAction extends Action { + + constructor() { + let [ + option_strings, + dest, + default_value, + help + ] = _parse_opts(arguments, { + option_strings: no_default, + dest: SUPPRESS, + default: SUPPRESS, + help: undefined + }) + + super({ + option_strings, + dest, + default: default_value, + nargs: 0, + help + }) + } + + call(parser/*, namespace, values, option_string = undefined*/) { + parser.print_help() + parser.exit() + } +}) + + +const _VersionAction = _callable(class _VersionAction extends Action { + + constructor() { + let [ + option_strings, + version, + dest, + default_value, + help + ] = _parse_opts(arguments, { + option_strings: no_default, + version: undefined, + dest: SUPPRESS, + default: SUPPRESS, + help: "show program's version number and exit" + }) + + super({ + option_strings, + dest, + default: default_value, + nargs: 0, + help + }) + this.version = version + } + + call(parser/*, namespace, values, option_string = undefined*/) { + let version = this.version + if (version === undefined) { + version = parser.version + } + let formatter = parser._get_formatter() + formatter.add_text(version) + parser._print_message(formatter.format_help(), process.stdout) + parser.exit() + } +}) + + +const _SubParsersAction = _camelcase_alias(_callable(class _SubParsersAction extends Action { + + constructor() { + let [ + option_strings, + prog, + parser_class, + dest, + required, + help, + metavar + ] = _parse_opts(arguments, { + option_strings: no_default, + prog: no_default, + parser_class: no_default, + dest: SUPPRESS, + required: false, + help: undefined, + metavar: undefined + }) + + let name_parser_map = {} + + super({ + option_strings, + dest, + nargs: PARSER, + choices: name_parser_map, + required, + help, + metavar + }) + + this._prog_prefix = prog + this._parser_class = parser_class + this._name_parser_map = name_parser_map + this._choices_actions = [] + } + + add_parser() { + let [ + name, + kwargs + ] = _parse_opts(arguments, { + name: no_default, + '**kwargs': no_default + }) + + // set prog from the existing prefix + if (kwargs.prog === undefined) { + kwargs.prog = sub('%s %s', this._prog_prefix, name) + } + + let aliases = getattr(kwargs, 'aliases', []) + delete kwargs.aliases + + // create a pseudo-action to hold the choice help + if ('help' in kwargs) { + let help = kwargs.help + delete kwargs.help + let choice_action = this._ChoicesPseudoAction(name, aliases, help) + this._choices_actions.push(choice_action) + } + + // create the parser and add it to the map + let parser = new this._parser_class(kwargs) + this._name_parser_map[name] = parser + + // make parser available under aliases also + for (let alias of aliases) { + this._name_parser_map[alias] = parser + } + + return parser + } + + _get_subactions() { + return this._choices_actions + } + + call(parser, namespace, values/*, option_string = undefined*/) { + let parser_name = values[0] + let arg_strings = values.slice(1) + + // set the parser name if requested + if (this.dest !== SUPPRESS) { + setattr(namespace, this.dest, parser_name) + } + + // select the parser + if (hasattr(this._name_parser_map, parser_name)) { + parser = this._name_parser_map[parser_name] + } else { + let args = {parser_name, + choices: this._name_parser_map.join(', ')} + let msg = sub('unknown parser %(parser_name)r (choices: %(choices)s)', args) + throw new ArgumentError(this, msg) + } + + // parse all the remaining options into the namespace + // store any unrecognized options on the object, so that the top + // level parser can decide what to do with them + + // In case this subparser defines new defaults, we parse them + // in a new namespace object and then update the original + // namespace for the relevant parts. + let subnamespace + [ subnamespace, arg_strings ] = parser.parse_known_args(arg_strings, undefined) + for (let [ key, value ] of Object.entries(subnamespace)) { + setattr(namespace, key, value) + } + + if (arg_strings.length) { + setdefault(namespace, _UNRECOGNIZED_ARGS_ATTR, []) + getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).push(...arg_strings) + } + } +})) + + +_SubParsersAction.prototype._ChoicesPseudoAction = _callable(class _ChoicesPseudoAction extends Action { + constructor(name, aliases, help) { + let metavar = name, dest = name + if (aliases.length) { + metavar += sub(' (%s)', aliases.join(', ')) + } + super({ option_strings: [], dest, help, metavar }) + } +}) + + +const _ExtendAction = _callable(class _ExtendAction extends _AppendAction { + call(parser, namespace, values/*, option_string = undefined*/) { + let items = getattr(namespace, this.dest, undefined) + items = _copy_items(items) + items = items.concat(values) + setattr(namespace, this.dest, items) + } +}) + + +// ============== +// Type classes +// ============== +const FileType = _callable(class FileType extends Function { + /* + * Factory for creating file object types + * + * Instances of FileType are typically passed as type= arguments to the + * ArgumentParser add_argument() method. + * + * Keyword Arguments: + * - mode -- A string indicating how the file is to be opened. Accepts the + * same values as the builtin open() function. + * - bufsize -- The file's desired buffer size. Accepts the same values as + * the builtin open() function. + * - encoding -- The file's encoding. Accepts the same values as the + * builtin open() function. + * - errors -- A string indicating how encoding and decoding errors are to + * be handled. Accepts the same value as the builtin open() function. + */ + + constructor() { + let [ + flags, + encoding, + mode, + autoClose, + emitClose, + start, + end, + highWaterMark, + fs + ] = _parse_opts(arguments, { + flags: 'r', + encoding: undefined, + mode: undefined, // 0o666 + autoClose: undefined, // true + emitClose: undefined, // false + start: undefined, // 0 + end: undefined, // Infinity + highWaterMark: undefined, // 64 * 1024 + fs: undefined + }) + + // when this class is called as a function, redirect it to .call() method of itself + super('return arguments.callee.call.apply(arguments.callee, arguments)') + + Object.defineProperty(this, 'name', { + get() { + return sub('FileType(%r)', flags) + } + }) + this._flags = flags + this._options = {} + if (encoding !== undefined) this._options.encoding = encoding + if (mode !== undefined) this._options.mode = mode + if (autoClose !== undefined) this._options.autoClose = autoClose + if (emitClose !== undefined) this._options.emitClose = emitClose + if (start !== undefined) this._options.start = start + if (end !== undefined) this._options.end = end + if (highWaterMark !== undefined) this._options.highWaterMark = highWaterMark + if (fs !== undefined) this._options.fs = fs + } + + call(string) { + // the special argument "-" means sys.std{in,out} + if (string === '-') { + if (this._flags.includes('r')) { + return process.stdin + } else if (this._flags.includes('w')) { + return process.stdout + } else { + let msg = sub('argument "-" with mode %r', this._flags) + throw new TypeError(msg) + } + } + + // all other arguments are used as file names + let fd + try { + fd = fs.openSync(string, this._flags, this._options.mode) + } catch (e) { + let args = { filename: string, error: e.message } + let message = "can't open '%(filename)s': %(error)s" + throw new ArgumentTypeError(sub(message, args)) + } + + let options = Object.assign({ fd, flags: this._flags }, this._options) + if (this._flags.includes('r')) { + return fs.createReadStream(undefined, options) + } else if (this._flags.includes('w')) { + return fs.createWriteStream(undefined, options) + } else { + let msg = sub('argument "%s" with mode %r', string, this._flags) + throw new TypeError(msg) + } + } + + [util.inspect.custom]() { + let args = [ this._flags ] + let kwargs = Object.entries(this._options).map(([ k, v ]) => { + if (k === 'mode') v = { value: v, [util.inspect.custom]() { return '0o' + this.value.toString(8) } } + return [ k, v ] + }) + let args_str = [] + .concat(args.filter(arg => arg !== -1).map(repr)) + .concat(kwargs.filter(([/*kw*/, arg]) => arg !== undefined) + .map(([kw, arg]) => sub('%s=%r', kw, arg))) + .join(', ') + return sub('%s(%s)', this.constructor.name, args_str) + } + + toString() { + return this[util.inspect.custom]() + } +}) + +// =========================== +// Optional and Positional Parsing +// =========================== +const Namespace = _callable(class Namespace extends _AttributeHolder() { + /* + * Simple object for storing attributes. + * + * Implements equality by attribute names and values, and provides a simple + * string representation. + */ + + constructor(options = {}) { + super() + Object.assign(this, options) + } +}) + +// unset string tag to mimic plain object +Namespace.prototype[Symbol.toStringTag] = undefined + + +const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer { + + constructor() { + let [ + description, + prefix_chars, + argument_default, + conflict_handler + ] = _parse_opts(arguments, { + description: no_default, + prefix_chars: no_default, + argument_default: no_default, + conflict_handler: no_default + }) + + this.description = description + this.argument_default = argument_default + this.prefix_chars = prefix_chars + this.conflict_handler = conflict_handler + + // set up registries + this._registries = {} + + // register actions + this.register('action', undefined, _StoreAction) + this.register('action', 'store', _StoreAction) + this.register('action', 'store_const', _StoreConstAction) + this.register('action', 'store_true', _StoreTrueAction) + this.register('action', 'store_false', _StoreFalseAction) + this.register('action', 'append', _AppendAction) + this.register('action', 'append_const', _AppendConstAction) + this.register('action', 'count', _CountAction) + this.register('action', 'help', _HelpAction) + this.register('action', 'version', _VersionAction) + this.register('action', 'parsers', _SubParsersAction) + this.register('action', 'extend', _ExtendAction) + // LEGACY (v1 compatibility): camelcase variants + ;[ 'storeConst', 'storeTrue', 'storeFalse', 'appendConst' ].forEach(old_name => { + let new_name = _to_new_name(old_name) + this.register('action', old_name, util.deprecate(this._registry_get('action', new_name), + sub('{action: "%s"} is renamed to {action: "%s"}', old_name, new_name))) + }) + // end + + // raise an exception if the conflict handler is invalid + this._get_handler() + + // action storage + this._actions = [] + this._option_string_actions = {} + + // groups + this._action_groups = [] + this._mutually_exclusive_groups = [] + + // defaults storage + this._defaults = {} + + // determines whether an "option" looks like a negative number + this._negative_number_matcher = /^-\d+$|^-\d*\.\d+$/ + + // whether or not there are any optionals that look like negative + // numbers -- uses a list so it can be shared and edited + this._has_negative_number_optionals = [] + } + + // ==================== + // Registration methods + // ==================== + register(registry_name, value, object) { + let registry = setdefault(this._registries, registry_name, {}) + registry[value] = object + } + + _registry_get(registry_name, value, default_value = undefined) { + return getattr(this._registries[registry_name], value, default_value) + } + + // ================================== + // Namespace default accessor methods + // ================================== + set_defaults(kwargs) { + Object.assign(this._defaults, kwargs) + + // if these defaults match any existing arguments, replace + // the previous default on the object with the new one + for (let action of this._actions) { + if (action.dest in kwargs) { + action.default = kwargs[action.dest] + } + } + } + + get_default(dest) { + for (let action of this._actions) { + if (action.dest === dest && action.default !== undefined) { + return action.default + } + } + return this._defaults[dest] + } + + + // ======================= + // Adding argument actions + // ======================= + add_argument() { + /* + * add_argument(dest, ..., name=value, ...) + * add_argument(option_string, option_string, ..., name=value, ...) + */ + let [ + args, + kwargs + ] = _parse_opts(arguments, { + '*args': no_default, + '**kwargs': no_default + }) + // LEGACY (v1 compatibility), old-style add_argument([ args ], { options }) + if (args.length === 1 && Array.isArray(args[0])) { + args = args[0] + deprecate('argument-array', + sub('use add_argument(%(args)s, {...}) instead of add_argument([ %(args)s ], { ... })', { + args: args.map(repr).join(', ') + })) + } + // end + + // if no positional args are supplied or only one is supplied and + // it doesn't look like an option string, parse a positional + // argument + let chars = this.prefix_chars + if (!args.length || args.length === 1 && !chars.includes(args[0][0])) { + if (args.length && 'dest' in kwargs) { + throw new TypeError('dest supplied twice for positional argument') + } + kwargs = this._get_positional_kwargs(...args, kwargs) + + // otherwise, we're adding an optional argument + } else { + kwargs = this._get_optional_kwargs(...args, kwargs) + } + + // if no default was supplied, use the parser-level default + if (!('default' in kwargs)) { + let dest = kwargs.dest + if (dest in this._defaults) { + kwargs.default = this._defaults[dest] + } else if (this.argument_default !== undefined) { + kwargs.default = this.argument_default + } + } + + // create the action object, and add it to the parser + let action_class = this._pop_action_class(kwargs) + if (typeof action_class !== 'function') { + throw new TypeError(sub('unknown action "%s"', action_class)) + } + // eslint-disable-next-line new-cap + let action = new action_class(kwargs) + + // raise an error if the action type is not callable + let type_func = this._registry_get('type', action.type, action.type) + if (typeof type_func !== 'function') { + throw new TypeError(sub('%r is not callable', type_func)) + } + + if (type_func === FileType) { + throw new TypeError(sub('%r is a FileType class object, instance of it' + + ' must be passed', type_func)) + } + + // raise an error if the metavar does not match the type + if ('_get_formatter' in this) { + try { + this._get_formatter()._format_args(action, undefined) + } catch (err) { + // check for 'invalid nargs value' is an artifact of TypeError and ValueError in js being the same + if (err instanceof TypeError && err.message !== 'invalid nargs value') { + throw new TypeError('length of metavar tuple does not match nargs') + } else { + throw err + } + } + } + + return this._add_action(action) + } + + add_argument_group() { + let group = _ArgumentGroup(this, ...arguments) + this._action_groups.push(group) + return group + } + + add_mutually_exclusive_group() { + // eslint-disable-next-line no-use-before-define + let group = _MutuallyExclusiveGroup(this, ...arguments) + this._mutually_exclusive_groups.push(group) + return group + } + + _add_action(action) { + // resolve any conflicts + this._check_conflict(action) + + // add to actions list + this._actions.push(action) + action.container = this + + // index the action by any option strings it has + for (let option_string of action.option_strings) { + this._option_string_actions[option_string] = action + } + + // set the flag if any option strings look like negative numbers + for (let option_string of action.option_strings) { + if (this._negative_number_matcher.test(option_string)) { + if (!this._has_negative_number_optionals.length) { + this._has_negative_number_optionals.push(true) + } + } + } + + // return the created action + return action + } + + _remove_action(action) { + _array_remove(this._actions, action) + } + + _add_container_actions(container) { + // collect groups by titles + let title_group_map = {} + for (let group of this._action_groups) { + if (group.title in title_group_map) { + let msg = 'cannot merge actions - two groups are named %r' + throw new TypeError(sub(msg, group.title)) + } + title_group_map[group.title] = group + } + + // map each action to its group + let group_map = new Map() + for (let group of container._action_groups) { + + // if a group with the title exists, use that, otherwise + // create a new group matching the container's group + if (!(group.title in title_group_map)) { + title_group_map[group.title] = this.add_argument_group({ + title: group.title, + description: group.description, + conflict_handler: group.conflict_handler + }) + } + + // map the actions to their new group + for (let action of group._group_actions) { + group_map.set(action, title_group_map[group.title]) + } + } + + // add container's mutually exclusive groups + // NOTE: if add_mutually_exclusive_group ever gains title= and + // description= then this code will need to be expanded as above + for (let group of container._mutually_exclusive_groups) { + let mutex_group = this.add_mutually_exclusive_group({ + required: group.required + }) + + // map the actions to their new mutex group + for (let action of group._group_actions) { + group_map.set(action, mutex_group) + } + } + + // add all actions to this container or their group + for (let action of container._actions) { + group_map.get(action)._add_action(action) + } + } + + _get_positional_kwargs() { + let [ + dest, + kwargs + ] = _parse_opts(arguments, { + dest: no_default, + '**kwargs': no_default + }) + + // make sure required is not specified + if ('required' in kwargs) { + let msg = "'required' is an invalid argument for positionals" + throw new TypeError(msg) + } + + // mark positional arguments as required if at least one is + // always required + if (![OPTIONAL, ZERO_OR_MORE].includes(kwargs.nargs)) { + kwargs.required = true + } + if (kwargs.nargs === ZERO_OR_MORE && !('default' in kwargs)) { + kwargs.required = true + } + + // return the keyword arguments with no option strings + return Object.assign(kwargs, { dest, option_strings: [] }) + } + + _get_optional_kwargs() { + let [ + args, + kwargs + ] = _parse_opts(arguments, { + '*args': no_default, + '**kwargs': no_default + }) + + // determine short and long option strings + let option_strings = [] + let long_option_strings = [] + let option_string + for (option_string of args) { + // error on strings that don't start with an appropriate prefix + if (!this.prefix_chars.includes(option_string[0])) { + let args = {option: option_string, + prefix_chars: this.prefix_chars} + let msg = 'invalid option string %(option)r: ' + + 'must start with a character %(prefix_chars)r' + throw new TypeError(sub(msg, args)) + } + + // strings starting with two prefix characters are long options + option_strings.push(option_string) + if (option_string.length > 1 && this.prefix_chars.includes(option_string[1])) { + long_option_strings.push(option_string) + } + } + + // infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x' + let dest = kwargs.dest + delete kwargs.dest + if (dest === undefined) { + let dest_option_string + if (long_option_strings.length) { + dest_option_string = long_option_strings[0] + } else { + dest_option_string = option_strings[0] + } + dest = _string_lstrip(dest_option_string, this.prefix_chars) + if (!dest) { + let msg = 'dest= is required for options like %r' + throw new TypeError(sub(msg, option_string)) + } + dest = dest.replace(/-/g, '_') + } + + // return the updated keyword arguments + return Object.assign(kwargs, { dest, option_strings }) + } + + _pop_action_class(kwargs, default_value = undefined) { + let action = getattr(kwargs, 'action', default_value) + delete kwargs.action + return this._registry_get('action', action, action) + } + + _get_handler() { + // determine function from conflict handler string + let handler_func_name = sub('_handle_conflict_%s', this.conflict_handler) + if (typeof this[handler_func_name] === 'function') { + return this[handler_func_name] + } else { + let msg = 'invalid conflict_resolution value: %r' + throw new TypeError(sub(msg, this.conflict_handler)) + } + } + + _check_conflict(action) { + + // find all options that conflict with this option + let confl_optionals = [] + for (let option_string of action.option_strings) { + if (hasattr(this._option_string_actions, option_string)) { + let confl_optional = this._option_string_actions[option_string] + confl_optionals.push([ option_string, confl_optional ]) + } + } + + // resolve any conflicts + if (confl_optionals.length) { + let conflict_handler = this._get_handler() + conflict_handler.call(this, action, confl_optionals) + } + } + + _handle_conflict_error(action, conflicting_actions) { + let message = conflicting_actions.length === 1 ? + 'conflicting option string: %s' : + 'conflicting option strings: %s' + let conflict_string = conflicting_actions.map(([ option_string/*, action*/ ]) => option_string).join(', ') + throw new ArgumentError(action, sub(message, conflict_string)) + } + + _handle_conflict_resolve(action, conflicting_actions) { + + // remove all conflicting options + for (let [ option_string, action ] of conflicting_actions) { + + // remove the conflicting option + _array_remove(action.option_strings, option_string) + delete this._option_string_actions[option_string] + + // if the option now has no option string, remove it from the + // container holding it + if (!action.option_strings.length) { + action.container._remove_action(action) + } + } + } +})) + + +const _ArgumentGroup = _callable(class _ArgumentGroup extends _ActionsContainer { + + constructor() { + let [ + container, + title, + description, + kwargs + ] = _parse_opts(arguments, { + container: no_default, + title: undefined, + description: undefined, + '**kwargs': no_default + }) + + // add any missing keyword arguments by checking the container + setdefault(kwargs, 'conflict_handler', container.conflict_handler) + setdefault(kwargs, 'prefix_chars', container.prefix_chars) + setdefault(kwargs, 'argument_default', container.argument_default) + super(Object.assign({ description }, kwargs)) + + // group attributes + this.title = title + this._group_actions = [] + + // share most attributes with the container + this._registries = container._registries + this._actions = container._actions + this._option_string_actions = container._option_string_actions + this._defaults = container._defaults + this._has_negative_number_optionals = + container._has_negative_number_optionals + this._mutually_exclusive_groups = container._mutually_exclusive_groups + } + + _add_action(action) { + action = super._add_action(action) + this._group_actions.push(action) + return action + } + + _remove_action(action) { + super._remove_action(action) + _array_remove(this._group_actions, action) + } +}) + + +const _MutuallyExclusiveGroup = _callable(class _MutuallyExclusiveGroup extends _ArgumentGroup { + + constructor() { + let [ + container, + required + ] = _parse_opts(arguments, { + container: no_default, + required: false + }) + + super(container) + this.required = required + this._container = container + } + + _add_action(action) { + if (action.required) { + let msg = 'mutually exclusive arguments must be optional' + throw new TypeError(msg) + } + action = this._container._add_action(action) + this._group_actions.push(action) + return action + } + + _remove_action(action) { + this._container._remove_action(action) + _array_remove(this._group_actions, action) + } +}) + + +const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _AttributeHolder(_ActionsContainer) { + /* + * Object for parsing command line strings into Python objects. + * + * Keyword Arguments: + * - prog -- The name of the program (default: sys.argv[0]) + * - usage -- A usage message (default: auto-generated from arguments) + * - description -- A description of what the program does + * - epilog -- Text following the argument descriptions + * - parents -- Parsers whose arguments should be copied into this one + * - formatter_class -- HelpFormatter class for printing help messages + * - prefix_chars -- Characters that prefix optional arguments + * - fromfile_prefix_chars -- Characters that prefix files containing + * additional arguments + * - argument_default -- The default value for all arguments + * - conflict_handler -- String indicating how to handle conflicts + * - add_help -- Add a -h/-help option + * - allow_abbrev -- Allow long options to be abbreviated unambiguously + * - exit_on_error -- Determines whether or not ArgumentParser exits with + * error info when an error occurs + */ + + constructor() { + let [ + prog, + usage, + description, + epilog, + parents, + formatter_class, + prefix_chars, + fromfile_prefix_chars, + argument_default, + conflict_handler, + add_help, + allow_abbrev, + exit_on_error, + debug, // LEGACY (v1 compatibility), debug mode + version // LEGACY (v1 compatibility), version + ] = _parse_opts(arguments, { + prog: undefined, + usage: undefined, + description: undefined, + epilog: undefined, + parents: [], + formatter_class: HelpFormatter, + prefix_chars: '-', + fromfile_prefix_chars: undefined, + argument_default: undefined, + conflict_handler: 'error', + add_help: true, + allow_abbrev: true, + exit_on_error: true, + debug: undefined, // LEGACY (v1 compatibility), debug mode + version: undefined // LEGACY (v1 compatibility), version + }) + + // LEGACY (v1 compatibility) + if (debug !== undefined) { + deprecate('debug', + 'The "debug" argument to ArgumentParser is deprecated. Please ' + + 'override ArgumentParser.exit function instead.' + ) + } + + if (version !== undefined) { + deprecate('version', + 'The "version" argument to ArgumentParser is deprecated. Please use ' + + "add_argument(..., { action: 'version', version: 'N', ... }) instead." + ) + } + // end + + super({ + description, + prefix_chars, + argument_default, + conflict_handler + }) + + // default setting for prog + if (prog === undefined) { + prog = path.basename(get_argv()[0] || '') + } + + this.prog = prog + this.usage = usage + this.epilog = epilog + this.formatter_class = formatter_class + this.fromfile_prefix_chars = fromfile_prefix_chars + this.add_help = add_help + this.allow_abbrev = allow_abbrev + this.exit_on_error = exit_on_error + // LEGACY (v1 compatibility), debug mode + this.debug = debug + // end + + this._positionals = this.add_argument_group('positional arguments') + this._optionals = this.add_argument_group('optional arguments') + this._subparsers = undefined + + // register types + function identity(string) { + return string + } + this.register('type', undefined, identity) + this.register('type', null, identity) + this.register('type', 'auto', identity) + this.register('type', 'int', function (x) { + let result = Number(x) + if (!Number.isInteger(result)) { + throw new TypeError(sub('could not convert string to int: %r', x)) + } + return result + }) + this.register('type', 'float', function (x) { + let result = Number(x) + if (isNaN(result)) { + throw new TypeError(sub('could not convert string to float: %r', x)) + } + return result + }) + this.register('type', 'str', String) + // LEGACY (v1 compatibility): custom types + this.register('type', 'string', + util.deprecate(String, 'use {type:"str"} or {type:String} instead of {type:"string"}')) + // end + + // add help argument if necessary + // (using explicit default to override global argument_default) + let default_prefix = prefix_chars.includes('-') ? '-' : prefix_chars[0] + if (this.add_help) { + this.add_argument( + default_prefix + 'h', + default_prefix.repeat(2) + 'help', + { + action: 'help', + default: SUPPRESS, + help: 'show this help message and exit' + } + ) + } + // LEGACY (v1 compatibility), version + if (version) { + this.add_argument( + default_prefix + 'v', + default_prefix.repeat(2) + 'version', + { + action: 'version', + default: SUPPRESS, + version: this.version, + help: "show program's version number and exit" + } + ) + } + // end + + // add parent arguments and defaults + for (let parent of parents) { + this._add_container_actions(parent) + Object.assign(this._defaults, parent._defaults) + } + } + + // ======================= + // Pretty __repr__ methods + // ======================= + _get_kwargs() { + let names = [ + 'prog', + 'usage', + 'description', + 'formatter_class', + 'conflict_handler', + 'add_help' + ] + return names.map(name => [ name, getattr(this, name) ]) + } + + // ================================== + // Optional/Positional adding methods + // ================================== + add_subparsers() { + let [ + kwargs + ] = _parse_opts(arguments, { + '**kwargs': no_default + }) + + if (this._subparsers !== undefined) { + this.error('cannot have multiple subparser arguments') + } + + // add the parser class to the arguments if it's not present + setdefault(kwargs, 'parser_class', this.constructor) + + if ('title' in kwargs || 'description' in kwargs) { + let title = getattr(kwargs, 'title', 'subcommands') + let description = getattr(kwargs, 'description', undefined) + delete kwargs.title + delete kwargs.description + this._subparsers = this.add_argument_group(title, description) + } else { + this._subparsers = this._positionals + } + + // prog defaults to the usage message of this parser, skipping + // optional arguments and with no "usage:" prefix + if (kwargs.prog === undefined) { + let formatter = this._get_formatter() + let positionals = this._get_positional_actions() + let groups = this._mutually_exclusive_groups + formatter.add_usage(this.usage, positionals, groups, '') + kwargs.prog = formatter.format_help().trim() + } + + // create the parsers action and add it to the positionals list + let parsers_class = this._pop_action_class(kwargs, 'parsers') + // eslint-disable-next-line new-cap + let action = new parsers_class(Object.assign({ option_strings: [] }, kwargs)) + this._subparsers._add_action(action) + + // return the created parsers action + return action + } + + _add_action(action) { + if (action.option_strings.length) { + this._optionals._add_action(action) + } else { + this._positionals._add_action(action) + } + return action + } + + _get_optional_actions() { + return this._actions.filter(action => action.option_strings.length) + } + + _get_positional_actions() { + return this._actions.filter(action => !action.option_strings.length) + } + + // ===================================== + // Command line argument parsing methods + // ===================================== + parse_args(args = undefined, namespace = undefined) { + let argv + [ args, argv ] = this.parse_known_args(args, namespace) + if (argv && argv.length > 0) { + let msg = 'unrecognized arguments: %s' + this.error(sub(msg, argv.join(' '))) + } + return args + } + + parse_known_args(args = undefined, namespace = undefined) { + if (args === undefined) { + args = get_argv().slice(1) + } + + // default Namespace built from parser defaults + if (namespace === undefined) { + namespace = new Namespace() + } + + // add any action defaults that aren't present + for (let action of this._actions) { + if (action.dest !== SUPPRESS) { + if (!hasattr(namespace, action.dest)) { + if (action.default !== SUPPRESS) { + setattr(namespace, action.dest, action.default) + } + } + } + } + + // add any parser defaults that aren't present + for (let dest of Object.keys(this._defaults)) { + if (!hasattr(namespace, dest)) { + setattr(namespace, dest, this._defaults[dest]) + } + } + + // parse the arguments and exit if there are any errors + if (this.exit_on_error) { + try { + [ namespace, args ] = this._parse_known_args(args, namespace) + } catch (err) { + if (err instanceof ArgumentError) { + this.error(err.message) + } else { + throw err + } + } + } else { + [ namespace, args ] = this._parse_known_args(args, namespace) + } + + if (hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) { + args = args.concat(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) + delattr(namespace, _UNRECOGNIZED_ARGS_ATTR) + } + + return [ namespace, args ] + } + + _parse_known_args(arg_strings, namespace) { + // replace arg strings that are file references + if (this.fromfile_prefix_chars !== undefined) { + arg_strings = this._read_args_from_files(arg_strings) + } + + // map all mutually exclusive arguments to the other arguments + // they can't occur with + let action_conflicts = new Map() + for (let mutex_group of this._mutually_exclusive_groups) { + let group_actions = mutex_group._group_actions + for (let [ i, mutex_action ] of Object.entries(mutex_group._group_actions)) { + let conflicts = action_conflicts.get(mutex_action) || [] + conflicts = conflicts.concat(group_actions.slice(0, +i)) + conflicts = conflicts.concat(group_actions.slice(+i + 1)) + action_conflicts.set(mutex_action, conflicts) + } + } + + // find all option indices, and determine the arg_string_pattern + // which has an 'O' if there is an option at an index, + // an 'A' if there is an argument, or a '-' if there is a '--' + let option_string_indices = {} + let arg_string_pattern_parts = [] + let arg_strings_iter = Object.entries(arg_strings)[Symbol.iterator]() + for (let [ i, arg_string ] of arg_strings_iter) { + + // all args after -- are non-options + if (arg_string === '--') { + arg_string_pattern_parts.push('-') + for ([ i, arg_string ] of arg_strings_iter) { + arg_string_pattern_parts.push('A') + } + + // otherwise, add the arg to the arg strings + // and note the index if it was an option + } else { + let option_tuple = this._parse_optional(arg_string) + let pattern + if (option_tuple === undefined) { + pattern = 'A' + } else { + option_string_indices[i] = option_tuple + pattern = 'O' + } + arg_string_pattern_parts.push(pattern) + } + } + + // join the pieces together to form the pattern + let arg_strings_pattern = arg_string_pattern_parts.join('') + + // converts arg strings to the appropriate and then takes the action + let seen_actions = new Set() + let seen_non_default_actions = new Set() + let extras + + let take_action = (action, argument_strings, option_string = undefined) => { + seen_actions.add(action) + let argument_values = this._get_values(action, argument_strings) + + // error if this argument is not allowed with other previously + // seen arguments, assuming that actions that use the default + // value don't really count as "present" + if (argument_values !== action.default) { + seen_non_default_actions.add(action) + for (let conflict_action of action_conflicts.get(action) || []) { + if (seen_non_default_actions.has(conflict_action)) { + let msg = 'not allowed with argument %s' + let action_name = _get_action_name(conflict_action) + throw new ArgumentError(action, sub(msg, action_name)) + } + } + } + + // take the action if we didn't receive a SUPPRESS value + // (e.g. from a default) + if (argument_values !== SUPPRESS) { + action(this, namespace, argument_values, option_string) + } + } + + // function to convert arg_strings into an optional action + let consume_optional = start_index => { + + // get the optional identified at this index + let option_tuple = option_string_indices[start_index] + let [ action, option_string, explicit_arg ] = option_tuple + + // identify additional optionals in the same arg string + // (e.g. -xyz is the same as -x -y -z if no args are required) + let action_tuples = [] + let stop + for (;;) { + + // if we found no optional action, skip it + if (action === undefined) { + extras.push(arg_strings[start_index]) + return start_index + 1 + } + + // if there is an explicit argument, try to match the + // optional's string arguments to only this + if (explicit_arg !== undefined) { + let arg_count = this._match_argument(action, 'A') + + // if the action is a single-dash option and takes no + // arguments, try to parse more single-dash options out + // of the tail of the option string + let chars = this.prefix_chars + if (arg_count === 0 && !chars.includes(option_string[1])) { + action_tuples.push([ action, [], option_string ]) + let char = option_string[0] + option_string = char + explicit_arg[0] + let new_explicit_arg = explicit_arg.slice(1) || undefined + let optionals_map = this._option_string_actions + if (hasattr(optionals_map, option_string)) { + action = optionals_map[option_string] + explicit_arg = new_explicit_arg + } else { + let msg = 'ignored explicit argument %r' + throw new ArgumentError(action, sub(msg, explicit_arg)) + } + + // if the action expect exactly one argument, we've + // successfully matched the option; exit the loop + } else if (arg_count === 1) { + stop = start_index + 1 + let args = [ explicit_arg ] + action_tuples.push([ action, args, option_string ]) + break + + // error if a double-dash option did not use the + // explicit argument + } else { + let msg = 'ignored explicit argument %r' + throw new ArgumentError(action, sub(msg, explicit_arg)) + } + + // if there is no explicit argument, try to match the + // optional's string arguments with the following strings + // if successful, exit the loop + } else { + let start = start_index + 1 + let selected_patterns = arg_strings_pattern.slice(start) + let arg_count = this._match_argument(action, selected_patterns) + stop = start + arg_count + let args = arg_strings.slice(start, stop) + action_tuples.push([ action, args, option_string ]) + break + } + } + + // add the Optional to the list and return the index at which + // the Optional's string args stopped + assert(action_tuples.length) + for (let [ action, args, option_string ] of action_tuples) { + take_action(action, args, option_string) + } + return stop + } + + // the list of Positionals left to be parsed; this is modified + // by consume_positionals() + let positionals = this._get_positional_actions() + + // function to convert arg_strings into positional actions + let consume_positionals = start_index => { + // match as many Positionals as possible + let selected_pattern = arg_strings_pattern.slice(start_index) + let arg_counts = this._match_arguments_partial(positionals, selected_pattern) + + // slice off the appropriate arg strings for each Positional + // and add the Positional and its args to the list + for (let i = 0; i < positionals.length && i < arg_counts.length; i++) { + let action = positionals[i] + let arg_count = arg_counts[i] + let args = arg_strings.slice(start_index, start_index + arg_count) + start_index += arg_count + take_action(action, args) + } + + // slice off the Positionals that we just parsed and return the + // index at which the Positionals' string args stopped + positionals = positionals.slice(arg_counts.length) + return start_index + } + + // consume Positionals and Optionals alternately, until we have + // passed the last option string + extras = [] + let start_index = 0 + let max_option_string_index = Math.max(-1, ...Object.keys(option_string_indices).map(Number)) + while (start_index <= max_option_string_index) { + + // consume any Positionals preceding the next option + let next_option_string_index = Math.min( + // eslint-disable-next-line no-loop-func + ...Object.keys(option_string_indices).map(Number).filter(index => index >= start_index) + ) + if (start_index !== next_option_string_index) { + let positionals_end_index = consume_positionals(start_index) + + // only try to parse the next optional if we didn't consume + // the option string during the positionals parsing + if (positionals_end_index > start_index) { + start_index = positionals_end_index + continue + } else { + start_index = positionals_end_index + } + } + + // if we consumed all the positionals we could and we're not + // at the index of an option string, there were extra arguments + if (!(start_index in option_string_indices)) { + let strings = arg_strings.slice(start_index, next_option_string_index) + extras = extras.concat(strings) + start_index = next_option_string_index + } + + // consume the next optional and any arguments for it + start_index = consume_optional(start_index) + } + + // consume any positionals following the last Optional + let stop_index = consume_positionals(start_index) + + // if we didn't consume all the argument strings, there were extras + extras = extras.concat(arg_strings.slice(stop_index)) + + // make sure all required actions were present and also convert + // action defaults which were not given as arguments + let required_actions = [] + for (let action of this._actions) { + if (!seen_actions.has(action)) { + if (action.required) { + required_actions.push(_get_action_name(action)) + } else { + // Convert action default now instead of doing it before + // parsing arguments to avoid calling convert functions + // twice (which may fail) if the argument was given, but + // only if it was defined already in the namespace + if (action.default !== undefined && + typeof action.default === 'string' && + hasattr(namespace, action.dest) && + action.default === getattr(namespace, action.dest)) { + setattr(namespace, action.dest, + this._get_value(action, action.default)) + } + } + } + } + + if (required_actions.length) { + this.error(sub('the following arguments are required: %s', + required_actions.join(', '))) + } + + // make sure all required groups had one option present + for (let group of this._mutually_exclusive_groups) { + if (group.required) { + let no_actions_used = true + for (let action of group._group_actions) { + if (seen_non_default_actions.has(action)) { + no_actions_used = false + break + } + } + + // if no actions were used, report the error + if (no_actions_used) { + let names = group._group_actions + .filter(action => action.help !== SUPPRESS) + .map(action => _get_action_name(action)) + let msg = 'one of the arguments %s is required' + this.error(sub(msg, names.join(' '))) + } + } + } + + // return the updated namespace and the extra arguments + return [ namespace, extras ] + } + + _read_args_from_files(arg_strings) { + // expand arguments referencing files + let new_arg_strings = [] + for (let arg_string of arg_strings) { + + // for regular arguments, just add them back into the list + if (!arg_string || !this.fromfile_prefix_chars.includes(arg_string[0])) { + new_arg_strings.push(arg_string) + + // replace arguments referencing files with the file content + } else { + try { + let args_file = fs.readFileSync(arg_string.slice(1), 'utf8') + let arg_strings = [] + for (let arg_line of splitlines(args_file)) { + for (let arg of this.convert_arg_line_to_args(arg_line)) { + arg_strings.push(arg) + } + } + arg_strings = this._read_args_from_files(arg_strings) + new_arg_strings = new_arg_strings.concat(arg_strings) + } catch (err) { + this.error(err.message) + } + } + } + + // return the modified argument list + return new_arg_strings + } + + convert_arg_line_to_args(arg_line) { + return [arg_line] + } + + _match_argument(action, arg_strings_pattern) { + // match the pattern for this action to the arg strings + let nargs_pattern = this._get_nargs_pattern(action) + let match = arg_strings_pattern.match(new RegExp('^' + nargs_pattern)) + + // raise an exception if we weren't able to find a match + if (match === null) { + let nargs_errors = { + undefined: 'expected one argument', + [OPTIONAL]: 'expected at most one argument', + [ONE_OR_MORE]: 'expected at least one argument' + } + let msg = nargs_errors[action.nargs] + if (msg === undefined) { + msg = sub(action.nargs === 1 ? 'expected %s argument' : 'expected %s arguments', action.nargs) + } + throw new ArgumentError(action, msg) + } + + // return the number of arguments matched + return match[1].length + } + + _match_arguments_partial(actions, arg_strings_pattern) { + // progressively shorten the actions list by slicing off the + // final actions until we find a match + let result = [] + for (let i of range(actions.length, 0, -1)) { + let actions_slice = actions.slice(0, i) + let pattern = actions_slice.map(action => this._get_nargs_pattern(action)).join('') + let match = arg_strings_pattern.match(new RegExp('^' + pattern)) + if (match !== null) { + result = result.concat(match.slice(1).map(string => string.length)) + break + } + } + + // return the list of arg string counts + return result + } + + _parse_optional(arg_string) { + // if it's an empty string, it was meant to be a positional + if (!arg_string) { + return undefined + } + + // if it doesn't start with a prefix, it was meant to be positional + if (!this.prefix_chars.includes(arg_string[0])) { + return undefined + } + + // if the option string is present in the parser, return the action + if (arg_string in this._option_string_actions) { + let action = this._option_string_actions[arg_string] + return [ action, arg_string, undefined ] + } + + // if it's just a single character, it was meant to be positional + if (arg_string.length === 1) { + return undefined + } + + // if the option string before the "=" is present, return the action + if (arg_string.includes('=')) { + let [ option_string, explicit_arg ] = _string_split(arg_string, '=', 1) + if (option_string in this._option_string_actions) { + let action = this._option_string_actions[option_string] + return [ action, option_string, explicit_arg ] + } + } + + // search through all possible prefixes of the option string + // and all actions in the parser for possible interpretations + let option_tuples = this._get_option_tuples(arg_string) + + // if multiple actions match, the option string was ambiguous + if (option_tuples.length > 1) { + let options = option_tuples.map(([ /*action*/, option_string/*, explicit_arg*/ ]) => option_string).join(', ') + let args = {option: arg_string, matches: options} + let msg = 'ambiguous option: %(option)s could match %(matches)s' + this.error(sub(msg, args)) + + // if exactly one action matched, this segmentation is good, + // so return the parsed action + } else if (option_tuples.length === 1) { + let [ option_tuple ] = option_tuples + return option_tuple + } + + // if it was not found as an option, but it looks like a negative + // number, it was meant to be positional + // unless there are negative-number-like options + if (this._negative_number_matcher.test(arg_string)) { + if (!this._has_negative_number_optionals.length) { + return undefined + } + } + + // if it contains a space, it was meant to be a positional + if (arg_string.includes(' ')) { + return undefined + } + + // it was meant to be an optional but there is no such option + // in this parser (though it might be a valid option in a subparser) + return [ undefined, arg_string, undefined ] + } + + _get_option_tuples(option_string) { + let result = [] + + // option strings starting with two prefix characters are only + // split at the '=' + let chars = this.prefix_chars + if (chars.includes(option_string[0]) && chars.includes(option_string[1])) { + if (this.allow_abbrev) { + let option_prefix, explicit_arg + if (option_string.includes('=')) { + [ option_prefix, explicit_arg ] = _string_split(option_string, '=', 1) + } else { + option_prefix = option_string + explicit_arg = undefined + } + for (let option_string of Object.keys(this._option_string_actions)) { + if (option_string.startsWith(option_prefix)) { + let action = this._option_string_actions[option_string] + let tup = [ action, option_string, explicit_arg ] + result.push(tup) + } + } + } + + // single character options can be concatenated with their arguments + // but multiple character options always have to have their argument + // separate + } else if (chars.includes(option_string[0]) && !chars.includes(option_string[1])) { + let option_prefix = option_string + let explicit_arg = undefined + let short_option_prefix = option_string.slice(0, 2) + let short_explicit_arg = option_string.slice(2) + + for (let option_string of Object.keys(this._option_string_actions)) { + if (option_string === short_option_prefix) { + let action = this._option_string_actions[option_string] + let tup = [ action, option_string, short_explicit_arg ] + result.push(tup) + } else if (option_string.startsWith(option_prefix)) { + let action = this._option_string_actions[option_string] + let tup = [ action, option_string, explicit_arg ] + result.push(tup) + } + } + + // shouldn't ever get here + } else { + this.error(sub('unexpected option string: %s', option_string)) + } + + // return the collected option tuples + return result + } + + _get_nargs_pattern(action) { + // in all examples below, we have to allow for '--' args + // which are represented as '-' in the pattern + let nargs = action.nargs + let nargs_pattern + + // the default (None) is assumed to be a single argument + if (nargs === undefined) { + nargs_pattern = '(-*A-*)' + + // allow zero or one arguments + } else if (nargs === OPTIONAL) { + nargs_pattern = '(-*A?-*)' + + // allow zero or more arguments + } else if (nargs === ZERO_OR_MORE) { + nargs_pattern = '(-*[A-]*)' + + // allow one or more arguments + } else if (nargs === ONE_OR_MORE) { + nargs_pattern = '(-*A[A-]*)' + + // allow any number of options or arguments + } else if (nargs === REMAINDER) { + nargs_pattern = '([-AO]*)' + + // allow one argument followed by any number of options or arguments + } else if (nargs === PARSER) { + nargs_pattern = '(-*A[-AO]*)' + + // suppress action, like nargs=0 + } else if (nargs === SUPPRESS) { + nargs_pattern = '(-*-*)' + + // all others should be integers + } else { + nargs_pattern = sub('(-*%s-*)', 'A'.repeat(nargs).split('').join('-*')) + } + + // if this is an optional action, -- is not allowed + if (action.option_strings.length) { + nargs_pattern = nargs_pattern.replace(/-\*/g, '') + nargs_pattern = nargs_pattern.replace(/-/g, '') + } + + // return the pattern + return nargs_pattern + } + + // ======================== + // Alt command line argument parsing, allowing free intermix + // ======================== + + parse_intermixed_args(args = undefined, namespace = undefined) { + let argv + [ args, argv ] = this.parse_known_intermixed_args(args, namespace) + if (argv.length) { + let msg = 'unrecognized arguments: %s' + this.error(sub(msg, argv.join(' '))) + } + return args + } + + parse_known_intermixed_args(args = undefined, namespace = undefined) { + // returns a namespace and list of extras + // + // positional can be freely intermixed with optionals. optionals are + // first parsed with all positional arguments deactivated. The 'extras' + // are then parsed. If the parser definition is incompatible with the + // intermixed assumptions (e.g. use of REMAINDER, subparsers) a + // TypeError is raised. + // + // positionals are 'deactivated' by setting nargs and default to + // SUPPRESS. This blocks the addition of that positional to the + // namespace + + let extras + let positionals = this._get_positional_actions() + let a = positionals.filter(action => [ PARSER, REMAINDER ].includes(action.nargs)) + if (a.length) { + throw new TypeError(sub('parse_intermixed_args: positional arg' + + ' with nargs=%s', a[0].nargs)) + } + + for (let group of this._mutually_exclusive_groups) { + for (let action of group._group_actions) { + if (positionals.includes(action)) { + throw new TypeError('parse_intermixed_args: positional in' + + ' mutuallyExclusiveGroup') + } + } + } + + let save_usage + try { + save_usage = this.usage + let remaining_args + try { + if (this.usage === undefined) { + // capture the full usage for use in error messages + this.usage = this.format_usage().slice(7) + } + for (let action of positionals) { + // deactivate positionals + action.save_nargs = action.nargs + // action.nargs = 0 + action.nargs = SUPPRESS + action.save_default = action.default + action.default = SUPPRESS + } + [ namespace, remaining_args ] = this.parse_known_args(args, + namespace) + for (let action of positionals) { + // remove the empty positional values from namespace + let attr = getattr(namespace, action.dest) + if (Array.isArray(attr) && attr.length === 0) { + // eslint-disable-next-line no-console + console.warn(sub('Do not expect %s in %s', action.dest, namespace)) + delattr(namespace, action.dest) + } + } + } finally { + // restore nargs and usage before exiting + for (let action of positionals) { + action.nargs = action.save_nargs + action.default = action.save_default + } + } + let optionals = this._get_optional_actions() + try { + // parse positionals. optionals aren't normally required, but + // they could be, so make sure they aren't. + for (let action of optionals) { + action.save_required = action.required + action.required = false + } + for (let group of this._mutually_exclusive_groups) { + group.save_required = group.required + group.required = false + } + [ namespace, extras ] = this.parse_known_args(remaining_args, + namespace) + } finally { + // restore parser values before exiting + for (let action of optionals) { + action.required = action.save_required + } + for (let group of this._mutually_exclusive_groups) { + group.required = group.save_required + } + } + } finally { + this.usage = save_usage + } + return [ namespace, extras ] + } + + // ======================== + // Value conversion methods + // ======================== + _get_values(action, arg_strings) { + // for everything but PARSER, REMAINDER args, strip out first '--' + if (![PARSER, REMAINDER].includes(action.nargs)) { + try { + _array_remove(arg_strings, '--') + } catch (err) {} + } + + let value + // optional argument produces a default when not present + if (!arg_strings.length && action.nargs === OPTIONAL) { + if (action.option_strings.length) { + value = action.const + } else { + value = action.default + } + if (typeof value === 'string') { + value = this._get_value(action, value) + this._check_value(action, value) + } + + // when nargs='*' on a positional, if there were no command-line + // args, use the default if it is anything other than None + } else if (!arg_strings.length && action.nargs === ZERO_OR_MORE && + !action.option_strings.length) { + if (action.default !== undefined) { + value = action.default + } else { + value = arg_strings + } + this._check_value(action, value) + + // single argument or optional argument produces a single value + } else if (arg_strings.length === 1 && [undefined, OPTIONAL].includes(action.nargs)) { + let arg_string = arg_strings[0] + value = this._get_value(action, arg_string) + this._check_value(action, value) + + // REMAINDER arguments convert all values, checking none + } else if (action.nargs === REMAINDER) { + value = arg_strings.map(v => this._get_value(action, v)) + + // PARSER arguments convert all values, but check only the first + } else if (action.nargs === PARSER) { + value = arg_strings.map(v => this._get_value(action, v)) + this._check_value(action, value[0]) + + // SUPPRESS argument does not put anything in the namespace + } else if (action.nargs === SUPPRESS) { + value = SUPPRESS + + // all other types of nargs produce a list + } else { + value = arg_strings.map(v => this._get_value(action, v)) + for (let v of value) { + this._check_value(action, v) + } + } + + // return the converted value + return value + } + + _get_value(action, arg_string) { + let type_func = this._registry_get('type', action.type, action.type) + if (typeof type_func !== 'function') { + let msg = '%r is not callable' + throw new ArgumentError(action, sub(msg, type_func)) + } + + // convert the value to the appropriate type + let result + try { + try { + result = type_func(arg_string) + } catch (err) { + // Dear TC39, why would you ever consider making es6 classes not callable? + // We had one universal interface, [[Call]], which worked for anything + // (with familiar this-instanceof guard for classes). Now we have two. + if (err instanceof TypeError && + /Class constructor .* cannot be invoked without 'new'/.test(err.message)) { + // eslint-disable-next-line new-cap + result = new type_func(arg_string) + } else { + throw err + } + } + + } catch (err) { + // ArgumentTypeErrors indicate errors + if (err instanceof ArgumentTypeError) { + //let name = getattr(action.type, 'name', repr(action.type)) + let msg = err.message + throw new ArgumentError(action, msg) + + // TypeErrors or ValueErrors also indicate errors + } else if (err instanceof TypeError) { + let name = getattr(action.type, 'name', repr(action.type)) + let args = {type: name, value: arg_string} + let msg = 'invalid %(type)s value: %(value)r' + throw new ArgumentError(action, sub(msg, args)) + } else { + throw err + } + } + + // return the converted value + return result + } + + _check_value(action, value) { + // converted value must be one of the choices (if specified) + if (action.choices !== undefined && !_choices_to_array(action.choices).includes(value)) { + let args = {value, + choices: _choices_to_array(action.choices).map(repr).join(', ')} + let msg = 'invalid choice: %(value)r (choose from %(choices)s)' + throw new ArgumentError(action, sub(msg, args)) + } + } + + // ======================= + // Help-formatting methods + // ======================= + format_usage() { + let formatter = this._get_formatter() + formatter.add_usage(this.usage, this._actions, + this._mutually_exclusive_groups) + return formatter.format_help() + } + + format_help() { + let formatter = this._get_formatter() + + // usage + formatter.add_usage(this.usage, this._actions, + this._mutually_exclusive_groups) + + // description + formatter.add_text(this.description) + + // positionals, optionals and user-defined groups + for (let action_group of this._action_groups) { + formatter.start_section(action_group.title) + formatter.add_text(action_group.description) + formatter.add_arguments(action_group._group_actions) + formatter.end_section() + } + + // epilog + formatter.add_text(this.epilog) + + // determine help from format above + return formatter.format_help() + } + + _get_formatter() { + // eslint-disable-next-line new-cap + return new this.formatter_class({ prog: this.prog }) + } + + // ===================== + // Help-printing methods + // ===================== + print_usage(file = undefined) { + if (file === undefined) file = process.stdout + this._print_message(this.format_usage(), file) + } + + print_help(file = undefined) { + if (file === undefined) file = process.stdout + this._print_message(this.format_help(), file) + } + + _print_message(message, file = undefined) { + if (message) { + if (file === undefined) file = process.stderr + file.write(message) + } + } + + // =============== + // Exiting methods + // =============== + exit(status = 0, message = undefined) { + if (message) { + this._print_message(message, process.stderr) + } + process.exit(status) + } + + error(message) { + /* + * error(message: string) + * + * Prints a usage message incorporating the message to stderr and + * exits. + * + * If you override this in a subclass, it should not return -- it + * should either exit or raise an exception. + */ + + // LEGACY (v1 compatibility), debug mode + if (this.debug === true) throw new Error(message) + // end + this.print_usage(process.stderr) + let args = {prog: this.prog, message: message} + this.exit(2, sub('%(prog)s: error: %(message)s\n', args)) + } +})) + + +module.exports = { + ArgumentParser, + ArgumentError, + ArgumentTypeError, + BooleanOptionalAction, + FileType, + HelpFormatter, + ArgumentDefaultsHelpFormatter, + RawDescriptionHelpFormatter, + RawTextHelpFormatter, + MetavarTypeHelpFormatter, + Namespace, + Action, + ONE_OR_MORE, + OPTIONAL, + PARSER, + REMAINDER, + SUPPRESS, + ZERO_OR_MORE +} + +// LEGACY (v1 compatibility), Const alias +Object.defineProperty(module.exports, 'Const', { + get() { + let result = {} + Object.entries({ ONE_OR_MORE, OPTIONAL, PARSER, REMAINDER, SUPPRESS, ZERO_OR_MORE }).forEach(([ n, v ]) => { + Object.defineProperty(result, n, { + get() { + deprecate(n, sub('use argparse.%s instead of argparse.Const.%s', n, n)) + return v + } + }) + }) + Object.entries({ _UNRECOGNIZED_ARGS_ATTR }).forEach(([ n, v ]) => { + Object.defineProperty(result, n, { + get() { + deprecate(n, sub('argparse.Const.%s is an internal symbol and will no longer be available', n)) + return v + } + }) + }) + return result + }, + enumerable: false +}) +// end diff --git a/libs/events/node_modules/argparse/lib/sub.js b/libs/events/node_modules/argparse/lib/sub.js new file mode 100644 index 000000000..e3eb3215f --- /dev/null +++ b/libs/events/node_modules/argparse/lib/sub.js @@ -0,0 +1,67 @@ +// Limited implementation of python % string operator, supports only %s and %r for now +// (other formats are not used here, but may appear in custom templates) + +'use strict' + +const { inspect } = require('util') + + +module.exports = function sub(pattern, ...values) { + let regex = /%(?:(%)|(-)?(\*)?(?:\((\w+)\))?([A-Za-z]))/g + + let result = pattern.replace(regex, function (_, is_literal, is_left_align, is_padded, name, format) { + if (is_literal) return '%' + + let padded_count = 0 + if (is_padded) { + if (values.length === 0) throw new TypeError('not enough arguments for format string') + padded_count = values.shift() + if (!Number.isInteger(padded_count)) throw new TypeError('* wants int') + } + + let str + if (name !== undefined) { + let dict = values[0] + if (typeof dict !== 'object' || dict === null) throw new TypeError('format requires a mapping') + if (!(name in dict)) throw new TypeError(`no such key: '${name}'`) + str = dict[name] + } else { + if (values.length === 0) throw new TypeError('not enough arguments for format string') + str = values.shift() + } + + switch (format) { + case 's': + str = String(str) + break + case 'r': + str = inspect(str) + break + case 'd': + case 'i': + if (typeof str !== 'number') { + throw new TypeError(`%${format} format: a number is required, not ${typeof str}`) + } + str = String(str.toFixed(0)) + break + default: + throw new TypeError(`unsupported format character '${format}'`) + } + + if (padded_count > 0) { + return is_left_align ? str.padEnd(padded_count) : str.padStart(padded_count) + } else { + return str + } + }) + + if (values.length) { + if (values.length === 1 && typeof values[0] === 'object' && values[0] !== null) { + // mapping + } else { + throw new TypeError('not all arguments converted during string formatting') + } + } + + return result +} diff --git a/libs/events/node_modules/argparse/lib/textwrap.js b/libs/events/node_modules/argparse/lib/textwrap.js new file mode 100644 index 000000000..23d51cdb9 --- /dev/null +++ b/libs/events/node_modules/argparse/lib/textwrap.js @@ -0,0 +1,440 @@ +// Partial port of python's argparse module, version 3.9.0 (only wrap and fill functions): +// https://github.com/python/cpython/blob/v3.9.0b4/Lib/textwrap.py + +'use strict' + +/* + * Text wrapping and filling. + */ + +// Copyright (C) 1999-2001 Gregory P. Ward. +// Copyright (C) 2002, 2003 Python Software Foundation. +// Copyright (C) 2020 argparse.js authors +// Originally written by Greg Ward + +// Hardcode the recognized whitespace characters to the US-ASCII +// whitespace characters. The main reason for doing this is that +// some Unicode spaces (like \u00a0) are non-breaking whitespaces. +// +// This less funky little regex just split on recognized spaces. E.g. +// "Hello there -- you goof-ball, use the -b option!" +// splits into +// Hello/ /there/ /--/ /you/ /goof-ball,/ /use/ /the/ /-b/ /option!/ +const wordsep_simple_re = /([\t\n\x0b\x0c\r ]+)/ + +class TextWrapper { + /* + * Object for wrapping/filling text. The public interface consists of + * the wrap() and fill() methods; the other methods are just there for + * subclasses to override in order to tweak the default behaviour. + * If you want to completely replace the main wrapping algorithm, + * you'll probably have to override _wrap_chunks(). + * + * Several instance attributes control various aspects of wrapping: + * width (default: 70) + * the maximum width of wrapped lines (unless break_long_words + * is false) + * initial_indent (default: "") + * string that will be prepended to the first line of wrapped + * output. Counts towards the line's width. + * subsequent_indent (default: "") + * string that will be prepended to all lines save the first + * of wrapped output; also counts towards each line's width. + * expand_tabs (default: true) + * Expand tabs in input text to spaces before further processing. + * Each tab will become 0 .. 'tabsize' spaces, depending on its position + * in its line. If false, each tab is treated as a single character. + * tabsize (default: 8) + * Expand tabs in input text to 0 .. 'tabsize' spaces, unless + * 'expand_tabs' is false. + * replace_whitespace (default: true) + * Replace all whitespace characters in the input text by spaces + * after tab expansion. Note that if expand_tabs is false and + * replace_whitespace is true, every tab will be converted to a + * single space! + * fix_sentence_endings (default: false) + * Ensure that sentence-ending punctuation is always followed + * by two spaces. Off by default because the algorithm is + * (unavoidably) imperfect. + * break_long_words (default: true) + * Break words longer than 'width'. If false, those words will not + * be broken, and some lines might be longer than 'width'. + * break_on_hyphens (default: true) + * Allow breaking hyphenated words. If true, wrapping will occur + * preferably on whitespaces and right after hyphens part of + * compound words. + * drop_whitespace (default: true) + * Drop leading and trailing whitespace from lines. + * max_lines (default: None) + * Truncate wrapped lines. + * placeholder (default: ' [...]') + * Append to the last line of truncated text. + */ + + constructor(options = {}) { + let { + width = 70, + initial_indent = '', + subsequent_indent = '', + expand_tabs = true, + replace_whitespace = true, + fix_sentence_endings = false, + break_long_words = true, + drop_whitespace = true, + break_on_hyphens = true, + tabsize = 8, + max_lines = undefined, + placeholder=' [...]' + } = options + + this.width = width + this.initial_indent = initial_indent + this.subsequent_indent = subsequent_indent + this.expand_tabs = expand_tabs + this.replace_whitespace = replace_whitespace + this.fix_sentence_endings = fix_sentence_endings + this.break_long_words = break_long_words + this.drop_whitespace = drop_whitespace + this.break_on_hyphens = break_on_hyphens + this.tabsize = tabsize + this.max_lines = max_lines + this.placeholder = placeholder + } + + + // -- Private methods ----------------------------------------------- + // (possibly useful for subclasses to override) + + _munge_whitespace(text) { + /* + * _munge_whitespace(text : string) -> string + * + * Munge whitespace in text: expand tabs and convert all other + * whitespace characters to spaces. Eg. " foo\\tbar\\n\\nbaz" + * becomes " foo bar baz". + */ + if (this.expand_tabs) { + text = text.replace(/\t/g, ' '.repeat(this.tabsize)) // not strictly correct in js + } + if (this.replace_whitespace) { + text = text.replace(/[\t\n\x0b\x0c\r]/g, ' ') + } + return text + } + + _split(text) { + /* + * _split(text : string) -> [string] + * + * Split the text to wrap into indivisible chunks. Chunks are + * not quite the same as words; see _wrap_chunks() for full + * details. As an example, the text + * Look, goof-ball -- use the -b option! + * breaks into the following chunks: + * 'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ', + * 'use', ' ', 'the', ' ', '-b', ' ', 'option!' + * if break_on_hyphens is True, or in: + * 'Look,', ' ', 'goof-ball', ' ', '--', ' ', + * 'use', ' ', 'the', ' ', '-b', ' ', option!' + * otherwise. + */ + let chunks = text.split(wordsep_simple_re) + chunks = chunks.filter(Boolean) + return chunks + } + + _handle_long_word(reversed_chunks, cur_line, cur_len, width) { + /* + * _handle_long_word(chunks : [string], + * cur_line : [string], + * cur_len : int, width : int) + * + * Handle a chunk of text (most likely a word, not whitespace) that + * is too long to fit in any line. + */ + // Figure out when indent is larger than the specified width, and make + // sure at least one character is stripped off on every pass + let space_left + if (width < 1) { + space_left = 1 + } else { + space_left = width - cur_len + } + + // If we're allowed to break long words, then do so: put as much + // of the next chunk onto the current line as will fit. + if (this.break_long_words) { + cur_line.push(reversed_chunks[reversed_chunks.length - 1].slice(0, space_left)) + reversed_chunks[reversed_chunks.length - 1] = reversed_chunks[reversed_chunks.length - 1].slice(space_left) + + // Otherwise, we have to preserve the long word intact. Only add + // it to the current line if there's nothing already there -- + // that minimizes how much we violate the width constraint. + } else if (!cur_line) { + cur_line.push(...reversed_chunks.pop()) + } + + // If we're not allowed to break long words, and there's already + // text on the current line, do nothing. Next time through the + // main loop of _wrap_chunks(), we'll wind up here again, but + // cur_len will be zero, so the next line will be entirely + // devoted to the long word that we can't handle right now. + } + + _wrap_chunks(chunks) { + /* + * _wrap_chunks(chunks : [string]) -> [string] + * + * Wrap a sequence of text chunks and return a list of lines of + * length 'self.width' or less. (If 'break_long_words' is false, + * some lines may be longer than this.) Chunks correspond roughly + * to words and the whitespace between them: each chunk is + * indivisible (modulo 'break_long_words'), but a line break can + * come between any two chunks. Chunks should not have internal + * whitespace; ie. a chunk is either all whitespace or a "word". + * Whitespace chunks will be removed from the beginning and end of + * lines, but apart from that whitespace is preserved. + */ + let lines = [] + let indent + if (this.width <= 0) { + throw Error(`invalid width ${this.width} (must be > 0)`) + } + if (this.max_lines !== undefined) { + if (this.max_lines > 1) { + indent = this.subsequent_indent + } else { + indent = this.initial_indent + } + if (indent.length + this.placeholder.trimStart().length > this.width) { + throw Error('placeholder too large for max width') + } + } + + // Arrange in reverse order so items can be efficiently popped + // from a stack of chucks. + chunks = chunks.reverse() + + while (chunks.length > 0) { + + // Start the list of chunks that will make up the current line. + // cur_len is just the length of all the chunks in cur_line. + let cur_line = [] + let cur_len = 0 + + // Figure out which static string will prefix this line. + let indent + if (lines) { + indent = this.subsequent_indent + } else { + indent = this.initial_indent + } + + // Maximum width for this line. + let width = this.width - indent.length + + // First chunk on line is whitespace -- drop it, unless this + // is the very beginning of the text (ie. no lines started yet). + if (this.drop_whitespace && chunks[chunks.length - 1].trim() === '' && lines.length > 0) { + chunks.pop() + } + + while (chunks.length > 0) { + let l = chunks[chunks.length - 1].length + + // Can at least squeeze this chunk onto the current line. + if (cur_len + l <= width) { + cur_line.push(chunks.pop()) + cur_len += l + + // Nope, this line is full. + } else { + break + } + } + + // The current line is full, and the next chunk is too big to + // fit on *any* line (not just this one). + if (chunks.length && chunks[chunks.length - 1].length > width) { + this._handle_long_word(chunks, cur_line, cur_len, width) + cur_len = cur_line.map(l => l.length).reduce((a, b) => a + b, 0) + } + + // If the last chunk on this line is all whitespace, drop it. + if (this.drop_whitespace && cur_line.length > 0 && cur_line[cur_line.length - 1].trim() === '') { + cur_len -= cur_line[cur_line.length - 1].length + cur_line.pop() + } + + if (cur_line) { + if (this.max_lines === undefined || + lines.length + 1 < this.max_lines || + (chunks.length === 0 || + this.drop_whitespace && + chunks.length === 1 && + !chunks[0].trim()) && cur_len <= width) { + // Convert current line back to a string and store it in + // list of all lines (return value). + lines.push(indent + cur_line.join('')) + } else { + let had_break = false + while (cur_line) { + if (cur_line[cur_line.length - 1].trim() && + cur_len + this.placeholder.length <= width) { + cur_line.push(this.placeholder) + lines.push(indent + cur_line.join('')) + had_break = true + break + } + cur_len -= cur_line[-1].length + cur_line.pop() + } + if (!had_break) { + if (lines) { + let prev_line = lines[lines.length - 1].trimEnd() + if (prev_line.length + this.placeholder.length <= + this.width) { + lines[lines.length - 1] = prev_line + this.placeholder + break + } + } + lines.push(indent + this.placeholder.lstrip()) + } + break + } + } + } + + return lines + } + + _split_chunks(text) { + text = this._munge_whitespace(text) + return this._split(text) + } + + // -- Public interface ---------------------------------------------- + + wrap(text) { + /* + * wrap(text : string) -> [string] + * + * Reformat the single paragraph in 'text' so it fits in lines of + * no more than 'self.width' columns, and return a list of wrapped + * lines. Tabs in 'text' are expanded with string.expandtabs(), + * and all other whitespace characters (including newline) are + * converted to space. + */ + let chunks = this._split_chunks(text) + // not implemented in js + //if (this.fix_sentence_endings) { + // this._fix_sentence_endings(chunks) + //} + return this._wrap_chunks(chunks) + } + + fill(text) { + /* + * fill(text : string) -> string + * + * Reformat the single paragraph in 'text' to fit in lines of no + * more than 'self.width' columns, and return a new string + * containing the entire wrapped paragraph. + */ + return this.wrap(text).join('\n') + } +} + + +// -- Convenience interface --------------------------------------------- + +function wrap(text, options = {}) { + /* + * Wrap a single paragraph of text, returning a list of wrapped lines. + * + * Reformat the single paragraph in 'text' so it fits in lines of no + * more than 'width' columns, and return a list of wrapped lines. By + * default, tabs in 'text' are expanded with string.expandtabs(), and + * all other whitespace characters (including newline) are converted to + * space. See TextWrapper class for available keyword args to customize + * wrapping behaviour. + */ + let { width = 70, ...kwargs } = options + let w = new TextWrapper(Object.assign({ width }, kwargs)) + return w.wrap(text) +} + +function fill(text, options = {}) { + /* + * Fill a single paragraph of text, returning a new string. + * + * Reformat the single paragraph in 'text' to fit in lines of no more + * than 'width' columns, and return a new string containing the entire + * wrapped paragraph. As with wrap(), tabs are expanded and other + * whitespace characters converted to space. See TextWrapper class for + * available keyword args to customize wrapping behaviour. + */ + let { width = 70, ...kwargs } = options + let w = new TextWrapper(Object.assign({ width }, kwargs)) + return w.fill(text) +} + +// -- Loosely related functionality ------------------------------------- + +let _whitespace_only_re = /^[ \t]+$/mg +let _leading_whitespace_re = /(^[ \t]*)(?:[^ \t\n])/mg + +function dedent(text) { + /* + * Remove any common leading whitespace from every line in `text`. + * + * This can be used to make triple-quoted strings line up with the left + * edge of the display, while still presenting them in the source code + * in indented form. + * + * Note that tabs and spaces are both treated as whitespace, but they + * are not equal: the lines " hello" and "\\thello" are + * considered to have no common leading whitespace. + * + * Entirely blank lines are normalized to a newline character. + */ + // Look for the longest leading string of spaces and tabs common to + // all lines. + let margin = undefined + text = text.replace(_whitespace_only_re, '') + let indents = text.match(_leading_whitespace_re) || [] + for (let indent of indents) { + indent = indent.slice(0, -1) + + if (margin === undefined) { + margin = indent + + // Current line more deeply indented than previous winner: + // no change (previous winner is still on top). + } else if (indent.startsWith(margin)) { + // pass + + // Current line consistent with and no deeper than previous winner: + // it's the new winner. + } else if (margin.startsWith(indent)) { + margin = indent + + // Find the largest common whitespace between current line and previous + // winner. + } else { + for (let i = 0; i < margin.length && i < indent.length; i++) { + if (margin[i] !== indent[i]) { + margin = margin.slice(0, i) + break + } + } + } + } + + if (margin) { + text = text.replace(new RegExp('^' + margin, 'mg'), '') + } + return text +} + +module.exports = { wrap, fill, dedent } diff --git a/libs/events/node_modules/argparse/package.json b/libs/events/node_modules/argparse/package.json new file mode 100644 index 000000000..647d2aff1 --- /dev/null +++ b/libs/events/node_modules/argparse/package.json @@ -0,0 +1,31 @@ +{ + "name": "argparse", + "description": "CLI arguments parser. Native port of python's argparse.", + "version": "2.0.1", + "keywords": [ + "cli", + "parser", + "argparse", + "option", + "args" + ], + "main": "argparse.js", + "files": [ + "argparse.js", + "lib/" + ], + "license": "Python-2.0", + "repository": "nodeca/argparse", + "scripts": { + "lint": "eslint .", + "test": "npm run lint && nyc mocha", + "coverage": "npm run test && nyc report --reporter html" + }, + "devDependencies": { + "@babel/eslint-parser": "^7.11.0", + "@babel/plugin-syntax-class-properties": "^7.10.4", + "eslint": "^7.5.0", + "mocha": "^8.0.1", + "nyc": "^15.1.0" + } +} diff --git a/libs/events/node_modules/balanced-match/.github/FUNDING.yml b/libs/events/node_modules/balanced-match/.github/FUNDING.yml new file mode 100644 index 000000000..cea8b16e9 --- /dev/null +++ b/libs/events/node_modules/balanced-match/.github/FUNDING.yml @@ -0,0 +1,2 @@ +tidelift: "npm/balanced-match" +patreon: juliangruber diff --git a/libs/events/node_modules/balanced-match/LICENSE.md b/libs/events/node_modules/balanced-match/LICENSE.md new file mode 100644 index 000000000..2cdc8e414 --- /dev/null +++ b/libs/events/node_modules/balanced-match/LICENSE.md @@ -0,0 +1,21 @@ +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/balanced-match/README.md b/libs/events/node_modules/balanced-match/README.md new file mode 100644 index 000000000..d2a48b6b4 --- /dev/null +++ b/libs/events/node_modules/balanced-match/README.md @@ -0,0 +1,97 @@ +# balanced-match + +Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well! + +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) + +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) + +## Example + +Get the first matching pair of braces: + +```js +var balanced = require('balanced-match'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); +console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); +``` + +The matches are: + +```bash +$ node example.js +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } +{ start: 3, + end: 9, + pre: 'pre', + body: 'first', + post: 'between{second}post' } +{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } +``` + +## API + +### var m = balanced(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +object with those keys: + +* **start** the index of the first match of `a` +* **end** the index of the matching `b` +* **pre** the preamble, `a` and `b` not included +* **body** the match, `a` and `b` not included +* **post** the postscript, `a` and `b` not included + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. + +### var r = balanced.range(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +array with indexes: `[ , ]`. + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install balanced-match +``` + +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/balanced-match/index.js b/libs/events/node_modules/balanced-match/index.js new file mode 100644 index 000000000..c67a64608 --- /dev/null +++ b/libs/events/node_modules/balanced-match/index.js @@ -0,0 +1,62 @@ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + if(a===b) { + return [ai, bi]; + } + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} diff --git a/libs/events/node_modules/balanced-match/package.json b/libs/events/node_modules/balanced-match/package.json new file mode 100644 index 000000000..ce6073e04 --- /dev/null +++ b/libs/events/node_modules/balanced-match/package.json @@ -0,0 +1,48 @@ +{ + "name": "balanced-match", + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "version": "1.0.2", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/balanced-match.git" + }, + "homepage": "https://github.com/juliangruber/balanced-match", + "main": "index.js", + "scripts": { + "test": "tape test/test.js", + "bench": "matcha test/bench.js" + }, + "devDependencies": { + "matcha": "^0.7.0", + "tape": "^4.6.0" + }, + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT", + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + } +} diff --git a/libs/events/node_modules/brace-expansion/.github/FUNDING.yml b/libs/events/node_modules/brace-expansion/.github/FUNDING.yml new file mode 100644 index 000000000..79d1eafce --- /dev/null +++ b/libs/events/node_modules/brace-expansion/.github/FUNDING.yml @@ -0,0 +1,2 @@ +tidelift: "npm/brace-expansion" +patreon: juliangruber diff --git a/libs/events/node_modules/brace-expansion/LICENSE b/libs/events/node_modules/brace-expansion/LICENSE new file mode 100644 index 000000000..de3226673 --- /dev/null +++ b/libs/events/node_modules/brace-expansion/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013 Julian Gruber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/brace-expansion/README.md b/libs/events/node_modules/brace-expansion/README.md new file mode 100644 index 000000000..e55c583dd --- /dev/null +++ b/libs/events/node_modules/brace-expansion/README.md @@ -0,0 +1,135 @@ +# brace-expansion + +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +as known from sh/bash, in JavaScript. + +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) +[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/) + +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) + +## Example + +```js +var expand = require('brace-expansion'); + +expand('file-{a,b,c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('-v{,,}') +// => ['-v', '-v', '-v'] + +expand('file{0..2}.jpg') +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] + +expand('file-{a..c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('file{2..0}.jpg') +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] + +expand('file{0..4..2}.jpg') +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] + +expand('file-{a..e..2}.jpg') +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] + +expand('file{00..10..5}.jpg') +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] + +expand('{{A..C},{a..c}}') +// => ['A', 'B', 'C', 'a', 'b', 'c'] + +expand('ppp{,config,oe{,conf}}') +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] +``` + +## API + +```js +var expand = require('brace-expansion'); +``` + +### var expanded = expand(str) + +Return an array of all possible and valid expansions of `str`. If none are +found, `[str]` is returned. + +Valid expansions are: + +```js +/^(.*,)+(.+)?$/ +// {a,b,...} +``` + +A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +A numeric sequence from `x` to `y` inclusive, with optional increment. +If `x` or `y` start with a leading `0`, all the numbers will be padded +to have equal length. Negative numbers and backwards iteration work too. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +An alphabetic sequence from `x` to `y` inclusive, with optional increment. +`x` and `y` must be exactly one character, and if given, `incr` must be a +number. + +For compatibility reasons, the string `${` is not eligible for brace expansion. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install brace-expansion +``` + +## Contributors + +- [Julian Gruber](https://github.com/juliangruber) +- [Isaac Z. Schlueter](https://github.com/isaacs) + +## Sponsors + +This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)! + +Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)! + +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/brace-expansion/index.js b/libs/events/node_modules/brace-expansion/index.js new file mode 100644 index 000000000..4af9ddee4 --- /dev/null +++ b/libs/events/node_modules/brace-expansion/index.js @@ -0,0 +1,203 @@ +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m) return [str]; + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + if (/\$$/.test(m.pre)) { + for (var k = 0; k < post.length; k++) { + var expansion = pre+ '{' + m.body + '}' + post[k]; + expansions.push(expansion); + } + } else { + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = []; + + for (var j = 0; j < n.length; j++) { + N.push.apply(N, expand(n[j], false)); + } + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + } + + return expansions; +} + diff --git a/libs/events/node_modules/brace-expansion/package.json b/libs/events/node_modules/brace-expansion/package.json new file mode 100644 index 000000000..7097d41e3 --- /dev/null +++ b/libs/events/node_modules/brace-expansion/package.json @@ -0,0 +1,46 @@ +{ + "name": "brace-expansion", + "description": "Brace expansion as known from sh/bash", + "version": "2.0.1", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "homepage": "https://github.com/juliangruber/brace-expansion", + "main": "index.js", + "scripts": { + "test": "tape test/*.js", + "gentest": "bash test/generate.sh", + "bench": "matcha test/perf/bench.js" + }, + "dependencies": { + "balanced-match": "^1.0.0" + }, + "devDependencies": { + "@c4312/matcha": "^1.3.1", + "tape": "^4.6.0" + }, + "keywords": [], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT", + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + } +} diff --git a/libs/events/node_modules/braces/CHANGELOG.md b/libs/events/node_modules/braces/CHANGELOG.md new file mode 100644 index 000000000..36f798b00 --- /dev/null +++ b/libs/events/node_modules/braces/CHANGELOG.md @@ -0,0 +1,184 @@ +# Release history + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +
+ Guiding Principles + +- Changelogs are for humans, not machines. +- There should be an entry for every single version. +- The same types of changes should be grouped. +- Versions and sections should be linkable. +- The latest version comes first. +- The release date of each versions is displayed. +- Mention whether you follow Semantic Versioning. + +
+ +
+ Types of changes + +Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_): + +- `Added` for new features. +- `Changed` for changes in existing functionality. +- `Deprecated` for soon-to-be removed features. +- `Removed` for now removed features. +- `Fixed` for any bug fixes. +- `Security` in case of vulnerabilities. + +
+ +## [3.0.0] - 2018-04-08 + +v3.0 is a complete refactor, resulting in a faster, smaller codebase, with fewer deps, and a more accurate parser and compiler. + +**Breaking Changes** + +- The undocumented `.makeRe` method was removed + +**Non-breaking changes** + +- Caching was removed + +## [2.3.2] - 2018-04-08 + +- start refactoring +- cover sets +- better range handling + +## [2.3.1] - 2018-02-17 + +- Remove unnecessary escape in Regex. (#14) + +## [2.3.0] - 2017-10-19 + +- minor code reorganization +- optimize regex +- expose `maxLength` option + +## [2.2.1] - 2017-05-30 + +- don't condense when braces contain extglobs + +## [2.2.0] - 2017-05-28 + +- ensure word boundaries are preserved +- fixes edge case where extglob characters precede a brace pattern + +## [2.1.1] - 2017-04-27 + +- use snapdragon-node +- handle edge case +- optimizations, lint + +## [2.0.4] - 2017-04-11 + +- pass opts to compiler +- minor optimization in create method +- re-write parser handlers to remove negation regex + +## [2.0.3] - 2016-12-10 + +- use split-string +- clear queue at the end +- adds sequences example +- add unit tests + +## [2.0.2] - 2016-10-21 + +- fix comma handling in nested extglobs + +## [2.0.1] - 2016-10-20 + +- add comments +- more tests, ensure quotes are stripped + +## [2.0.0] - 2016-10-19 + +- don't expand braces inside character classes +- add quantifier pattern + +## [1.8.5] - 2016-05-21 + +- Refactor (#10) + +## [1.8.4] - 2016-04-20 + +- fixes https://github.com/jonschlinkert/micromatch/issues/66 + +## [1.8.0] - 2015-03-18 + +- adds exponent examples, tests +- fixes the first example in https://github.com/jonschlinkert/micromatch/issues/38 + +## [1.6.0] - 2015-01-30 + +- optimizations, `bash` mode: +- improve path escaping + +## [1.5.0] - 2015-01-28 + +- Merge pull request #5 from eush77/lib-files + +## [1.4.0] - 2015-01-24 + +- add extglob tests +- externalize exponent function +- better whitespace handling + +## [1.3.0] - 2015-01-24 + +- make regex patterns explicity + +## [1.1.0] - 2015-01-11 + +- don't create a match group with `makeRe` + +## [1.0.0] - 2014-12-23 + +- Merge commit '97b05f5544f8348736a8efaecf5c32bbe3e2ad6e' +- support empty brace syntax +- better bash coverage +- better support for regex strings + +## [0.1.4] - 2014-11-14 + +- improve recognition of bad args, recognize mismatched argument types +- support escaping +- remove pathname-expansion +- support whitespace in patterns + +## [0.1.0] + +- first commit + +[2.3.2]: https://github.com/micromatch/braces/compare/2.3.1...2.3.2 +[2.3.1]: https://github.com/micromatch/braces/compare/2.3.0...2.3.1 +[2.3.0]: https://github.com/micromatch/braces/compare/2.2.1...2.3.0 +[2.2.1]: https://github.com/micromatch/braces/compare/2.2.0...2.2.1 +[2.2.0]: https://github.com/micromatch/braces/compare/2.1.1...2.2.0 +[2.1.1]: https://github.com/micromatch/braces/compare/2.1.0...2.1.1 +[2.1.0]: https://github.com/micromatch/braces/compare/2.0.4...2.1.0 +[2.0.4]: https://github.com/micromatch/braces/compare/2.0.3...2.0.4 +[2.0.3]: https://github.com/micromatch/braces/compare/2.0.2...2.0.3 +[2.0.2]: https://github.com/micromatch/braces/compare/2.0.1...2.0.2 +[2.0.1]: https://github.com/micromatch/braces/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/micromatch/braces/compare/1.8.5...2.0.0 +[1.8.5]: https://github.com/micromatch/braces/compare/1.8.4...1.8.5 +[1.8.4]: https://github.com/micromatch/braces/compare/1.8.0...1.8.4 +[1.8.0]: https://github.com/micromatch/braces/compare/1.6.0...1.8.0 +[1.6.0]: https://github.com/micromatch/braces/compare/1.5.0...1.6.0 +[1.5.0]: https://github.com/micromatch/braces/compare/1.4.0...1.5.0 +[1.4.0]: https://github.com/micromatch/braces/compare/1.3.0...1.4.0 +[1.3.0]: https://github.com/micromatch/braces/compare/1.2.0...1.3.0 +[1.2.0]: https://github.com/micromatch/braces/compare/1.1.0...1.2.0 +[1.1.0]: https://github.com/micromatch/braces/compare/1.0.0...1.1.0 +[1.0.0]: https://github.com/micromatch/braces/compare/0.1.4...1.0.0 +[0.1.4]: https://github.com/micromatch/braces/compare/0.1.0...0.1.4 + +[Unreleased]: https://github.com/micromatch/braces/compare/0.1.0...HEAD +[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog \ No newline at end of file diff --git a/libs/events/node_modules/braces/LICENSE b/libs/events/node_modules/braces/LICENSE new file mode 100644 index 000000000..d32ab4426 --- /dev/null +++ b/libs/events/node_modules/braces/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/braces/README.md b/libs/events/node_modules/braces/README.md new file mode 100644 index 000000000..cba2f600d --- /dev/null +++ b/libs/events/node_modules/braces/README.md @@ -0,0 +1,593 @@ +# braces [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/braces.svg?style=flat)](https://www.npmjs.com/package/braces) [![NPM monthly downloads](https://img.shields.io/npm/dm/braces.svg?style=flat)](https://npmjs.org/package/braces) [![NPM total downloads](https://img.shields.io/npm/dt/braces.svg?style=flat)](https://npmjs.org/package/braces) [![Linux Build Status](https://img.shields.io/travis/micromatch/braces.svg?style=flat&label=Travis)](https://travis-ci.org/micromatch/braces) + +> Bash-like brace expansion, implemented in JavaScript. Safer than other brace expansion libs, with complete support for the Bash 4.3 braces specification, without sacrificing speed. + +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save braces +``` + +## v3.0.0 Released!! + +See the [changelog](CHANGELOG.md) for details. + +## Why use braces? + +Brace patterns make globs more powerful by adding the ability to match specific ranges and sequences of characters. + +* **Accurate** - complete support for the [Bash 4.3 Brace Expansion](www.gnu.org/software/bash/) specification (passes all of the Bash braces tests) +* **[fast and performant](#benchmarks)** - Starts fast, runs fast and [scales well](#performance) as patterns increase in complexity. +* **Organized code base** - The parser and compiler are easy to maintain and update when edge cases crop up. +* **Well-tested** - Thousands of test assertions, and passes all of the Bash, minimatch, and [brace-expansion](https://github.com/juliangruber/brace-expansion) unit tests (as of the date this was written). +* **Safer** - You shouldn't have to worry about users defining aggressive or malicious brace patterns that can break your application. Braces takes measures to prevent malicious regex that can be used for DDoS attacks (see [catastrophic backtracking](https://www.regular-expressions.info/catastrophic.html)). +* [Supports lists](#lists) - (aka "sets") `a/{b,c}/d` => `['a/b/d', 'a/c/d']` +* [Supports sequences](#sequences) - (aka "ranges") `{01..03}` => `['01', '02', '03']` +* [Supports steps](#steps) - (aka "increments") `{2..10..2}` => `['2', '4', '6', '8', '10']` +* [Supports escaping](#escaping) - To prevent evaluation of special characters. + +## Usage + +The main export is a function that takes one or more brace `patterns` and `options`. + +```js +const braces = require('braces'); +// braces(patterns[, options]); + +console.log(braces(['{01..05}', '{a..e}'])); +//=> ['(0[1-5])', '([a-e])'] + +console.log(braces(['{01..05}', '{a..e}'], { expand: true })); +//=> ['01', '02', '03', '04', '05', 'a', 'b', 'c', 'd', 'e'] +``` + +### Brace Expansion vs. Compilation + +By default, brace patterns are compiled into strings that are optimized for creating regular expressions and matching. + +**Compiled** + +```js +console.log(braces('a/{x,y,z}/b')); +//=> ['a/(x|y|z)/b'] +console.log(braces(['a/{01..20}/b', 'a/{1..5}/b'])); +//=> [ 'a/(0[1-9]|1[0-9]|20)/b', 'a/([1-5])/b' ] +``` + +**Expanded** + +Enable brace expansion by setting the `expand` option to true, or by using [braces.expand()](#expand) (returns an array similar to what you'd expect from Bash, or `echo {1..5}`, or [minimatch](https://github.com/isaacs/minimatch)): + +```js +console.log(braces('a/{x,y,z}/b', { expand: true })); +//=> ['a/x/b', 'a/y/b', 'a/z/b'] + +console.log(braces.expand('{01..10}')); +//=> ['01','02','03','04','05','06','07','08','09','10'] +``` + +### Lists + +Expand lists (like Bash "sets"): + +```js +console.log(braces('a/{foo,bar,baz}/*.js')); +//=> ['a/(foo|bar|baz)/*.js'] + +console.log(braces.expand('a/{foo,bar,baz}/*.js')); +//=> ['a/foo/*.js', 'a/bar/*.js', 'a/baz/*.js'] +``` + +### Sequences + +Expand ranges of characters (like Bash "sequences"): + +```js +console.log(braces.expand('{1..3}')); // ['1', '2', '3'] +console.log(braces.expand('a/{1..3}/b')); // ['a/1/b', 'a/2/b', 'a/3/b'] +console.log(braces('{a..c}', { expand: true })); // ['a', 'b', 'c'] +console.log(braces('foo/{a..c}', { expand: true })); // ['foo/a', 'foo/b', 'foo/c'] + +// supports zero-padded ranges +console.log(braces('a/{01..03}/b')); //=> ['a/(0[1-3])/b'] +console.log(braces('a/{001..300}/b')); //=> ['a/(0{2}[1-9]|0[1-9][0-9]|[12][0-9]{2}|300)/b'] +``` + +See [fill-range](https://github.com/jonschlinkert/fill-range) for all available range-expansion options. + +### Steppped ranges + +Steps, or increments, may be used with ranges: + +```js +console.log(braces.expand('{2..10..2}')); +//=> ['2', '4', '6', '8', '10'] + +console.log(braces('{2..10..2}')); +//=> ['(2|4|6|8|10)'] +``` + +When the [.optimize](#optimize) method is used, or [options.optimize](#optionsoptimize) is set to true, sequences are passed to [to-regex-range](https://github.com/jonschlinkert/to-regex-range) for expansion. + +### Nesting + +Brace patterns may be nested. The results of each expanded string are not sorted, and left to right order is preserved. + +**"Expanded" braces** + +```js +console.log(braces.expand('a{b,c,/{x,y}}/e')); +//=> ['ab/e', 'ac/e', 'a/x/e', 'a/y/e'] + +console.log(braces.expand('a/{x,{1..5},y}/c')); +//=> ['a/x/c', 'a/1/c', 'a/2/c', 'a/3/c', 'a/4/c', 'a/5/c', 'a/y/c'] +``` + +**"Optimized" braces** + +```js +console.log(braces('a{b,c,/{x,y}}/e')); +//=> ['a(b|c|/(x|y))/e'] + +console.log(braces('a/{x,{1..5},y}/c')); +//=> ['a/(x|([1-5])|y)/c'] +``` + +### Escaping + +**Escaping braces** + +A brace pattern will not be expanded or evaluted if _either the opening or closing brace is escaped_: + +```js +console.log(braces.expand('a\\{d,c,b}e')); +//=> ['a{d,c,b}e'] + +console.log(braces.expand('a{d,c,b\\}e')); +//=> ['a{d,c,b}e'] +``` + +**Escaping commas** + +Commas inside braces may also be escaped: + +```js +console.log(braces.expand('a{b\\,c}d')); +//=> ['a{b,c}d'] + +console.log(braces.expand('a{d\\,c,b}e')); +//=> ['ad,ce', 'abe'] +``` + +**Single items** + +Following bash conventions, a brace pattern is also not expanded when it contains a single character: + +```js +console.log(braces.expand('a{b}c')); +//=> ['a{b}c'] +``` + +## Options + +### options.maxLength + +**Type**: `Number` + +**Default**: `65,536` + +**Description**: Limit the length of the input string. Useful when the input string is generated or your application allows users to pass a string, et cetera. + +```js +console.log(braces('a/{b,c}/d', { maxLength: 3 })); //=> throws an error +``` + +### options.expand + +**Type**: `Boolean` + +**Default**: `undefined` + +**Description**: Generate an "expanded" brace pattern (alternatively you can use the `braces.expand()` method, which does the same thing). + +```js +console.log(braces('a/{b,c}/d', { expand: true })); +//=> [ 'a/b/d', 'a/c/d' ] +``` + +### options.nodupes + +**Type**: `Boolean` + +**Default**: `undefined` + +**Description**: Remove duplicates from the returned array. + +### options.rangeLimit + +**Type**: `Number` + +**Default**: `1000` + +**Description**: To prevent malicious patterns from being passed by users, an error is thrown when `braces.expand()` is used or `options.expand` is true and the generated range will exceed the `rangeLimit`. + +You can customize `options.rangeLimit` or set it to `Inifinity` to disable this altogether. + +**Examples** + +```js +// pattern exceeds the "rangeLimit", so it's optimized automatically +console.log(braces.expand('{1..1000}')); +//=> ['([1-9]|[1-9][0-9]{1,2}|1000)'] + +// pattern does not exceed "rangeLimit", so it's NOT optimized +console.log(braces.expand('{1..100}')); +//=> ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100'] +``` + +### options.transform + +**Type**: `Function` + +**Default**: `undefined` + +**Description**: Customize range expansion. + +**Example: Transforming non-numeric values** + +```js +const alpha = braces.expand('x/{a..e}/y', { + transform(value, index) { + // When non-numeric values are passed, "value" is a character code. + return 'foo/' + String.fromCharCode(value) + '-' + index; + } +}); +console.log(alpha); +//=> [ 'x/foo/a-0/y', 'x/foo/b-1/y', 'x/foo/c-2/y', 'x/foo/d-3/y', 'x/foo/e-4/y' ] +``` + +**Example: Transforming numeric values** + +```js +const numeric = braces.expand('{1..5}', { + transform(value) { + // when numeric values are passed, "value" is a number + return 'foo/' + value * 2; + } +}); +console.log(numeric); +//=> [ 'foo/2', 'foo/4', 'foo/6', 'foo/8', 'foo/10' ] +``` + +### options.quantifiers + +**Type**: `Boolean` + +**Default**: `undefined` + +**Description**: In regular expressions, quanitifiers can be used to specify how many times a token can be repeated. For example, `a{1,3}` will match the letter `a` one to three times. + +Unfortunately, regex quantifiers happen to share the same syntax as [Bash lists](#lists) + +The `quantifiers` option tells braces to detect when [regex quantifiers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#quantifiers) are defined in the given pattern, and not to try to expand them as lists. + +**Examples** + +```js +const braces = require('braces'); +console.log(braces('a/b{1,3}/{x,y,z}')); +//=> [ 'a/b(1|3)/(x|y|z)' ] +console.log(braces('a/b{1,3}/{x,y,z}', {quantifiers: true})); +//=> [ 'a/b{1,3}/(x|y|z)' ] +console.log(braces('a/b{1,3}/{x,y,z}', {quantifiers: true, expand: true})); +//=> [ 'a/b{1,3}/x', 'a/b{1,3}/y', 'a/b{1,3}/z' ] +``` + +### options.unescape + +**Type**: `Boolean` + +**Default**: `undefined` + +**Description**: Strip backslashes that were used for escaping from the result. + +## What is "brace expansion"? + +Brace expansion is a type of parameter expansion that was made popular by unix shells for generating lists of strings, as well as regex-like matching when used alongside wildcards (globs). + +In addition to "expansion", braces are also used for matching. In other words: + +* [brace expansion](#brace-expansion) is for generating new lists +* [brace matching](#brace-matching) is for filtering existing lists + +
+More about brace expansion (click to expand) + +There are two main types of brace expansion: + +1. **lists**: which are defined using comma-separated values inside curly braces: `{a,b,c}` +2. **sequences**: which are defined using a starting value and an ending value, separated by two dots: `a{1..3}b`. Optionally, a third argument may be passed to define a "step" or increment to use: `a{1..100..10}b`. These are also sometimes referred to as "ranges". + +Here are some example brace patterns to illustrate how they work: + +**Sets** + +``` +{a,b,c} => a b c +{a,b,c}{1,2} => a1 a2 b1 b2 c1 c2 +``` + +**Sequences** + +``` +{1..9} => 1 2 3 4 5 6 7 8 9 +{4..-4} => 4 3 2 1 0 -1 -2 -3 -4 +{1..20..3} => 1 4 7 10 13 16 19 +{a..j} => a b c d e f g h i j +{j..a} => j i h g f e d c b a +{a..z..3} => a d g j m p s v y +``` + +**Combination** + +Sets and sequences can be mixed together or used along with any other strings. + +``` +{a,b,c}{1..3} => a1 a2 a3 b1 b2 b3 c1 c2 c3 +foo/{a,b,c}/bar => foo/a/bar foo/b/bar foo/c/bar +``` + +The fact that braces can be "expanded" from relatively simple patterns makes them ideal for quickly generating test fixtures, file paths, and similar use cases. + +## Brace matching + +In addition to _expansion_, brace patterns are also useful for performing regular-expression-like matching. + +For example, the pattern `foo/{1..3}/bar` would match any of following strings: + +``` +foo/1/bar +foo/2/bar +foo/3/bar +``` + +But not: + +``` +baz/1/qux +baz/2/qux +baz/3/qux +``` + +Braces can also be combined with [glob patterns](https://github.com/jonschlinkert/micromatch) to perform more advanced wildcard matching. For example, the pattern `*/{1..3}/*` would match any of following strings: + +``` +foo/1/bar +foo/2/bar +foo/3/bar +baz/1/qux +baz/2/qux +baz/3/qux +``` + +## Brace matching pitfalls + +Although brace patterns offer a user-friendly way of matching ranges or sets of strings, there are also some major disadvantages and potential risks you should be aware of. + +### tldr + +**"brace bombs"** + +* brace expansion can eat up a huge amount of processing resources +* as brace patterns increase _linearly in size_, the system resources required to expand the pattern increase exponentially +* users can accidentally (or intentially) exhaust your system's resources resulting in the equivalent of a DoS attack (bonus: no programming knowledge is required!) + +For a more detailed explanation with examples, see the [geometric complexity](#geometric-complexity) section. + +### The solution + +Jump to the [performance section](#performance) to see how Braces solves this problem in comparison to other libraries. + +### Geometric complexity + +At minimum, brace patterns with sets limited to two elements have quadradic or `O(n^2)` complexity. But the complexity of the algorithm increases exponentially as the number of sets, _and elements per set_, increases, which is `O(n^c)`. + +For example, the following sets demonstrate quadratic (`O(n^2)`) complexity: + +``` +{1,2}{3,4} => (2X2) => 13 14 23 24 +{1,2}{3,4}{5,6} => (2X2X2) => 135 136 145 146 235 236 245 246 +``` + +But add an element to a set, and we get a n-fold Cartesian product with `O(n^c)` complexity: + +``` +{1,2,3}{4,5,6}{7,8,9} => (3X3X3) => 147 148 149 157 158 159 167 168 169 247 248 + 249 257 258 259 267 268 269 347 348 349 357 + 358 359 367 368 369 +``` + +Now, imagine how this complexity grows given that each element is a n-tuple: + +``` +{1..100}{1..100} => (100X100) => 10,000 elements (38.4 kB) +{1..100}{1..100}{1..100} => (100X100X100) => 1,000,000 elements (5.76 MB) +``` + +Although these examples are clearly contrived, they demonstrate how brace patterns can quickly grow out of control. + +**More information** + +Interested in learning more about brace expansion? + +* [linuxjournal/bash-brace-expansion](http://www.linuxjournal.com/content/bash-brace-expansion) +* [rosettacode/Brace_expansion](https://rosettacode.org/wiki/Brace_expansion) +* [cartesian product](https://en.wikipedia.org/wiki/Cartesian_product) + +
+ +## Performance + +Braces is not only screaming fast, it's also more accurate the other brace expansion libraries. + +### Better algorithms + +Fortunately there is a solution to the ["brace bomb" problem](#brace-matching-pitfalls): _don't expand brace patterns into an array when they're used for matching_. + +Instead, convert the pattern into an optimized regular expression. This is easier said than done, and braces is the only library that does this currently. + +**The proof is in the numbers** + +Minimatch gets exponentially slower as patterns increase in complexity, braces does not. The following results were generated using `braces()` and `minimatch.braceExpand()`, respectively. + +| **Pattern** | **braces** | **[minimatch][]** | +| --- | --- | --- | +| `{1..9007199254740991}`[^1] | `298 B` (5ms 459μs)| N/A (freezes) | +| `{1..1000000000000000}` | `41 B` (1ms 15μs) | N/A (freezes) | +| `{1..100000000000000}` | `40 B` (890μs) | N/A (freezes) | +| `{1..10000000000000}` | `39 B` (2ms 49μs) | N/A (freezes) | +| `{1..1000000000000}` | `38 B` (608μs) | N/A (freezes) | +| `{1..100000000000}` | `37 B` (397μs) | N/A (freezes) | +| `{1..10000000000}` | `35 B` (983μs) | N/A (freezes) | +| `{1..1000000000}` | `34 B` (798μs) | N/A (freezes) | +| `{1..100000000}` | `33 B` (733μs) | N/A (freezes) | +| `{1..10000000}` | `32 B` (5ms 632μs) | `78.89 MB` (16s 388ms 569μs) | +| `{1..1000000}` | `31 B` (1ms 381μs) | `6.89 MB` (1s 496ms 887μs) | +| `{1..100000}` | `30 B` (950μs) | `588.89 kB` (146ms 921μs) | +| `{1..10000}` | `29 B` (1ms 114μs) | `48.89 kB` (14ms 187μs) | +| `{1..1000}` | `28 B` (760μs) | `3.89 kB` (1ms 453μs) | +| `{1..100}` | `22 B` (345μs) | `291 B` (196μs) | +| `{1..10}` | `10 B` (533μs) | `20 B` (37μs) | +| `{1..3}` | `7 B` (190μs) | `5 B` (27μs) | + +### Faster algorithms + +When you need expansion, braces is still much faster. + +_(the following results were generated using `braces.expand()` and `minimatch.braceExpand()`, respectively)_ + +| **Pattern** | **braces** | **[minimatch][]** | +| --- | --- | --- | +| `{1..10000000}` | `78.89 MB` (2s 698ms 642μs) | `78.89 MB` (18s 601ms 974μs) | +| `{1..1000000}` | `6.89 MB` (458ms 576μs) | `6.89 MB` (1s 491ms 621μs) | +| `{1..100000}` | `588.89 kB` (20ms 728μs) | `588.89 kB` (156ms 919μs) | +| `{1..10000}` | `48.89 kB` (2ms 202μs) | `48.89 kB` (13ms 641μs) | +| `{1..1000}` | `3.89 kB` (1ms 796μs) | `3.89 kB` (1ms 958μs) | +| `{1..100}` | `291 B` (424μs) | `291 B` (211μs) | +| `{1..10}` | `20 B` (487μs) | `20 B` (72μs) | +| `{1..3}` | `5 B` (166μs) | `5 B` (27μs) | + +If you'd like to run these comparisons yourself, see [test/support/generate.js](test/support/generate.js). + +## Benchmarks + +### Running benchmarks + +Install dev dependencies: + +```bash +npm i -d && npm benchmark +``` + +### Latest results + +Braces is more accurate, without sacrificing performance. + +```bash +# range (expanded) + braces x 29,040 ops/sec ±3.69% (91 runs sampled)) + minimatch x 4,735 ops/sec ±1.28% (90 runs sampled) + +# range (optimized for regex) + braces x 382,878 ops/sec ±0.56% (94 runs sampled) + minimatch x 1,040 ops/sec ±0.44% (93 runs sampled) + +# nested ranges (expanded) + braces x 19,744 ops/sec ±2.27% (92 runs sampled)) + minimatch x 4,579 ops/sec ±0.50% (93 runs sampled) + +# nested ranges (optimized for regex) + braces x 246,019 ops/sec ±2.02% (93 runs sampled) + minimatch x 1,028 ops/sec ±0.39% (94 runs sampled) + +# set (expanded) + braces x 138,641 ops/sec ±0.53% (95 runs sampled) + minimatch x 219,582 ops/sec ±0.98% (94 runs sampled) + +# set (optimized for regex) + braces x 388,408 ops/sec ±0.41% (95 runs sampled) + minimatch x 44,724 ops/sec ±0.91% (89 runs sampled) + +# nested sets (expanded) + braces x 84,966 ops/sec ±0.48% (94 runs sampled) + minimatch x 140,720 ops/sec ±0.37% (95 runs sampled) + +# nested sets (optimized for regex) + braces x 263,340 ops/sec ±2.06% (92 runs sampled) + minimatch x 28,714 ops/sec ±0.40% (90 runs sampled) +``` + +## About + +
+Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +
+ +
+Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` + +
+ +
+Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +$ npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
+ +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 197 | [jonschlinkert](https://github.com/jonschlinkert) | +| 4 | [doowb](https://github.com/doowb) | +| 1 | [es128](https://github.com/es128) | +| 1 | [eush77](https://github.com/eush77) | +| 1 | [hemanth](https://github.com/hemanth) | +| 1 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) | + +### Author + +**Jon Schlinkert** + +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +### License + +Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 08, 2019._ \ No newline at end of file diff --git a/libs/events/node_modules/braces/index.js b/libs/events/node_modules/braces/index.js new file mode 100644 index 000000000..0eee0f567 --- /dev/null +++ b/libs/events/node_modules/braces/index.js @@ -0,0 +1,170 @@ +'use strict'; + +const stringify = require('./lib/stringify'); +const compile = require('./lib/compile'); +const expand = require('./lib/expand'); +const parse = require('./lib/parse'); + +/** + * Expand the given pattern or create a regex-compatible string. + * + * ```js + * const braces = require('braces'); + * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] + * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {String} + * @api public + */ + +const braces = (input, options = {}) => { + let output = []; + + if (Array.isArray(input)) { + for (let pattern of input) { + let result = braces.create(pattern, options); + if (Array.isArray(result)) { + output.push(...result); + } else { + output.push(result); + } + } + } else { + output = [].concat(braces.create(input, options)); + } + + if (options && options.expand === true && options.nodupes === true) { + output = [...new Set(output)]; + } + return output; +}; + +/** + * Parse the given `str` with the given `options`. + * + * ```js + * // braces.parse(pattern, [, options]); + * const ast = braces.parse('a/{b,c}/d'); + * console.log(ast); + * ``` + * @param {String} pattern Brace pattern to parse + * @param {Object} options + * @return {Object} Returns an AST + * @api public + */ + +braces.parse = (input, options = {}) => parse(input, options); + +/** + * Creates a braces string from an AST, or an AST node. + * + * ```js + * const braces = require('braces'); + * let ast = braces.parse('foo/{a,b}/bar'); + * console.log(stringify(ast.nodes[2])); //=> '{a,b}' + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.stringify = (input, options = {}) => { + if (typeof input === 'string') { + return stringify(braces.parse(input, options), options); + } + return stringify(input, options); +}; + +/** + * Compiles a brace pattern into a regex-compatible, optimized string. + * This method is called by the main [braces](#braces) function by default. + * + * ```js + * const braces = require('braces'); + * console.log(braces.compile('a/{b,c}/d')); + * //=> ['a/(b|c)/d'] + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.compile = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } + return compile(input, options); +}; + +/** + * Expands a brace pattern into an array. This method is called by the + * main [braces](#braces) function when `options.expand` is true. Before + * using this method it's recommended that you read the [performance notes](#performance)) + * and advantages of using [.compile](#compile) instead. + * + * ```js + * const braces = require('braces'); + * console.log(braces.expand('a/{b,c}/d')); + * //=> ['a/b/d', 'a/c/d']; + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.expand = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } + + let result = expand(input, options); + + // filter out empty strings if specified + if (options.noempty === true) { + result = result.filter(Boolean); + } + + // filter out duplicates if specified + if (options.nodupes === true) { + result = [...new Set(result)]; + } + + return result; +}; + +/** + * Processes a brace pattern and returns either an expanded array + * (if `options.expand` is true), a highly optimized regex-compatible string. + * This method is called by the main [braces](#braces) function. + * + * ```js + * const braces = require('braces'); + * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) + * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.create = (input, options = {}) => { + if (input === '' || input.length < 3) { + return [input]; + } + + return options.expand !== true + ? braces.compile(input, options) + : braces.expand(input, options); +}; + +/** + * Expose "braces" + */ + +module.exports = braces; diff --git a/libs/events/node_modules/braces/lib/compile.js b/libs/events/node_modules/braces/lib/compile.js new file mode 100644 index 000000000..3e984a4bb --- /dev/null +++ b/libs/events/node_modules/braces/lib/compile.js @@ -0,0 +1,57 @@ +'use strict'; + +const fill = require('fill-range'); +const utils = require('./utils'); + +const compile = (ast, options = {}) => { + let walk = (node, parent = {}) => { + let invalidBlock = utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let invalid = invalidBlock === true || invalidNode === true; + let prefix = options.escapeInvalid === true ? '\\' : ''; + let output = ''; + + if (node.isOpen === true) { + return prefix + node.value; + } + if (node.isClose === true) { + return prefix + node.value; + } + + if (node.type === 'open') { + return invalid ? (prefix + node.value) : '('; + } + + if (node.type === 'close') { + return invalid ? (prefix + node.value) : ')'; + } + + if (node.type === 'comma') { + return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); + } + + if (node.value) { + return node.value; + } + + if (node.nodes && node.ranges > 0) { + let args = utils.reduce(node.nodes); + let range = fill(...args, { ...options, wrap: false, toRegex: true }); + + if (range.length !== 0) { + return args.length > 1 && range.length > 1 ? `(${range})` : range; + } + } + + if (node.nodes) { + for (let child of node.nodes) { + output += walk(child, node); + } + } + return output; + }; + + return walk(ast); +}; + +module.exports = compile; diff --git a/libs/events/node_modules/braces/lib/constants.js b/libs/events/node_modules/braces/lib/constants.js new file mode 100644 index 000000000..a93794366 --- /dev/null +++ b/libs/events/node_modules/braces/lib/constants.js @@ -0,0 +1,57 @@ +'use strict'; + +module.exports = { + MAX_LENGTH: 1024 * 64, + + // Digits + CHAR_0: '0', /* 0 */ + CHAR_9: '9', /* 9 */ + + // Alphabet chars. + CHAR_UPPERCASE_A: 'A', /* A */ + CHAR_LOWERCASE_A: 'a', /* a */ + CHAR_UPPERCASE_Z: 'Z', /* Z */ + CHAR_LOWERCASE_Z: 'z', /* z */ + + CHAR_LEFT_PARENTHESES: '(', /* ( */ + CHAR_RIGHT_PARENTHESES: ')', /* ) */ + + CHAR_ASTERISK: '*', /* * */ + + // Non-alphabetic chars. + CHAR_AMPERSAND: '&', /* & */ + CHAR_AT: '@', /* @ */ + CHAR_BACKSLASH: '\\', /* \ */ + CHAR_BACKTICK: '`', /* ` */ + CHAR_CARRIAGE_RETURN: '\r', /* \r */ + CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ + CHAR_COLON: ':', /* : */ + CHAR_COMMA: ',', /* , */ + CHAR_DOLLAR: '$', /* . */ + CHAR_DOT: '.', /* . */ + CHAR_DOUBLE_QUOTE: '"', /* " */ + CHAR_EQUAL: '=', /* = */ + CHAR_EXCLAMATION_MARK: '!', /* ! */ + CHAR_FORM_FEED: '\f', /* \f */ + CHAR_FORWARD_SLASH: '/', /* / */ + CHAR_HASH: '#', /* # */ + CHAR_HYPHEN_MINUS: '-', /* - */ + CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ + CHAR_LEFT_CURLY_BRACE: '{', /* { */ + CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ + CHAR_LINE_FEED: '\n', /* \n */ + CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ + CHAR_PERCENT: '%', /* % */ + CHAR_PLUS: '+', /* + */ + CHAR_QUESTION_MARK: '?', /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ + CHAR_RIGHT_CURLY_BRACE: '}', /* } */ + CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ + CHAR_SEMICOLON: ';', /* ; */ + CHAR_SINGLE_QUOTE: '\'', /* ' */ + CHAR_SPACE: ' ', /* */ + CHAR_TAB: '\t', /* \t */ + CHAR_UNDERSCORE: '_', /* _ */ + CHAR_VERTICAL_LINE: '|', /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ +}; diff --git a/libs/events/node_modules/braces/lib/expand.js b/libs/events/node_modules/braces/lib/expand.js new file mode 100644 index 000000000..376c748af --- /dev/null +++ b/libs/events/node_modules/braces/lib/expand.js @@ -0,0 +1,113 @@ +'use strict'; + +const fill = require('fill-range'); +const stringify = require('./stringify'); +const utils = require('./utils'); + +const append = (queue = '', stash = '', enclose = false) => { + let result = []; + + queue = [].concat(queue); + stash = [].concat(stash); + + if (!stash.length) return queue; + if (!queue.length) { + return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; + } + + for (let item of queue) { + if (Array.isArray(item)) { + for (let value of item) { + result.push(append(value, stash, enclose)); + } + } else { + for (let ele of stash) { + if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; + result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); + } + } + } + return utils.flatten(result); +}; + +const expand = (ast, options = {}) => { + let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; + + let walk = (node, parent = {}) => { + node.queue = []; + + let p = parent; + let q = parent.queue; + + while (p.type !== 'brace' && p.type !== 'root' && p.parent) { + p = p.parent; + q = p.queue; + } + + if (node.invalid || node.dollar) { + q.push(append(q.pop(), stringify(node, options))); + return; + } + + if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { + q.push(append(q.pop(), ['{}'])); + return; + } + + if (node.nodes && node.ranges > 0) { + let args = utils.reduce(node.nodes); + + if (utils.exceedsLimit(...args, options.step, rangeLimit)) { + throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); + } + + let range = fill(...args, options); + if (range.length === 0) { + range = stringify(node, options); + } + + q.push(append(q.pop(), range)); + node.nodes = []; + return; + } + + let enclose = utils.encloseBrace(node); + let queue = node.queue; + let block = node; + + while (block.type !== 'brace' && block.type !== 'root' && block.parent) { + block = block.parent; + queue = block.queue; + } + + for (let i = 0; i < node.nodes.length; i++) { + let child = node.nodes[i]; + + if (child.type === 'comma' && node.type === 'brace') { + if (i === 1) queue.push(''); + queue.push(''); + continue; + } + + if (child.type === 'close') { + q.push(append(q.pop(), queue, enclose)); + continue; + } + + if (child.value && child.type !== 'open') { + queue.push(append(queue.pop(), child.value)); + continue; + } + + if (child.nodes) { + walk(child, node); + } + } + + return queue; + }; + + return utils.flatten(walk(ast)); +}; + +module.exports = expand; diff --git a/libs/events/node_modules/braces/lib/parse.js b/libs/events/node_modules/braces/lib/parse.js new file mode 100644 index 000000000..145ea2648 --- /dev/null +++ b/libs/events/node_modules/braces/lib/parse.js @@ -0,0 +1,333 @@ +'use strict'; + +const stringify = require('./stringify'); + +/** + * Constants + */ + +const { + MAX_LENGTH, + CHAR_BACKSLASH, /* \ */ + CHAR_BACKTICK, /* ` */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_RIGHT_SQUARE_BRACKET, /* ] */ + CHAR_DOUBLE_QUOTE, /* " */ + CHAR_SINGLE_QUOTE, /* ' */ + CHAR_NO_BREAK_SPACE, + CHAR_ZERO_WIDTH_NOBREAK_SPACE +} = require('./constants'); + +/** + * parse + */ + +const parse = (input, options = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); + } + + let opts = options || {}; + let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + if (input.length > max) { + throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); + } + + let ast = { type: 'root', input, nodes: [] }; + let stack = [ast]; + let block = ast; + let prev = ast; + let brackets = 0; + let length = input.length; + let index = 0; + let depth = 0; + let value; + let memo = {}; + + /** + * Helpers + */ + + const advance = () => input[index++]; + const push = node => { + if (node.type === 'text' && prev.type === 'dot') { + prev.type = 'text'; + } + + if (prev && prev.type === 'text' && node.type === 'text') { + prev.value += node.value; + return; + } + + block.nodes.push(node); + node.parent = block; + node.prev = prev; + prev = node; + return node; + }; + + push({ type: 'bos' }); + + while (index < length) { + block = stack[stack.length - 1]; + value = advance(); + + /** + * Invalid chars + */ + + if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { + continue; + } + + /** + * Escaped chars + */ + + if (value === CHAR_BACKSLASH) { + push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); + continue; + } + + /** + * Right square bracket (literal): ']' + */ + + if (value === CHAR_RIGHT_SQUARE_BRACKET) { + push({ type: 'text', value: '\\' + value }); + continue; + } + + /** + * Left square bracket: '[' + */ + + if (value === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + + let closed = true; + let next; + + while (index < length && (next = advance())) { + value += next; + + if (next === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + continue; + } + + if (next === CHAR_BACKSLASH) { + value += advance(); + continue; + } + + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + brackets--; + + if (brackets === 0) { + break; + } + } + } + + push({ type: 'text', value }); + continue; + } + + /** + * Parentheses + */ + + if (value === CHAR_LEFT_PARENTHESES) { + block = push({ type: 'paren', nodes: [] }); + stack.push(block); + push({ type: 'text', value }); + continue; + } + + if (value === CHAR_RIGHT_PARENTHESES) { + if (block.type !== 'paren') { + push({ type: 'text', value }); + continue; + } + block = stack.pop(); + push({ type: 'text', value }); + block = stack[stack.length - 1]; + continue; + } + + /** + * Quotes: '|"|` + */ + + if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { + let open = value; + let next; + + if (options.keepQuotes !== true) { + value = ''; + } + + while (index < length && (next = advance())) { + if (next === CHAR_BACKSLASH) { + value += next + advance(); + continue; + } + + if (next === open) { + if (options.keepQuotes === true) value += next; + break; + } + + value += next; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Left curly brace: '{' + */ + + if (value === CHAR_LEFT_CURLY_BRACE) { + depth++; + + let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; + let brace = { + type: 'brace', + open: true, + close: false, + dollar, + depth, + commas: 0, + ranges: 0, + nodes: [] + }; + + block = push(brace); + stack.push(block); + push({ type: 'open', value }); + continue; + } + + /** + * Right curly brace: '}' + */ + + if (value === CHAR_RIGHT_CURLY_BRACE) { + if (block.type !== 'brace') { + push({ type: 'text', value }); + continue; + } + + let type = 'close'; + block = stack.pop(); + block.close = true; + + push({ type, value }); + depth--; + + block = stack[stack.length - 1]; + continue; + } + + /** + * Comma: ',' + */ + + if (value === CHAR_COMMA && depth > 0) { + if (block.ranges > 0) { + block.ranges = 0; + let open = block.nodes.shift(); + block.nodes = [open, { type: 'text', value: stringify(block) }]; + } + + push({ type: 'comma', value }); + block.commas++; + continue; + } + + /** + * Dot: '.' + */ + + if (value === CHAR_DOT && depth > 0 && block.commas === 0) { + let siblings = block.nodes; + + if (depth === 0 || siblings.length === 0) { + push({ type: 'text', value }); + continue; + } + + if (prev.type === 'dot') { + block.range = []; + prev.value += value; + prev.type = 'range'; + + if (block.nodes.length !== 3 && block.nodes.length !== 5) { + block.invalid = true; + block.ranges = 0; + prev.type = 'text'; + continue; + } + + block.ranges++; + block.args = []; + continue; + } + + if (prev.type === 'range') { + siblings.pop(); + + let before = siblings[siblings.length - 1]; + before.value += prev.value + value; + prev = before; + block.ranges--; + continue; + } + + push({ type: 'dot', value }); + continue; + } + + /** + * Text + */ + + push({ type: 'text', value }); + } + + // Mark imbalanced braces and brackets as invalid + do { + block = stack.pop(); + + if (block.type !== 'root') { + block.nodes.forEach(node => { + if (!node.nodes) { + if (node.type === 'open') node.isOpen = true; + if (node.type === 'close') node.isClose = true; + if (!node.nodes) node.type = 'text'; + node.invalid = true; + } + }); + + // get the location of the block on parent.nodes (block's siblings) + let parent = stack[stack.length - 1]; + let index = parent.nodes.indexOf(block); + // replace the (invalid) block with it's nodes + parent.nodes.splice(index, 1, ...block.nodes); + } + } while (stack.length > 0); + + push({ type: 'eos' }); + return ast; +}; + +module.exports = parse; diff --git a/libs/events/node_modules/braces/lib/stringify.js b/libs/events/node_modules/braces/lib/stringify.js new file mode 100644 index 000000000..414b7bcc6 --- /dev/null +++ b/libs/events/node_modules/braces/lib/stringify.js @@ -0,0 +1,32 @@ +'use strict'; + +const utils = require('./utils'); + +module.exports = (ast, options = {}) => { + let stringify = (node, parent = {}) => { + let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let output = ''; + + if (node.value) { + if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { + return '\\' + node.value; + } + return node.value; + } + + if (node.value) { + return node.value; + } + + if (node.nodes) { + for (let child of node.nodes) { + output += stringify(child); + } + } + return output; + }; + + return stringify(ast); +}; + diff --git a/libs/events/node_modules/braces/lib/utils.js b/libs/events/node_modules/braces/lib/utils.js new file mode 100644 index 000000000..e3551a674 --- /dev/null +++ b/libs/events/node_modules/braces/lib/utils.js @@ -0,0 +1,112 @@ +'use strict'; + +exports.isInteger = num => { + if (typeof num === 'number') { + return Number.isInteger(num); + } + if (typeof num === 'string' && num.trim() !== '') { + return Number.isInteger(Number(num)); + } + return false; +}; + +/** + * Find a node of the given type + */ + +exports.find = (node, type) => node.nodes.find(node => node.type === type); + +/** + * Find a node of the given type + */ + +exports.exceedsLimit = (min, max, step = 1, limit) => { + if (limit === false) return false; + if (!exports.isInteger(min) || !exports.isInteger(max)) return false; + return ((Number(max) - Number(min)) / Number(step)) >= limit; +}; + +/** + * Escape the given node with '\\' before node.value + */ + +exports.escapeNode = (block, n = 0, type) => { + let node = block.nodes[n]; + if (!node) return; + + if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { + if (node.escaped !== true) { + node.value = '\\' + node.value; + node.escaped = true; + } + } +}; + +/** + * Returns true if the given brace node should be enclosed in literal braces + */ + +exports.encloseBrace = node => { + if (node.type !== 'brace') return false; + if ((node.commas >> 0 + node.ranges >> 0) === 0) { + node.invalid = true; + return true; + } + return false; +}; + +/** + * Returns true if a brace node is invalid. + */ + +exports.isInvalidBrace = block => { + if (block.type !== 'brace') return false; + if (block.invalid === true || block.dollar) return true; + if ((block.commas >> 0 + block.ranges >> 0) === 0) { + block.invalid = true; + return true; + } + if (block.open !== true || block.close !== true) { + block.invalid = true; + return true; + } + return false; +}; + +/** + * Returns true if a node is an open or close node + */ + +exports.isOpenOrClose = node => { + if (node.type === 'open' || node.type === 'close') { + return true; + } + return node.open === true || node.close === true; +}; + +/** + * Reduce an array of text nodes. + */ + +exports.reduce = nodes => nodes.reduce((acc, node) => { + if (node.type === 'text') acc.push(node.value); + if (node.type === 'range') node.type = 'text'; + return acc; +}, []); + +/** + * Flatten an array + */ + +exports.flatten = (...args) => { + const result = []; + const flat = arr => { + for (let i = 0; i < arr.length; i++) { + let ele = arr[i]; + Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele); + } + return result; + }; + flat(args); + return result; +}; diff --git a/libs/events/node_modules/braces/package.json b/libs/events/node_modules/braces/package.json new file mode 100644 index 000000000..3f52e346f --- /dev/null +++ b/libs/events/node_modules/braces/package.json @@ -0,0 +1,77 @@ +{ + "name": "braces", + "description": "Bash-like brace expansion, implemented in JavaScript. Safer than other brace expansion libs, with complete support for the Bash 4.3 braces specification, without sacrificing speed.", + "version": "3.0.2", + "homepage": "https://github.com/micromatch/braces", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "contributors": [ + "Brian Woodward (https://twitter.com/doowb)", + "Elan Shanker (https://github.com/es128)", + "Eugene Sharygin (https://github.com/eush77)", + "hemanth.hm (http://h3manth.com)", + "Jon Schlinkert (http://twitter.com/jonschlinkert)" + ], + "repository": "micromatch/braces", + "bugs": { + "url": "https://github.com/micromatch/braces/issues" + }, + "license": "MIT", + "files": [ + "index.js", + "lib" + ], + "main": "index.js", + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "mocha", + "benchmark": "node benchmark" + }, + "dependencies": { + "fill-range": "^7.0.1" + }, + "devDependencies": { + "ansi-colors": "^3.2.4", + "bash-path": "^2.0.1", + "gulp-format-md": "^2.0.0", + "mocha": "^6.1.1" + }, + "keywords": [ + "alpha", + "alphabetical", + "bash", + "brace", + "braces", + "expand", + "expansion", + "filepath", + "fill", + "fs", + "glob", + "globbing", + "letter", + "match", + "matches", + "matching", + "number", + "numerical", + "path", + "range", + "ranges", + "sh" + ], + "verb": { + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "lint": { + "reflinks": true + }, + "plugins": [ + "gulp-format-md" + ] + } +} diff --git a/libs/events/node_modules/extend/.editorconfig b/libs/events/node_modules/extend/.editorconfig new file mode 100644 index 000000000..bc228f826 --- /dev/null +++ b/libs/events/node_modules/extend/.editorconfig @@ -0,0 +1,20 @@ +root = true + +[*] +indent_style = tab +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 150 + +[CHANGELOG.md] +indent_style = space +indent_size = 2 + +[*.json] +max_line_length = off + +[Makefile] +max_line_length = off diff --git a/libs/events/node_modules/extend/.eslintrc b/libs/events/node_modules/extend/.eslintrc new file mode 100644 index 000000000..a34cf2831 --- /dev/null +++ b/libs/events/node_modules/extend/.eslintrc @@ -0,0 +1,17 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "complexity": [2, 20], + "eqeqeq": [2, "allow-null"], + "func-name-matching": [1], + "max-depth": [1, 4], + "max-statements": [2, 26], + "no-extra-parens": [1], + "no-magic-numbers": [0], + "no-restricted-syntax": [2, "BreakStatement", "ContinueStatement", "DebuggerStatement", "LabeledStatement", "WithStatement"], + "sort-keys": [0], + } +} diff --git a/libs/events/node_modules/extend/.jscs.json b/libs/events/node_modules/extend/.jscs.json new file mode 100644 index 000000000..3cce01d78 --- /dev/null +++ b/libs/events/node_modules/extend/.jscs.json @@ -0,0 +1,175 @@ +{ + "es3": true, + + "additionalRules": [], + + "requireSemicolons": true, + + "disallowMultipleSpaces": true, + + "disallowIdentifierNames": [], + + "requireCurlyBraces": { + "allExcept": [], + "keywords": ["if", "else", "for", "while", "do", "try", "catch"] + }, + + "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"], + + "disallowSpaceAfterKeywords": [], + + "disallowSpaceBeforeComma": true, + "disallowSpaceAfterComma": false, + "disallowSpaceBeforeSemicolon": true, + + "disallowNodeTypes": [ + "DebuggerStatement", + "LabeledStatement", + "SwitchCase", + "SwitchStatement", + "WithStatement" + ], + + "requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] }, + + "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true }, + "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true }, + "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true }, + "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true }, + "disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true }, + + "requireSpaceBetweenArguments": true, + + "disallowSpacesInsideParentheses": true, + + "disallowSpacesInsideArrayBrackets": true, + + "disallowQuotedKeysInObjects": { "allExcept": ["reserved"] }, + + "disallowSpaceAfterObjectKeys": true, + + "requireCommaBeforeLineBreak": true, + + "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], + "requireSpaceAfterPrefixUnaryOperators": [], + + "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], + "requireSpaceBeforePostfixUnaryOperators": [], + + "disallowSpaceBeforeBinaryOperators": [], + "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], + + "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], + "disallowSpaceAfterBinaryOperators": [], + + "disallowImplicitTypeConversion": ["binary", "string"], + + "disallowKeywords": ["with", "eval"], + + "requireKeywordsOnNewLine": [], + "disallowKeywordsOnNewLine": ["else"], + + "requireLineFeedAtFileEnd": true, + + "disallowTrailingWhitespace": true, + + "disallowTrailingComma": true, + + "excludeFiles": ["node_modules/**", "vendor/**"], + + "disallowMultipleLineStrings": true, + + "requireDotNotation": { "allExcept": ["keywords"] }, + + "requireParenthesesAroundIIFE": true, + + "validateLineBreaks": "LF", + + "validateQuoteMarks": { + "escape": true, + "mark": "'" + }, + + "disallowOperatorBeforeLineBreak": [], + + "requireSpaceBeforeKeywords": [ + "do", + "for", + "if", + "else", + "switch", + "case", + "try", + "catch", + "finally", + "while", + "with", + "return" + ], + + "validateAlignedFunctionParameters": { + "lineBreakAfterOpeningBraces": true, + "lineBreakBeforeClosingBraces": true + }, + + "requirePaddingNewLinesBeforeExport": true, + + "validateNewlineAfterArrayElements": { + "maximum": 6 + }, + + "requirePaddingNewLinesAfterUseStrict": true, + + "disallowArrowFunctions": true, + + "disallowMultiLineTernary": true, + + "validateOrderInObjectKeys": false, + + "disallowIdenticalDestructuringNames": true, + + "disallowNestedTernaries": { "maxLevel": 1 }, + + "requireSpaceAfterComma": { "allExcept": ["trailing"] }, + "requireAlignedMultilineParams": false, + + "requireSpacesInGenerator": { + "afterStar": true + }, + + "disallowSpacesInGenerator": { + "beforeStar": true + }, + + "disallowVar": false, + + "requireArrayDestructuring": false, + + "requireEnhancedObjectLiterals": false, + + "requireObjectDestructuring": false, + + "requireEarlyReturn": false, + + "requireCapitalizedConstructorsNew": { + "allExcept": ["Function", "String", "Object", "Symbol", "Number", "Date", "RegExp", "Error", "Boolean", "Array"] + }, + + "requireImportAlphabetized": false, + + "requireSpaceBeforeObjectValues": true, + "requireSpaceBeforeDestructuredValues": true, + + "disallowSpacesInsideTemplateStringPlaceholders": true, + + "disallowArrayDestructuringReturn": false, + + "requireNewlineBeforeSingleStatementsInIf": false, + + "disallowUnusedVariables": true, + + "requireSpacesInsideImportedObjectBraces": true, + + "requireUseStrict": true +} + diff --git a/libs/events/node_modules/extend/.travis.yml b/libs/events/node_modules/extend/.travis.yml new file mode 100644 index 000000000..5ccdfc494 --- /dev/null +++ b/libs/events/node_modules/extend/.travis.yml @@ -0,0 +1,230 @@ +language: node_js +os: + - linux +node_js: + - "10.7" + - "9.11" + - "8.11" + - "7.10" + - "6.14" + - "5.12" + - "4.9" + - "iojs-v3.3" + - "iojs-v2.5" + - "iojs-v1.8" + - "0.12" + - "0.10" + - "0.8" +before_install: + - 'case "${TRAVIS_NODE_VERSION}" in 0.*) export NPM_CONFIG_STRICT_SSL=false ;; esac' + - 'nvm install-latest-npm' +install: + - 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ] || [ "${TRAVIS_NODE_VERSION}" = "0.9" ]; then nvm install --latest-npm 0.8 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;' +script: + - 'if [ -n "${PRETEST-}" ]; then npm run pretest ; fi' + - 'if [ -n "${POSTTEST-}" ]; then npm run posttest ; fi' + - 'if [ -n "${COVERAGE-}" ]; then npm run coverage ; fi' + - 'if [ -n "${TEST-}" ]; then npm run tests-only ; fi' +sudo: false +env: + - TEST=true +matrix: + fast_finish: true + include: + - node_js: "lts/*" + env: PRETEST=true + - node_js: "lts/*" + env: POSTTEST=true + - node_js: "4" + env: COVERAGE=true + - node_js: "10.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "10.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "10.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "10.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "10.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "10.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "10.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.10" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.10" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.13" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.12" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.11" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.10" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.11" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.10" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v3.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v3.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v3.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "0.11" + env: TEST=true ALLOW_FAILURE=true + - node_js: "0.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "0.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "0.4" + env: TEST=true ALLOW_FAILURE=true + allow_failures: + - os: osx + - env: TEST=true ALLOW_FAILURE=true diff --git a/libs/events/node_modules/extend/CHANGELOG.md b/libs/events/node_modules/extend/CHANGELOG.md new file mode 100644 index 000000000..2cf7de6fb --- /dev/null +++ b/libs/events/node_modules/extend/CHANGELOG.md @@ -0,0 +1,83 @@ +3.0.2 / 2018-07-19 +================== + * [Fix] Prevent merging `__proto__` property (#48) + * [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape` + * [Tests] up to `node` `v10.7`, `v9.11`, `v8.11`, `v7.10`, `v6.14`, `v4.9`; use `nvm install-latest-npm` + +3.0.1 / 2017-04-27 +================== + * [Fix] deep extending should work with a non-object (#46) + * [Dev Deps] update `tape`, `eslint`, `@ljharb/eslint-config` + * [Tests] up to `node` `v7.9`, `v6.10`, `v4.8`; improve matrix + * [Docs] Switch from vb.teelaun.ch to versionbadg.es for the npm version badge SVG. + * [Docs] Add example to readme (#34) + +3.0.0 / 2015-07-01 +================== + * [Possible breaking change] Use global "strict" directive (#32) + * [Tests] `int` is an ES3 reserved word + * [Tests] Test up to `io.js` `v2.3` + * [Tests] Add `npm run eslint` + * [Dev Deps] Update `covert`, `jscs` + +2.0.1 / 2015-04-25 +================== + * Use an inline `isArray` check, for ES3 browsers. (#27) + * Some old browsers fail when an identifier is `toString` + * Test latest `node` and `io.js` versions on `travis-ci`; speed up builds + * Add license info to package.json (#25) + * Update `tape`, `jscs` + * Adding a CHANGELOG + +2.0.0 / 2014-10-01 +================== + * Increase code coverage to 100%; run code coverage as part of tests + * Add `npm run lint`; Run linter as part of tests + * Remove nodeType and setInterval checks in isPlainObject + * Updating `tape`, `jscs`, `covert` + * General style and README cleanup + +1.3.0 / 2014-06-20 +================== + * Add component.json for browser support (#18) + * Use SVG for badges in README (#16) + * Updating `tape`, `covert` + * Updating travis-ci to work with multiple node versions + * Fix `deep === false` bug (returning target as {}) (#14) + * Fixing constructor checks in isPlainObject + * Adding additional test coverage + * Adding `npm run coverage` + * Add LICENSE (#13) + * Adding a warning about `false`, per #11 + * General style and whitespace cleanup + +1.2.1 / 2013-09-14 +================== + * Fixing hasOwnProperty bugs that would only have shown up in specific browsers. Fixes #8 + * Updating `tape` + +1.2.0 / 2013-09-02 +================== + * Updating the README: add badges + * Adding a missing variable reference. + * Using `tape` instead of `buster` for tests; add more tests (#7) + * Adding node 0.10 to Travis CI (#6) + * Enabling "npm test" and cleaning up package.json (#5) + * Add Travis CI. + +1.1.3 / 2012-12-06 +================== + * Added unit tests. + * Ensure extend function is named. (Looks nicer in a stack trace.) + * README cleanup. + +1.1.1 / 2012-11-07 +================== + * README cleanup. + * Added installation instructions. + * Added a missing semicolon + +1.0.0 / 2012-04-08 +================== + * Initial commit + diff --git a/libs/events/node_modules/extend/LICENSE b/libs/events/node_modules/extend/LICENSE new file mode 100644 index 000000000..e16d6a56c --- /dev/null +++ b/libs/events/node_modules/extend/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2014 Stefan Thomas + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/libs/events/node_modules/extend/README.md b/libs/events/node_modules/extend/README.md new file mode 100644 index 000000000..5b8249aa9 --- /dev/null +++ b/libs/events/node_modules/extend/README.md @@ -0,0 +1,81 @@ +[![Build Status][travis-svg]][travis-url] +[![dependency status][deps-svg]][deps-url] +[![dev dependency status][dev-deps-svg]][dev-deps-url] + +# extend() for Node.js [![Version Badge][npm-version-png]][npm-url] + +`node-extend` is a port of the classic extend() method from jQuery. It behaves as you expect. It is simple, tried and true. + +Notes: + +* Since Node.js >= 4, + [`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + now offers the same functionality natively (but without the "deep copy" option). + See [ECMAScript 2015 (ES6) in Node.js](https://nodejs.org/en/docs/es6). +* Some native implementations of `Object.assign` in both Node.js and many + browsers (since NPM modules are for the browser too) may not be fully + spec-compliant. + Check [`object.assign`](https://www.npmjs.com/package/object.assign) module for + a compliant candidate. + +## Installation + +This package is available on [npm][npm-url] as: `extend` + +``` sh +npm install extend +``` + +## Usage + +**Syntax:** extend **(** [`deep`], `target`, `object1`, [`objectN`] **)** + +*Extend one object with one or more others, returning the modified object.* + +**Example:** + +``` js +var extend = require('extend'); +extend(targetObject, object1, object2); +``` + +Keep in mind that the target object will be modified, and will be returned from extend(). + +If a boolean true is specified as the first argument, extend performs a deep copy, recursively copying any objects it finds. Otherwise, the copy will share structure with the original object(s). +Undefined properties are not copied. However, properties inherited from the object's prototype will be copied over. +Warning: passing `false` as the first argument is not supported. + +### Arguments + +* `deep` *Boolean* (optional) +If set, the merge becomes recursive (i.e. deep copy). +* `target` *Object* +The object to extend. +* `object1` *Object* +The object that will be merged into the first. +* `objectN` *Object* (Optional) +More objects to merge into the first. + +## License + +`node-extend` is licensed under the [MIT License][mit-license-url]. + +## Acknowledgements + +All credit to the jQuery authors for perfecting this amazing utility. + +Ported to Node.js by [Stefan Thomas][github-justmoon] with contributions by [Jonathan Buchanan][github-insin] and [Jordan Harband][github-ljharb]. + +[travis-svg]: https://travis-ci.org/justmoon/node-extend.svg +[travis-url]: https://travis-ci.org/justmoon/node-extend +[npm-url]: https://npmjs.org/package/extend +[mit-license-url]: http://opensource.org/licenses/MIT +[github-justmoon]: https://github.com/justmoon +[github-insin]: https://github.com/insin +[github-ljharb]: https://github.com/ljharb +[npm-version-png]: http://versionbadg.es/justmoon/node-extend.svg +[deps-svg]: https://david-dm.org/justmoon/node-extend.svg +[deps-url]: https://david-dm.org/justmoon/node-extend +[dev-deps-svg]: https://david-dm.org/justmoon/node-extend/dev-status.svg +[dev-deps-url]: https://david-dm.org/justmoon/node-extend#info=devDependencies + diff --git a/libs/events/node_modules/extend/component.json b/libs/events/node_modules/extend/component.json new file mode 100644 index 000000000..1500a2f37 --- /dev/null +++ b/libs/events/node_modules/extend/component.json @@ -0,0 +1,32 @@ +{ + "name": "extend", + "author": "Stefan Thomas (http://www.justmoon.net)", + "version": "3.0.0", + "description": "Port of jQuery.extend for node.js and the browser.", + "scripts": [ + "index.js" + ], + "contributors": [ + { + "name": "Jordan Harband", + "url": "https://github.com/ljharb" + } + ], + "keywords": [ + "extend", + "clone", + "merge" + ], + "repository" : { + "type": "git", + "url": "https://github.com/justmoon/node-extend.git" + }, + "dependencies": { + }, + "devDependencies": { + "tape" : "~3.0.0", + "covert": "~0.4.0", + "jscs": "~1.6.2" + } +} + diff --git a/libs/events/node_modules/extend/index.js b/libs/events/node_modules/extend/index.js new file mode 100644 index 000000000..2aa3faae6 --- /dev/null +++ b/libs/events/node_modules/extend/index.js @@ -0,0 +1,117 @@ +'use strict'; + +var hasOwn = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; +var defineProperty = Object.defineProperty; +var gOPD = Object.getOwnPropertyDescriptor; + +var isArray = function isArray(arr) { + if (typeof Array.isArray === 'function') { + return Array.isArray(arr); + } + + return toStr.call(arr) === '[object Array]'; +}; + +var isPlainObject = function isPlainObject(obj) { + if (!obj || toStr.call(obj) !== '[object Object]') { + return false; + } + + var hasOwnConstructor = hasOwn.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); + // Not own constructor property must be Object + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + var key; + for (key in obj) { /**/ } + + return typeof key === 'undefined' || hasOwn.call(obj, key); +}; + +// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target +var setProperty = function setProperty(target, options) { + if (defineProperty && options.name === '__proto__') { + defineProperty(target, options.name, { + enumerable: true, + configurable: true, + value: options.newValue, + writable: true + }); + } else { + target[options.name] = options.newValue; + } +}; + +// Return undefined instead of __proto__ if '__proto__' is not an own property +var getProperty = function getProperty(obj, name) { + if (name === '__proto__') { + if (!hasOwn.call(obj, name)) { + return void 0; + } else if (gOPD) { + // In early versions of node, obj['__proto__'] is buggy when obj has + // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. + return gOPD(obj, name).value; + } + } + + return obj[name]; +}; + +module.exports = function extend() { + var options, name, src, copy, copyIsArray, clone; + var target = arguments[0]; + var i = 1; + var length = arguments.length; + var deep = false; + + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { + target = {}; + } + + for (; i < length; ++i) { + options = arguments[i]; + // Only deal with non-null/undefined values + if (options != null) { + // Extend the base object + for (name in options) { + src = getProperty(target, name); + copy = getProperty(options, name); + + // Prevent never-ending loop + if (target !== copy) { + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + } else { + clone = src && isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); + + // Don't bring in undefined values + } else if (typeof copy !== 'undefined') { + setProperty(target, { name: name, newValue: copy }); + } + } + } + } + } + + // Return the modified object + return target; +}; diff --git a/libs/events/node_modules/extend/package.json b/libs/events/node_modules/extend/package.json new file mode 100644 index 000000000..85279f780 --- /dev/null +++ b/libs/events/node_modules/extend/package.json @@ -0,0 +1,42 @@ +{ + "name": "extend", + "author": "Stefan Thomas (http://www.justmoon.net)", + "version": "3.0.2", + "description": "Port of jQuery.extend for node.js and the browser", + "main": "index", + "scripts": { + "pretest": "npm run lint", + "test": "npm run tests-only", + "posttest": "npm run coverage-quiet", + "tests-only": "node test", + "coverage": "covert test/index.js", + "coverage-quiet": "covert test/index.js --quiet", + "lint": "npm run jscs && npm run eslint", + "jscs": "jscs *.js */*.js", + "eslint": "eslint *.js */*.js" + }, + "contributors": [ + { + "name": "Jordan Harband", + "url": "https://github.com/ljharb" + } + ], + "keywords": [ + "extend", + "clone", + "merge" + ], + "repository": { + "type": "git", + "url": "https://github.com/justmoon/node-extend.git" + }, + "dependencies": {}, + "devDependencies": { + "@ljharb/eslint-config": "^12.2.1", + "covert": "^1.1.0", + "eslint": "^4.19.1", + "jscs": "^3.0.7", + "tape": "^4.9.1" + }, + "license": "MIT" +} diff --git a/libs/events/node_modules/fast-deep-equal/LICENSE b/libs/events/node_modules/fast-deep-equal/LICENSE new file mode 100644 index 000000000..7f1543566 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Evgeny Poberezkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/fast-deep-equal/README.md b/libs/events/node_modules/fast-deep-equal/README.md new file mode 100644 index 000000000..d3f4ffcc3 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/README.md @@ -0,0 +1,96 @@ +# fast-deep-equal +The fastest deep equal with ES6 Map, Set and Typed arrays support. + +[![Build Status](https://travis-ci.org/epoberezkin/fast-deep-equal.svg?branch=master)](https://travis-ci.org/epoberezkin/fast-deep-equal) +[![npm](https://img.shields.io/npm/v/fast-deep-equal.svg)](https://www.npmjs.com/package/fast-deep-equal) +[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/fast-deep-equal/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/fast-deep-equal?branch=master) + + +## Install + +```bash +npm install fast-deep-equal +``` + + +## Features + +- ES5 compatible +- works in node.js (8+) and browsers (IE9+) +- checks equality of Date and RegExp objects by value. + +ES6 equal (`require('fast-deep-equal/es6')`) also supports: +- Maps +- Sets +- Typed arrays + + +## Usage + +```javascript +var equal = require('fast-deep-equal'); +console.log(equal({foo: 'bar'}, {foo: 'bar'})); // true +``` + +To support ES6 Maps, Sets and Typed arrays equality use: + +```javascript +var equal = require('fast-deep-equal/es6'); +console.log(equal(Int16Array([1, 2]), Int16Array([1, 2]))); // true +``` + +To use with React (avoiding the traversal of React elements' _owner +property that contains circular references and is not needed when +comparing the elements - borrowed from [react-fast-compare](https://github.com/FormidableLabs/react-fast-compare)): + +```javascript +var equal = require('fast-deep-equal/react'); +var equal = require('fast-deep-equal/es6/react'); +``` + + +## Performance benchmark + +Node.js v12.6.0: + +``` +fast-deep-equal x 261,950 ops/sec ±0.52% (89 runs sampled) +fast-deep-equal/es6 x 212,991 ops/sec ±0.34% (92 runs sampled) +fast-equals x 230,957 ops/sec ±0.83% (85 runs sampled) +nano-equal x 187,995 ops/sec ±0.53% (88 runs sampled) +shallow-equal-fuzzy x 138,302 ops/sec ±0.49% (90 runs sampled) +underscore.isEqual x 74,423 ops/sec ±0.38% (89 runs sampled) +lodash.isEqual x 36,637 ops/sec ±0.72% (90 runs sampled) +deep-equal x 2,310 ops/sec ±0.37% (90 runs sampled) +deep-eql x 35,312 ops/sec ±0.67% (91 runs sampled) +ramda.equals x 12,054 ops/sec ±0.40% (91 runs sampled) +util.isDeepStrictEqual x 46,440 ops/sec ±0.43% (90 runs sampled) +assert.deepStrictEqual x 456 ops/sec ±0.71% (88 runs sampled) + +The fastest is fast-deep-equal +``` + +To run benchmark (requires node.js 6+): + +```bash +npm run benchmark +``` + +__Please note__: this benchmark runs against the available test cases. To choose the most performant library for your application, it is recommended to benchmark against your data and to NOT expect this benchmark to reflect the performance difference in your application. + + +## Enterprise support + +fast-deep-equal package is a part of [Tidelift enterprise subscription](https://tidelift.com/subscription/pkg/npm-fast-deep-equal?utm_source=npm-fast-deep-equal&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - it provides a centralised commercial support to open-source software users, in addition to the support provided by software maintainers. + + +## Security contact + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. Please do NOT report security vulnerability via GitHub issues. + + +## License + +[MIT](https://github.com/epoberezkin/fast-deep-equal/blob/master/LICENSE) diff --git a/libs/events/node_modules/fast-deep-equal/es6/index.d.ts b/libs/events/node_modules/fast-deep-equal/es6/index.d.ts new file mode 100644 index 000000000..c7eb9c796 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/es6/index.d.ts @@ -0,0 +1,2 @@ +declare const equal: (a: any, b: any) => boolean; +export = equal; diff --git a/libs/events/node_modules/fast-deep-equal/es6/index.js b/libs/events/node_modules/fast-deep-equal/es6/index.js new file mode 100644 index 000000000..d980be257 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/es6/index.js @@ -0,0 +1,72 @@ +'use strict'; + +// do not edit .js files directly - edit src/index.jst + + + var envHasBigInt64Array = typeof BigInt64Array !== 'undefined'; + + +module.exports = function equal(a, b) { + if (a === b) return true; + + if (a && b && typeof a == 'object' && typeof b == 'object') { + if (a.constructor !== b.constructor) return false; + + var length, i, keys; + if (Array.isArray(a)) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0;) + if (!equal(a[i], b[i])) return false; + return true; + } + + + if ((a instanceof Map) && (b instanceof Map)) { + if (a.size !== b.size) return false; + for (i of a.entries()) + if (!b.has(i[0])) return false; + for (i of a.entries()) + if (!equal(i[1], b.get(i[0]))) return false; + return true; + } + + if ((a instanceof Set) && (b instanceof Set)) { + if (a.size !== b.size) return false; + for (i of a.entries()) + if (!b.has(i[0])) return false; + return true; + } + + if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0;) + if (a[i] !== b[i]) return false; + return true; + } + + + if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; + if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); + if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); + + keys = Object.keys(a); + length = keys.length; + if (length !== Object.keys(b).length) return false; + + for (i = length; i-- !== 0;) + if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; + + for (i = length; i-- !== 0;) { + var key = keys[i]; + + if (!equal(a[key], b[key])) return false; + } + + return true; + } + + // true if both NaN, false otherwise + return a!==a && b!==b; +}; diff --git a/libs/events/node_modules/fast-deep-equal/es6/react.d.ts b/libs/events/node_modules/fast-deep-equal/es6/react.d.ts new file mode 100644 index 000000000..c7eb9c796 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/es6/react.d.ts @@ -0,0 +1,2 @@ +declare const equal: (a: any, b: any) => boolean; +export = equal; diff --git a/libs/events/node_modules/fast-deep-equal/es6/react.js b/libs/events/node_modules/fast-deep-equal/es6/react.js new file mode 100644 index 000000000..98e2f9b71 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/es6/react.js @@ -0,0 +1,79 @@ +'use strict'; + +// do not edit .js files directly - edit src/index.jst + + + var envHasBigInt64Array = typeof BigInt64Array !== 'undefined'; + + +module.exports = function equal(a, b) { + if (a === b) return true; + + if (a && b && typeof a == 'object' && typeof b == 'object') { + if (a.constructor !== b.constructor) return false; + + var length, i, keys; + if (Array.isArray(a)) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0;) + if (!equal(a[i], b[i])) return false; + return true; + } + + + if ((a instanceof Map) && (b instanceof Map)) { + if (a.size !== b.size) return false; + for (i of a.entries()) + if (!b.has(i[0])) return false; + for (i of a.entries()) + if (!equal(i[1], b.get(i[0]))) return false; + return true; + } + + if ((a instanceof Set) && (b instanceof Set)) { + if (a.size !== b.size) return false; + for (i of a.entries()) + if (!b.has(i[0])) return false; + return true; + } + + if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0;) + if (a[i] !== b[i]) return false; + return true; + } + + + if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; + if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); + if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); + + keys = Object.keys(a); + length = keys.length; + if (length !== Object.keys(b).length) return false; + + for (i = length; i-- !== 0;) + if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; + + for (i = length; i-- !== 0;) { + var key = keys[i]; + + if (key === '_owner' && a.$$typeof) { + // React-specific: avoid traversing React elements' _owner. + // _owner contains circular references + // and is not needed when comparing the actual elements (and not their owners) + continue; + } + + if (!equal(a[key], b[key])) return false; + } + + return true; + } + + // true if both NaN, false otherwise + return a!==a && b!==b; +}; diff --git a/libs/events/node_modules/fast-deep-equal/index.d.ts b/libs/events/node_modules/fast-deep-equal/index.d.ts new file mode 100644 index 000000000..3c042caa7 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/index.d.ts @@ -0,0 +1,4 @@ +declare module 'fast-deep-equal' { + const equal: (a: any, b: any) => boolean; + export = equal; +} diff --git a/libs/events/node_modules/fast-deep-equal/index.js b/libs/events/node_modules/fast-deep-equal/index.js new file mode 100644 index 000000000..30dd1ba78 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/index.js @@ -0,0 +1,46 @@ +'use strict'; + +// do not edit .js files directly - edit src/index.jst + + + +module.exports = function equal(a, b) { + if (a === b) return true; + + if (a && b && typeof a == 'object' && typeof b == 'object') { + if (a.constructor !== b.constructor) return false; + + var length, i, keys; + if (Array.isArray(a)) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0;) + if (!equal(a[i], b[i])) return false; + return true; + } + + + + if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; + if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); + if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); + + keys = Object.keys(a); + length = keys.length; + if (length !== Object.keys(b).length) return false; + + for (i = length; i-- !== 0;) + if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; + + for (i = length; i-- !== 0;) { + var key = keys[i]; + + if (!equal(a[key], b[key])) return false; + } + + return true; + } + + // true if both NaN, false otherwise + return a!==a && b!==b; +}; diff --git a/libs/events/node_modules/fast-deep-equal/package.json b/libs/events/node_modules/fast-deep-equal/package.json new file mode 100644 index 000000000..3cfe66c68 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/package.json @@ -0,0 +1,61 @@ +{ + "name": "fast-deep-equal", + "version": "3.1.3", + "description": "Fast deep equal", + "main": "index.js", + "scripts": { + "eslint": "eslint *.js benchmark/*.js spec/*.js", + "build": "node build", + "benchmark": "npm i && npm run build && cd ./benchmark && npm i && node ./", + "test-spec": "mocha spec/*.spec.js -R spec", + "test-cov": "nyc npm run test-spec", + "test-ts": "tsc --target ES5 --noImplicitAny index.d.ts", + "test": "npm run build && npm run eslint && npm run test-ts && npm run test-cov", + "prepublish": "npm run build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/epoberezkin/fast-deep-equal.git" + }, + "keywords": [ + "fast", + "equal", + "deep-equal" + ], + "author": "Evgeny Poberezkin", + "license": "MIT", + "bugs": { + "url": "https://github.com/epoberezkin/fast-deep-equal/issues" + }, + "homepage": "https://github.com/epoberezkin/fast-deep-equal#readme", + "devDependencies": { + "coveralls": "^3.1.0", + "dot": "^1.1.2", + "eslint": "^7.2.0", + "mocha": "^7.2.0", + "nyc": "^15.1.0", + "pre-commit": "^1.2.2", + "react": "^16.12.0", + "react-test-renderer": "^16.12.0", + "sinon": "^9.0.2", + "typescript": "^3.9.5" + }, + "nyc": { + "exclude": [ + "**/spec/**", + "node_modules" + ], + "reporter": [ + "lcov", + "text-summary" + ] + }, + "files": [ + "index.js", + "index.d.ts", + "react.js", + "react.d.ts", + "es6/" + ], + "types": "index.d.ts" +} diff --git a/libs/events/node_modules/fast-deep-equal/react.d.ts b/libs/events/node_modules/fast-deep-equal/react.d.ts new file mode 100644 index 000000000..c7eb9c796 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/react.d.ts @@ -0,0 +1,2 @@ +declare const equal: (a: any, b: any) => boolean; +export = equal; diff --git a/libs/events/node_modules/fast-deep-equal/react.js b/libs/events/node_modules/fast-deep-equal/react.js new file mode 100644 index 000000000..3489b9833 --- /dev/null +++ b/libs/events/node_modules/fast-deep-equal/react.js @@ -0,0 +1,53 @@ +'use strict'; + +// do not edit .js files directly - edit src/index.jst + + + +module.exports = function equal(a, b) { + if (a === b) return true; + + if (a && b && typeof a == 'object' && typeof b == 'object') { + if (a.constructor !== b.constructor) return false; + + var length, i, keys; + if (Array.isArray(a)) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0;) + if (!equal(a[i], b[i])) return false; + return true; + } + + + + if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; + if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); + if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); + + keys = Object.keys(a); + length = keys.length; + if (length !== Object.keys(b).length) return false; + + for (i = length; i-- !== 0;) + if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; + + for (i = length; i-- !== 0;) { + var key = keys[i]; + + if (key === '_owner' && a.$$typeof) { + // React-specific: avoid traversing React elements' _owner. + // _owner contains circular references + // and is not needed when comparing the actual elements (and not their owners) + continue; + } + + if (!equal(a[key], b[key])) return false; + } + + return true; + } + + // true if both NaN, false otherwise + return a!==a && b!==b; +}; diff --git a/libs/events/node_modules/fast-glob/LICENSE b/libs/events/node_modules/fast-glob/LICENSE new file mode 100644 index 000000000..65a999460 --- /dev/null +++ b/libs/events/node_modules/fast-glob/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Denis Malinochkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/fast-glob/README.md b/libs/events/node_modules/fast-glob/README.md new file mode 100644 index 000000000..be6087422 --- /dev/null +++ b/libs/events/node_modules/fast-glob/README.md @@ -0,0 +1,830 @@ +# fast-glob + +> It's a very fast and efficient [glob][glob_definition] library for [Node.js][node_js]. + +This package provides methods for traversing the file system and returning pathnames that matched a defined set of a specified pattern according to the rules used by the Unix Bash shell with some simplifications, meanwhile results are returned in **arbitrary order**. Quick, simple, effective. + +## Table of Contents + +
+Details + +* [Highlights](#highlights) +* [Old and modern mode](#old-and-modern-mode) +* [Pattern syntax](#pattern-syntax) + * [Basic syntax](#basic-syntax) + * [Advanced syntax](#advanced-syntax) +* [Installation](#installation) +* [API](#api) + * [Asynchronous](#asynchronous) + * [Synchronous](#synchronous) + * [Stream](#stream) + * [patterns](#patterns) + * [[options]](#options) + * [Helpers](#helpers) + * [generateTasks](#generatetaskspatterns-options) + * [isDynamicPattern](#isdynamicpatternpattern-options) + * [escapePath](#escapepathpath) + * [convertPathToPattern](#convertpathtopatternpath) +* [Options](#options-3) + * [Common](#common) + * [concurrency](#concurrency) + * [cwd](#cwd) + * [deep](#deep) + * [followSymbolicLinks](#followsymboliclinks) + * [fs](#fs) + * [ignore](#ignore) + * [suppressErrors](#suppresserrors) + * [throwErrorOnBrokenSymbolicLink](#throwerroronbrokensymboliclink) + * [Output control](#output-control) + * [absolute](#absolute) + * [markDirectories](#markdirectories) + * [objectMode](#objectmode) + * [onlyDirectories](#onlydirectories) + * [onlyFiles](#onlyfiles) + * [stats](#stats) + * [unique](#unique) + * [Matching control](#matching-control) + * [braceExpansion](#braceexpansion) + * [caseSensitiveMatch](#casesensitivematch) + * [dot](#dot) + * [extglob](#extglob) + * [globstar](#globstar) + * [baseNameMatch](#basenamematch) +* [FAQ](#faq) + * [What is a static or dynamic pattern?](#what-is-a-static-or-dynamic-pattern) + * [How to write patterns on Windows?](#how-to-write-patterns-on-windows) + * [Why are parentheses match wrong?](#why-are-parentheses-match-wrong) + * [How to exclude directory from reading?](#how-to-exclude-directory-from-reading) + * [How to use UNC path?](#how-to-use-unc-path) + * [Compatible with `node-glob`?](#compatible-with-node-glob) +* [Benchmarks](#benchmarks) + * [Server](#server) + * [Nettop](#nettop) +* [Changelog](#changelog) +* [License](#license) + +
+ +## Highlights + +* Fast. Probably the fastest. +* Supports multiple and negative patterns. +* Synchronous, Promise and Stream API. +* Object mode. Can return more than just strings. +* Error-tolerant. + +## Old and modern mode + +This package works in two modes, depending on the environment in which it is used. + +* **Old mode**. Node.js below 10.10 or when the [`stats`](#stats) option is *enabled*. +* **Modern mode**. Node.js 10.10+ and the [`stats`](#stats) option is *disabled*. + +The modern mode is faster. Learn more about the [internal mechanism][nodelib_fs_scandir_old_and_modern_modern]. + +## Pattern syntax + +> :warning: Always use forward-slashes in glob expressions (patterns and [`ignore`](#ignore) option). Use backslashes for escaping characters. + +There is more than one form of syntax: basic and advanced. Below is a brief overview of the supported features. Also pay attention to our [FAQ](#faq). + +> :book: This package uses [`micromatch`][micromatch] as a library for pattern matching. + +### Basic syntax + +* An asterisk (`*`) — matches everything except slashes (path separators), hidden files (names starting with `.`). +* A double star or globstar (`**`) — matches zero or more directories. +* Question mark (`?`) – matches any single character except slashes (path separators). +* Sequence (`[seq]`) — matches any character in sequence. + +> :book: A few additional words about the [basic matching behavior][picomatch_matching_behavior]. + +Some examples: + +* `src/**/*.js` — matches all files in the `src` directory (any level of nesting) that have the `.js` extension. +* `src/*.??` — matches all files in the `src` directory (only first level of nesting) that have a two-character extension. +* `file-[01].js` — matches files: `file-0.js`, `file-1.js`. + +### Advanced syntax + +* [Escapes characters][micromatch_backslashes] (`\\`) — matching special characters (`$^*+?()[]`) as literals. +* [POSIX character classes][picomatch_posix_brackets] (`[[:digit:]]`). +* [Extended globs][micromatch_extglobs] (`?(pattern-list)`). +* [Bash style brace expansions][micromatch_braces] (`{}`). +* [Regexp character classes][micromatch_regex_character_classes] (`[1-5]`). +* [Regex groups][regular_expressions_brackets] (`(a|b)`). + +> :book: A few additional words about the [advanced matching behavior][micromatch_extended_globbing]. + +Some examples: + +* `src/**/*.{css,scss}` — matches all files in the `src` directory (any level of nesting) that have the `.css` or `.scss` extension. +* `file-[[:digit:]].js` — matches files: `file-0.js`, `file-1.js`, …, `file-9.js`. +* `file-{1..3}.js` — matches files: `file-1.js`, `file-2.js`, `file-3.js`. +* `file-(1|2)` — matches files: `file-1.js`, `file-2.js`. + +## Installation + +```console +npm install fast-glob +``` + +## API + +### Asynchronous + +```js +fg(patterns, [options]) +fg.async(patterns, [options]) +fg.glob(patterns, [options]) +``` + +Returns a `Promise` with an array of matching entries. + +```js +const fg = require('fast-glob'); + +const entries = await fg(['.editorconfig', '**/index.js'], { dot: true }); + +// ['.editorconfig', 'services/index.js'] +``` + +### Synchronous + +```js +fg.sync(patterns, [options]) +fg.globSync(patterns, [options]) +``` + +Returns an array of matching entries. + +```js +const fg = require('fast-glob'); + +const entries = fg.sync(['.editorconfig', '**/index.js'], { dot: true }); + +// ['.editorconfig', 'services/index.js'] +``` + +### Stream + +```js +fg.stream(patterns, [options]) +fg.globStream(patterns, [options]) +``` + +Returns a [`ReadableStream`][node_js_stream_readable_streams] when the `data` event will be emitted with matching entry. + +```js +const fg = require('fast-glob'); + +const stream = fg.stream(['.editorconfig', '**/index.js'], { dot: true }); + +for await (const entry of stream) { + // .editorconfig + // services/index.js +} +``` + +#### patterns + +* Required: `true` +* Type: `string | string[]` + +Any correct pattern(s). + +> :1234: [Pattern syntax](#pattern-syntax) +> +> :warning: This package does not respect the order of patterns. First, all the negative patterns are applied, and only then the positive patterns. If you want to get a certain order of records, use sorting or split calls. + +#### [options] + +* Required: `false` +* Type: [`Options`](#options-3) + +See [Options](#options-3) section. + +### Helpers + +#### `generateTasks(patterns, [options])` + +Returns the internal representation of patterns ([`Task`](./src/managers/tasks.ts) is a combining patterns by base directory). + +```js +fg.generateTasks('*'); + +[{ + base: '.', // Parent directory for all patterns inside this task + dynamic: true, // Dynamic or static patterns are in this task + patterns: ['*'], + positive: ['*'], + negative: [] +}] +``` + +##### patterns + +* Required: `true` +* Type: `string | string[]` + +Any correct pattern(s). + +##### [options] + +* Required: `false` +* Type: [`Options`](#options-3) + +See [Options](#options-3) section. + +#### `isDynamicPattern(pattern, [options])` + +Returns `true` if the passed pattern is a dynamic pattern. + +> :1234: [What is a static or dynamic pattern?](#what-is-a-static-or-dynamic-pattern) + +```js +fg.isDynamicPattern('*'); // true +fg.isDynamicPattern('abc'); // false +``` + +##### pattern + +* Required: `true` +* Type: `string` + +Any correct pattern. + +##### [options] + +* Required: `false` +* Type: [`Options`](#options-3) + +See [Options](#options-3) section. + +#### `escapePath(path)` + +Returns the path with escaped special characters depending on the platform. + +* Posix: + * `*?|(){}[]`; + * `!` at the beginning of line; + * `@+!` before the opening parenthesis; + * `\\` before non-special characters; +* Windows: + * `(){}` + * `!` at the beginning of line; + * `@+!` before the opening parenthesis; + * Characters like `*?|[]` cannot be used in the path ([windows_naming_conventions][windows_naming_conventions]), so they will not be escaped; + +```js +fg.escapePath('!abc'); +// \\!abc +fg.escapePath('[OpenSource] mrmlnc – fast-glob (Deluxe Edition) 2014') + '/*.flac' +// \\[OpenSource\\] mrmlnc – fast-glob \\(Deluxe Edition\\) 2014/*.flac + +fg.posix.escapePath('C:\\Program Files (x86)\\**\\*'); +// C:\\\\Program Files \\(x86\\)\\*\\*\\* +fg.win32.escapePath('C:\\Program Files (x86)\\**\\*'); +// Windows: C:\\Program Files \\(x86\\)\\**\\* +``` + +#### `convertPathToPattern(path)` + +Converts a path to a pattern depending on the platform, including special character escaping. + +* Posix. Works similarly to the `fg.posix.escapePath` method. +* Windows. Works similarly to the `fg.win32.escapePath` method, additionally converting backslashes to forward slashes in cases where they are not escape characters (`!()+@{}`). + +```js +fg.convertPathToPattern('[OpenSource] mrmlnc – fast-glob (Deluxe Edition) 2014') + '/*.flac'; +// \\[OpenSource\\] mrmlnc – fast-glob \\(Deluxe Edition\\) 2014/*.flac + +fg.convertPathToPattern('C:/Program Files (x86)/**/*'); +// Posix: C:/Program Files \\(x86\\)/\\*\\*/\\* +// Windows: C:/Program Files \\(x86\\)/**/* + +fg.convertPathToPattern('C:\\Program Files (x86)\\**\\*'); +// Posix: C:\\\\Program Files \\(x86\\)\\*\\*\\* +// Windows: C:/Program Files \\(x86\\)/**/* + +fg.posix.convertPathToPattern('\\\\?\\c:\\Program Files (x86)') + '/**/*'; +// Posix: \\\\\\?\\\\c:\\\\Program Files \\(x86\\)/**/* (broken pattern) +fg.win32.convertPathToPattern('\\\\?\\c:\\Program Files (x86)') + '/**/*'; +// Windows: //?/c:/Program Files \\(x86\\)/**/* +``` + +## Options + +### Common options + +#### concurrency + +* Type: `number` +* Default: `os.cpus().length` + +Specifies the maximum number of concurrent requests from a reader to read directories. + +> :book: The higher the number, the higher the performance and load on the file system. If you want to read in quiet mode, set the value to a comfortable number or `1`. + +
+ +More details + +In Node, there are [two types of threads][nodejs_thread_pool]: Event Loop (code) and a Thread Pool (fs, dns, …). The thread pool size controlled by the `UV_THREADPOOL_SIZE` environment variable. Its default size is 4 ([documentation][libuv_thread_pool]). The pool is one for all tasks within a single Node process. + +Any code can make 4 real concurrent accesses to the file system. The rest of the FS requests will wait in the queue. + +> :book: Each new instance of FG in the same Node process will use the same Thread pool. + +But this package also has the `concurrency` option. This option allows you to control the number of concurrent accesses to the FS at the package level. By default, this package has a value equal to the number of cores available for the current Node process. This allows you to set a value smaller than the pool size (`concurrency: 1`) or, conversely, to prepare tasks for the pool queue more quickly (`concurrency: Number.POSITIVE_INFINITY`). + +So, in fact, this package can **only make 4 concurrent requests to the FS**. You can increase this value by using an environment variable (`UV_THREADPOOL_SIZE`), but in practice this does not give a multiple advantage. + +
+ +#### cwd + +* Type: `string` +* Default: `process.cwd()` + +The current working directory in which to search. + +#### deep + +* Type: `number` +* Default: `Infinity` + +Specifies the maximum depth of a read directory relative to the start directory. + +For example, you have the following tree: + +```js +dir/ +└── one/ // 1 + └── two/ // 2 + └── file.js // 3 +``` + +```js +// With base directory +fg.sync('dir/**', { onlyFiles: false, deep: 1 }); // ['dir/one'] +fg.sync('dir/**', { onlyFiles: false, deep: 2 }); // ['dir/one', 'dir/one/two'] + +// With cwd option +fg.sync('**', { onlyFiles: false, cwd: 'dir', deep: 1 }); // ['one'] +fg.sync('**', { onlyFiles: false, cwd: 'dir', deep: 2 }); // ['one', 'one/two'] +``` + +> :book: If you specify a pattern with some base directory, this directory will not participate in the calculation of the depth of the found directories. Think of it as a [`cwd`](#cwd) option. + +#### followSymbolicLinks + +* Type: `boolean` +* Default: `true` + +Indicates whether to traverse descendants of symbolic link directories when expanding `**` patterns. + +> :book: Note that this option does not affect the base directory of the pattern. For example, if `./a` is a symlink to directory `./b` and you specified `['./a**', './b/**']` patterns, then directory `./a` will still be read. + +> :book: If the [`stats`](#stats) option is specified, the information about the symbolic link (`fs.lstat`) will be replaced with information about the entry (`fs.stat`) behind it. + +#### fs + +* Type: `FileSystemAdapter` +* Default: `fs.*` + +Custom implementation of methods for working with the file system. + +```ts +export interface FileSystemAdapter { + lstat?: typeof fs.lstat; + stat?: typeof fs.stat; + lstatSync?: typeof fs.lstatSync; + statSync?: typeof fs.statSync; + readdir?: typeof fs.readdir; + readdirSync?: typeof fs.readdirSync; +} +``` + +#### ignore + +* Type: `string[]` +* Default: `[]` + +An array of glob patterns to exclude matches. This is an alternative way to use negative patterns. + +```js +dir/ +├── package-lock.json +└── package.json +``` + +```js +fg.sync(['*.json', '!package-lock.json']); // ['package.json'] +fg.sync('*.json', { ignore: ['package-lock.json'] }); // ['package.json'] +``` + +#### suppressErrors + +* Type: `boolean` +* Default: `false` + +By default this package suppress only `ENOENT` errors. Set to `true` to suppress any error. + +> :book: Can be useful when the directory has entries with a special level of access. + +#### throwErrorOnBrokenSymbolicLink + +* Type: `boolean` +* Default: `false` + +Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`. + +> :book: This option has no effect on errors when reading the symbolic link directory. + +### Output control + +#### absolute + +* Type: `boolean` +* Default: `false` + +Return the absolute path for entries. + +```js +fg.sync('*.js', { absolute: false }); // ['index.js'] +fg.sync('*.js', { absolute: true }); // ['/home/user/index.js'] +``` + +> :book: This option is required if you want to use negative patterns with absolute path, for example, `!${__dirname}/*.js`. + +#### markDirectories + +* Type: `boolean` +* Default: `false` + +Mark the directory path with the final slash. + +```js +fg.sync('*', { onlyFiles: false, markDirectories: false }); // ['index.js', 'controllers'] +fg.sync('*', { onlyFiles: false, markDirectories: true }); // ['index.js', 'controllers/'] +``` + +#### objectMode + +* Type: `boolean` +* Default: `false` + +Returns objects (instead of strings) describing entries. + +```js +fg.sync('*', { objectMode: false }); // ['src/index.js'] +fg.sync('*', { objectMode: true }); // [{ name: 'index.js', path: 'src/index.js', dirent: }] +``` + +The object has the following fields: + +* name (`string`) — the last part of the path (basename) +* path (`string`) — full path relative to the pattern base directory +* dirent ([`fs.Dirent`][node_js_fs_class_fs_dirent]) — instance of `fs.Dirent` + +> :book: An object is an internal representation of entry, so getting it does not affect performance. + +#### onlyDirectories + +* Type: `boolean` +* Default: `false` + +Return only directories. + +```js +fg.sync('*', { onlyDirectories: false }); // ['index.js', 'src'] +fg.sync('*', { onlyDirectories: true }); // ['src'] +``` + +> :book: If `true`, the [`onlyFiles`](#onlyfiles) option is automatically `false`. + +#### onlyFiles + +* Type: `boolean` +* Default: `true` + +Return only files. + +```js +fg.sync('*', { onlyFiles: false }); // ['index.js', 'src'] +fg.sync('*', { onlyFiles: true }); // ['index.js'] +``` + +#### stats + +* Type: `boolean` +* Default: `false` + +Enables an [object mode](#objectmode) with an additional field: + +* stats ([`fs.Stats`][node_js_fs_class_fs_stats]) — instance of `fs.Stats` + +```js +fg.sync('*', { stats: false }); // ['src/index.js'] +fg.sync('*', { stats: true }); // [{ name: 'index.js', path: 'src/index.js', dirent: , stats: }] +``` + +> :book: Returns `fs.stat` instead of `fs.lstat` for symbolic links when the [`followSymbolicLinks`](#followsymboliclinks) option is specified. +> +> :warning: Unlike [object mode](#objectmode) this mode requires additional calls to the file system. On average, this mode is slower at least twice. See [old and modern mode](#old-and-modern-mode) for more details. + +#### unique + +* Type: `boolean` +* Default: `true` + +Ensures that the returned entries are unique. + +```js +fg.sync(['*.json', 'package.json'], { unique: false }); // ['package.json', 'package.json'] +fg.sync(['*.json', 'package.json'], { unique: true }); // ['package.json'] +``` + +If `true` and similar entries are found, the result is the first found. + +### Matching control + +#### braceExpansion + +* Type: `boolean` +* Default: `true` + +Enables Bash-like brace expansion. + +> :1234: [Syntax description][bash_hackers_syntax_expansion_brace] or more [detailed description][micromatch_braces]. + +```js +dir/ +├── abd +├── acd +└── a{b,c}d +``` + +```js +fg.sync('a{b,c}d', { braceExpansion: false }); // ['a{b,c}d'] +fg.sync('a{b,c}d', { braceExpansion: true }); // ['abd', 'acd'] +``` + +#### caseSensitiveMatch + +* Type: `boolean` +* Default: `true` + +Enables a [case-sensitive][wikipedia_case_sensitivity] mode for matching files. + +```js +dir/ +├── file.txt +└── File.txt +``` + +```js +fg.sync('file.txt', { caseSensitiveMatch: false }); // ['file.txt', 'File.txt'] +fg.sync('file.txt', { caseSensitiveMatch: true }); // ['file.txt'] +``` + +#### dot + +* Type: `boolean` +* Default: `false` + +Allow patterns to match entries that begin with a period (`.`). + +> :book: Note that an explicit dot in a portion of the pattern will always match dot files. + +```js +dir/ +├── .editorconfig +└── package.json +``` + +```js +fg.sync('*', { dot: false }); // ['package.json'] +fg.sync('*', { dot: true }); // ['.editorconfig', 'package.json'] +``` + +#### extglob + +* Type: `boolean` +* Default: `true` + +Enables Bash-like `extglob` functionality. + +> :1234: [Syntax description][micromatch_extglobs]. + +```js +dir/ +├── README.md +└── package.json +``` + +```js +fg.sync('*.+(json|md)', { extglob: false }); // [] +fg.sync('*.+(json|md)', { extglob: true }); // ['README.md', 'package.json'] +``` + +#### globstar + +* Type: `boolean` +* Default: `true` + +Enables recursively repeats a pattern containing `**`. If `false`, `**` behaves exactly like `*`. + +```js +dir/ +└── a + └── b +``` + +```js +fg.sync('**', { onlyFiles: false, globstar: false }); // ['a'] +fg.sync('**', { onlyFiles: false, globstar: true }); // ['a', 'a/b'] +``` + +#### baseNameMatch + +* Type: `boolean` +* Default: `false` + +If set to `true`, then patterns without slashes will be matched against the basename of the path if it contains slashes. + +```js +dir/ +└── one/ + └── file.md +``` + +```js +fg.sync('*.md', { baseNameMatch: false }); // [] +fg.sync('*.md', { baseNameMatch: true }); // ['one/file.md'] +``` + +## FAQ + +## What is a static or dynamic pattern? + +All patterns can be divided into two types: + +* **static**. A pattern is considered static if it can be used to get an entry on the file system without using matching mechanisms. For example, the `file.js` pattern is a static pattern because we can just verify that it exists on the file system. +* **dynamic**. A pattern is considered dynamic if it cannot be used directly to find occurrences without using a matching mechanisms. For example, the `*` pattern is a dynamic pattern because we cannot use this pattern directly. + +A pattern is considered dynamic if it contains the following characters (`…` — any characters or their absence) or options: + +* The [`caseSensitiveMatch`](#casesensitivematch) option is disabled +* `\\` (the escape character) +* `*`, `?`, `!` (at the beginning of line) +* `[…]` +* `(…|…)` +* `@(…)`, `!(…)`, `*(…)`, `?(…)`, `+(…)` (respects the [`extglob`](#extglob) option) +* `{…,…}`, `{…..…}` (respects the [`braceExpansion`](#braceexpansion) option) + +## How to write patterns on Windows? + +Always use forward-slashes in glob expressions (patterns and [`ignore`](#ignore) option). Use backslashes for escaping characters. With the [`cwd`](#cwd) option use a convenient format. + +**Bad** + +```ts +[ + 'directory\\*', + path.join(process.cwd(), '**') +] +``` + +**Good** + +```ts +[ + 'directory/*', + fg.convertPathToPattern(process.cwd()) + '/**' +] +``` + +> :book: Use the [`.convertPathToPattern`](#convertpathtopatternpath) package to convert Windows-style path to a Unix-style path. + +Read more about [matching with backslashes][micromatch_backslashes]. + +## Why are parentheses match wrong? + +```js +dir/ +└── (special-*file).txt +``` + +```js +fg.sync(['(special-*file).txt']) // [] +``` + +Refers to Bash. You need to escape special characters: + +```js +fg.sync(['\\(special-*file\\).txt']) // ['(special-*file).txt'] +``` + +Read more about [matching special characters as literals][picomatch_matching_special_characters_as_literals]. Or use the [`.escapePath`](#escapepathpath). + +## How to exclude directory from reading? + +You can use a negative pattern like this: `!**/node_modules` or `!**/node_modules/**`. Also you can use [`ignore`](#ignore) option. Just look at the example below. + +```js +first/ +├── file.md +└── second/ + └── file.txt +``` + +If you don't want to read the `second` directory, you must write the following pattern: `!**/second` or `!**/second/**`. + +```js +fg.sync(['**/*.md', '!**/second']); // ['first/file.md'] +fg.sync(['**/*.md'], { ignore: ['**/second/**'] }); // ['first/file.md'] +``` + +> :warning: When you write `!**/second/**/*` it means that the directory will be **read**, but all the entries will not be included in the results. + +You have to understand that if you write the pattern to exclude directories, then the directory will not be read under any circumstances. + +## How to use UNC path? + +You cannot use [Uniform Naming Convention (UNC)][unc_path] paths as patterns (due to syntax) directly, but you can use them as [`cwd`](#cwd) directory or use the `fg.convertPathToPattern` method. + +```ts +// cwd +fg.sync('*', { cwd: '\\\\?\\C:\\Python27' /* or //?/C:/Python27 */ }); +fg.sync('Python27/*', { cwd: '\\\\?\\C:\\' /* or //?/C:/ */ }); + +// .convertPathToPattern +fg.sync(fg.convertPathToPattern('\\\\?\\c:\\Python27') + '/*'); +``` + +## Compatible with `node-glob`? + +| node-glob | fast-glob | +| :----------: | :-------: | +| `cwd` | [`cwd`](#cwd) | +| `root` | – | +| `dot` | [`dot`](#dot) | +| `nomount` | – | +| `mark` | [`markDirectories`](#markdirectories) | +| `nosort` | – | +| `nounique` | [`unique`](#unique) | +| `nobrace` | [`braceExpansion`](#braceexpansion) | +| `noglobstar` | [`globstar`](#globstar) | +| `noext` | [`extglob`](#extglob) | +| `nocase` | [`caseSensitiveMatch`](#casesensitivematch) | +| `matchBase` | [`baseNameMatch`](#basenamematch) | +| `nodir` | [`onlyFiles`](#onlyfiles) | +| `ignore` | [`ignore`](#ignore) | +| `follow` | [`followSymbolicLinks`](#followsymboliclinks) | +| `realpath` | – | +| `absolute` | [`absolute`](#absolute) | + +## Benchmarks + +You can see results [here](https://github.com/mrmlnc/fast-glob/actions/workflows/benchmark.yml?query=branch%3Amaster) for every commit into the `main` branch. + +* **Product benchmark** – comparison with the main competitors. +* **Regress benchmark** – regression between the current version and the version from the npm registry. + +## Changelog + +See the [Releases section of our GitHub project][github_releases] for changelog for each release version. + +## License + +This software is released under the terms of the MIT license. + +[bash_hackers_syntax_expansion_brace]: https://wiki.bash-hackers.org/syntax/expansion/brace +[github_releases]: https://github.com/mrmlnc/fast-glob/releases +[glob_definition]: https://en.wikipedia.org/wiki/Glob_(programming) +[glob_linux_man]: http://man7.org/linux/man-pages/man3/glob.3.html +[micromatch_backslashes]: https://github.com/micromatch/micromatch#backslashes +[micromatch_braces]: https://github.com/micromatch/braces +[micromatch_extended_globbing]: https://github.com/micromatch/micromatch#extended-globbing +[micromatch_extglobs]: https://github.com/micromatch/micromatch#extglobs +[micromatch_regex_character_classes]: https://github.com/micromatch/micromatch#regex-character-classes +[micromatch]: https://github.com/micromatch/micromatch +[node_js_fs_class_fs_dirent]: https://nodejs.org/api/fs.html#fs_class_fs_dirent +[node_js_fs_class_fs_stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats +[node_js_stream_readable_streams]: https://nodejs.org/api/stream.html#stream_readable_streams +[node_js]: https://nodejs.org/en +[nodelib_fs_scandir_old_and_modern_modern]: https://github.com/nodelib/nodelib/blob/master/packages/fs/fs.scandir/README.md#old-and-modern-mode +[npm_normalize_path]: https://www.npmjs.com/package/normalize-path +[npm_unixify]: https://www.npmjs.com/package/unixify +[picomatch_matching_behavior]: https://github.com/micromatch/picomatch#matching-behavior-vs-bash +[picomatch_matching_special_characters_as_literals]: https://github.com/micromatch/picomatch#matching-special-characters-as-literals +[picomatch_posix_brackets]: https://github.com/micromatch/picomatch#posix-brackets +[regular_expressions_brackets]: https://www.regular-expressions.info/brackets.html +[unc_path]: https://learn.microsoft.com/openspecs/windows_protocols/ms-dtyp/62e862f4-2a51-452e-8eeb-dc4ff5ee33cc +[wikipedia_case_sensitivity]: https://en.wikipedia.org/wiki/Case_sensitivity +[nodejs_thread_pool]: https://nodejs.org/en/docs/guides/dont-block-the-event-loop +[libuv_thread_pool]: http://docs.libuv.org/en/v1.x/threadpool.html +[windows_naming_conventions]: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions diff --git a/libs/events/node_modules/fast-glob/out/index.d.ts b/libs/events/node_modules/fast-glob/out/index.d.ts new file mode 100644 index 000000000..46823bb5f --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/index.d.ts @@ -0,0 +1,40 @@ +/// +import * as taskManager from './managers/tasks'; +import { Options as OptionsInternal } from './settings'; +import { Entry as EntryInternal, FileSystemAdapter as FileSystemAdapterInternal, Pattern as PatternInternal } from './types'; +type EntryObjectModePredicate = { + [TKey in keyof Pick]-?: true; +}; +type EntryStatsPredicate = { + [TKey in keyof Pick]-?: true; +}; +type EntryObjectPredicate = EntryObjectModePredicate | EntryStatsPredicate; +declare function FastGlob(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): Promise; +declare function FastGlob(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Promise; +declare namespace FastGlob { + type Options = OptionsInternal; + type Entry = EntryInternal; + type Task = taskManager.Task; + type Pattern = PatternInternal; + type FileSystemAdapter = FileSystemAdapterInternal; + const glob: typeof FastGlob; + const globSync: typeof sync; + const globStream: typeof stream; + const async: typeof FastGlob; + function sync(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): EntryInternal[]; + function sync(source: PatternInternal | PatternInternal[], options?: OptionsInternal): string[]; + function stream(source: PatternInternal | PatternInternal[], options?: OptionsInternal): NodeJS.ReadableStream; + function generateTasks(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Task[]; + function isDynamicPattern(source: PatternInternal, options?: OptionsInternal): boolean; + function escapePath(source: string): PatternInternal; + function convertPathToPattern(source: string): PatternInternal; + namespace posix { + function escapePath(source: string): PatternInternal; + function convertPathToPattern(source: string): PatternInternal; + } + namespace win32 { + function escapePath(source: string): PatternInternal; + function convertPathToPattern(source: string): PatternInternal; + } +} +export = FastGlob; diff --git a/libs/events/node_modules/fast-glob/out/index.js b/libs/events/node_modules/fast-glob/out/index.js new file mode 100644 index 000000000..90365d488 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/index.js @@ -0,0 +1,102 @@ +"use strict"; +const taskManager = require("./managers/tasks"); +const async_1 = require("./providers/async"); +const stream_1 = require("./providers/stream"); +const sync_1 = require("./providers/sync"); +const settings_1 = require("./settings"); +const utils = require("./utils"); +async function FastGlob(source, options) { + assertPatternsInput(source); + const works = getWorks(source, async_1.default, options); + const result = await Promise.all(works); + return utils.array.flatten(result); +} +// https://github.com/typescript-eslint/typescript-eslint/issues/60 +// eslint-disable-next-line no-redeclare +(function (FastGlob) { + FastGlob.glob = FastGlob; + FastGlob.globSync = sync; + FastGlob.globStream = stream; + FastGlob.async = FastGlob; + function sync(source, options) { + assertPatternsInput(source); + const works = getWorks(source, sync_1.default, options); + return utils.array.flatten(works); + } + FastGlob.sync = sync; + function stream(source, options) { + assertPatternsInput(source); + const works = getWorks(source, stream_1.default, options); + /** + * The stream returned by the provider cannot work with an asynchronous iterator. + * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams. + * This affects performance (+25%). I don't see best solution right now. + */ + return utils.stream.merge(works); + } + FastGlob.stream = stream; + function generateTasks(source, options) { + assertPatternsInput(source); + const patterns = [].concat(source); + const settings = new settings_1.default(options); + return taskManager.generate(patterns, settings); + } + FastGlob.generateTasks = generateTasks; + function isDynamicPattern(source, options) { + assertPatternsInput(source); + const settings = new settings_1.default(options); + return utils.pattern.isDynamicPattern(source, settings); + } + FastGlob.isDynamicPattern = isDynamicPattern; + function escapePath(source) { + assertPatternsInput(source); + return utils.path.escape(source); + } + FastGlob.escapePath = escapePath; + function convertPathToPattern(source) { + assertPatternsInput(source); + return utils.path.convertPathToPattern(source); + } + FastGlob.convertPathToPattern = convertPathToPattern; + let posix; + (function (posix) { + function escapePath(source) { + assertPatternsInput(source); + return utils.path.escapePosixPath(source); + } + posix.escapePath = escapePath; + function convertPathToPattern(source) { + assertPatternsInput(source); + return utils.path.convertPosixPathToPattern(source); + } + posix.convertPathToPattern = convertPathToPattern; + })(posix = FastGlob.posix || (FastGlob.posix = {})); + let win32; + (function (win32) { + function escapePath(source) { + assertPatternsInput(source); + return utils.path.escapeWindowsPath(source); + } + win32.escapePath = escapePath; + function convertPathToPattern(source) { + assertPatternsInput(source); + return utils.path.convertWindowsPathToPattern(source); + } + win32.convertPathToPattern = convertPathToPattern; + })(win32 = FastGlob.win32 || (FastGlob.win32 = {})); +})(FastGlob || (FastGlob = {})); +function getWorks(source, _Provider, options) { + const patterns = [].concat(source); + const settings = new settings_1.default(options); + const tasks = taskManager.generate(patterns, settings); + const provider = new _Provider(settings); + return tasks.map(provider.read, provider); +} +function assertPatternsInput(input) { + const source = [].concat(input); + const isValidSource = source.every((item) => utils.string.isString(item) && !utils.string.isEmpty(item)); + if (!isValidSource) { + throw new TypeError('Patterns must be a string (non empty) or an array of strings'); + } +} +module.exports = FastGlob; diff --git a/libs/events/node_modules/fast-glob/out/managers/tasks.d.ts b/libs/events/node_modules/fast-glob/out/managers/tasks.d.ts new file mode 100644 index 000000000..59d2c4272 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/managers/tasks.d.ts @@ -0,0 +1,22 @@ +import Settings from '../settings'; +import { Pattern, PatternsGroup } from '../types'; +export type Task = { + base: string; + dynamic: boolean; + patterns: Pattern[]; + positive: Pattern[]; + negative: Pattern[]; +}; +export declare function generate(input: Pattern[], settings: Settings): Task[]; +/** + * Returns tasks grouped by basic pattern directories. + * + * Patterns that can be found inside (`./`) and outside (`../`) the current directory are handled separately. + * This is necessary because directory traversal starts at the base directory and goes deeper. + */ +export declare function convertPatternsToTasks(positive: Pattern[], negative: Pattern[], dynamic: boolean): Task[]; +export declare function getPositivePatterns(patterns: Pattern[]): Pattern[]; +export declare function getNegativePatternsAsPositive(patterns: Pattern[], ignore: Pattern[]): Pattern[]; +export declare function groupPatternsByBaseDirectory(patterns: Pattern[]): PatternsGroup; +export declare function convertPatternGroupsToTasks(positive: PatternsGroup, negative: Pattern[], dynamic: boolean): Task[]; +export declare function convertPatternGroupToTask(base: string, positive: Pattern[], negative: Pattern[], dynamic: boolean): Task; diff --git a/libs/events/node_modules/fast-glob/out/managers/tasks.js b/libs/events/node_modules/fast-glob/out/managers/tasks.js new file mode 100644 index 000000000..335a7651d --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/managers/tasks.js @@ -0,0 +1,110 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.convertPatternGroupToTask = exports.convertPatternGroupsToTasks = exports.groupPatternsByBaseDirectory = exports.getNegativePatternsAsPositive = exports.getPositivePatterns = exports.convertPatternsToTasks = exports.generate = void 0; +const utils = require("../utils"); +function generate(input, settings) { + const patterns = processPatterns(input, settings); + const ignore = processPatterns(settings.ignore, settings); + const positivePatterns = getPositivePatterns(patterns); + const negativePatterns = getNegativePatternsAsPositive(patterns, ignore); + const staticPatterns = positivePatterns.filter((pattern) => utils.pattern.isStaticPattern(pattern, settings)); + const dynamicPatterns = positivePatterns.filter((pattern) => utils.pattern.isDynamicPattern(pattern, settings)); + const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false); + const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true); + return staticTasks.concat(dynamicTasks); +} +exports.generate = generate; +function processPatterns(input, settings) { + let patterns = input; + /** + * The original pattern like `{,*,**,a/*}` can lead to problems checking the depth when matching entry + * and some problems with the micromatch package (see fast-glob issues: #365, #394). + * + * To solve this problem, we expand all patterns containing brace expansion. This can lead to a slight slowdown + * in matching in the case of a large set of patterns after expansion. + */ + if (settings.braceExpansion) { + patterns = utils.pattern.expandPatternsWithBraceExpansion(patterns); + } + /** + * If the `baseNameMatch` option is enabled, we must add globstar to patterns, so that they can be used + * at any nesting level. + * + * We do this here, because otherwise we have to complicate the filtering logic. For example, we need to change + * the pattern in the filter before creating a regular expression. There is no need to change the patterns + * in the application. Only on the input. + */ + if (settings.baseNameMatch) { + patterns = patterns.map((pattern) => pattern.includes('/') ? pattern : `**/${pattern}`); + } + /** + * This method also removes duplicate slashes that may have been in the pattern or formed as a result of expansion. + */ + return patterns.map((pattern) => utils.pattern.removeDuplicateSlashes(pattern)); +} +/** + * Returns tasks grouped by basic pattern directories. + * + * Patterns that can be found inside (`./`) and outside (`../`) the current directory are handled separately. + * This is necessary because directory traversal starts at the base directory and goes deeper. + */ +function convertPatternsToTasks(positive, negative, dynamic) { + const tasks = []; + const patternsOutsideCurrentDirectory = utils.pattern.getPatternsOutsideCurrentDirectory(positive); + const patternsInsideCurrentDirectory = utils.pattern.getPatternsInsideCurrentDirectory(positive); + const outsideCurrentDirectoryGroup = groupPatternsByBaseDirectory(patternsOutsideCurrentDirectory); + const insideCurrentDirectoryGroup = groupPatternsByBaseDirectory(patternsInsideCurrentDirectory); + tasks.push(...convertPatternGroupsToTasks(outsideCurrentDirectoryGroup, negative, dynamic)); + /* + * For the sake of reducing future accesses to the file system, we merge all tasks within the current directory + * into a global task, if at least one pattern refers to the root (`.`). In this case, the global task covers the rest. + */ + if ('.' in insideCurrentDirectoryGroup) { + tasks.push(convertPatternGroupToTask('.', patternsInsideCurrentDirectory, negative, dynamic)); + } + else { + tasks.push(...convertPatternGroupsToTasks(insideCurrentDirectoryGroup, negative, dynamic)); + } + return tasks; +} +exports.convertPatternsToTasks = convertPatternsToTasks; +function getPositivePatterns(patterns) { + return utils.pattern.getPositivePatterns(patterns); +} +exports.getPositivePatterns = getPositivePatterns; +function getNegativePatternsAsPositive(patterns, ignore) { + const negative = utils.pattern.getNegativePatterns(patterns).concat(ignore); + const positive = negative.map(utils.pattern.convertToPositivePattern); + return positive; +} +exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; +function groupPatternsByBaseDirectory(patterns) { + const group = {}; + return patterns.reduce((collection, pattern) => { + const base = utils.pattern.getBaseDirectory(pattern); + if (base in collection) { + collection[base].push(pattern); + } + else { + collection[base] = [pattern]; + } + return collection; + }, group); +} +exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; +function convertPatternGroupsToTasks(positive, negative, dynamic) { + return Object.keys(positive).map((base) => { + return convertPatternGroupToTask(base, positive[base], negative, dynamic); + }); +} +exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; +function convertPatternGroupToTask(base, positive, negative, dynamic) { + return { + dynamic, + positive, + negative, + base, + patterns: [].concat(positive, negative.map(utils.pattern.convertToNegativePattern)) + }; +} +exports.convertPatternGroupToTask = convertPatternGroupToTask; diff --git a/libs/events/node_modules/fast-glob/out/providers/async.d.ts b/libs/events/node_modules/fast-glob/out/providers/async.d.ts new file mode 100644 index 000000000..274261643 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/async.d.ts @@ -0,0 +1,9 @@ +import { Task } from '../managers/tasks'; +import { Entry, EntryItem, ReaderOptions } from '../types'; +import ReaderAsync from '../readers/async'; +import Provider from './provider'; +export default class ProviderAsync extends Provider> { + protected _reader: ReaderAsync; + read(task: Task): Promise; + api(root: string, task: Task, options: ReaderOptions): Promise; +} diff --git a/libs/events/node_modules/fast-glob/out/providers/async.js b/libs/events/node_modules/fast-glob/out/providers/async.js new file mode 100644 index 000000000..0c5286e7e --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/async.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const async_1 = require("../readers/async"); +const provider_1 = require("./provider"); +class ProviderAsync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new async_1.default(this._settings); + } + async read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = await this.api(root, task, options); + return entries.map((entry) => options.transform(entry)); + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderAsync; diff --git a/libs/events/node_modules/fast-glob/out/providers/filters/deep.d.ts b/libs/events/node_modules/fast-glob/out/providers/filters/deep.d.ts new file mode 100644 index 000000000..377fab889 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/filters/deep.d.ts @@ -0,0 +1,16 @@ +import { MicromatchOptions, EntryFilterFunction, Pattern } from '../../types'; +import Settings from '../../settings'; +export default class DeepFilter { + private readonly _settings; + private readonly _micromatchOptions; + constructor(_settings: Settings, _micromatchOptions: MicromatchOptions); + getFilter(basePath: string, positive: Pattern[], negative: Pattern[]): EntryFilterFunction; + private _getMatcher; + private _getNegativePatternsRe; + private _filter; + private _isSkippedByDeep; + private _getEntryLevel; + private _isSkippedSymbolicLink; + private _isSkippedByPositivePatterns; + private _isSkippedByNegativePatterns; +} diff --git a/libs/events/node_modules/fast-glob/out/providers/filters/deep.js b/libs/events/node_modules/fast-glob/out/providers/filters/deep.js new file mode 100644 index 000000000..644bf41b5 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/filters/deep.js @@ -0,0 +1,62 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../../utils"); +const partial_1 = require("../matchers/partial"); +class DeepFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + } + getFilter(basePath, positive, negative) { + const matcher = this._getMatcher(positive); + const negativeRe = this._getNegativePatternsRe(negative); + return (entry) => this._filter(basePath, entry, matcher, negativeRe); + } + _getMatcher(patterns) { + return new partial_1.default(patterns, this._settings, this._micromatchOptions); + } + _getNegativePatternsRe(patterns) { + const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern); + return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); + } + _filter(basePath, entry, matcher, negativeRe) { + if (this._isSkippedByDeep(basePath, entry.path)) { + return false; + } + if (this._isSkippedSymbolicLink(entry)) { + return false; + } + const filepath = utils.path.removeLeadingDotSegment(entry.path); + if (this._isSkippedByPositivePatterns(filepath, matcher)) { + return false; + } + return this._isSkippedByNegativePatterns(filepath, negativeRe); + } + _isSkippedByDeep(basePath, entryPath) { + /** + * Avoid unnecessary depth calculations when it doesn't matter. + */ + if (this._settings.deep === Infinity) { + return false; + } + return this._getEntryLevel(basePath, entryPath) >= this._settings.deep; + } + _getEntryLevel(basePath, entryPath) { + const entryPathDepth = entryPath.split('/').length; + if (basePath === '') { + return entryPathDepth; + } + const basePathDepth = basePath.split('/').length; + return entryPathDepth - basePathDepth; + } + _isSkippedSymbolicLink(entry) { + return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); + } + _isSkippedByPositivePatterns(entryPath, matcher) { + return !this._settings.baseNameMatch && !matcher.match(entryPath); + } + _isSkippedByNegativePatterns(entryPath, patternsRe) { + return !utils.pattern.matchAny(entryPath, patternsRe); + } +} +exports.default = DeepFilter; diff --git a/libs/events/node_modules/fast-glob/out/providers/filters/entry.d.ts b/libs/events/node_modules/fast-glob/out/providers/filters/entry.d.ts new file mode 100644 index 000000000..ee7128194 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/filters/entry.d.ts @@ -0,0 +1,16 @@ +import Settings from '../../settings'; +import { EntryFilterFunction, MicromatchOptions, Pattern } from '../../types'; +export default class EntryFilter { + private readonly _settings; + private readonly _micromatchOptions; + readonly index: Map; + constructor(_settings: Settings, _micromatchOptions: MicromatchOptions); + getFilter(positive: Pattern[], negative: Pattern[]): EntryFilterFunction; + private _filter; + private _isDuplicateEntry; + private _createIndexRecord; + private _onlyFileFilter; + private _onlyDirectoryFilter; + private _isSkippedByAbsoluteNegativePatterns; + private _isMatchToPatterns; +} diff --git a/libs/events/node_modules/fast-glob/out/providers/filters/entry.js b/libs/events/node_modules/fast-glob/out/providers/filters/entry.js new file mode 100644 index 000000000..361a7b4a1 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/filters/entry.js @@ -0,0 +1,63 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../../utils"); +class EntryFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this.index = new Map(); + } + getFilter(positive, negative) { + const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions); + const negativeRe = utils.pattern.convertPatternsToRe(negative, Object.assign(Object.assign({}, this._micromatchOptions), { dot: true })); + return (entry) => this._filter(entry, positiveRe, negativeRe); + } + _filter(entry, positiveRe, negativeRe) { + const filepath = utils.path.removeLeadingDotSegment(entry.path); + if (this._settings.unique && this._isDuplicateEntry(filepath)) { + return false; + } + if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { + return false; + } + if (this._isSkippedByAbsoluteNegativePatterns(filepath, negativeRe)) { + return false; + } + const isDirectory = entry.dirent.isDirectory(); + const isMatched = this._isMatchToPatterns(filepath, positiveRe, isDirectory) && !this._isMatchToPatterns(filepath, negativeRe, isDirectory); + if (this._settings.unique && isMatched) { + this._createIndexRecord(filepath); + } + return isMatched; + } + _isDuplicateEntry(filepath) { + return this.index.has(filepath); + } + _createIndexRecord(filepath) { + this.index.set(filepath, undefined); + } + _onlyFileFilter(entry) { + return this._settings.onlyFiles && !entry.dirent.isFile(); + } + _onlyDirectoryFilter(entry) { + return this._settings.onlyDirectories && !entry.dirent.isDirectory(); + } + _isSkippedByAbsoluteNegativePatterns(entryPath, patternsRe) { + if (!this._settings.absolute) { + return false; + } + const fullpath = utils.path.makeAbsolute(this._settings.cwd, entryPath); + return utils.pattern.matchAny(fullpath, patternsRe); + } + _isMatchToPatterns(filepath, patternsRe, isDirectory) { + // Trying to match files and directories by patterns. + const isMatched = utils.pattern.matchAny(filepath, patternsRe); + // A pattern with a trailling slash can be used for directory matching. + // To apply such pattern, we need to add a tralling slash to the path. + if (!isMatched && isDirectory) { + return utils.pattern.matchAny(filepath + '/', patternsRe); + } + return isMatched; + } +} +exports.default = EntryFilter; diff --git a/libs/events/node_modules/fast-glob/out/providers/filters/error.d.ts b/libs/events/node_modules/fast-glob/out/providers/filters/error.d.ts new file mode 100644 index 000000000..170eb251c --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/filters/error.d.ts @@ -0,0 +1,8 @@ +import Settings from '../../settings'; +import { ErrorFilterFunction } from '../../types'; +export default class ErrorFilter { + private readonly _settings; + constructor(_settings: Settings); + getFilter(): ErrorFilterFunction; + private _isNonFatalError; +} diff --git a/libs/events/node_modules/fast-glob/out/providers/filters/error.js b/libs/events/node_modules/fast-glob/out/providers/filters/error.js new file mode 100644 index 000000000..1c6f24165 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/filters/error.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../../utils"); +class ErrorFilter { + constructor(_settings) { + this._settings = _settings; + } + getFilter() { + return (error) => this._isNonFatalError(error); + } + _isNonFatalError(error) { + return utils.errno.isEnoentCodeError(error) || this._settings.suppressErrors; + } +} +exports.default = ErrorFilter; diff --git a/libs/events/node_modules/fast-glob/out/providers/matchers/matcher.d.ts b/libs/events/node_modules/fast-glob/out/providers/matchers/matcher.d.ts new file mode 100644 index 000000000..d04c23220 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/matchers/matcher.d.ts @@ -0,0 +1,33 @@ +import { Pattern, MicromatchOptions, PatternRe } from '../../types'; +import Settings from '../../settings'; +export type PatternSegment = StaticPatternSegment | DynamicPatternSegment; +type StaticPatternSegment = { + dynamic: false; + pattern: Pattern; +}; +type DynamicPatternSegment = { + dynamic: true; + pattern: Pattern; + patternRe: PatternRe; +}; +export type PatternSection = PatternSegment[]; +export type PatternInfo = { + /** + * Indicates that the pattern has a globstar (more than a single section). + */ + complete: boolean; + pattern: Pattern; + segments: PatternSegment[]; + sections: PatternSection[]; +}; +export default abstract class Matcher { + private readonly _patterns; + private readonly _settings; + private readonly _micromatchOptions; + protected readonly _storage: PatternInfo[]; + constructor(_patterns: Pattern[], _settings: Settings, _micromatchOptions: MicromatchOptions); + private _fillStorage; + private _getPatternSegments; + private _splitSegmentsIntoSections; +} +export {}; diff --git a/libs/events/node_modules/fast-glob/out/providers/matchers/matcher.js b/libs/events/node_modules/fast-glob/out/providers/matchers/matcher.js new file mode 100644 index 000000000..eae67c980 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/matchers/matcher.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../../utils"); +class Matcher { + constructor(_patterns, _settings, _micromatchOptions) { + this._patterns = _patterns; + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this._storage = []; + this._fillStorage(); + } + _fillStorage() { + for (const pattern of this._patterns) { + const segments = this._getPatternSegments(pattern); + const sections = this._splitSegmentsIntoSections(segments); + this._storage.push({ + complete: sections.length <= 1, + pattern, + segments, + sections + }); + } + } + _getPatternSegments(pattern) { + const parts = utils.pattern.getPatternParts(pattern, this._micromatchOptions); + return parts.map((part) => { + const dynamic = utils.pattern.isDynamicPattern(part, this._settings); + if (!dynamic) { + return { + dynamic: false, + pattern: part + }; + } + return { + dynamic: true, + pattern: part, + patternRe: utils.pattern.makeRe(part, this._micromatchOptions) + }; + }); + } + _splitSegmentsIntoSections(segments) { + return utils.array.splitWhen(segments, (segment) => segment.dynamic && utils.pattern.hasGlobStar(segment.pattern)); + } +} +exports.default = Matcher; diff --git a/libs/events/node_modules/fast-glob/out/providers/matchers/partial.d.ts b/libs/events/node_modules/fast-glob/out/providers/matchers/partial.d.ts new file mode 100644 index 000000000..91520f64a --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/matchers/partial.d.ts @@ -0,0 +1,4 @@ +import Matcher from './matcher'; +export default class PartialMatcher extends Matcher { + match(filepath: string): boolean; +} diff --git a/libs/events/node_modules/fast-glob/out/providers/matchers/partial.js b/libs/events/node_modules/fast-glob/out/providers/matchers/partial.js new file mode 100644 index 000000000..1dfffeb52 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/matchers/partial.js @@ -0,0 +1,38 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const matcher_1 = require("./matcher"); +class PartialMatcher extends matcher_1.default { + match(filepath) { + const parts = filepath.split('/'); + const levels = parts.length; + const patterns = this._storage.filter((info) => !info.complete || info.segments.length > levels); + for (const pattern of patterns) { + const section = pattern.sections[0]; + /** + * In this case, the pattern has a globstar and we must read all directories unconditionally, + * but only if the level has reached the end of the first group. + * + * fixtures/{a,b}/** + * ^ true/false ^ always true + */ + if (!pattern.complete && levels > section.length) { + return true; + } + const match = parts.every((part, index) => { + const segment = pattern.segments[index]; + if (segment.dynamic && segment.patternRe.test(part)) { + return true; + } + if (!segment.dynamic && segment.pattern === part) { + return true; + } + return false; + }); + if (match) { + return true; + } + } + return false; + } +} +exports.default = PartialMatcher; diff --git a/libs/events/node_modules/fast-glob/out/providers/provider.d.ts b/libs/events/node_modules/fast-glob/out/providers/provider.d.ts new file mode 100644 index 000000000..1053460a8 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/provider.d.ts @@ -0,0 +1,19 @@ +import { Task } from '../managers/tasks'; +import Settings from '../settings'; +import { MicromatchOptions, ReaderOptions } from '../types'; +import DeepFilter from './filters/deep'; +import EntryFilter from './filters/entry'; +import ErrorFilter from './filters/error'; +import EntryTransformer from './transformers/entry'; +export default abstract class Provider { + protected readonly _settings: Settings; + readonly errorFilter: ErrorFilter; + readonly entryFilter: EntryFilter; + readonly deepFilter: DeepFilter; + readonly entryTransformer: EntryTransformer; + constructor(_settings: Settings); + abstract read(_task: Task): T; + protected _getRootDirectory(task: Task): string; + protected _getReaderOptions(task: Task): ReaderOptions; + protected _getMicromatchOptions(): MicromatchOptions; +} diff --git a/libs/events/node_modules/fast-glob/out/providers/provider.js b/libs/events/node_modules/fast-glob/out/providers/provider.js new file mode 100644 index 000000000..da88ee028 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/provider.js @@ -0,0 +1,48 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); +const deep_1 = require("./filters/deep"); +const entry_1 = require("./filters/entry"); +const error_1 = require("./filters/error"); +const entry_2 = require("./transformers/entry"); +class Provider { + constructor(_settings) { + this._settings = _settings; + this.errorFilter = new error_1.default(this._settings); + this.entryFilter = new entry_1.default(this._settings, this._getMicromatchOptions()); + this.deepFilter = new deep_1.default(this._settings, this._getMicromatchOptions()); + this.entryTransformer = new entry_2.default(this._settings); + } + _getRootDirectory(task) { + return path.resolve(this._settings.cwd, task.base); + } + _getReaderOptions(task) { + const basePath = task.base === '.' ? '' : task.base; + return { + basePath, + pathSegmentSeparator: '/', + concurrency: this._settings.concurrency, + deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), + entryFilter: this.entryFilter.getFilter(task.positive, task.negative), + errorFilter: this.errorFilter.getFilter(), + followSymbolicLinks: this._settings.followSymbolicLinks, + fs: this._settings.fs, + stats: this._settings.stats, + throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, + transform: this.entryTransformer.getTransformer() + }; + } + _getMicromatchOptions() { + return { + dot: this._settings.dot, + matchBase: this._settings.baseNameMatch, + nobrace: !this._settings.braceExpansion, + nocase: !this._settings.caseSensitiveMatch, + noext: !this._settings.extglob, + noglobstar: !this._settings.globstar, + posix: true, + strictSlashes: false + }; + } +} +exports.default = Provider; diff --git a/libs/events/node_modules/fast-glob/out/providers/stream.d.ts b/libs/events/node_modules/fast-glob/out/providers/stream.d.ts new file mode 100644 index 000000000..3d02a1f44 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/stream.d.ts @@ -0,0 +1,11 @@ +/// +import { Readable } from 'stream'; +import { Task } from '../managers/tasks'; +import ReaderStream from '../readers/stream'; +import { ReaderOptions } from '../types'; +import Provider from './provider'; +export default class ProviderStream extends Provider { + protected _reader: ReaderStream; + read(task: Task): Readable; + api(root: string, task: Task, options: ReaderOptions): Readable; +} diff --git a/libs/events/node_modules/fast-glob/out/providers/stream.js b/libs/events/node_modules/fast-glob/out/providers/stream.js new file mode 100644 index 000000000..85da62eba --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/stream.js @@ -0,0 +1,31 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = require("stream"); +const stream_2 = require("../readers/stream"); +const provider_1 = require("./provider"); +class ProviderStream extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new stream_2.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const source = this.api(root, task, options); + const destination = new stream_1.Readable({ objectMode: true, read: () => { } }); + source + .once('error', (error) => destination.emit('error', error)) + .on('data', (entry) => destination.emit('data', options.transform(entry))) + .once('end', () => destination.emit('end')); + destination + .once('close', () => source.destroy()); + return destination; + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderStream; diff --git a/libs/events/node_modules/fast-glob/out/providers/sync.d.ts b/libs/events/node_modules/fast-glob/out/providers/sync.d.ts new file mode 100644 index 000000000..9c0fe1e11 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/sync.d.ts @@ -0,0 +1,9 @@ +import { Task } from '../managers/tasks'; +import ReaderSync from '../readers/sync'; +import { Entry, EntryItem, ReaderOptions } from '../types'; +import Provider from './provider'; +export default class ProviderSync extends Provider { + protected _reader: ReaderSync; + read(task: Task): EntryItem[]; + api(root: string, task: Task, options: ReaderOptions): Entry[]; +} diff --git a/libs/events/node_modules/fast-glob/out/providers/sync.js b/libs/events/node_modules/fast-glob/out/providers/sync.js new file mode 100644 index 000000000..d70aa1b1d --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/sync.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const sync_1 = require("../readers/sync"); +const provider_1 = require("./provider"); +class ProviderSync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new sync_1.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = this.api(root, task, options); + return entries.map(options.transform); + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderSync; diff --git a/libs/events/node_modules/fast-glob/out/providers/transformers/entry.d.ts b/libs/events/node_modules/fast-glob/out/providers/transformers/entry.d.ts new file mode 100644 index 000000000..e9b85fa7c --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/transformers/entry.d.ts @@ -0,0 +1,8 @@ +import Settings from '../../settings'; +import { EntryTransformerFunction } from '../../types'; +export default class EntryTransformer { + private readonly _settings; + constructor(_settings: Settings); + getTransformer(): EntryTransformerFunction; + private _transform; +} diff --git a/libs/events/node_modules/fast-glob/out/providers/transformers/entry.js b/libs/events/node_modules/fast-glob/out/providers/transformers/entry.js new file mode 100644 index 000000000..d11903c8b --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/providers/transformers/entry.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../../utils"); +class EntryTransformer { + constructor(_settings) { + this._settings = _settings; + } + getTransformer() { + return (entry) => this._transform(entry); + } + _transform(entry) { + let filepath = entry.path; + if (this._settings.absolute) { + filepath = utils.path.makeAbsolute(this._settings.cwd, filepath); + filepath = utils.path.unixify(filepath); + } + if (this._settings.markDirectories && entry.dirent.isDirectory()) { + filepath += '/'; + } + if (!this._settings.objectMode) { + return filepath; + } + return Object.assign(Object.assign({}, entry), { path: filepath }); + } +} +exports.default = EntryTransformer; diff --git a/libs/events/node_modules/fast-glob/out/readers/async.d.ts b/libs/events/node_modules/fast-glob/out/readers/async.d.ts new file mode 100644 index 000000000..fbca4286a --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/readers/async.d.ts @@ -0,0 +1,10 @@ +import * as fsWalk from '@nodelib/fs.walk'; +import { Entry, ReaderOptions, Pattern } from '../types'; +import Reader from './reader'; +import ReaderStream from './stream'; +export default class ReaderAsync extends Reader> { + protected _walkAsync: typeof fsWalk.walk; + protected _readerStream: ReaderStream; + dynamic(root: string, options: ReaderOptions): Promise; + static(patterns: Pattern[], options: ReaderOptions): Promise; +} diff --git a/libs/events/node_modules/fast-glob/out/readers/async.js b/libs/events/node_modules/fast-glob/out/readers/async.js new file mode 100644 index 000000000..d024145bb --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/readers/async.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const fsWalk = require("@nodelib/fs.walk"); +const reader_1 = require("./reader"); +const stream_1 = require("./stream"); +class ReaderAsync extends reader_1.default { + constructor() { + super(...arguments); + this._walkAsync = fsWalk.walk; + this._readerStream = new stream_1.default(this._settings); + } + dynamic(root, options) { + return new Promise((resolve, reject) => { + this._walkAsync(root, options, (error, entries) => { + if (error === null) { + resolve(entries); + } + else { + reject(error); + } + }); + }); + } + async static(patterns, options) { + const entries = []; + const stream = this._readerStream.static(patterns, options); + // After #235, replace it with an asynchronous iterator. + return new Promise((resolve, reject) => { + stream.once('error', reject); + stream.on('data', (entry) => entries.push(entry)); + stream.once('end', () => resolve(entries)); + }); + } +} +exports.default = ReaderAsync; diff --git a/libs/events/node_modules/fast-glob/out/readers/reader.d.ts b/libs/events/node_modules/fast-glob/out/readers/reader.d.ts new file mode 100644 index 000000000..2af16b670 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/readers/reader.d.ts @@ -0,0 +1,15 @@ +/// +import * as fs from 'fs'; +import * as fsStat from '@nodelib/fs.stat'; +import Settings from '../settings'; +import { Entry, ErrnoException, Pattern, ReaderOptions } from '../types'; +export default abstract class Reader { + protected readonly _settings: Settings; + protected readonly _fsStatSettings: fsStat.Settings; + constructor(_settings: Settings); + abstract dynamic(root: string, options: ReaderOptions): T; + abstract static(patterns: Pattern[], options: ReaderOptions): T; + protected _getFullEntryPath(filepath: string): string; + protected _makeEntry(stats: fs.Stats, pattern: Pattern): Entry; + protected _isFatalError(error: ErrnoException): boolean; +} diff --git a/libs/events/node_modules/fast-glob/out/readers/reader.js b/libs/events/node_modules/fast-glob/out/readers/reader.js new file mode 100644 index 000000000..7b40255ac --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/readers/reader.js @@ -0,0 +1,33 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); +const fsStat = require("@nodelib/fs.stat"); +const utils = require("../utils"); +class Reader { + constructor(_settings) { + this._settings = _settings; + this._fsStatSettings = new fsStat.Settings({ + followSymbolicLink: this._settings.followSymbolicLinks, + fs: this._settings.fs, + throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks + }); + } + _getFullEntryPath(filepath) { + return path.resolve(this._settings.cwd, filepath); + } + _makeEntry(stats, pattern) { + const entry = { + name: pattern, + path: pattern, + dirent: utils.fs.createDirentFromStats(pattern, stats) + }; + if (this._settings.stats) { + entry.stats = stats; + } + return entry; + } + _isFatalError(error) { + return !utils.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; + } +} +exports.default = Reader; diff --git a/libs/events/node_modules/fast-glob/out/readers/stream.d.ts b/libs/events/node_modules/fast-glob/out/readers/stream.d.ts new file mode 100644 index 000000000..1c74cac6e --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/readers/stream.d.ts @@ -0,0 +1,14 @@ +/// +import { Readable } from 'stream'; +import * as fsStat from '@nodelib/fs.stat'; +import * as fsWalk from '@nodelib/fs.walk'; +import { Pattern, ReaderOptions } from '../types'; +import Reader from './reader'; +export default class ReaderStream extends Reader { + protected _walkStream: typeof fsWalk.walkStream; + protected _stat: typeof fsStat.stat; + dynamic(root: string, options: ReaderOptions): Readable; + static(patterns: Pattern[], options: ReaderOptions): Readable; + private _getEntry; + private _getStat; +} diff --git a/libs/events/node_modules/fast-glob/out/readers/stream.js b/libs/events/node_modules/fast-glob/out/readers/stream.js new file mode 100644 index 000000000..317c6d5db --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/readers/stream.js @@ -0,0 +1,55 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = require("stream"); +const fsStat = require("@nodelib/fs.stat"); +const fsWalk = require("@nodelib/fs.walk"); +const reader_1 = require("./reader"); +class ReaderStream extends reader_1.default { + constructor() { + super(...arguments); + this._walkStream = fsWalk.walkStream; + this._stat = fsStat.stat; + } + dynamic(root, options) { + return this._walkStream(root, options); + } + static(patterns, options) { + const filepaths = patterns.map(this._getFullEntryPath, this); + const stream = new stream_1.PassThrough({ objectMode: true }); + stream._write = (index, _enc, done) => { + return this._getEntry(filepaths[index], patterns[index], options) + .then((entry) => { + if (entry !== null && options.entryFilter(entry)) { + stream.push(entry); + } + if (index === filepaths.length - 1) { + stream.end(); + } + done(); + }) + .catch(done); + }; + for (let i = 0; i < filepaths.length; i++) { + stream.write(i); + } + return stream; + } + _getEntry(filepath, pattern, options) { + return this._getStat(filepath) + .then((stats) => this._makeEntry(stats, pattern)) + .catch((error) => { + if (options.errorFilter(error)) { + return null; + } + throw error; + }); + } + _getStat(filepath) { + return new Promise((resolve, reject) => { + this._stat(filepath, this._fsStatSettings, (error, stats) => { + return error === null ? resolve(stats) : reject(error); + }); + }); + } +} +exports.default = ReaderStream; diff --git a/libs/events/node_modules/fast-glob/out/readers/sync.d.ts b/libs/events/node_modules/fast-glob/out/readers/sync.d.ts new file mode 100644 index 000000000..c96ffeed3 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/readers/sync.d.ts @@ -0,0 +1,12 @@ +import * as fsStat from '@nodelib/fs.stat'; +import * as fsWalk from '@nodelib/fs.walk'; +import { Entry, Pattern, ReaderOptions } from '../types'; +import Reader from './reader'; +export default class ReaderSync extends Reader { + protected _walkSync: typeof fsWalk.walkSync; + protected _statSync: typeof fsStat.statSync; + dynamic(root: string, options: ReaderOptions): Entry[]; + static(patterns: Pattern[], options: ReaderOptions): Entry[]; + private _getEntry; + private _getStat; +} diff --git a/libs/events/node_modules/fast-glob/out/readers/sync.js b/libs/events/node_modules/fast-glob/out/readers/sync.js new file mode 100644 index 000000000..4704d65d1 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/readers/sync.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = require("@nodelib/fs.stat"); +const fsWalk = require("@nodelib/fs.walk"); +const reader_1 = require("./reader"); +class ReaderSync extends reader_1.default { + constructor() { + super(...arguments); + this._walkSync = fsWalk.walkSync; + this._statSync = fsStat.statSync; + } + dynamic(root, options) { + return this._walkSync(root, options); + } + static(patterns, options) { + const entries = []; + for (const pattern of patterns) { + const filepath = this._getFullEntryPath(pattern); + const entry = this._getEntry(filepath, pattern, options); + if (entry === null || !options.entryFilter(entry)) { + continue; + } + entries.push(entry); + } + return entries; + } + _getEntry(filepath, pattern, options) { + try { + const stats = this._getStat(filepath); + return this._makeEntry(stats, pattern); + } + catch (error) { + if (options.errorFilter(error)) { + return null; + } + throw error; + } + } + _getStat(filepath) { + return this._statSync(filepath, this._fsStatSettings); + } +} +exports.default = ReaderSync; diff --git a/libs/events/node_modules/fast-glob/out/settings.d.ts b/libs/events/node_modules/fast-glob/out/settings.d.ts new file mode 100644 index 000000000..76a74f8a7 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/settings.d.ts @@ -0,0 +1,164 @@ +import { FileSystemAdapter, Pattern } from './types'; +export declare const DEFAULT_FILE_SYSTEM_ADAPTER: FileSystemAdapter; +export type Options = { + /** + * Return the absolute path for entries. + * + * @default false + */ + absolute?: boolean; + /** + * If set to `true`, then patterns without slashes will be matched against + * the basename of the path if it contains slashes. + * + * @default false + */ + baseNameMatch?: boolean; + /** + * Enables Bash-like brace expansion. + * + * @default true + */ + braceExpansion?: boolean; + /** + * Enables a case-sensitive mode for matching files. + * + * @default true + */ + caseSensitiveMatch?: boolean; + /** + * Specifies the maximum number of concurrent requests from a reader to read + * directories. + * + * @default os.cpus().length + */ + concurrency?: number; + /** + * The current working directory in which to search. + * + * @default process.cwd() + */ + cwd?: string; + /** + * Specifies the maximum depth of a read directory relative to the start + * directory. + * + * @default Infinity + */ + deep?: number; + /** + * Allow patterns to match entries that begin with a period (`.`). + * + * @default false + */ + dot?: boolean; + /** + * Enables Bash-like `extglob` functionality. + * + * @default true + */ + extglob?: boolean; + /** + * Indicates whether to traverse descendants of symbolic link directories. + * + * @default true + */ + followSymbolicLinks?: boolean; + /** + * Custom implementation of methods for working with the file system. + * + * @default fs.* + */ + fs?: Partial; + /** + * Enables recursively repeats a pattern containing `**`. + * If `false`, `**` behaves exactly like `*`. + * + * @default true + */ + globstar?: boolean; + /** + * An array of glob patterns to exclude matches. + * This is an alternative way to use negative patterns. + * + * @default [] + */ + ignore?: Pattern[]; + /** + * Mark the directory path with the final slash. + * + * @default false + */ + markDirectories?: boolean; + /** + * Returns objects (instead of strings) describing entries. + * + * @default false + */ + objectMode?: boolean; + /** + * Return only directories. + * + * @default false + */ + onlyDirectories?: boolean; + /** + * Return only files. + * + * @default true + */ + onlyFiles?: boolean; + /** + * Enables an object mode (`objectMode`) with an additional `stats` field. + * + * @default false + */ + stats?: boolean; + /** + * By default this package suppress only `ENOENT` errors. + * Set to `true` to suppress any error. + * + * @default false + */ + suppressErrors?: boolean; + /** + * Throw an error when symbolic link is broken if `true` or safely + * return `lstat` call if `false`. + * + * @default false + */ + throwErrorOnBrokenSymbolicLink?: boolean; + /** + * Ensures that the returned entries are unique. + * + * @default true + */ + unique?: boolean; +}; +export default class Settings { + private readonly _options; + readonly absolute: boolean; + readonly baseNameMatch: boolean; + readonly braceExpansion: boolean; + readonly caseSensitiveMatch: boolean; + readonly concurrency: number; + readonly cwd: string; + readonly deep: number; + readonly dot: boolean; + readonly extglob: boolean; + readonly followSymbolicLinks: boolean; + readonly fs: FileSystemAdapter; + readonly globstar: boolean; + readonly ignore: Pattern[]; + readonly markDirectories: boolean; + readonly objectMode: boolean; + readonly onlyDirectories: boolean; + readonly onlyFiles: boolean; + readonly stats: boolean; + readonly suppressErrors: boolean; + readonly throwErrorOnBrokenSymbolicLink: boolean; + readonly unique: boolean; + constructor(_options?: Options); + private _getValue; + private _getFileSystemMethods; +} diff --git a/libs/events/node_modules/fast-glob/out/settings.js b/libs/events/node_modules/fast-glob/out/settings.js new file mode 100644 index 000000000..23f916c8c --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/settings.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DEFAULT_FILE_SYSTEM_ADAPTER = void 0; +const fs = require("fs"); +const os = require("os"); +/** + * The `os.cpus` method can return zero. We expect the number of cores to be greater than zero. + * https://github.com/nodejs/node/blob/7faeddf23a98c53896f8b574a6e66589e8fb1eb8/lib/os.js#L106-L107 + */ +const CPU_COUNT = Math.max(os.cpus().length, 1); +exports.DEFAULT_FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + lstatSync: fs.lstatSync, + stat: fs.stat, + statSync: fs.statSync, + readdir: fs.readdir, + readdirSync: fs.readdirSync +}; +class Settings { + constructor(_options = {}) { + this._options = _options; + this.absolute = this._getValue(this._options.absolute, false); + this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); + this.braceExpansion = this._getValue(this._options.braceExpansion, true); + this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); + this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); + this.cwd = this._getValue(this._options.cwd, process.cwd()); + this.deep = this._getValue(this._options.deep, Infinity); + this.dot = this._getValue(this._options.dot, false); + this.extglob = this._getValue(this._options.extglob, true); + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); + this.fs = this._getFileSystemMethods(this._options.fs); + this.globstar = this._getValue(this._options.globstar, true); + this.ignore = this._getValue(this._options.ignore, []); + this.markDirectories = this._getValue(this._options.markDirectories, false); + this.objectMode = this._getValue(this._options.objectMode, false); + this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); + this.onlyFiles = this._getValue(this._options.onlyFiles, true); + this.stats = this._getValue(this._options.stats, false); + this.suppressErrors = this._getValue(this._options.suppressErrors, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); + this.unique = this._getValue(this._options.unique, true); + if (this.onlyDirectories) { + this.onlyFiles = false; + } + if (this.stats) { + this.objectMode = true; + } + // Remove the cast to the array in the next major (#404). + this.ignore = [].concat(this.ignore); + } + _getValue(option, value) { + return option === undefined ? value : option; + } + _getFileSystemMethods(methods = {}) { + return Object.assign(Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER), methods); + } +} +exports.default = Settings; diff --git a/libs/events/node_modules/fast-glob/out/types/index.d.ts b/libs/events/node_modules/fast-glob/out/types/index.d.ts new file mode 100644 index 000000000..6506cafd1 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/types/index.d.ts @@ -0,0 +1,31 @@ +/// +import * as fsWalk from '@nodelib/fs.walk'; +export type ErrnoException = NodeJS.ErrnoException; +export type Entry = fsWalk.Entry; +export type EntryItem = string | Entry; +export type Pattern = string; +export type PatternRe = RegExp; +export type PatternsGroup = Record; +export type ReaderOptions = fsWalk.Options & { + transform(entry: Entry): EntryItem; + deepFilter: DeepFilterFunction; + entryFilter: EntryFilterFunction; + errorFilter: ErrorFilterFunction; + fs: FileSystemAdapter; + stats: boolean; +}; +export type ErrorFilterFunction = fsWalk.ErrorFilterFunction; +export type EntryFilterFunction = fsWalk.EntryFilterFunction; +export type DeepFilterFunction = fsWalk.DeepFilterFunction; +export type EntryTransformerFunction = (entry: Entry) => EntryItem; +export type MicromatchOptions = { + dot?: boolean; + matchBase?: boolean; + nobrace?: boolean; + nocase?: boolean; + noext?: boolean; + noglobstar?: boolean; + posix?: boolean; + strictSlashes?: boolean; +}; +export type FileSystemAdapter = fsWalk.FileSystemAdapter; diff --git a/libs/events/node_modules/fast-glob/out/types/index.js b/libs/events/node_modules/fast-glob/out/types/index.js new file mode 100644 index 000000000..c8ad2e549 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/types/index.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/libs/events/node_modules/fast-glob/out/utils/array.d.ts b/libs/events/node_modules/fast-glob/out/utils/array.d.ts new file mode 100644 index 000000000..98e73250d --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/array.d.ts @@ -0,0 +1,2 @@ +export declare function flatten(items: T[][]): T[]; +export declare function splitWhen(items: T[], predicate: (item: T) => boolean): T[][]; diff --git a/libs/events/node_modules/fast-glob/out/utils/array.js b/libs/events/node_modules/fast-glob/out/utils/array.js new file mode 100644 index 000000000..50c406e86 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/array.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.splitWhen = exports.flatten = void 0; +function flatten(items) { + return items.reduce((collection, item) => [].concat(collection, item), []); +} +exports.flatten = flatten; +function splitWhen(items, predicate) { + const result = [[]]; + let groupIndex = 0; + for (const item of items) { + if (predicate(item)) { + groupIndex++; + result[groupIndex] = []; + } + else { + result[groupIndex].push(item); + } + } + return result; +} +exports.splitWhen = splitWhen; diff --git a/libs/events/node_modules/fast-glob/out/utils/errno.d.ts b/libs/events/node_modules/fast-glob/out/utils/errno.d.ts new file mode 100644 index 000000000..1c08d3ba8 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/errno.d.ts @@ -0,0 +1,2 @@ +import { ErrnoException } from '../types'; +export declare function isEnoentCodeError(error: ErrnoException): boolean; diff --git a/libs/events/node_modules/fast-glob/out/utils/errno.js b/libs/events/node_modules/fast-glob/out/utils/errno.js new file mode 100644 index 000000000..f0bd8015d --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/errno.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isEnoentCodeError = void 0; +function isEnoentCodeError(error) { + return error.code === 'ENOENT'; +} +exports.isEnoentCodeError = isEnoentCodeError; diff --git a/libs/events/node_modules/fast-glob/out/utils/fs.d.ts b/libs/events/node_modules/fast-glob/out/utils/fs.d.ts new file mode 100644 index 000000000..64c61ce6c --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/fs.d.ts @@ -0,0 +1,4 @@ +/// +import * as fs from 'fs'; +import { Dirent } from '@nodelib/fs.walk'; +export declare function createDirentFromStats(name: string, stats: fs.Stats): Dirent; diff --git a/libs/events/node_modules/fast-glob/out/utils/fs.js b/libs/events/node_modules/fast-glob/out/utils/fs.js new file mode 100644 index 000000000..ace7c74d6 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/fs.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createDirentFromStats = void 0; +class DirentFromStats { + constructor(name, stats) { + this.name = name; + this.isBlockDevice = stats.isBlockDevice.bind(stats); + this.isCharacterDevice = stats.isCharacterDevice.bind(stats); + this.isDirectory = stats.isDirectory.bind(stats); + this.isFIFO = stats.isFIFO.bind(stats); + this.isFile = stats.isFile.bind(stats); + this.isSocket = stats.isSocket.bind(stats); + this.isSymbolicLink = stats.isSymbolicLink.bind(stats); + } +} +function createDirentFromStats(name, stats) { + return new DirentFromStats(name, stats); +} +exports.createDirentFromStats = createDirentFromStats; diff --git a/libs/events/node_modules/fast-glob/out/utils/index.d.ts b/libs/events/node_modules/fast-glob/out/utils/index.d.ts new file mode 100644 index 000000000..f634cad04 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/index.d.ts @@ -0,0 +1,8 @@ +import * as array from './array'; +import * as errno from './errno'; +import * as fs from './fs'; +import * as path from './path'; +import * as pattern from './pattern'; +import * as stream from './stream'; +import * as string from './string'; +export { array, errno, fs, path, pattern, stream, string }; diff --git a/libs/events/node_modules/fast-glob/out/utils/index.js b/libs/events/node_modules/fast-glob/out/utils/index.js new file mode 100644 index 000000000..0f92c1667 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/index.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.string = exports.stream = exports.pattern = exports.path = exports.fs = exports.errno = exports.array = void 0; +const array = require("./array"); +exports.array = array; +const errno = require("./errno"); +exports.errno = errno; +const fs = require("./fs"); +exports.fs = fs; +const path = require("./path"); +exports.path = path; +const pattern = require("./pattern"); +exports.pattern = pattern; +const stream = require("./stream"); +exports.stream = stream; +const string = require("./string"); +exports.string = string; diff --git a/libs/events/node_modules/fast-glob/out/utils/path.d.ts b/libs/events/node_modules/fast-glob/out/utils/path.d.ts new file mode 100644 index 000000000..0b13f4b48 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/path.d.ts @@ -0,0 +1,13 @@ +import { Pattern } from '../types'; +/** + * Designed to work only with simple paths: `dir\\file`. + */ +export declare function unixify(filepath: string): string; +export declare function makeAbsolute(cwd: string, filepath: string): string; +export declare function removeLeadingDotSegment(entry: string): string; +export declare const escape: typeof escapeWindowsPath; +export declare function escapeWindowsPath(pattern: Pattern): Pattern; +export declare function escapePosixPath(pattern: Pattern): Pattern; +export declare const convertPathToPattern: typeof convertWindowsPathToPattern; +export declare function convertWindowsPathToPattern(filepath: string): Pattern; +export declare function convertPosixPathToPattern(filepath: string): Pattern; diff --git a/libs/events/node_modules/fast-glob/out/utils/path.js b/libs/events/node_modules/fast-glob/out/utils/path.js new file mode 100644 index 000000000..97a7b492b --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/path.js @@ -0,0 +1,68 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.convertPosixPathToPattern = exports.convertWindowsPathToPattern = exports.convertPathToPattern = exports.escapePosixPath = exports.escapeWindowsPath = exports.escape = exports.removeLeadingDotSegment = exports.makeAbsolute = exports.unixify = void 0; +const os = require("os"); +const path = require("path"); +const IS_WINDOWS_PLATFORM = os.platform() === 'win32'; +const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\ +/** + * All non-escaped special characters. + * Posix: ()*?[\]{|}, !+@ before (, ! at the beginning, \\ before non-special characters. + * Windows: (){}, !+@ before (, ! at the beginning. + */ +const POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g; +const WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([(){}]|^!|[!+@](?=\())/g; +/** + * The device path (\\.\ or \\?\). + * https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#dos-device-paths + */ +const DOS_DEVICE_PATH_RE = /^\\\\([.?])/; +/** + * All backslashes except those escaping special characters. + * Windows: !()+@{} + * https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions + */ +const WINDOWS_BACKSLASHES_RE = /\\(?![!()+@{}])/g; +/** + * Designed to work only with simple paths: `dir\\file`. + */ +function unixify(filepath) { + return filepath.replace(/\\/g, '/'); +} +exports.unixify = unixify; +function makeAbsolute(cwd, filepath) { + return path.resolve(cwd, filepath); +} +exports.makeAbsolute = makeAbsolute; +function removeLeadingDotSegment(entry) { + // We do not use `startsWith` because this is 10x slower than current implementation for some cases. + // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with + if (entry.charAt(0) === '.') { + const secondCharactery = entry.charAt(1); + if (secondCharactery === '/' || secondCharactery === '\\') { + return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT); + } + } + return entry; +} +exports.removeLeadingDotSegment = removeLeadingDotSegment; +exports.escape = IS_WINDOWS_PLATFORM ? escapeWindowsPath : escapePosixPath; +function escapeWindowsPath(pattern) { + return pattern.replace(WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); +} +exports.escapeWindowsPath = escapeWindowsPath; +function escapePosixPath(pattern) { + return pattern.replace(POSIX_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); +} +exports.escapePosixPath = escapePosixPath; +exports.convertPathToPattern = IS_WINDOWS_PLATFORM ? convertWindowsPathToPattern : convertPosixPathToPattern; +function convertWindowsPathToPattern(filepath) { + return escapeWindowsPath(filepath) + .replace(DOS_DEVICE_PATH_RE, '//$1') + .replace(WINDOWS_BACKSLASHES_RE, '/'); +} +exports.convertWindowsPathToPattern = convertWindowsPathToPattern; +function convertPosixPathToPattern(filepath) { + return escapePosixPath(filepath); +} +exports.convertPosixPathToPattern = convertPosixPathToPattern; diff --git a/libs/events/node_modules/fast-glob/out/utils/pattern.d.ts b/libs/events/node_modules/fast-glob/out/utils/pattern.d.ts new file mode 100644 index 000000000..e7ff07bb8 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/pattern.d.ts @@ -0,0 +1,47 @@ +import { MicromatchOptions, Pattern, PatternRe } from '../types'; +type PatternTypeOptions = { + braceExpansion?: boolean; + caseSensitiveMatch?: boolean; + extglob?: boolean; +}; +export declare function isStaticPattern(pattern: Pattern, options?: PatternTypeOptions): boolean; +export declare function isDynamicPattern(pattern: Pattern, options?: PatternTypeOptions): boolean; +export declare function convertToPositivePattern(pattern: Pattern): Pattern; +export declare function convertToNegativePattern(pattern: Pattern): Pattern; +export declare function isNegativePattern(pattern: Pattern): boolean; +export declare function isPositivePattern(pattern: Pattern): boolean; +export declare function getNegativePatterns(patterns: Pattern[]): Pattern[]; +export declare function getPositivePatterns(patterns: Pattern[]): Pattern[]; +/** + * Returns patterns that can be applied inside the current directory. + * + * @example + * // ['./*', '*', 'a/*'] + * getPatternsInsideCurrentDirectory(['./*', '*', 'a/*', '../*', './../*']) + */ +export declare function getPatternsInsideCurrentDirectory(patterns: Pattern[]): Pattern[]; +/** + * Returns patterns to be expanded relative to (outside) the current directory. + * + * @example + * // ['../*', './../*'] + * getPatternsInsideCurrentDirectory(['./*', '*', 'a/*', '../*', './../*']) + */ +export declare function getPatternsOutsideCurrentDirectory(patterns: Pattern[]): Pattern[]; +export declare function isPatternRelatedToParentDirectory(pattern: Pattern): boolean; +export declare function getBaseDirectory(pattern: Pattern): string; +export declare function hasGlobStar(pattern: Pattern): boolean; +export declare function endsWithSlashGlobStar(pattern: Pattern): boolean; +export declare function isAffectDepthOfReadingPattern(pattern: Pattern): boolean; +export declare function expandPatternsWithBraceExpansion(patterns: Pattern[]): Pattern[]; +export declare function expandBraceExpansion(pattern: Pattern): Pattern[]; +export declare function getPatternParts(pattern: Pattern, options: MicromatchOptions): Pattern[]; +export declare function makeRe(pattern: Pattern, options: MicromatchOptions): PatternRe; +export declare function convertPatternsToRe(patterns: Pattern[], options: MicromatchOptions): PatternRe[]; +export declare function matchAny(entry: string, patternsRe: PatternRe[]): boolean; +/** + * This package only works with forward slashes as a path separator. + * Because of this, we cannot use the standard `path.normalize` method, because on Windows platform it will use of backslashes. + */ +export declare function removeDuplicateSlashes(pattern: string): string; +export {}; diff --git a/libs/events/node_modules/fast-glob/out/utils/pattern.js b/libs/events/node_modules/fast-glob/out/utils/pattern.js new file mode 100644 index 000000000..0f5e9ca73 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/pattern.js @@ -0,0 +1,188 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.removeDuplicateSlashes = exports.matchAny = exports.convertPatternsToRe = exports.makeRe = exports.getPatternParts = exports.expandBraceExpansion = exports.expandPatternsWithBraceExpansion = exports.isAffectDepthOfReadingPattern = exports.endsWithSlashGlobStar = exports.hasGlobStar = exports.getBaseDirectory = exports.isPatternRelatedToParentDirectory = exports.getPatternsOutsideCurrentDirectory = exports.getPatternsInsideCurrentDirectory = exports.getPositivePatterns = exports.getNegativePatterns = exports.isPositivePattern = exports.isNegativePattern = exports.convertToNegativePattern = exports.convertToPositivePattern = exports.isDynamicPattern = exports.isStaticPattern = void 0; +const path = require("path"); +const globParent = require("glob-parent"); +const micromatch = require("micromatch"); +const GLOBSTAR = '**'; +const ESCAPE_SYMBOL = '\\'; +const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; +const REGEX_CHARACTER_CLASS_SYMBOLS_RE = /\[[^[]*]/; +const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\([^(]*\|[^|]*\)/; +const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\([^(]*\)/; +const BRACE_EXPANSION_SEPARATORS_RE = /,|\.\./; +/** + * Matches a sequence of two or more consecutive slashes, excluding the first two slashes at the beginning of the string. + * The latter is due to the presence of the device path at the beginning of the UNC path. + */ +const DOUBLE_SLASH_RE = /(?!^)\/{2,}/g; +function isStaticPattern(pattern, options = {}) { + return !isDynamicPattern(pattern, options); +} +exports.isStaticPattern = isStaticPattern; +function isDynamicPattern(pattern, options = {}) { + /** + * A special case with an empty string is necessary for matching patterns that start with a forward slash. + * An empty string cannot be a dynamic pattern. + * For example, the pattern `/lib/*` will be spread into parts: '', 'lib', '*'. + */ + if (pattern === '') { + return false; + } + /** + * When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check + * filepath directly (without read directory). + */ + if (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) { + return true; + } + if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) { + return true; + } + if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) { + return true; + } + if (options.braceExpansion !== false && hasBraceExpansion(pattern)) { + return true; + } + return false; +} +exports.isDynamicPattern = isDynamicPattern; +function hasBraceExpansion(pattern) { + const openingBraceIndex = pattern.indexOf('{'); + if (openingBraceIndex === -1) { + return false; + } + const closingBraceIndex = pattern.indexOf('}', openingBraceIndex + 1); + if (closingBraceIndex === -1) { + return false; + } + const braceContent = pattern.slice(openingBraceIndex, closingBraceIndex); + return BRACE_EXPANSION_SEPARATORS_RE.test(braceContent); +} +function convertToPositivePattern(pattern) { + return isNegativePattern(pattern) ? pattern.slice(1) : pattern; +} +exports.convertToPositivePattern = convertToPositivePattern; +function convertToNegativePattern(pattern) { + return '!' + pattern; +} +exports.convertToNegativePattern = convertToNegativePattern; +function isNegativePattern(pattern) { + return pattern.startsWith('!') && pattern[1] !== '('; +} +exports.isNegativePattern = isNegativePattern; +function isPositivePattern(pattern) { + return !isNegativePattern(pattern); +} +exports.isPositivePattern = isPositivePattern; +function getNegativePatterns(patterns) { + return patterns.filter(isNegativePattern); +} +exports.getNegativePatterns = getNegativePatterns; +function getPositivePatterns(patterns) { + return patterns.filter(isPositivePattern); +} +exports.getPositivePatterns = getPositivePatterns; +/** + * Returns patterns that can be applied inside the current directory. + * + * @example + * // ['./*', '*', 'a/*'] + * getPatternsInsideCurrentDirectory(['./*', '*', 'a/*', '../*', './../*']) + */ +function getPatternsInsideCurrentDirectory(patterns) { + return patterns.filter((pattern) => !isPatternRelatedToParentDirectory(pattern)); +} +exports.getPatternsInsideCurrentDirectory = getPatternsInsideCurrentDirectory; +/** + * Returns patterns to be expanded relative to (outside) the current directory. + * + * @example + * // ['../*', './../*'] + * getPatternsInsideCurrentDirectory(['./*', '*', 'a/*', '../*', './../*']) + */ +function getPatternsOutsideCurrentDirectory(patterns) { + return patterns.filter(isPatternRelatedToParentDirectory); +} +exports.getPatternsOutsideCurrentDirectory = getPatternsOutsideCurrentDirectory; +function isPatternRelatedToParentDirectory(pattern) { + return pattern.startsWith('..') || pattern.startsWith('./..'); +} +exports.isPatternRelatedToParentDirectory = isPatternRelatedToParentDirectory; +function getBaseDirectory(pattern) { + return globParent(pattern, { flipBackslashes: false }); +} +exports.getBaseDirectory = getBaseDirectory; +function hasGlobStar(pattern) { + return pattern.includes(GLOBSTAR); +} +exports.hasGlobStar = hasGlobStar; +function endsWithSlashGlobStar(pattern) { + return pattern.endsWith('/' + GLOBSTAR); +} +exports.endsWithSlashGlobStar = endsWithSlashGlobStar; +function isAffectDepthOfReadingPattern(pattern) { + const basename = path.basename(pattern); + return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); +} +exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; +function expandPatternsWithBraceExpansion(patterns) { + return patterns.reduce((collection, pattern) => { + return collection.concat(expandBraceExpansion(pattern)); + }, []); +} +exports.expandPatternsWithBraceExpansion = expandPatternsWithBraceExpansion; +function expandBraceExpansion(pattern) { + const patterns = micromatch.braces(pattern, { expand: true, nodupes: true }); + /** + * Sort the patterns by length so that the same depth patterns are processed side by side. + * `a/{b,}/{c,}/*` – `['a///*', 'a/b//*', 'a//c/*', 'a/b/c/*']` + */ + patterns.sort((a, b) => a.length - b.length); + /** + * Micromatch can return an empty string in the case of patterns like `{a,}`. + */ + return patterns.filter((pattern) => pattern !== ''); +} +exports.expandBraceExpansion = expandBraceExpansion; +function getPatternParts(pattern, options) { + let { parts } = micromatch.scan(pattern, Object.assign(Object.assign({}, options), { parts: true })); + /** + * The scan method returns an empty array in some cases. + * See micromatch/picomatch#58 for more details. + */ + if (parts.length === 0) { + parts = [pattern]; + } + /** + * The scan method does not return an empty part for the pattern with a forward slash. + * This is another part of micromatch/picomatch#58. + */ + if (parts[0].startsWith('/')) { + parts[0] = parts[0].slice(1); + parts.unshift(''); + } + return parts; +} +exports.getPatternParts = getPatternParts; +function makeRe(pattern, options) { + return micromatch.makeRe(pattern, options); +} +exports.makeRe = makeRe; +function convertPatternsToRe(patterns, options) { + return patterns.map((pattern) => makeRe(pattern, options)); +} +exports.convertPatternsToRe = convertPatternsToRe; +function matchAny(entry, patternsRe) { + return patternsRe.some((patternRe) => patternRe.test(entry)); +} +exports.matchAny = matchAny; +/** + * This package only works with forward slashes as a path separator. + * Because of this, we cannot use the standard `path.normalize` method, because on Windows platform it will use of backslashes. + */ +function removeDuplicateSlashes(pattern) { + return pattern.replace(DOUBLE_SLASH_RE, '/'); +} +exports.removeDuplicateSlashes = removeDuplicateSlashes; diff --git a/libs/events/node_modules/fast-glob/out/utils/stream.d.ts b/libs/events/node_modules/fast-glob/out/utils/stream.d.ts new file mode 100644 index 000000000..4daf9137f --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/stream.d.ts @@ -0,0 +1,4 @@ +/// +/// +import { Readable } from 'stream'; +export declare function merge(streams: Readable[]): NodeJS.ReadableStream; diff --git a/libs/events/node_modules/fast-glob/out/utils/stream.js b/libs/events/node_modules/fast-glob/out/utils/stream.js new file mode 100644 index 000000000..b32028ce4 --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/stream.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.merge = void 0; +const merge2 = require("merge2"); +function merge(streams) { + const mergedStream = merge2(streams); + streams.forEach((stream) => { + stream.once('error', (error) => mergedStream.emit('error', error)); + }); + mergedStream.once('close', () => propagateCloseEventToSources(streams)); + mergedStream.once('end', () => propagateCloseEventToSources(streams)); + return mergedStream; +} +exports.merge = merge; +function propagateCloseEventToSources(streams) { + streams.forEach((stream) => stream.emit('close')); +} diff --git a/libs/events/node_modules/fast-glob/out/utils/string.d.ts b/libs/events/node_modules/fast-glob/out/utils/string.d.ts new file mode 100644 index 000000000..c8847356c --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/string.d.ts @@ -0,0 +1,2 @@ +export declare function isString(input: unknown): input is string; +export declare function isEmpty(input: string): boolean; diff --git a/libs/events/node_modules/fast-glob/out/utils/string.js b/libs/events/node_modules/fast-glob/out/utils/string.js new file mode 100644 index 000000000..76e7ea54b --- /dev/null +++ b/libs/events/node_modules/fast-glob/out/utils/string.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isEmpty = exports.isString = void 0; +function isString(input) { + return typeof input === 'string'; +} +exports.isString = isString; +function isEmpty(input) { + return input === ''; +} +exports.isEmpty = isEmpty; diff --git a/libs/events/node_modules/fast-glob/package.json b/libs/events/node_modules/fast-glob/package.json new file mode 100644 index 000000000..bbcc0eabf --- /dev/null +++ b/libs/events/node_modules/fast-glob/package.json @@ -0,0 +1,81 @@ +{ + "name": "fast-glob", + "version": "3.3.1", + "description": "It's a very fast and efficient glob library for Node.js", + "license": "MIT", + "repository": "mrmlnc/fast-glob", + "author": { + "name": "Denis Malinochkin", + "url": "https://mrmlnc.com" + }, + "engines": { + "node": ">=8.6.0" + }, + "main": "out/index.js", + "typings": "out/index.d.ts", + "files": [ + "out", + "!out/{benchmark,tests}", + "!out/**/*.map", + "!out/**/*.spec.*" + ], + "keywords": [ + "glob", + "patterns", + "fast", + "implementation" + ], + "devDependencies": { + "@nodelib/fs.macchiato": "^1.0.1", + "@types/glob-parent": "^5.1.0", + "@types/merge2": "^1.1.4", + "@types/micromatch": "^4.0.0", + "@types/mocha": "^5.2.7", + "@types/node": "^14.18.53", + "@types/picomatch": "^2.3.0", + "@types/sinon": "^7.5.0", + "bencho": "^0.1.1", + "eslint": "^6.5.1", + "eslint-config-mrmlnc": "^1.1.0", + "execa": "^7.1.1", + "fast-glob": "^3.0.4", + "fdir": "^6.0.1", + "glob": "^10.0.0", + "hereby": "^1.8.1", + "mocha": "^6.2.1", + "rimraf": "^5.0.0", + "sinon": "^7.5.0", + "snap-shot-it": "^7.9.10", + "typescript": "^4.9.5" + }, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "scripts": { + "clean": "rimraf out", + "lint": "eslint \"src/**/*.ts\" --cache", + "compile": "tsc", + "test": "mocha \"out/**/*.spec.js\" -s 0", + "test:e2e": "mocha \"out/**/*.e2e.js\" -s 0", + "test:e2e:sync": "mocha \"out/**/*.e2e.js\" -s 0 --grep \"\\(sync\\)\"", + "test:e2e:async": "mocha \"out/**/*.e2e.js\" -s 0 --grep \"\\(async\\)\"", + "test:e2e:stream": "mocha \"out/**/*.e2e.js\" -s 0 --grep \"\\(stream\\)\"", + "build": "npm run clean && npm run compile && npm run lint && npm test", + "watch": "npm run clean && npm run compile -- --sourceMap --watch", + "bench:async": "npm run bench:product:async && npm run bench:regression:async", + "bench:stream": "npm run bench:product:stream && npm run bench:regression:stream", + "bench:sync": "npm run bench:product:sync && npm run bench:regression:sync", + "bench:product": "npm run bench:product:async && npm run bench:product:sync && npm run bench:product:stream", + "bench:product:async": "hereby bench:product:async", + "bench:product:sync": "hereby bench:product:sync", + "bench:product:stream": "hereby bench:product:stream", + "bench:regression": "npm run bench:regression:async && npm run bench:regression:sync && npm run bench:regression:stream", + "bench:regression:async": "hereby bench:regression:async", + "bench:regression:sync": "hereby bench:regression:sync", + "bench:regression:stream": "hereby bench:regression:stream" + } +} diff --git a/libs/events/node_modules/fastq/.github/dependabot.yml b/libs/events/node_modules/fastq/.github/dependabot.yml new file mode 100644 index 000000000..7e7cbe1b0 --- /dev/null +++ b/libs/events/node_modules/fastq/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: +- package-ecosystem: npm + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 + ignore: + - dependency-name: standard + versions: + - 16.0.3 diff --git a/libs/events/node_modules/fastq/.github/workflows/ci.yml b/libs/events/node_modules/fastq/.github/workflows/ci.yml new file mode 100644 index 000000000..50e66b5e5 --- /dev/null +++ b/libs/events/node_modules/fastq/.github/workflows/ci.yml @@ -0,0 +1,50 @@ +name: ci + +on: [push, pull_request] + +jobs: + legacy: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: ['0.10', '0.12', 4.x, 6.x, 8.x] + + steps: + - uses: actions/checkout@v2 + + - name: Use Node.js + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install + run: | + npm install --production && npm install tape + + - name: Run tests + run: | + npm run legacy + + test: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [10.x, 12.x, 13.x, 14.x, 15.x, 16.x] + + steps: + - uses: actions/checkout@v2 + + - name: Use Node.js + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install + run: | + npm install + + - name: Run tests + run: | + npm run test diff --git a/libs/events/node_modules/fastq/LICENSE b/libs/events/node_modules/fastq/LICENSE new file mode 100644 index 000000000..27c7bb462 --- /dev/null +++ b/libs/events/node_modules/fastq/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2015-2020, Matteo Collina + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/libs/events/node_modules/fastq/README.md b/libs/events/node_modules/fastq/README.md new file mode 100644 index 000000000..8a25fef83 --- /dev/null +++ b/libs/events/node_modules/fastq/README.md @@ -0,0 +1,309 @@ +# fastq + +![ci][ci-url] +[![npm version][npm-badge]][npm-url] +[![Dependency Status][david-badge]][david-url] + +Fast, in memory work queue. + +Benchmarks (1 million tasks): + +* setImmediate: 812ms +* fastq: 854ms +* async.queue: 1298ms +* neoAsync.queue: 1249ms + +Obtained on node 12.16.1, on a dedicated server. + +If you need zero-overhead series function call, check out +[fastseries](http://npm.im/fastseries). For zero-overhead parallel +function call, check out [fastparallel](http://npm.im/fastparallel). + +[![js-standard-style](https://raw.githubusercontent.com/feross/standard/master/badge.png)](https://github.com/feross/standard) + + *
Installation + * Usage + * API + * Licence & copyright + +## Install + +`npm i fastq --save` + +## Usage (callback API) + +```js +'use strict' + +const queue = require('fastq')(worker, 1) + +queue.push(42, function (err, result) { + if (err) { throw err } + console.log('the result is', result) +}) + +function worker (arg, cb) { + cb(null, arg * 2) +} +``` + +## Usage (promise API) + +```js +const queue = require('fastq').promise(worker, 1) + +async function worker (arg) { + return arg * 2 +} + +async function run () { + const result = await queue.push(42) + console.log('the result is', result) +} + +run() +``` + +### Setting "this" + +```js +'use strict' + +const that = { hello: 'world' } +const queue = require('fastq')(that, worker, 1) + +queue.push(42, function (err, result) { + if (err) { throw err } + console.log(this) + console.log('the result is', result) +}) + +function worker (arg, cb) { + console.log(this) + cb(null, arg * 2) +} +``` + +### Using with TypeScript (callback API) + +```ts +'use strict' + +import * as fastq from "fastq"; +import type { queue, done } from "fastq"; + +type Task = { + id: number +} + +const q: queue = fastq(worker, 1) + +q.push({ id: 42}) + +function worker (arg: Task, cb: done) { + console.log(arg.id) + cb(null) +} +``` + +### Using with TypeScript (promise API) + +```ts +'use strict' + +import * as fastq from "fastq"; +import type { queueAsPromised } from "fastq"; + +type Task = { + id: number +} + +const q: queueAsPromised = fastq.promise(asyncWorker, 1) + +q.push({ id: 42}).catch((err) => console.error(err)) + +async function asyncWorker (arg: Task): Promise { + // No need for a try-catch block, fastq handles errors automatically + console.log(arg.id) +} +``` + +## API + +* fastqueue() +* queue#push() +* queue#unshift() +* queue#pause() +* queue#resume() +* queue#idle() +* queue#length() +* queue#getQueue() +* queue#kill() +* queue#killAndDrain() +* queue#error() +* queue#concurrency +* queue#drain +* queue#empty +* queue#saturated +* fastqueue.promise() + +------------------------------------------------------- + +### fastqueue([that], worker, concurrency) + +Creates a new queue. + +Arguments: + +* `that`, optional context of the `worker` function. +* `worker`, worker function, it would be called with `that` as `this`, + if that is specified. +* `concurrency`, number of concurrent tasks that could be executed in + parallel. + +------------------------------------------------------- + +### queue.push(task, done) + +Add a task at the end of the queue. `done(err, result)` will be called +when the task was processed. + +------------------------------------------------------- + +### queue.unshift(task, done) + +Add a task at the beginning of the queue. `done(err, result)` will be called +when the task was processed. + +------------------------------------------------------- + +### queue.pause() + +Pause the processing of tasks. Currently worked tasks are not +stopped. + +------------------------------------------------------- + +### queue.resume() + +Resume the processing of tasks. + +------------------------------------------------------- + +### queue.idle() + +Returns `false` if there are tasks being processed or waiting to be processed. +`true` otherwise. + +------------------------------------------------------- + +### queue.length() + +Returns the number of tasks waiting to be processed (in the queue). + +------------------------------------------------------- + +### queue.getQueue() + +Returns all the tasks be processed (in the queue). Returns empty array when there are no tasks + +------------------------------------------------------- + +### queue.kill() + +Removes all tasks waiting to be processed, and reset `drain` to an empty +function. + +------------------------------------------------------- + +### queue.killAndDrain() + +Same than `kill` but the `drain` function will be called before reset to empty. + +------------------------------------------------------- + +### queue.error(handler) + +Set a global error handler. `handler(err, task)` will be called +each time a task is completed, `err` will be not null if the task has thrown an error. + +------------------------------------------------------- + +### queue.concurrency + +Property that returns the number of concurrent tasks that could be executed in +parallel. It can be altered at runtime. + +------------------------------------------------------- + +### queue.drain + +Function that will be called when the last +item from the queue has been processed by a worker. +It can be altered at runtime. + +------------------------------------------------------- + +### queue.empty + +Function that will be called when the last +item from the queue has been assigned to a worker. +It can be altered at runtime. + +------------------------------------------------------- + +### queue.saturated + +Function that will be called when the queue hits the concurrency +limit. +It can be altered at runtime. + +------------------------------------------------------- + +### fastqueue.promise([that], worker(arg), concurrency) + +Creates a new queue with `Promise` apis. It also offers all the methods +and properties of the object returned by [`fastqueue`](#fastqueue) with the modified +[`push`](#pushPromise) and [`unshift`](#unshiftPromise) methods. + +Node v10+ is required to use the promisified version. + +Arguments: +* `that`, optional context of the `worker` function. +* `worker`, worker function, it would be called with `that` as `this`, + if that is specified. It MUST return a `Promise`. +* `concurrency`, number of concurrent tasks that could be executed in + parallel. + + +#### queue.push(task) => Promise + +Add a task at the end of the queue. The returned `Promise` will be fulfilled (rejected) +when the task is completed successfully (unsuccessfully). + +This promise could be ignored as it will not lead to a `'unhandledRejection'`. + + +#### queue.unshift(task) => Promise + +Add a task at the beginning of the queue. The returned `Promise` will be fulfilled (rejected) +when the task is completed successfully (unsuccessfully). + +This promise could be ignored as it will not lead to a `'unhandledRejection'`. + + +#### queue.drained() => Promise + +Wait for the queue to be drained. The returned `Promise` will be resolved when all tasks in the queue have been processed by a worker. + +This promise could be ignored as it will not lead to a `'unhandledRejection'`. + +## License + +ISC + +[ci-url]: https://github.com/mcollina/fastq/workflows/ci/badge.svg +[npm-badge]: https://badge.fury.io/js/fastq.svg +[npm-url]: https://badge.fury.io/js/fastq +[david-badge]: https://david-dm.org/mcollina/fastq.svg +[david-url]: https://david-dm.org/mcollina/fastq diff --git a/libs/events/node_modules/fastq/bench.js b/libs/events/node_modules/fastq/bench.js new file mode 100644 index 000000000..4eaa829f3 --- /dev/null +++ b/libs/events/node_modules/fastq/bench.js @@ -0,0 +1,66 @@ +'use strict' + +const max = 1000000 +const fastqueue = require('./')(worker, 1) +const { promisify } = require('util') +const immediate = promisify(setImmediate) +const qPromise = require('./').promise(immediate, 1) +const async = require('async') +const neo = require('neo-async') +const asyncqueue = async.queue(worker, 1) +const neoqueue = neo.queue(worker, 1) + +function bench (func, done) { + const key = max + '*' + func.name + let count = -1 + + console.time(key) + end() + + function end () { + if (++count < max) { + func(end) + } else { + console.timeEnd(key) + if (done) { + done() + } + } + } +} + +function benchFastQ (done) { + fastqueue.push(42, done) +} + +function benchAsyncQueue (done) { + asyncqueue.push(42, done) +} + +function benchNeoQueue (done) { + neoqueue.push(42, done) +} + +function worker (arg, cb) { + setImmediate(cb) +} + +function benchSetImmediate (cb) { + worker(42, cb) +} + +function benchFastQPromise (done) { + qPromise.push(42).then(function () { done() }, done) +} + +function runBench (done) { + async.eachSeries([ + benchSetImmediate, + benchFastQ, + benchNeoQueue, + benchAsyncQueue, + benchFastQPromise + ], bench, done) +} + +runBench(runBench) diff --git a/libs/events/node_modules/fastq/example.js b/libs/events/node_modules/fastq/example.js new file mode 100644 index 000000000..665fdc841 --- /dev/null +++ b/libs/events/node_modules/fastq/example.js @@ -0,0 +1,14 @@ +'use strict' + +/* eslint-disable no-var */ + +var queue = require('./')(worker, 1) + +queue.push(42, function (err, result) { + if (err) { throw err } + console.log('the result is', result) +}) + +function worker (arg, cb) { + cb(null, 42 * 2) +} diff --git a/libs/events/node_modules/fastq/example.mjs b/libs/events/node_modules/fastq/example.mjs new file mode 100644 index 000000000..81be789a0 --- /dev/null +++ b/libs/events/node_modules/fastq/example.mjs @@ -0,0 +1,11 @@ +import { promise as queueAsPromised } from './queue.js' + +/* eslint-disable */ + +const queue = queueAsPromised(worker, 1) + +console.log('the result is', await queue.push(42)) + +async function worker (arg) { + return 42 * 2 +} diff --git a/libs/events/node_modules/fastq/index.d.ts b/libs/events/node_modules/fastq/index.d.ts new file mode 100644 index 000000000..65ebe6582 --- /dev/null +++ b/libs/events/node_modules/fastq/index.d.ts @@ -0,0 +1,37 @@ +declare function fastq(context: C, worker: fastq.worker, concurrency: number): fastq.queue +declare function fastq(worker: fastq.worker, concurrency: number): fastq.queue + +declare namespace fastq { + type worker = (this: C, task: T, cb: fastq.done) => void + type asyncWorker = (this: C, task: T) => Promise + type done = (err: Error | null, result?: R) => void + type errorHandler = (err: Error, task: T) => void + + interface queue { + push(task: T, done?: done): void + unshift(task: T, done?: done): void + pause(): any + resume(): any + idle(): boolean + length(): number + getQueue(): T[] + kill(): any + killAndDrain(): any + error(handler: errorHandler): void + concurrency: number + drain(): any + empty: () => void + saturated: () => void + } + + interface queueAsPromised extends queue { + push(task: T): Promise + unshift(task: T): Promise + drained(): Promise + } + + function promise(context: C, worker: fastq.asyncWorker, concurrency: number): fastq.queueAsPromised + function promise(worker: fastq.asyncWorker, concurrency: number): fastq.queueAsPromised +} + +export = fastq diff --git a/libs/events/node_modules/fastq/package.json b/libs/events/node_modules/fastq/package.json new file mode 100644 index 000000000..bf572e317 --- /dev/null +++ b/libs/events/node_modules/fastq/package.json @@ -0,0 +1,52 @@ +{ + "name": "fastq", + "version": "1.15.0", + "description": "Fast, in memory work queue", + "main": "queue.js", + "scripts": { + "lint": "standard --verbose | snazzy", + "unit": "nyc --lines 100 --branches 100 --functions 100 --check-coverage --reporter=text tape test/test.js test/promise.js", + "coverage": "nyc --reporter=html --reporter=cobertura --reporter=text tape test/test.js test/promise.js", + "test:report": "npm run lint && npm run unit:report", + "test": "npm run lint && npm run unit && npm run typescript", + "typescript": "tsc --project ./test/tsconfig.json", + "legacy": "tape test/test.js" + }, + "pre-commit": [ + "test" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/mcollina/fastq.git" + }, + "keywords": [ + "fast", + "queue", + "async", + "worker" + ], + "author": "Matteo Collina ", + "license": "ISC", + "bugs": { + "url": "https://github.com/mcollina/fastq/issues" + }, + "homepage": "https://github.com/mcollina/fastq#readme", + "devDependencies": { + "async": "^3.1.0", + "neo-async": "^2.6.1", + "nyc": "^15.0.0", + "pre-commit": "^1.2.2", + "snazzy": "^9.0.0", + "standard": "^16.0.0", + "tape": "^5.0.0", + "typescript": "^4.0.2" + }, + "dependencies": { + "reusify": "^1.0.4" + }, + "standard": { + "ignore": [ + "example.mjs" + ] + } +} diff --git a/libs/events/node_modules/fastq/queue.js b/libs/events/node_modules/fastq/queue.js new file mode 100644 index 000000000..03fe1127e --- /dev/null +++ b/libs/events/node_modules/fastq/queue.js @@ -0,0 +1,289 @@ +'use strict' + +/* eslint-disable no-var */ + +var reusify = require('reusify') + +function fastqueue (context, worker, concurrency) { + if (typeof context === 'function') { + concurrency = worker + worker = context + context = null + } + + if (concurrency < 1) { + throw new Error('fastqueue concurrency must be greater than 1') + } + + var cache = reusify(Task) + var queueHead = null + var queueTail = null + var _running = 0 + var errorHandler = null + + var self = { + push: push, + drain: noop, + saturated: noop, + pause: pause, + paused: false, + concurrency: concurrency, + running: running, + resume: resume, + idle: idle, + length: length, + getQueue: getQueue, + unshift: unshift, + empty: noop, + kill: kill, + killAndDrain: killAndDrain, + error: error + } + + return self + + function running () { + return _running + } + + function pause () { + self.paused = true + } + + function length () { + var current = queueHead + var counter = 0 + + while (current) { + current = current.next + counter++ + } + + return counter + } + + function getQueue () { + var current = queueHead + var tasks = [] + + while (current) { + tasks.push(current.value) + current = current.next + } + + return tasks + } + + function resume () { + if (!self.paused) return + self.paused = false + for (var i = 0; i < self.concurrency; i++) { + _running++ + release() + } + } + + function idle () { + return _running === 0 && self.length() === 0 + } + + function push (value, done) { + var current = cache.get() + + current.context = context + current.release = release + current.value = value + current.callback = done || noop + current.errorHandler = errorHandler + + if (_running === self.concurrency || self.paused) { + if (queueTail) { + queueTail.next = current + queueTail = current + } else { + queueHead = current + queueTail = current + self.saturated() + } + } else { + _running++ + worker.call(context, current.value, current.worked) + } + } + + function unshift (value, done) { + var current = cache.get() + + current.context = context + current.release = release + current.value = value + current.callback = done || noop + + if (_running === self.concurrency || self.paused) { + if (queueHead) { + current.next = queueHead + queueHead = current + } else { + queueHead = current + queueTail = current + self.saturated() + } + } else { + _running++ + worker.call(context, current.value, current.worked) + } + } + + function release (holder) { + if (holder) { + cache.release(holder) + } + var next = queueHead + if (next) { + if (!self.paused) { + if (queueTail === queueHead) { + queueTail = null + } + queueHead = next.next + next.next = null + worker.call(context, next.value, next.worked) + if (queueTail === null) { + self.empty() + } + } else { + _running-- + } + } else if (--_running === 0) { + self.drain() + } + } + + function kill () { + queueHead = null + queueTail = null + self.drain = noop + } + + function killAndDrain () { + queueHead = null + queueTail = null + self.drain() + self.drain = noop + } + + function error (handler) { + errorHandler = handler + } +} + +function noop () {} + +function Task () { + this.value = null + this.callback = noop + this.next = null + this.release = noop + this.context = null + this.errorHandler = null + + var self = this + + this.worked = function worked (err, result) { + var callback = self.callback + var errorHandler = self.errorHandler + var val = self.value + self.value = null + self.callback = noop + if (self.errorHandler) { + errorHandler(err, val) + } + callback.call(self.context, err, result) + self.release(self) + } +} + +function queueAsPromised (context, worker, concurrency) { + if (typeof context === 'function') { + concurrency = worker + worker = context + context = null + } + + function asyncWrapper (arg, cb) { + worker.call(this, arg) + .then(function (res) { + cb(null, res) + }, cb) + } + + var queue = fastqueue(context, asyncWrapper, concurrency) + + var pushCb = queue.push + var unshiftCb = queue.unshift + + queue.push = push + queue.unshift = unshift + queue.drained = drained + + return queue + + function push (value) { + var p = new Promise(function (resolve, reject) { + pushCb(value, function (err, result) { + if (err) { + reject(err) + return + } + resolve(result) + }) + }) + + // Let's fork the promise chain to + // make the error bubble up to the user but + // not lead to a unhandledRejection + p.catch(noop) + + return p + } + + function unshift (value) { + var p = new Promise(function (resolve, reject) { + unshiftCb(value, function (err, result) { + if (err) { + reject(err) + return + } + resolve(result) + }) + }) + + // Let's fork the promise chain to + // make the error bubble up to the user but + // not lead to a unhandledRejection + p.catch(noop) + + return p + } + + function drained () { + if (queue.idle()) { + return new Promise(function (resolve) { + resolve() + }) + } + + var previousDrain = queue.drain + + var p = new Promise(function (resolve) { + queue.drain = function () { + previousDrain() + resolve() + } + }) + + return p + } +} + +module.exports = fastqueue +module.exports.promise = queueAsPromised diff --git a/libs/events/node_modules/fastq/test/example.ts b/libs/events/node_modules/fastq/test/example.ts new file mode 100644 index 000000000..c454e9d0b --- /dev/null +++ b/libs/events/node_modules/fastq/test/example.ts @@ -0,0 +1,81 @@ +import * as fastq from '../' +import { promise as queueAsPromised } from '../' + +// Basic example + +const queue = fastq(worker, 1) + +queue.push('world', (err, result) => { + if (err) throw err + console.log('the result is', result) +}) + +queue.push('push without cb') + +queue.concurrency + +queue.drain() + +queue.empty = () => undefined + +console.log('the queue tasks are', queue.getQueue()) + +queue.idle() + +queue.kill() + +queue.killAndDrain() + +queue.length + +queue.pause() + +queue.resume() + +queue.saturated = () => undefined + +queue.unshift('world', (err, result) => { + if (err) throw err + console.log('the result is', result) +}) + +queue.unshift('unshift without cb') + +function worker(task: any, cb: fastq.done) { + cb(null, 'hello ' + task) +} + +// Generics example + +interface GenericsContext { + base: number; +} + +const genericsQueue = fastq({ base: 6 }, genericsWorker, 1) + +genericsQueue.push(7, (err, done) => { + if (err) throw err + console.log('the result is', done) +}) + +genericsQueue.unshift(7, (err, done) => { + if (err) throw err + console.log('the result is', done) +}) + +function genericsWorker(this: GenericsContext, task: number, cb: fastq.done) { + cb(null, 'the meaning of life is ' + (this.base * task)) +} + +const queue2 = queueAsPromised(asyncWorker, 1) + +async function asyncWorker(task: any) { + return 'hello ' + task +} + +async function run () { + await queue.push(42) + await queue.unshift(42) +} + +run() diff --git a/libs/events/node_modules/fastq/test/promise.js b/libs/events/node_modules/fastq/test/promise.js new file mode 100644 index 000000000..fe014ffef --- /dev/null +++ b/libs/events/node_modules/fastq/test/promise.js @@ -0,0 +1,248 @@ +'use strict' + +const test = require('tape') +const buildQueue = require('../').promise +const { promisify } = require('util') +const sleep = promisify(setTimeout) +const immediate = promisify(setImmediate) + +test('concurrency', function (t) { + t.plan(2) + t.throws(buildQueue.bind(null, worker, 0)) + t.doesNotThrow(buildQueue.bind(null, worker, 1)) + + async function worker (arg) { + return true + } +}) + +test('worker execution', async function (t) { + const queue = buildQueue(worker, 1) + + const result = await queue.push(42) + + t.equal(result, true, 'result matches') + + async function worker (arg) { + t.equal(arg, 42) + return true + } +}) + +test('limit', async function (t) { + const queue = buildQueue(worker, 1) + + const [res1, res2] = await Promise.all([queue.push(10), queue.push(0)]) + t.equal(res1, 10, 'the result matches') + t.equal(res2, 0, 'the result matches') + + async function worker (arg) { + await sleep(arg) + return arg + } +}) + +test('multiple executions', async function (t) { + const queue = buildQueue(worker, 1) + const toExec = [1, 2, 3, 4, 5] + const expected = ['a', 'b', 'c', 'd', 'e'] + let count = 0 + + await Promise.all(toExec.map(async function (task, i) { + const result = await queue.push(task) + t.equal(result, expected[i], 'the result matches') + })) + + async function worker (arg) { + t.equal(arg, toExec[count], 'arg matches') + return expected[count++] + } +}) + +test('drained', async function (t) { + const queue = buildQueue(worker, 2) + + const toExec = new Array(10).fill(10) + let count = 0 + + async function worker (arg) { + await sleep(arg) + count++ + } + + toExec.forEach(function (i) { + queue.push(i) + }) + + await queue.drained() + + t.equal(count, toExec.length) + + toExec.forEach(function (i) { + queue.push(i) + }) + + await queue.drained() + + t.equal(count, toExec.length * 2) +}) + +test('drained with exception should not throw', async function (t) { + const queue = buildQueue(worker, 2) + + const toExec = new Array(10).fill(10) + + async function worker () { + throw new Error('foo') + } + + toExec.forEach(function (i) { + queue.push(i) + }) + + await queue.drained() +}) + +test('drained with drain function', async function (t) { + let drainCalled = false + const queue = buildQueue(worker, 2) + + queue.drain = function () { + drainCalled = true + } + + const toExec = new Array(10).fill(10) + let count = 0 + + async function worker (arg) { + await sleep(arg) + count++ + } + + toExec.forEach(function () { + queue.push() + }) + + await queue.drained() + + t.equal(count, toExec.length) + t.equal(drainCalled, true) +}) + +test('drained while idle should resolve', async function (t) { + const queue = buildQueue(worker, 2) + + async function worker (arg) { + await sleep(arg) + } + + await queue.drained() +}) + +test('drained while idle should not call the drain function', async function (t) { + let drainCalled = false + const queue = buildQueue(worker, 2) + + queue.drain = function () { + drainCalled = true + } + + async function worker (arg) { + await sleep(arg) + } + + await queue.drained() + + t.equal(drainCalled, false) +}) + +test('set this', async function (t) { + t.plan(1) + const that = {} + const queue = buildQueue(that, worker, 1) + + await queue.push(42) + + async function worker (arg) { + t.equal(this, that, 'this matches') + } +}) + +test('unshift', async function (t) { + const queue = buildQueue(worker, 1) + const expected = [1, 2, 3, 4] + + await Promise.all([ + queue.push(1), + queue.push(4), + queue.unshift(3), + queue.unshift(2) + ]) + + t.is(expected.length, 0) + + async function worker (arg) { + t.equal(expected.shift(), arg, 'tasks come in order') + } +}) + +test('push with worker throwing error', async function (t) { + t.plan(5) + const q = buildQueue(async function (task, cb) { + throw new Error('test error') + }, 1) + q.error(function (err, task) { + t.ok(err instanceof Error, 'global error handler should catch the error') + t.match(err.message, /test error/, 'error message should be "test error"') + t.equal(task, 42, 'The task executed should be passed') + }) + try { + await q.push(42) + } catch (err) { + t.ok(err instanceof Error, 'push callback should catch the error') + t.match(err.message, /test error/, 'error message should be "test error"') + } +}) + +test('unshift with worker throwing error', async function (t) { + t.plan(2) + const q = buildQueue(async function (task, cb) { + throw new Error('test error') + }, 1) + try { + await q.unshift(42) + } catch (err) { + t.ok(err instanceof Error, 'push callback should catch the error') + t.match(err.message, /test error/, 'error message should be "test error"') + } +}) + +test('no unhandledRejection (push)', async function (t) { + function handleRejection () { + t.fail('unhandledRejection') + } + process.once('unhandledRejection', handleRejection) + const q = buildQueue(async function (task, cb) { + throw new Error('test error') + }, 1) + + q.push(42) + + await immediate() + process.removeListener('unhandledRejection', handleRejection) +}) + +test('no unhandledRejection (unshift)', async function (t) { + function handleRejection () { + t.fail('unhandledRejection') + } + process.once('unhandledRejection', handleRejection) + const q = buildQueue(async function (task, cb) { + throw new Error('test error') + }, 1) + + q.unshift(42) + + await immediate() + process.removeListener('unhandledRejection', handleRejection) +}) diff --git a/libs/events/node_modules/fastq/test/test.js b/libs/events/node_modules/fastq/test/test.js new file mode 100644 index 000000000..1cc78a564 --- /dev/null +++ b/libs/events/node_modules/fastq/test/test.js @@ -0,0 +1,566 @@ +'use strict' + +/* eslint-disable no-var */ + +var test = require('tape') +var buildQueue = require('../') + +test('concurrency', function (t) { + t.plan(2) + t.throws(buildQueue.bind(null, worker, 0)) + t.doesNotThrow(buildQueue.bind(null, worker, 1)) + + function worker (arg, cb) { + cb(null, true) + } +}) + +test('worker execution', function (t) { + t.plan(3) + + var queue = buildQueue(worker, 1) + + queue.push(42, function (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + }) + + function worker (arg, cb) { + t.equal(arg, 42) + cb(null, true) + } +}) + +test('limit', function (t) { + t.plan(4) + + var expected = [10, 0] + var queue = buildQueue(worker, 1) + + queue.push(10, result) + queue.push(0, result) + + function result (err, arg) { + t.error(err, 'no error') + t.equal(arg, expected.shift(), 'the result matches') + } + + function worker (arg, cb) { + setTimeout(cb, arg, null, arg) + } +}) + +test('multiple executions', function (t) { + t.plan(15) + + var queue = buildQueue(worker, 1) + var toExec = [1, 2, 3, 4, 5] + var count = 0 + + toExec.forEach(function (task) { + queue.push(task, done) + }) + + function done (err, result) { + t.error(err, 'no error') + t.equal(result, toExec[count - 1], 'the result matches') + } + + function worker (arg, cb) { + t.equal(arg, toExec[count], 'arg matches') + count++ + setImmediate(cb, null, arg) + } +}) + +test('multiple executions, one after another', function (t) { + t.plan(15) + + var queue = buildQueue(worker, 1) + var toExec = [1, 2, 3, 4, 5] + var count = 0 + + queue.push(toExec[0], done) + + function done (err, result) { + t.error(err, 'no error') + t.equal(result, toExec[count - 1], 'the result matches') + if (count < toExec.length) { + queue.push(toExec[count], done) + } + } + + function worker (arg, cb) { + t.equal(arg, toExec[count], 'arg matches') + count++ + setImmediate(cb, null, arg) + } +}) + +test('set this', function (t) { + t.plan(3) + + var that = {} + var queue = buildQueue(that, worker, 1) + + queue.push(42, function (err, result) { + t.error(err, 'no error') + t.equal(this, that, 'this matches') + }) + + function worker (arg, cb) { + t.equal(this, that, 'this matches') + cb(null, true) + } +}) + +test('drain', function (t) { + t.plan(4) + + var queue = buildQueue(worker, 1) + var worked = false + + queue.push(42, function (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + }) + + queue.drain = function () { + t.equal(true, worked, 'drained') + } + + function worker (arg, cb) { + t.equal(arg, 42) + worked = true + setImmediate(cb, null, true) + } +}) + +test('pause && resume', function (t) { + t.plan(7) + + var queue = buildQueue(worker, 1) + var worked = false + + t.notOk(queue.paused, 'it should not be paused') + + queue.pause() + + queue.push(42, function (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + }) + + t.notOk(worked, 'it should be paused') + t.ok(queue.paused, 'it should be paused') + + queue.resume() + queue.resume() // second resume is a no-op + + t.notOk(queue.paused, 'it should not be paused') + + function worker (arg, cb) { + t.equal(arg, 42) + worked = true + cb(null, true) + } +}) + +test('pause in flight && resume', function (t) { + t.plan(9) + + var queue = buildQueue(worker, 1) + var expected = [42, 24] + + t.notOk(queue.paused, 'it should not be paused') + + queue.push(42, function (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + t.ok(queue.paused, 'it should be paused') + process.nextTick(function () { queue.resume() }) + }) + + queue.push(24, function (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + t.notOk(queue.paused, 'it should not be paused') + }) + + queue.pause() + + function worker (arg, cb) { + t.equal(arg, expected.shift()) + process.nextTick(function () { cb(null, true) }) + } +}) + +test('altering concurrency', function (t) { + t.plan(7) + + var queue = buildQueue(worker, 1) + var count = 0 + + queue.pause() + + queue.push(24, workDone) + queue.push(24, workDone) + + queue.concurrency = 2 + + queue.resume() + + t.equal(queue.running(), 2, '2 jobs running') + + function workDone (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + } + + function worker (arg, cb) { + t.equal(0, count, 'works in parallel') + setImmediate(function () { + count++ + cb(null, true) + }) + } +}) + +test('idle()', function (t) { + t.plan(12) + + var queue = buildQueue(worker, 1) + + t.ok(queue.idle(), 'queue is idle') + + queue.push(42, function (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + t.notOk(queue.idle(), 'queue is not idle') + }) + + queue.push(42, function (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + // it will go idle after executing this function + setImmediate(function () { + t.ok(queue.idle(), 'queue is now idle') + }) + }) + + t.notOk(queue.idle(), 'queue is not idle') + + function worker (arg, cb) { + t.notOk(queue.idle(), 'queue is not idle') + t.equal(arg, 42) + setImmediate(cb, null, true) + } +}) + +test('saturated', function (t) { + t.plan(9) + + var queue = buildQueue(worker, 1) + var preworked = 0 + var worked = 0 + + queue.saturated = function () { + t.pass('saturated') + t.equal(preworked, 1, 'started 1 task') + t.equal(worked, 0, 'worked zero task') + } + + queue.push(42, done) + queue.push(42, done) + + function done (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + } + + function worker (arg, cb) { + t.equal(arg, 42) + preworked++ + setImmediate(function () { + worked++ + cb(null, true) + }) + } +}) + +test('length', function (t) { + t.plan(7) + + var queue = buildQueue(worker, 1) + + t.equal(queue.length(), 0, 'nothing waiting') + queue.push(42, done) + t.equal(queue.length(), 0, 'nothing waiting') + queue.push(42, done) + t.equal(queue.length(), 1, 'one task waiting') + queue.push(42, done) + t.equal(queue.length(), 2, 'two tasks waiting') + + function done (err, result) { + t.error(err, 'no error') + } + + function worker (arg, cb) { + setImmediate(function () { + cb(null, true) + }) + } +}) + +test('getQueue', function (t) { + t.plan(10) + + var queue = buildQueue(worker, 1) + + t.equal(queue.getQueue().length, 0, 'nothing waiting') + queue.push(42, done) + t.equal(queue.getQueue().length, 0, 'nothing waiting') + queue.push(42, done) + t.equal(queue.getQueue().length, 1, 'one task waiting') + t.equal(queue.getQueue()[0], 42, 'should be equal') + queue.push(43, done) + t.equal(queue.getQueue().length, 2, 'two tasks waiting') + t.equal(queue.getQueue()[0], 42, 'should be equal') + t.equal(queue.getQueue()[1], 43, 'should be equal') + + function done (err, result) { + t.error(err, 'no error') + } + + function worker (arg, cb) { + setImmediate(function () { + cb(null, true) + }) + } +}) + +test('unshift', function (t) { + t.plan(8) + + var queue = buildQueue(worker, 1) + var expected = [1, 2, 3, 4] + + queue.push(1, done) + queue.push(4, done) + queue.unshift(3, done) + queue.unshift(2, done) + + function done (err, result) { + t.error(err, 'no error') + } + + function worker (arg, cb) { + t.equal(expected.shift(), arg, 'tasks come in order') + setImmediate(function () { + cb(null, true) + }) + } +}) + +test('unshift && empty', function (t) { + t.plan(2) + + var queue = buildQueue(worker, 1) + var completed = false + + queue.pause() + + queue.empty = function () { + t.notOk(completed, 'the task has not completed yet') + } + + queue.unshift(1, done) + + queue.resume() + + function done (err, result) { + completed = true + t.error(err, 'no error') + } + + function worker (arg, cb) { + setImmediate(function () { + cb(null, true) + }) + } +}) + +test('push && empty', function (t) { + t.plan(2) + + var queue = buildQueue(worker, 1) + var completed = false + + queue.pause() + + queue.empty = function () { + t.notOk(completed, 'the task has not completed yet') + } + + queue.push(1, done) + + queue.resume() + + function done (err, result) { + completed = true + t.error(err, 'no error') + } + + function worker (arg, cb) { + setImmediate(function () { + cb(null, true) + }) + } +}) + +test('kill', function (t) { + t.plan(5) + + var queue = buildQueue(worker, 1) + var expected = [1] + + var predrain = queue.drain + + queue.drain = function drain () { + t.fail('drain should never be called') + } + + queue.push(1, done) + queue.push(4, done) + queue.unshift(3, done) + queue.unshift(2, done) + queue.kill() + + function done (err, result) { + t.error(err, 'no error') + setImmediate(function () { + t.equal(queue.length(), 0, 'no queued tasks') + t.equal(queue.running(), 0, 'no running tasks') + t.equal(queue.drain, predrain, 'drain is back to default') + }) + } + + function worker (arg, cb) { + t.equal(expected.shift(), arg, 'tasks come in order') + setImmediate(function () { + cb(null, true) + }) + } +}) + +test('killAndDrain', function (t) { + t.plan(6) + + var queue = buildQueue(worker, 1) + var expected = [1] + + var predrain = queue.drain + + queue.drain = function drain () { + t.pass('drain has been called') + } + + queue.push(1, done) + queue.push(4, done) + queue.unshift(3, done) + queue.unshift(2, done) + queue.killAndDrain() + + function done (err, result) { + t.error(err, 'no error') + setImmediate(function () { + t.equal(queue.length(), 0, 'no queued tasks') + t.equal(queue.running(), 0, 'no running tasks') + t.equal(queue.drain, predrain, 'drain is back to default') + }) + } + + function worker (arg, cb) { + t.equal(expected.shift(), arg, 'tasks come in order') + setImmediate(function () { + cb(null, true) + }) + } +}) + +test('pause && idle', function (t) { + t.plan(11) + + var queue = buildQueue(worker, 1) + var worked = false + + t.notOk(queue.paused, 'it should not be paused') + t.ok(queue.idle(), 'should be idle') + + queue.pause() + + queue.push(42, function (err, result) { + t.error(err, 'no error') + t.equal(result, true, 'result matches') + }) + + t.notOk(worked, 'it should be paused') + t.ok(queue.paused, 'it should be paused') + t.notOk(queue.idle(), 'should not be idle') + + queue.resume() + + t.notOk(queue.paused, 'it should not be paused') + t.notOk(queue.idle(), 'it should not be idle') + + function worker (arg, cb) { + t.equal(arg, 42) + worked = true + process.nextTick(cb.bind(null, null, true)) + process.nextTick(function () { + t.ok(queue.idle(), 'is should be idle') + }) + } +}) + +test('push without cb', function (t) { + t.plan(1) + + var queue = buildQueue(worker, 1) + + queue.push(42) + + function worker (arg, cb) { + t.equal(arg, 42) + cb() + } +}) + +test('unshift without cb', function (t) { + t.plan(1) + + var queue = buildQueue(worker, 1) + + queue.unshift(42) + + function worker (arg, cb) { + t.equal(arg, 42) + cb() + } +}) + +test('push with worker throwing error', function (t) { + t.plan(5) + var q = buildQueue(function (task, cb) { + cb(new Error('test error'), null) + }, 1) + q.error(function (err, task) { + t.ok(err instanceof Error, 'global error handler should catch the error') + t.match(err.message, /test error/, 'error message should be "test error"') + t.equal(task, 42, 'The task executed should be passed') + }) + q.push(42, function (err) { + t.ok(err instanceof Error, 'push callback should catch the error') + t.match(err.message, /test error/, 'error message should be "test error"') + }) +}) diff --git a/libs/events/node_modules/fastq/test/tsconfig.json b/libs/events/node_modules/fastq/test/tsconfig.json new file mode 100644 index 000000000..66e16e930 --- /dev/null +++ b/libs/events/node_modules/fastq/test/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "noEmit": true, + "strict": true + }, + "files": [ + "./example.ts" + ] +} diff --git a/libs/events/node_modules/fill-range/LICENSE b/libs/events/node_modules/fill-range/LICENSE new file mode 100644 index 000000000..9af4a67d2 --- /dev/null +++ b/libs/events/node_modules/fill-range/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/fill-range/README.md b/libs/events/node_modules/fill-range/README.md new file mode 100644 index 000000000..8d756fe90 --- /dev/null +++ b/libs/events/node_modules/fill-range/README.md @@ -0,0 +1,237 @@ +# fill-range [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/fill-range.svg?style=flat)](https://www.npmjs.com/package/fill-range) [![NPM monthly downloads](https://img.shields.io/npm/dm/fill-range.svg?style=flat)](https://npmjs.org/package/fill-range) [![NPM total downloads](https://img.shields.io/npm/dt/fill-range.svg?style=flat)](https://npmjs.org/package/fill-range) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/fill-range.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/fill-range) + +> Fill in a range of numbers or letters, optionally passing an increment or `step` to use, or create a regex-compatible range with `options.toRegex` + +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save fill-range +``` + +## Usage + +Expands numbers and letters, optionally using a `step` as the last argument. _(Numbers may be defined as JavaScript numbers or strings)_. + +```js +const fill = require('fill-range'); +// fill(from, to[, step, options]); + +console.log(fill('1', '10')); //=> ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] +console.log(fill('1', '10', { toRegex: true })); //=> [1-9]|10 +``` + +**Params** + +* `from`: **{String|Number}** the number or letter to start with +* `to`: **{String|Number}** the number or letter to end with +* `step`: **{String|Number|Object|Function}** Optionally pass a [step](#optionsstep) to use. +* `options`: **{Object|Function}**: See all available [options](#options) + +## Examples + +By default, an array of values is returned. + +**Alphabetical ranges** + +```js +console.log(fill('a', 'e')); //=> ['a', 'b', 'c', 'd', 'e'] +console.log(fill('A', 'E')); //=> [ 'A', 'B', 'C', 'D', 'E' ] +``` + +**Numerical ranges** + +Numbers can be defined as actual numbers or strings. + +```js +console.log(fill(1, 5)); //=> [ 1, 2, 3, 4, 5 ] +console.log(fill('1', '5')); //=> [ 1, 2, 3, 4, 5 ] +``` + +**Negative ranges** + +Numbers can be defined as actual numbers or strings. + +```js +console.log(fill('-5', '-1')); //=> [ '-5', '-4', '-3', '-2', '-1' ] +console.log(fill('-5', '5')); //=> [ '-5', '-4', '-3', '-2', '-1', '0', '1', '2', '3', '4', '5' ] +``` + +**Steps (increments)** + +```js +// numerical ranges with increments +console.log(fill('0', '25', 4)); //=> [ '0', '4', '8', '12', '16', '20', '24' ] +console.log(fill('0', '25', 5)); //=> [ '0', '5', '10', '15', '20', '25' ] +console.log(fill('0', '25', 6)); //=> [ '0', '6', '12', '18', '24' ] + +// alphabetical ranges with increments +console.log(fill('a', 'z', 4)); //=> [ 'a', 'e', 'i', 'm', 'q', 'u', 'y' ] +console.log(fill('a', 'z', 5)); //=> [ 'a', 'f', 'k', 'p', 'u', 'z' ] +console.log(fill('a', 'z', 6)); //=> [ 'a', 'g', 'm', 's', 'y' ] +``` + +## Options + +### options.step + +**Type**: `number` (formatted as a string or number) + +**Default**: `undefined` + +**Description**: The increment to use for the range. Can be used with letters or numbers. + +**Example(s)** + +```js +// numbers +console.log(fill('1', '10', 2)); //=> [ '1', '3', '5', '7', '9' ] +console.log(fill('1', '10', 3)); //=> [ '1', '4', '7', '10' ] +console.log(fill('1', '10', 4)); //=> [ '1', '5', '9' ] + +// letters +console.log(fill('a', 'z', 5)); //=> [ 'a', 'f', 'k', 'p', 'u', 'z' ] +console.log(fill('a', 'z', 7)); //=> [ 'a', 'h', 'o', 'v' ] +console.log(fill('a', 'z', 9)); //=> [ 'a', 'j', 's' ] +``` + +### options.strictRanges + +**Type**: `boolean` + +**Default**: `false` + +**Description**: By default, `null` is returned when an invalid range is passed. Enable this option to throw a `RangeError` on invalid ranges. + +**Example(s)** + +The following are all invalid: + +```js +fill('1.1', '2'); // decimals not supported in ranges +fill('a', '2'); // incompatible range values +fill(1, 10, 'foo'); // invalid "step" argument +``` + +### options.stringify + +**Type**: `boolean` + +**Default**: `undefined` + +**Description**: Cast all returned values to strings. By default, integers are returned as numbers. + +**Example(s)** + +```js +console.log(fill(1, 5)); //=> [ 1, 2, 3, 4, 5 ] +console.log(fill(1, 5, { stringify: true })); //=> [ '1', '2', '3', '4', '5' ] +``` + +### options.toRegex + +**Type**: `boolean` + +**Default**: `undefined` + +**Description**: Create a regex-compatible source string, instead of expanding values to an array. + +**Example(s)** + +```js +// alphabetical range +console.log(fill('a', 'e', { toRegex: true })); //=> '[a-e]' +// alphabetical with step +console.log(fill('a', 'z', 3, { toRegex: true })); //=> 'a|d|g|j|m|p|s|v|y' +// numerical range +console.log(fill('1', '100', { toRegex: true })); //=> '[1-9]|[1-9][0-9]|100' +// numerical range with zero padding +console.log(fill('000001', '100000', { toRegex: true })); +//=> '0{5}[1-9]|0{4}[1-9][0-9]|0{3}[1-9][0-9]{2}|0{2}[1-9][0-9]{3}|0[1-9][0-9]{4}|100000' +``` + +### options.transform + +**Type**: `function` + +**Default**: `undefined` + +**Description**: Customize each value in the returned array (or [string](#optionstoRegex)). _(you can also pass this function as the last argument to `fill()`)_. + +**Example(s)** + +```js +// add zero padding +console.log(fill(1, 5, value => String(value).padStart(4, '0'))); +//=> ['0001', '0002', '0003', '0004', '0005'] +``` + +## About + +
+Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +
+ +
+Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` + +
+ +
+Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +$ npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
+ +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 116 | [jonschlinkert](https://github.com/jonschlinkert) | +| 4 | [paulmillr](https://github.com/paulmillr) | +| 2 | [realityking](https://github.com/realityking) | +| 2 | [bluelovers](https://github.com/bluelovers) | +| 1 | [edorivai](https://github.com/edorivai) | +| 1 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) | + +### Author + +**Jon Schlinkert** + +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +Please consider supporting me on Patreon, or [start your own Patreon page](https://patreon.com/invite/bxpbvm)! + + + + + +### License + +Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 08, 2019._ \ No newline at end of file diff --git a/libs/events/node_modules/fill-range/index.js b/libs/events/node_modules/fill-range/index.js new file mode 100644 index 000000000..97ce35a5b --- /dev/null +++ b/libs/events/node_modules/fill-range/index.js @@ -0,0 +1,249 @@ +/*! + * fill-range + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +const util = require('util'); +const toRegexRange = require('to-regex-range'); + +const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); + +const transform = toNumber => { + return value => toNumber === true ? Number(value) : String(value); +}; + +const isValidValue = value => { + return typeof value === 'number' || (typeof value === 'string' && value !== ''); +}; + +const isNumber = num => Number.isInteger(+num); + +const zeros = input => { + let value = `${input}`; + let index = -1; + if (value[0] === '-') value = value.slice(1); + if (value === '0') return false; + while (value[++index] === '0'); + return index > 0; +}; + +const stringify = (start, end, options) => { + if (typeof start === 'string' || typeof end === 'string') { + return true; + } + return options.stringify === true; +}; + +const pad = (input, maxLength, toNumber) => { + if (maxLength > 0) { + let dash = input[0] === '-' ? '-' : ''; + if (dash) input = input.slice(1); + input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); + } + if (toNumber === false) { + return String(input); + } + return input; +}; + +const toMaxLen = (input, maxLength) => { + let negative = input[0] === '-' ? '-' : ''; + if (negative) { + input = input.slice(1); + maxLength--; + } + while (input.length < maxLength) input = '0' + input; + return negative ? ('-' + input) : input; +}; + +const toSequence = (parts, options) => { + parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); + parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); + + let prefix = options.capture ? '' : '?:'; + let positives = ''; + let negatives = ''; + let result; + + if (parts.positives.length) { + positives = parts.positives.join('|'); + } + + if (parts.negatives.length) { + negatives = `-(${prefix}${parts.negatives.join('|')})`; + } + + if (positives && negatives) { + result = `${positives}|${negatives}`; + } else { + result = positives || negatives; + } + + if (options.wrap) { + return `(${prefix}${result})`; + } + + return result; +}; + +const toRange = (a, b, isNumbers, options) => { + if (isNumbers) { + return toRegexRange(a, b, { wrap: false, ...options }); + } + + let start = String.fromCharCode(a); + if (a === b) return start; + + let stop = String.fromCharCode(b); + return `[${start}-${stop}]`; +}; + +const toRegex = (start, end, options) => { + if (Array.isArray(start)) { + let wrap = options.wrap === true; + let prefix = options.capture ? '' : '?:'; + return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); + } + return toRegexRange(start, end, options); +}; + +const rangeError = (...args) => { + return new RangeError('Invalid range arguments: ' + util.inspect(...args)); +}; + +const invalidRange = (start, end, options) => { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; +}; + +const invalidStep = (step, options) => { + if (options.strictRanges === true) { + throw new TypeError(`Expected step "${step}" to be a number`); + } + return []; +}; + +const fillNumbers = (start, end, step = 1, options = {}) => { + let a = Number(start); + let b = Number(end); + + if (!Number.isInteger(a) || !Number.isInteger(b)) { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; + } + + // fix negative zero + if (a === 0) a = 0; + if (b === 0) b = 0; + + let descending = a > b; + let startString = String(start); + let endString = String(end); + let stepString = String(step); + step = Math.max(Math.abs(step), 1); + + let padded = zeros(startString) || zeros(endString) || zeros(stepString); + let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; + let toNumber = padded === false && stringify(start, end, options) === false; + let format = options.transform || transform(toNumber); + + if (options.toRegex && step === 1) { + return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); + } + + let parts = { negatives: [], positives: [] }; + let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); + let range = []; + let index = 0; + + while (descending ? a >= b : a <= b) { + if (options.toRegex === true && step > 1) { + push(a); + } else { + range.push(pad(format(a, index), maxLen, toNumber)); + } + a = descending ? a - step : a + step; + index++; + } + + if (options.toRegex === true) { + return step > 1 + ? toSequence(parts, options) + : toRegex(range, null, { wrap: false, ...options }); + } + + return range; +}; + +const fillLetters = (start, end, step = 1, options = {}) => { + if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { + return invalidRange(start, end, options); + } + + + let format = options.transform || (val => String.fromCharCode(val)); + let a = `${start}`.charCodeAt(0); + let b = `${end}`.charCodeAt(0); + + let descending = a > b; + let min = Math.min(a, b); + let max = Math.max(a, b); + + if (options.toRegex && step === 1) { + return toRange(min, max, false, options); + } + + let range = []; + let index = 0; + + while (descending ? a >= b : a <= b) { + range.push(format(a, index)); + a = descending ? a - step : a + step; + index++; + } + + if (options.toRegex === true) { + return toRegex(range, null, { wrap: false, options }); + } + + return range; +}; + +const fill = (start, end, step, options = {}) => { + if (end == null && isValidValue(start)) { + return [start]; + } + + if (!isValidValue(start) || !isValidValue(end)) { + return invalidRange(start, end, options); + } + + if (typeof step === 'function') { + return fill(start, end, 1, { transform: step }); + } + + if (isObject(step)) { + return fill(start, end, 0, step); + } + + let opts = { ...options }; + if (opts.capture === true) opts.wrap = true; + step = step || opts.step || 1; + + if (!isNumber(step)) { + if (step != null && !isObject(step)) return invalidStep(step, opts); + return fill(start, end, 1, step); + } + + if (isNumber(start) && isNumber(end)) { + return fillNumbers(start, end, step, opts); + } + + return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); +}; + +module.exports = fill; diff --git a/libs/events/node_modules/fill-range/package.json b/libs/events/node_modules/fill-range/package.json new file mode 100644 index 000000000..07d30767f --- /dev/null +++ b/libs/events/node_modules/fill-range/package.json @@ -0,0 +1,69 @@ +{ + "name": "fill-range", + "description": "Fill in a range of numbers or letters, optionally passing an increment or `step` to use, or create a regex-compatible range with `options.toRegex`", + "version": "7.0.1", + "homepage": "https://github.com/jonschlinkert/fill-range", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "contributors": [ + "Edo Rivai (edo.rivai.nl)", + "Jon Schlinkert (http://twitter.com/jonschlinkert)", + "Paul Miller (paulmillr.com)", + "Rouven Weßling (www.rouvenwessling.de)", + "(https://github.com/wtgtybhertgeghgtwtg)" + ], + "repository": "jonschlinkert/fill-range", + "bugs": { + "url": "https://github.com/jonschlinkert/fill-range/issues" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "main": "index.js", + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "mocha" + }, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "devDependencies": { + "gulp-format-md": "^2.0.0", + "mocha": "^6.1.1" + }, + "keywords": [ + "alpha", + "alphabetical", + "array", + "bash", + "brace", + "expand", + "expansion", + "fill", + "glob", + "match", + "matches", + "matching", + "number", + "numerical", + "range", + "ranges", + "regex", + "sh" + ], + "verb": { + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + } + } +} diff --git a/libs/events/node_modules/fs.realpath/LICENSE b/libs/events/node_modules/fs.realpath/LICENSE new file mode 100644 index 000000000..5bd884c25 --- /dev/null +++ b/libs/events/node_modules/fs.realpath/LICENSE @@ -0,0 +1,43 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +---- + +This library bundles a version of the `fs.realpath` and `fs.realpathSync` +methods from Node.js v0.10 under the terms of the Node.js MIT license. + +Node's license follows, also included at the header of `old.js` which contains +the licensed code: + + Copyright Joyent, Inc. and other Node contributors. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. diff --git a/libs/events/node_modules/fs.realpath/README.md b/libs/events/node_modules/fs.realpath/README.md new file mode 100644 index 000000000..a42ceac62 --- /dev/null +++ b/libs/events/node_modules/fs.realpath/README.md @@ -0,0 +1,33 @@ +# fs.realpath + +A backwards-compatible fs.realpath for Node v6 and above + +In Node v6, the JavaScript implementation of fs.realpath was replaced +with a faster (but less resilient) native implementation. That raises +new and platform-specific errors and cannot handle long or excessively +symlink-looping paths. + +This module handles those cases by detecting the new errors and +falling back to the JavaScript implementation. On versions of Node +prior to v6, it has no effect. + +## USAGE + +```js +var rp = require('fs.realpath') + +// async version +rp.realpath(someLongAndLoopingPath, function (er, real) { + // the ELOOP was handled, but it was a bit slower +}) + +// sync version +var real = rp.realpathSync(someLongAndLoopingPath) + +// monkeypatch at your own risk! +// This replaces the fs.realpath/fs.realpathSync builtins +rp.monkeypatch() + +// un-do the monkeypatching +rp.unmonkeypatch() +``` diff --git a/libs/events/node_modules/fs.realpath/index.js b/libs/events/node_modules/fs.realpath/index.js new file mode 100644 index 000000000..b09c7c7e6 --- /dev/null +++ b/libs/events/node_modules/fs.realpath/index.js @@ -0,0 +1,66 @@ +module.exports = realpath +realpath.realpath = realpath +realpath.sync = realpathSync +realpath.realpathSync = realpathSync +realpath.monkeypatch = monkeypatch +realpath.unmonkeypatch = unmonkeypatch + +var fs = require('fs') +var origRealpath = fs.realpath +var origRealpathSync = fs.realpathSync + +var version = process.version +var ok = /^v[0-5]\./.test(version) +var old = require('./old.js') + +function newError (er) { + return er && er.syscall === 'realpath' && ( + er.code === 'ELOOP' || + er.code === 'ENOMEM' || + er.code === 'ENAMETOOLONG' + ) +} + +function realpath (p, cache, cb) { + if (ok) { + return origRealpath(p, cache, cb) + } + + if (typeof cache === 'function') { + cb = cache + cache = null + } + origRealpath(p, cache, function (er, result) { + if (newError(er)) { + old.realpath(p, cache, cb) + } else { + cb(er, result) + } + }) +} + +function realpathSync (p, cache) { + if (ok) { + return origRealpathSync(p, cache) + } + + try { + return origRealpathSync(p, cache) + } catch (er) { + if (newError(er)) { + return old.realpathSync(p, cache) + } else { + throw er + } + } +} + +function monkeypatch () { + fs.realpath = realpath + fs.realpathSync = realpathSync +} + +function unmonkeypatch () { + fs.realpath = origRealpath + fs.realpathSync = origRealpathSync +} diff --git a/libs/events/node_modules/fs.realpath/old.js b/libs/events/node_modules/fs.realpath/old.js new file mode 100644 index 000000000..b40305e73 --- /dev/null +++ b/libs/events/node_modules/fs.realpath/old.js @@ -0,0 +1,303 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var pathModule = require('path'); +var isWindows = process.platform === 'win32'; +var fs = require('fs'); + +// JavaScript implementation of realpath, ported from node pre-v6 + +var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); + +function rethrow() { + // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and + // is fairly slow to generate. + var callback; + if (DEBUG) { + var backtrace = new Error; + callback = debugCallback; + } else + callback = missingCallback; + + return callback; + + function debugCallback(err) { + if (err) { + backtrace.message = err.message; + err = backtrace; + missingCallback(err); + } + } + + function missingCallback(err) { + if (err) { + if (process.throwDeprecation) + throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs + else if (!process.noDeprecation) { + var msg = 'fs: missing callback ' + (err.stack || err.message); + if (process.traceDeprecation) + console.trace(msg); + else + console.error(msg); + } + } + } +} + +function maybeCallback(cb) { + return typeof cb === 'function' ? cb : rethrow(); +} + +var normalize = pathModule.normalize; + +// Regexp that finds the next partion of a (partial) path +// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] +if (isWindows) { + var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; +} else { + var nextPartRe = /(.*?)(?:[\/]+|$)/g; +} + +// Regex to find the device root, including trailing slash. E.g. 'c:\\'. +if (isWindows) { + var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; +} else { + var splitRootRe = /^[\/]*/; +} + +exports.realpathSync = function realpathSync(p, cache) { + // make p is absolute + p = pathModule.resolve(p); + + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return cache[p]; + } + + var original = p, + seenLinks = {}, + knownHard = {}; + + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; + + start(); + + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstatSync(base); + knownHard[base] = true; + } + } + + // walk down the path, swapping out linked pathparts for their real + // values + // NB: p.length changes. + while (pos < p.length) { + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + continue; + } + + var resolvedLink; + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // some known symbolic link. no need to stat again. + resolvedLink = cache[base]; + } else { + var stat = fs.lstatSync(base); + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + continue; + } + + // read the link if it wasn't read before + // dev/ino always return 0 on windows, so skip the check. + var linkTarget = null; + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + linkTarget = seenLinks[id]; + } + } + if (linkTarget === null) { + fs.statSync(base); + linkTarget = fs.readlinkSync(base); + } + resolvedLink = pathModule.resolve(previous, linkTarget); + // track this, if given a cache. + if (cache) cache[base] = resolvedLink; + if (!isWindows) seenLinks[id] = linkTarget; + } + + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } + + if (cache) cache[original] = p; + + return p; +}; + + +exports.realpath = function realpath(p, cache, cb) { + if (typeof cb !== 'function') { + cb = maybeCallback(cache); + cache = null; + } + + // make p is absolute + p = pathModule.resolve(p); + + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return process.nextTick(cb.bind(null, null, cache[p])); + } + + var original = p, + seenLinks = {}, + knownHard = {}; + + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; + + start(); + + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstat(base, function(err) { + if (err) return cb(err); + knownHard[base] = true; + LOOP(); + }); + } else { + process.nextTick(LOOP); + } + } + + // walk down the path, swapping out linked pathparts for their real + // values + function LOOP() { + // stop if scanned past end of path + if (pos >= p.length) { + if (cache) cache[original] = p; + return cb(null, p); + } + + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + return process.nextTick(LOOP); + } + + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // known symbolic link. no need to stat again. + return gotResolvedLink(cache[base]); + } + + return fs.lstat(base, gotStat); + } + + function gotStat(err, stat) { + if (err) return cb(err); + + // if not a symlink, skip to the next path part + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + return process.nextTick(LOOP); + } + + // stat & read the link if not read before + // call gotTarget as soon as the link target is known + // dev/ino always return 0 on windows, so skip the check. + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + return gotTarget(null, seenLinks[id], base); + } + } + fs.stat(base, function(err) { + if (err) return cb(err); + + fs.readlink(base, function(err, target) { + if (!isWindows) seenLinks[id] = target; + gotTarget(err, target); + }); + }); + } + + function gotTarget(err, target, base) { + if (err) return cb(err); + + var resolvedLink = pathModule.resolve(previous, target); + if (cache) cache[base] = resolvedLink; + gotResolvedLink(resolvedLink); + } + + function gotResolvedLink(resolvedLink) { + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } +}; diff --git a/libs/events/node_modules/fs.realpath/package.json b/libs/events/node_modules/fs.realpath/package.json new file mode 100644 index 000000000..3edc57d21 --- /dev/null +++ b/libs/events/node_modules/fs.realpath/package.json @@ -0,0 +1,26 @@ +{ + "name": "fs.realpath", + "version": "1.0.0", + "description": "Use node's fs.realpath, but fall back to the JS implementation if the native one fails", + "main": "index.js", + "dependencies": {}, + "devDependencies": {}, + "scripts": { + "test": "tap test/*.js --cov" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/fs.realpath.git" + }, + "keywords": [ + "realpath", + "fs", + "polyfill" + ], + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "ISC", + "files": [ + "old.js", + "index.js" + ] +} diff --git a/libs/events/node_modules/glob-parent/CHANGELOG.md b/libs/events/node_modules/glob-parent/CHANGELOG.md new file mode 100644 index 000000000..fb9de9618 --- /dev/null +++ b/libs/events/node_modules/glob-parent/CHANGELOG.md @@ -0,0 +1,110 @@ +### [5.1.2](https://github.com/gulpjs/glob-parent/compare/v5.1.1...v5.1.2) (2021-03-06) + + +### Bug Fixes + +* eliminate ReDoS ([#36](https://github.com/gulpjs/glob-parent/issues/36)) ([f923116](https://github.com/gulpjs/glob-parent/commit/f9231168b0041fea3f8f954b3cceb56269fc6366)) + +### [5.1.1](https://github.com/gulpjs/glob-parent/compare/v5.1.0...v5.1.1) (2021-01-27) + + +### Bug Fixes + +* unescape exclamation mark ([#26](https://github.com/gulpjs/glob-parent/issues/26)) ([a98874f](https://github.com/gulpjs/glob-parent/commit/a98874f1a59e407f4fb1beb0db4efa8392da60bb)) + +## [5.1.0](https://github.com/gulpjs/glob-parent/compare/v5.0.0...v5.1.0) (2021-01-27) + + +### Features + +* add `flipBackslashes` option to disable auto conversion of slashes (closes [#24](https://github.com/gulpjs/glob-parent/issues/24)) ([#25](https://github.com/gulpjs/glob-parent/issues/25)) ([eecf91d](https://github.com/gulpjs/glob-parent/commit/eecf91d5e3834ed78aee39c4eaaae654d76b87b3)) + +## [5.0.0](https://github.com/gulpjs/glob-parent/compare/v4.0.0...v5.0.0) (2021-01-27) + + +### ⚠ BREAKING CHANGES + +* Drop support for node <6 & bump dependencies + +### Miscellaneous Chores + +* Drop support for node <6 & bump dependencies ([896c0c0](https://github.com/gulpjs/glob-parent/commit/896c0c00b4e7362f60b96e7fc295ae929245255a)) + +## [4.0.0](https://github.com/gulpjs/glob-parent/compare/v3.1.0...v4.0.0) (2021-01-27) + + +### ⚠ BREAKING CHANGES + +* question marks are valid path characters on Windows so avoid flagging as a glob when alone +* Update is-glob dependency + +### Features + +* hoist regexps and strings for performance gains ([4a80667](https://github.com/gulpjs/glob-parent/commit/4a80667c69355c76a572a5892b0f133c8e1f457e)) +* question marks are valid path characters on Windows so avoid flagging as a glob when alone ([2a551dd](https://github.com/gulpjs/glob-parent/commit/2a551dd0dc3235e78bf3c94843d4107072d17841)) +* Update is-glob dependency ([e41fcd8](https://github.com/gulpjs/glob-parent/commit/e41fcd895d1f7bc617dba45c9d935a7949b9c281)) + +## [3.1.0](https://github.com/gulpjs/glob-parent/compare/v3.0.1...v3.1.0) (2021-01-27) + + +### Features + +* allow basic win32 backslash use ([272afa5](https://github.com/gulpjs/glob-parent/commit/272afa5fd070fc0f796386a5993d4ee4a846988b)) +* handle extglobs (parentheses) containing separators ([7db1bdb](https://github.com/gulpjs/glob-parent/commit/7db1bdb0756e55fd14619e8ce31aa31b17b117fd)) +* new approach to braces/brackets handling ([8269bd8](https://github.com/gulpjs/glob-parent/commit/8269bd89290d99fac9395a354fb56fdcdb80f0be)) +* pre-process braces/brackets sections ([9ef8a87](https://github.com/gulpjs/glob-parent/commit/9ef8a87f66b1a43d0591e7a8e4fc5a18415ee388)) +* preserve escaped brace/bracket at end of string ([8cfb0ba](https://github.com/gulpjs/glob-parent/commit/8cfb0ba84202d51571340dcbaf61b79d16a26c76)) + + +### Bug Fixes + +* trailing escaped square brackets ([99ec9fe](https://github.com/gulpjs/glob-parent/commit/99ec9fecc60ee488ded20a94dd4f18b4f55c4ccf)) + +### [3.0.1](https://github.com/gulpjs/glob-parent/compare/v3.0.0...v3.0.1) (2021-01-27) + + +### Features + +* use path-dirname ponyfill ([cdbea5f](https://github.com/gulpjs/glob-parent/commit/cdbea5f32a58a54e001a75ddd7c0fccd4776aacc)) + + +### Bug Fixes + +* unescape glob-escaped dirnames on output ([598c533](https://github.com/gulpjs/glob-parent/commit/598c533bdf49c1428bc063aa9b8db40c5a86b030)) + +## [3.0.0](https://github.com/gulpjs/glob-parent/compare/v2.0.0...v3.0.0) (2021-01-27) + + +### ⚠ BREAKING CHANGES + +* update is-glob dependency + +### Features + +* update is-glob dependency ([5c5f8ef](https://github.com/gulpjs/glob-parent/commit/5c5f8efcee362a8e7638cf8220666acd8784f6bd)) + +## [2.0.0](https://github.com/gulpjs/glob-parent/compare/v1.3.0...v2.0.0) (2021-01-27) + + +### Features + +* move up to dirname regardless of glob characters ([f97fb83](https://github.com/gulpjs/glob-parent/commit/f97fb83be2e0a9fc8d3b760e789d2ecadd6aa0c2)) + +## [1.3.0](https://github.com/gulpjs/glob-parent/compare/v1.2.0...v1.3.0) (2021-01-27) + +## [1.2.0](https://github.com/gulpjs/glob-parent/compare/v1.1.0...v1.2.0) (2021-01-27) + + +### Reverts + +* feat: make regex test strings smaller ([dc80fa9](https://github.com/gulpjs/glob-parent/commit/dc80fa9658dca20549cfeba44bbd37d5246fcce0)) + +## [1.1.0](https://github.com/gulpjs/glob-parent/compare/v1.0.0...v1.1.0) (2021-01-27) + + +### Features + +* make regex test strings smaller ([cd83220](https://github.com/gulpjs/glob-parent/commit/cd832208638f45169f986d80fcf66e401f35d233)) + +## 1.0.0 (2021-01-27) + diff --git a/libs/events/node_modules/glob-parent/LICENSE b/libs/events/node_modules/glob-parent/LICENSE new file mode 100644 index 000000000..63222d7a8 --- /dev/null +++ b/libs/events/node_modules/glob-parent/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2015, 2019 Elan Shanker + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/libs/events/node_modules/glob-parent/README.md b/libs/events/node_modules/glob-parent/README.md new file mode 100644 index 000000000..36a279384 --- /dev/null +++ b/libs/events/node_modules/glob-parent/README.md @@ -0,0 +1,137 @@ +

+ + + +

+ +# glob-parent + +[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Azure Pipelines Build Status][azure-pipelines-image]][azure-pipelines-url] [![Travis Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![Gitter chat][gitter-image]][gitter-url] + +Extract the non-magic parent path from a glob string. + +## Usage + +```js +var globParent = require('glob-parent'); + +globParent('path/to/*.js'); // 'path/to' +globParent('/root/path/to/*.js'); // '/root/path/to' +globParent('/*.js'); // '/' +globParent('*.js'); // '.' +globParent('**/*.js'); // '.' +globParent('path/{to,from}'); // 'path' +globParent('path/!(to|from)'); // 'path' +globParent('path/?(to|from)'); // 'path' +globParent('path/+(to|from)'); // 'path' +globParent('path/*(to|from)'); // 'path' +globParent('path/@(to|from)'); // 'path' +globParent('path/**/*'); // 'path' + +// if provided a non-glob path, returns the nearest dir +globParent('path/foo/bar.js'); // 'path/foo' +globParent('path/foo/'); // 'path/foo' +globParent('path/foo'); // 'path' (see issue #3 for details) +``` + +## API + +### `globParent(maybeGlobString, [options])` + +Takes a string and returns the part of the path before the glob begins. Be aware of Escaping rules and Limitations below. + +#### options + +```js +{ + // Disables the automatic conversion of slashes for Windows + flipBackslashes: true +} +``` + +## Escaping + +The following characters have special significance in glob patterns and must be escaped if you want them to be treated as regular path characters: + +- `?` (question mark) unless used as a path segment alone +- `*` (asterisk) +- `|` (pipe) +- `(` (opening parenthesis) +- `)` (closing parenthesis) +- `{` (opening curly brace) +- `}` (closing curly brace) +- `[` (opening bracket) +- `]` (closing bracket) + +**Example** + +```js +globParent('foo/[bar]/') // 'foo' +globParent('foo/\\[bar]/') // 'foo/[bar]' +``` + +## Limitations + +### Braces & Brackets +This library attempts a quick and imperfect method of determining which path +parts have glob magic without fully parsing/lexing the pattern. There are some +advanced use cases that can trip it up, such as nested braces where the outer +pair is escaped and the inner one contains a path separator. If you find +yourself in the unlikely circumstance of being affected by this or need to +ensure higher-fidelity glob handling in your library, it is recommended that you +pre-process your input with [expand-braces] and/or [expand-brackets]. + +### Windows +Backslashes are not valid path separators for globs. If a path with backslashes +is provided anyway, for simple cases, glob-parent will replace the path +separator for you and return the non-glob parent path (now with +forward-slashes, which are still valid as Windows path separators). + +This cannot be used in conjunction with escape characters. + +```js +// BAD +globParent('C:\\Program Files \\(x86\\)\\*.ext') // 'C:/Program Files /(x86/)' + +// GOOD +globParent('C:/Program Files\\(x86\\)/*.ext') // 'C:/Program Files (x86)' +``` + +If you are using escape characters for a pattern without path parts (i.e. +relative to `cwd`), prefix with `./` to avoid confusing glob-parent. + +```js +// BAD +globParent('foo \\[bar]') // 'foo ' +globParent('foo \\[bar]*') // 'foo ' + +// GOOD +globParent('./foo \\[bar]') // 'foo [bar]' +globParent('./foo \\[bar]*') // '.' +``` + +## License + +ISC + +[expand-braces]: https://github.com/jonschlinkert/expand-braces +[expand-brackets]: https://github.com/jonschlinkert/expand-brackets + +[downloads-image]: https://img.shields.io/npm/dm/glob-parent.svg +[npm-url]: https://www.npmjs.com/package/glob-parent +[npm-image]: https://img.shields.io/npm/v/glob-parent.svg + +[azure-pipelines-url]: https://dev.azure.com/gulpjs/gulp/_build/latest?definitionId=2&branchName=master +[azure-pipelines-image]: https://dev.azure.com/gulpjs/gulp/_apis/build/status/glob-parent?branchName=master + +[travis-url]: https://travis-ci.org/gulpjs/glob-parent +[travis-image]: https://img.shields.io/travis/gulpjs/glob-parent.svg?label=travis-ci + +[appveyor-url]: https://ci.appveyor.com/project/gulpjs/glob-parent +[appveyor-image]: https://img.shields.io/appveyor/ci/gulpjs/glob-parent.svg?label=appveyor + +[coveralls-url]: https://coveralls.io/r/gulpjs/glob-parent +[coveralls-image]: https://img.shields.io/coveralls/gulpjs/glob-parent/master.svg + +[gitter-url]: https://gitter.im/gulpjs/gulp +[gitter-image]: https://badges.gitter.im/gulpjs/gulp.svg diff --git a/libs/events/node_modules/glob-parent/index.js b/libs/events/node_modules/glob-parent/index.js new file mode 100644 index 000000000..09e257ea3 --- /dev/null +++ b/libs/events/node_modules/glob-parent/index.js @@ -0,0 +1,42 @@ +'use strict'; + +var isGlob = require('is-glob'); +var pathPosixDirname = require('path').posix.dirname; +var isWin32 = require('os').platform() === 'win32'; + +var slash = '/'; +var backslash = /\\/g; +var enclosure = /[\{\[].*[\}\]]$/; +var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; +var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; + +/** + * @param {string} str + * @param {Object} opts + * @param {boolean} [opts.flipBackslashes=true] + * @returns {string} + */ +module.exports = function globParent(str, opts) { + var options = Object.assign({ flipBackslashes: true }, opts); + + // flip windows path separators + if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { + str = str.replace(backslash, slash); + } + + // special case for strings ending in enclosure containing path separator + if (enclosure.test(str)) { + str += slash; + } + + // preserves full path in case of trailing path separator + str += 'a'; + + // remove path parts that are globby + do { + str = pathPosixDirname(str); + } while (isGlob(str) || globby.test(str)); + + // remove escape chars and return result + return str.replace(escaped, '$1'); +}; diff --git a/libs/events/node_modules/glob-parent/package.json b/libs/events/node_modules/glob-parent/package.json new file mode 100644 index 000000000..125c971c2 --- /dev/null +++ b/libs/events/node_modules/glob-parent/package.json @@ -0,0 +1,48 @@ +{ + "name": "glob-parent", + "version": "5.1.2", + "description": "Extract the non-magic parent path from a glob string.", + "author": "Gulp Team (https://gulpjs.com/)", + "contributors": [ + "Elan Shanker (https://github.com/es128)", + "Blaine Bublitz " + ], + "repository": "gulpjs/glob-parent", + "license": "ISC", + "engines": { + "node": ">= 6" + }, + "main": "index.js", + "files": [ + "LICENSE", + "index.js" + ], + "scripts": { + "lint": "eslint .", + "pretest": "npm run lint", + "test": "nyc mocha --async-only", + "azure-pipelines": "nyc mocha --async-only --reporter xunit -O output=test.xunit", + "coveralls": "nyc report --reporter=text-lcov | coveralls" + }, + "dependencies": { + "is-glob": "^4.0.1" + }, + "devDependencies": { + "coveralls": "^3.0.11", + "eslint": "^2.13.1", + "eslint-config-gulp": "^3.0.1", + "expect": "^1.20.2", + "mocha": "^6.0.2", + "nyc": "^13.3.0" + }, + "keywords": [ + "glob", + "parent", + "strip", + "path", + "dirname", + "directory", + "base", + "wildcard" + ] +} diff --git a/libs/events/node_modules/glob/LICENSE b/libs/events/node_modules/glob/LICENSE new file mode 100644 index 000000000..ec7df9332 --- /dev/null +++ b/libs/events/node_modules/glob/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2009-2023 Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/libs/events/node_modules/glob/README.md b/libs/events/node_modules/glob/README.md new file mode 100644 index 000000000..bc7fabc4b --- /dev/null +++ b/libs/events/node_modules/glob/README.md @@ -0,0 +1,1086 @@ +# Glob + +Match files using the patterns the shell uses. + +The most correct and second fastest glob implementation in +JavaScript. (See **Comparison to Other JavaScript Glob +Implementations** at the bottom of this readme.) + +![a fun cartoon logo made of glob characters](https://github.com/isaacs/node-glob/raw/main/logo/glob.png) + +## Usage + +Install with npm + +``` +npm i glob +``` + +**Note** the npm package name is _not_ `node-glob` that's a +different thing that was abandoned years ago. Just `glob`. + +```js +// load using import +import { glob, globSync, globStream, globStreamSync, Glob } from 'glob' +// or using commonjs, that's fine, too +const { + glob, + globSync, + globStream, + globStreamSync, + Glob, +} = require('glob') + +// or default export is fine too, just returns the glob function +// with all the aliases attached. +import glob from 'glob' +// or using commonjs +const glob = require('glob') + +// the main glob() and globSync() resolve/return array of filenames + +// all js files, but don't look in node_modules +const jsfiles = await glob('**/*.js', { ignore: 'node_modules/**' }) + +// pass in a signal to cancel the glob walk +const stopAfter100ms = await glob('**/*.css', { + signal: AbortSignal.timeout(100), +}) + +// multiple patterns supported as well +const images = await glob(['css/*.{png,jpeg}', 'public/*.{png,jpeg}']) + +// but of course you can do that with the glob pattern also +// the sync function is the same, just returns a string[] instead +// of Promise +const imagesAlt = globSync('{css,public}/*.{png,jpeg}') + +// you can also stream them, this is a Minipass stream +const filesStream = globStream(['**/*.dat', 'logs/**/*.log']) + +// construct a Glob object if you wanna do it that way, which +// allows for much faster walks if you have to look in the same +// folder multiple times. +const g = new Glob('**/foo') +// glob objects are async iterators, can also do globIterate() or +// g.iterate(), same deal +for await (const file of g) { + console.log('found a foo file:', file) +} +// pass a glob as the glob options to reuse its settings and caches +const g2 = new Glob('**/bar', g) +// sync iteration works as well +for (const file of g2) { + console.log('found a bar file:', file) +} + +// you can also pass withFileTypes: true to get Path objects +// these are like a Dirent, but with some more added powers +// check out http://npm.im/path-scurry for more info on their API +const g3 = new Glob('**/baz/**', { withFileTypes: true }) +g3.stream().on('data', path => { + console.log( + 'got a path object', + path.fullpath(), + path.isDirectory(), + path.readdirSync().map(e => e.name) + ) +}) + +// if you use stat:true and withFileTypes, you can sort results +// by things like modified time, filter by permission mode, etc. +// All Stats fields will be avialable in that case. Slightly +// slower, though. +// For example: +const results = await glob('**', { stat: true, withFileTypes: true }) + +const timeSortedFiles = results + .sort((a, b) => a.mtimeMS - b.mtimeMS) + .map(path => path.fullpath()) + +const groupReadableFiles = results + .filter(path => path.mode & 0o040) + .map(path => path.fullpath()) + +// custom ignores can be done like this, for example by saying +// you'll ignore all markdown files, and all folders named 'docs' +const customIgnoreResults = await glob('**', { + ignore: { + ignored: (p) => /\.md$/.test(p.name), + childrenIgnored: (p) => p.isNamed('docs'), + }, +}) + +// another fun use case, only return files with the same name as +// their parent folder, plus either `.ts` or `.js` +const folderNamedModules = await glob('**/*.{ts,js}', { + ignore: { + ignored: (p) => { + const pp = p.parent + return !(p.isNamed(pp.name + '.ts') || p.isNamed(pp.name + '.js')) + } + } +}) + +// find all files edited in the last hour, to do this, we ignore +// all of them that are more than an hour old +const newFiles = await glob('**', { + // need stat so we have mtime + stat: true, + // only want the files, not the dirs + nodir: true, + ignore: { + ignored: (p) => { + return (new Date() - p.mtime) > (60 * 60 * 1000) + }, + // could add similar childrenIgnored here as well, but + // directory mtime is inconsistent across platforms, so + // probably better not to, unless you know the system + // tracks this reliably. + } +}) +``` + +**Note** Glob patterns should always use `/` as a path separator, +even on Windows systems, as `\` is used to escape glob +characters. If you wish to use `\` as a path separator _instead +of_ using it as an escape character on Windows platforms, you may +set `windowsPathsNoEscape:true` in the options. In this mode, +special glob characters cannot be escaped, making it impossible +to match a literal `*` `?` and so on in filenames. + +## `glob(pattern: string | string[], options?: GlobOptions) => Promise` + +Perform an asynchronous glob search for the pattern(s) specified. +Returns +[Path](https://isaacs.github.io/path-scurry/classes/PathBase) +objects if the `withFileTypes` option is set to `true`. See below +for full options field desciptions. + +## `globSync(pattern: string | string[], options?: GlobOptions) => string[] | Path[]` + +Synchronous form of `glob()`. + +Alias: `glob.sync()` + +## `globIterate(pattern: string | string[], options?: GlobOptions) => AsyncGenerator` + +Return an async iterator for walking glob pattern matches. + +Alias: `glob.iterate()` + +## `globIterateSync(pattern: string | string[], options?: GlobOptions) => Generator` + +Return a sync iterator for walking glob pattern matches. + +Alias: `glob.iterate.sync()`, `glob.sync.iterate()` + +## `globStream(pattern: string | string[], options?: GlobOptions) => Minipass` + +Return a stream that emits all the strings or `Path` objects and +then emits `end` when completed. + +Alias: `glob.stream()` + +## `globStreamSync(pattern: string | string[], options?: GlobOptions) => Minipass` + +Syncronous form of `globStream()`. Will read all the matches as +fast as you consume them, even all in a single tick if you +consume them immediately, but will still respond to backpressure +if they're not consumed immediately. + +Alias: `glob.stream.sync()`, `glob.sync.stream()` + +## `hasMagic(pattern: string | string[], options?: GlobOptions) => boolean` + +Returns `true` if the provided pattern contains any "magic" glob +characters, given the options provided. + +Brace expansion is not considered "magic" unless the +`magicalBraces` option is set, as brace expansion just turns one +string into an array of strings. So a pattern like `'x{a,b}y'` +would return `false`, because `'xay'` and `'xby'` both do not +contain any magic glob characters, and it's treated the same as +if you had called it on `['xay', 'xby']`. When +`magicalBraces:true` is in the options, brace expansion _is_ +treated as a pattern having magic. + +## `escape(pattern: string, options?: GlobOptions) => string` + +Escape all magic characters in a glob pattern, so that it will +only ever match literal strings + +If the `windowsPathsNoEscape` option is used, then characters are +escaped by wrapping in `[]`, because a magic character wrapped in +a character class can only be satisfied by that exact character. + +Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot +be escaped or unescaped. + +## `unescape(pattern: string, options?: GlobOptions) => string` + +Un-escape a glob string that may contain some escaped characters. + +If the `windowsPathsNoEscape` option is used, then square-brace +escapes are removed, but not backslash escapes. For example, it +will turn the string `'[*]'` into `*`, but it will not turn +`'\\*'` into `'*'`, because `\` is a path separator in +`windowsPathsNoEscape` mode. + +When `windowsPathsNoEscape` is not set, then both brace escapes +and backslash escapes are removed. + +Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot +be escaped or unescaped. + +## Class `Glob` + +An object that can perform glob pattern traversals. + +### `const g = new Glob(pattern: string | string[], options: GlobOptions)` + +See full options descriptions below. + +Note that a previous `Glob` object can be passed as the +`GlobOptions` to another `Glob` instantiation to re-use settings +and caches with a new pattern. + +Traversal functions can be called multiple times to run the walk +again. + +### `g.stream()` + +Stream results asynchronously, + +### `g.streamSync()` + +Stream results synchronously. + +### `g.iterate()` + +Default async iteration function. Returns an AsyncGenerator that +iterates over the results. + +### `g.iterateSync()` + +Default sync iteration function. Returns a Generator that +iterates over the results. + +### `g.walk()` + +Returns a Promise that resolves to the results array. + +### `g.walkSync()` + +Returns a results array. + +### Properties + +All options are stored as properties on the `Glob` object. + +- `opts` The options provided to the constructor. +- `patterns` An array of parsed immutable `Pattern` objects. + +## Options + +Exported as `GlobOptions` TypeScript interface. A `GlobOptions` +object may be provided to any of the exported methods, and must +be provided to the `Glob` constructor. + +All options are optional, boolean, and false by default, unless +otherwise noted. + +All resolved options are added to the Glob object as properties. + +If you are running many `glob` operations, you can pass a Glob +object as the `options` argument to a subsequent operation to +share the previously loaded cache. + +- `cwd` String path or `file://` string or URL object. The + current working directory in which to search. Defaults to + `process.cwd()`. See also: "Windows, CWDs, Drive Letters, and + UNC Paths", below. + + This option may be eiher a string path or a `file://` URL + object or string. + +- `root` A string path resolved against the `cwd` option, which + is used as the starting point for absolute patterns that start + with `/`, (but not drive letters or UNC paths on Windows). + + Note that this _doesn't_ necessarily limit the walk to the + `root` directory, and doesn't affect the cwd starting point for + non-absolute patterns. A pattern containing `..` will still be + able to traverse out of the root directory, if it is not an + actual root directory on the filesystem, and any non-absolute + patterns will be matched in the `cwd`. For example, the + pattern `/../*` with `{root:'/some/path'}` will return all + files in `/some`, not all files in `/some/path`. The pattern + `*` with `{root:'/some/path'}` will return all the entries in + the cwd, not the entries in `/some/path`. + + To start absolute and non-absolute patterns in the same + path, you can use `{root:''}`. However, be aware that on + Windows systems, a pattern like `x:/*` or `//host/share/*` will + _always_ start in the `x:/` or `//host/share` directory, + regardless of the `root` setting. + +- `windowsPathsNoEscape` Use `\\` as a path separator _only_, and + _never_ as an escape character. If set, all `\\` characters are + replaced with `/` in the pattern. + + Note that this makes it **impossible** to match against paths + containing literal glob pattern characters, but allows matching + with patterns constructed using `path.join()` and + `path.resolve()` on Windows platforms, mimicking the (buggy!) + behavior of Glob v7 and before on Windows. Please use with + caution, and be mindful of [the caveat below about Windows + paths](#windows). (For legacy reasons, this is also set if + `allowWindowsEscape` is set to the exact value `false`.) + +- `dot` Include `.dot` files in normal matches and `globstar` + matches. Note that an explicit dot in a portion of the pattern + will always match dot files. + +- `magicalBraces` Treat brace expansion like `{a,b}` as a "magic" + pattern. Has no effect if {@link nobrace} is set. + + Only has effect on the {@link hasMagic} function, no effect on + glob pattern matching itself. + +- `dotRelative` Prepend all relative path strings with `./` (or + `.\` on Windows). + + Without this option, returned relative paths are "bare", so + instead of returning `'./foo/bar'`, they are returned as + `'foo/bar'`. + + Relative patterns starting with `'../'` are not prepended with + `./`, even if this option is set. + +- `mark` Add a `/` character to directory matches. Note that this + requires additional stat calls. + +- `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets. + +- `noglobstar` Do not match `**` against multiple filenames. (Ie, + treat it as a normal `*` instead.) + +- `noext` Do not match "extglob" patterns such as `+(a|b)`. + +- `nocase` Perform a case-insensitive match. This defaults to + `true` on macOS and Windows systems, and `false` on all others. + + **Note** `nocase` should only be explicitly set when it is + known that the filesystem's case sensitivity differs from the + platform default. If set `true` on case-sensitive file + systems, or `false` on case-insensitive file systems, then the + walk may return more or less results than expected. + +- `maxDepth` Specify a number to limit the depth of the directory + traversal to this many levels below the `cwd`. + +- `matchBase` Perform a basename-only match if the pattern does + not contain any slash characters. That is, `*.js` would be + treated as equivalent to `**/*.js`, matching all js files in + all directories. + +- `nodir` Do not match directories, only files. (Note: to match + _only_ directories, put a `/` at the end of the pattern.) + +- `stat` Call `lstat()` on all entries, whether required or not + to determine whether it's a valid match. When used with + `withFileTypes`, this means that matches will include data such + as modified time, permissions, and so on. Note that this will + incur a performance cost due to the added system calls. + +- `ignore` string or string[], or an object with `ignore` and + `ignoreChildren` methods. + + If a string or string[] is provided, then this is treated as a + glob pattern or array of glob patterns to exclude from matches. + To ignore all children within a directory, as well as the entry + itself, append `'/**'` to the ignore pattern. + + **Note** `ignore` patterns are _always_ in `dot:true` mode, + regardless of any other settings. + + If an object is provided that has `ignored(path)` and/or + `childrenIgnored(path)` methods, then these methods will be + called to determine whether any Path is a match or if its + children should be traversed, respectively. + +- `follow` Follow symlinked directories when expanding `**` + patterns. This can result in a lot of duplicate references in + the presence of cyclic links, and make performance quite bad. + + By default, a `**` in a pattern will follow 1 symbolic link if + it is not the first item in the pattern, or none if it is the + first item in the pattern, following the same behavior as Bash. + +- `realpath` Set to true to call `fs.realpath` on all of the + results. In the case of an entry that cannot be resolved, the + entry is omitted. This incurs a slight performance penalty, of + course, because of the added system calls. + +- `absolute` Set to true to always receive absolute paths for + matched files. Set to `false` to always receive relative paths + for matched files. + + By default, when this option is not set, absolute paths are + returned for patterns that are absolute, and otherwise paths + are returned that are relative to the `cwd` setting. + + This does _not_ make an extra system call to get the realpath, + it only does string path resolution. + + `absolute` may not be used along with `withFileTypes`. + +- `platform` Defaults to value of `process.platform` if + available, or `'linux'` if not. Setting `platform:'win32'` on + non-Windows systems may cause strange behavior. + +- `withFileTypes` Return [PathScurry](http://npm.im/path-scurry) + `Path` objects instead of strings. These are similar to a + NodeJS `Dirent` object, but with additional methods and + properties. + + `withFileTypes` may not be used along with `absolute`. + +- `signal` An AbortSignal which will cancel the Glob walk when + triggered. + +- `fs` An override object to pass in custom filesystem methods. + See [PathScurry docs](http://npm.im/path-scurry) for what can + be overridden. + +- `scurry` A [PathScurry](http://npm.im/path-scurry) object used + to traverse the file system. If the `nocase` option is set + explicitly, then any provided `scurry` object must match this + setting. + +## Glob Primer + +Much more information about glob pattern expansion can be found +by running `man bash` and searching for `Pattern Matching`. + +"Globs" are the patterns you type when you do stuff like `ls +*.js` on the command line, or put `build/*` in a `.gitignore` +file. + +Before parsing the path part patterns, braced sections are +expanded into a set. Braced sections start with `{` and end with +`}`, with 2 or more comma-delimited sections within. Braced +sections may contain slash characters, so `a{/b/c,bcd}` would +expand into `a/b/c` and `abcd`. + +The following characters have special magic meaning when used in +a path portion. With the exception of `**`, none of these match +path separators (ie, `/` on all platforms, and `\` on Windows). + +- `*` Matches 0 or more characters in a single path portion. + When alone in a path portion, it must match at least 1 + character. If `dot:true` is not specified, then `*` will not + match against a `.` character at the start of a path portion. +- `?` Matches 1 character. If `dot:true` is not specified, then + `?` will not match against a `.` character at the start of a + path portion. +- `[...]` Matches a range of characters, similar to a RegExp + range. If the first character of the range is `!` or `^` then + it matches any character not in the range. If the first + character is `]`, then it will be considered the same as `\]`, + rather than the end of the character class. +- `!(pattern|pattern|pattern)` Matches anything that does not + match any of the patterns provided. May _not_ contain `/` + characters. Similar to `*`, if alone in a path portion, then + the path portion must have at least one character. +- `?(pattern|pattern|pattern)` Matches zero or one occurrence of + the patterns provided. May _not_ contain `/` characters. +- `+(pattern|pattern|pattern)` Matches one or more occurrences of + the patterns provided. May _not_ contain `/` characters. +- `*(a|b|c)` Matches zero or more occurrences of the patterns + provided. May _not_ contain `/` characters. +- `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns + provided. May _not_ contain `/` characters. +- `**` If a "globstar" is alone in a path portion, then it + matches zero or more directories and subdirectories searching + for matches. It does not crawl symlinked directories, unless + `{follow:true}` is passed in the options object. A pattern + like `a/b/**` will only match `a/b` if it is a directory. + Follows 1 symbolic link if not the first item in the pattern, + or 0 if it is the first item, unless `follow:true` is set, in + which case it follows all symbolic links. + +`[:class:]` patterns are supported by this implementation, but +`[=c=]` and `[.symbol.]` style class patterns are not. + +### Dots + +If a file or directory path portion has a `.` as the first +character, then it will not match any glob pattern unless that +pattern's corresponding path part also has a `.` as its first +character. + +For example, the pattern `a/.*/c` would match the file at +`a/.b/c`. However the pattern `a/*/c` would not, because `*` does +not start with a dot character. + +You can make glob treat dots as normal characters by setting +`dot:true` in the options. + +### Basename Matching + +If you set `matchBase:true` in the options, and the pattern has +no slashes in it, then it will seek for any file anywhere in the +tree with a matching basename. For example, `*.js` would match +`test/simple/basic.js`. + +### Empty Sets + +If no matching files are found, then an empty array is returned. +This differs from the shell, where the pattern itself is +returned. For example: + +```sh +$ echo a*s*d*f +a*s*d*f +``` + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a +worthwhile goal, some discrepancies exist between node-glob and +other implementations, and are intentional. + +The double-star character `**` is supported by default, unless +the `noglobstar` flag is set. This is supported in the manner of +bsdglob and bash 5, where `**` only has special significance if +it is the only thing in a path part. That is, `a/**/b` will match +`a/x/y/b`, but `a/**b` will not. + +Note that symlinked directories are not traversed as part of a +`**`, though their contents may match against subsequent portions +of the pattern. This prevents infinite loops and duplicates and +the like. You can force glob to traverse symlinks with `**` by +setting `{follow:true}` in the options. + +There is no equivalent of the `nonull` option. A pattern that +does not find any matches simply resolves to nothing. (An empty +array, immediately ended stream, etc.) + +If brace expansion is not disabled, then it is performed before +any other interpretation of the glob pattern. Thus, a pattern +like `+(a|{b),c)}`, which would not be valid in bash or zsh, is +expanded **first** into the set of `+(a|b)` and `+(a|c)`, and +those patterns are checked for validity. Since those two are +valid, matching proceeds. + +The character class patterns `[:class:]` (posix standard named +classes) style class patterns are supported and unicode-aware, +but `[=c=]` (locale-specific character collation weight), and +`[.symbol.]` (collating symbol), are not. + +### Repeated Slashes + +Unlike Bash and zsh, repeated `/` are always coalesced into a +single path separator. + +### Comments and Negation + +Previously, this module let you mark a pattern as a "comment" if +it started with a `#` character, or a "negated" pattern if it +started with a `!` character. + +These options were deprecated in version 5, and removed in +version 6. + +To specify things that should not match, use the `ignore` option. + +## Windows + +**Please only use forward-slashes in glob expressions.** + +Though windows uses either `/` or `\` as its path separator, only +`/` characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes will +always be interpreted as escape characters, not path separators. + +Results from absolute patterns such as `/foo/*` are mounted onto +the root setting using `path.join`. On windows, this will by +default result in `/foo/*` matching `C:\foo\bar.txt`. + +To automatically coerce all `\` characters to `/` in pattern +strings, **thus making it impossible to escape literal glob +characters**, you may set the `windowsPathsNoEscape` option to +`true`. + +### Windows, CWDs, Drive Letters, and UNC Paths + +On posix systems, when a pattern starts with `/`, any `cwd` +option is ignored, and the traversal starts at `/`, plus any +non-magic path portions specified in the pattern. + +On Windows systems, the behavior is similar, but the concept of +an "absolute path" is somewhat more involved. + +#### UNC Paths + +A UNC path may be used as the start of a pattern on Windows +platforms. For example, a pattern like: `//?/x:/*` will return +all file entries in the root of the `x:` drive. A pattern like +`//ComputerName/Share/*` will return all files in the associated +share. + +UNC path roots are always compared case insensitively. + +#### Drive Letters + +A pattern starting with a drive letter, like `c:/*`, will search +in that drive, regardless of any `cwd` option provided. + +If the pattern starts with `/`, and is not a UNC path, and there +is an explicit `cwd` option set with a drive letter, then the +drive letter in the `cwd` is used as the root of the directory +traversal. + +For example, `glob('/tmp', { cwd: 'c:/any/thing' })` will return +`['c:/tmp']` as the result. + +If an explicit `cwd` option is not provided, and the pattern +starts with `/`, then the traversal will run on the root of the +drive provided as the `cwd` option. (That is, it is the result of +`path.resolve('/')`.) + +## Race Conditions + +Glob searching, by its very nature, is susceptible to race +conditions, since it relies on directory walking. + +As a result, it is possible that a file that exists when glob +looks for it may have been deleted or modified by the time it +returns the result. + +By design, this implementation caches all readdir calls that it +makes, in order to cut down on system overhead. However, this +also makes it even more susceptible to races, especially if the +cache object is reused between glob calls. + +Users are thus advised not to use a glob result as a guarantee of +filesystem state in the face of rapid changes. For the vast +majority of operations, this is never a problem. + +### See Also: + +- `man sh` +- `man bash` [Pattern + Matching](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) +- `man 3 fnmatch` +- `man 5 gitignore` +- [minimatch documentation](https://github.com/isaacs/minimatch) + +## Glob Logo + +Glob's logo was created by [Tanya +Brassie](http://tanyabrassie.com/). Logo files can be found +[here](https://github.com/isaacs/node-glob/tree/master/logo). + +The logo is licensed under a [Creative Commons +Attribution-ShareAlike 4.0 International +License](https://creativecommons.org/licenses/by-sa/4.0/). + +## Contributing + +Any change to behavior (including bugfixes) must come with a +test. + +Patches that fail tests or reduce performance will be rejected. + +```sh +# to run tests +npm test + +# to re-generate test fixtures +npm run test-regen + +# run the benchmarks +npm run bench + +# to profile javascript +npm run prof +``` + +## Comparison to Other JavaScript Glob Implementations + +**tl;dr** + +- If you want glob matching that is as faithful as possible to + Bash pattern expansion semantics, and as fast as possible + within that constraint, _use this module_. +- If you are reasonably sure that the patterns you will encounter + are relatively simple, and want the absolutely fastest glob + matcher out there, _use [fast-glob](http://npm.im/fast-glob)_. +- If you are reasonably sure that the patterns you will encounter + are relatively simple, and want the convenience of + automatically respecting `.gitignore` files, _use + [globby](http://npm.im/globby)_. + +There are some other glob matcher libraries on npm, but these +three are (in my opinion, as of 2023) the best. + +--- + +**full explanation** + +Every library reflects a set of opinions and priorities in the +trade-offs it makes. Other than this library, I can personally +recommend both [globby](http://npm.im/globby) and +[fast-glob](http://npm.im/fast-glob), though they differ in their +benefits and drawbacks. + +Both have very nice APIs and are reasonably fast. + +`fast-glob` is, as far as I am aware, the fastest glob +implementation in JavaScript today. However, there are many +cases where the choices that `fast-glob` makes in pursuit of +speed mean that its results differ from the results returned by +Bash and other sh-like shells, which may be surprising. + +In my testing, `fast-glob` is around 10-20% faster than this +module when walking over 200k files nested 4 directories +deep[1](#fn-webscale). However, there are some inconsistencies +with Bash matching behavior that this module does not suffer +from: + +- `**` only matches files, not directories +- `..` path portions are not handled unless they appear at the + start of the pattern +- `./!()` will not match any files that _start_ with + ``, even if they do not match ``. For + example, `!(9).txt` will not match `9999.txt`. +- Some brace patterns in the middle of a pattern will result in + failing to find certain matches. +- Extglob patterns are allowed to contain `/` characters. + +Globby exhibits all of the same pattern semantics as fast-glob, +(as it is a wrapper around fast-glob) and is slightly slower than +node-glob (by about 10-20% in the benchmark test set, or in other +words, anywhere from 20-50% slower than fast-glob). However, it +adds some API conveniences that may be worth the costs. + +- Support for `.gitignore` and other ignore files. +- Support for negated globs (ie, patterns starting with `!` + rather than using a separate `ignore` option). + +The priority of this module is "correctness" in the sense of +performing a glob pattern expansion as faithfully as possible to +the behavior of Bash and other sh-like shells, with as much speed +as possible. + +Note that prior versions of `node-glob` are _not_ on this list. +Former versions of this module are far too slow for any cases +where performance matters at all, and were designed with APIs +that are extremely dated by current JavaScript standards. + +--- + +[1]: In the cases where this module +returns results and `fast-glob` doesn't, it's even faster, of +course. + +![lumpy space princess saying 'oh my GLOB'](https://github.com/isaacs/node-glob/raw/main/oh-my-glob.gif) + +### Benchmark Results + +First number is time, smaller is better. + +Second number is the count of results returned. + +``` +--- pattern: '**' --- +~~ sync ~~ +node fast-glob sync 0m0.598s 200364 +node globby sync 0m0.765s 200364 +node current globSync mjs 0m0.683s 222656 +node current glob syncStream 0m0.649s 222656 +~~ async ~~ +node fast-glob async 0m0.350s 200364 +node globby async 0m0.509s 200364 +node current glob async mjs 0m0.463s 222656 +node current glob stream 0m0.411s 222656 + +--- pattern: '**/..' --- +~~ sync ~~ +node fast-glob sync 0m0.486s 0 +node globby sync 0m0.769s 200364 +node current globSync mjs 0m0.564s 2242 +node current glob syncStream 0m0.583s 2242 +~~ async ~~ +node fast-glob async 0m0.283s 0 +node globby async 0m0.512s 200364 +node current glob async mjs 0m0.299s 2242 +node current glob stream 0m0.312s 2242 + +--- pattern: './**/0/**/0/**/0/**/0/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.490s 10 +node globby sync 0m0.517s 10 +node current globSync mjs 0m0.540s 10 +node current glob syncStream 0m0.550s 10 +~~ async ~~ +node fast-glob async 0m0.290s 10 +node globby async 0m0.296s 10 +node current glob async mjs 0m0.278s 10 +node current glob stream 0m0.302s 10 + +--- pattern: './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.500s 160 +node globby sync 0m0.528s 160 +node current globSync mjs 0m0.556s 160 +node current glob syncStream 0m0.573s 160 +~~ async ~~ +node fast-glob async 0m0.283s 160 +node globby async 0m0.301s 160 +node current glob async mjs 0m0.306s 160 +node current glob stream 0m0.322s 160 + +--- pattern: './**/0/**/0/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.502s 5230 +node globby sync 0m0.527s 5230 +node current globSync mjs 0m0.544s 5230 +node current glob syncStream 0m0.557s 5230 +~~ async ~~ +node fast-glob async 0m0.285s 5230 +node globby async 0m0.305s 5230 +node current glob async mjs 0m0.304s 5230 +node current glob stream 0m0.310s 5230 + +--- pattern: '**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.580s 200023 +node globby sync 0m0.771s 200023 +node current globSync mjs 0m0.685s 200023 +node current glob syncStream 0m0.649s 200023 +~~ async ~~ +node fast-glob async 0m0.349s 200023 +node globby async 0m0.509s 200023 +node current glob async mjs 0m0.427s 200023 +node current glob stream 0m0.388s 200023 + +--- pattern: '{**/*.txt,**/?/**/*.txt,**/?/**/?/**/*.txt,**/?/**/?/**/?/**/*.txt,**/?/**/?/**/?/**/?/**/*.txt}' --- +~~ sync ~~ +node fast-glob sync 0m0.589s 200023 +node globby sync 0m0.771s 200023 +node current globSync mjs 0m0.716s 200023 +node current glob syncStream 0m0.684s 200023 +~~ async ~~ +node fast-glob async 0m0.351s 200023 +node globby async 0m0.518s 200023 +node current glob async mjs 0m0.462s 200023 +node current glob stream 0m0.468s 200023 + +--- pattern: '**/5555/0000/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.496s 1000 +node globby sync 0m0.519s 1000 +node current globSync mjs 0m0.539s 1000 +node current glob syncStream 0m0.567s 1000 +~~ async ~~ +node fast-glob async 0m0.285s 1000 +node globby async 0m0.299s 1000 +node current glob async mjs 0m0.305s 1000 +node current glob stream 0m0.301s 1000 + +--- pattern: './**/0/**/../[01]/**/0/../**/0/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.484s 0 +node globby sync 0m0.507s 0 +node current globSync mjs 0m0.577s 4880 +node current glob syncStream 0m0.586s 4880 +~~ async ~~ +node fast-glob async 0m0.280s 0 +node globby async 0m0.298s 0 +node current glob async mjs 0m0.327s 4880 +node current glob stream 0m0.324s 4880 + +--- pattern: '**/????/????/????/????/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.547s 100000 +node globby sync 0m0.673s 100000 +node current globSync mjs 0m0.626s 100000 +node current glob syncStream 0m0.618s 100000 +~~ async ~~ +node fast-glob async 0m0.315s 100000 +node globby async 0m0.414s 100000 +node current glob async mjs 0m0.366s 100000 +node current glob stream 0m0.345s 100000 + +--- pattern: './{**/?{/**/?{/**/?{/**/?,,,,},,,,},,,,},,,}/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.588s 100000 +node globby sync 0m0.670s 100000 +node current globSync mjs 0m0.717s 200023 +node current glob syncStream 0m0.687s 200023 +~~ async ~~ +node fast-glob async 0m0.343s 100000 +node globby async 0m0.418s 100000 +node current glob async mjs 0m0.519s 200023 +node current glob stream 0m0.451s 200023 + +--- pattern: '**/!(0|9).txt' --- +~~ sync ~~ +node fast-glob sync 0m0.573s 160023 +node globby sync 0m0.731s 160023 +node current globSync mjs 0m0.680s 180023 +node current glob syncStream 0m0.659s 180023 +~~ async ~~ +node fast-glob async 0m0.345s 160023 +node globby async 0m0.476s 160023 +node current glob async mjs 0m0.427s 180023 +node current glob stream 0m0.388s 180023 + +--- pattern: './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,,,,},,,,},,,,},,,,},,,,}/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.483s 0 +node globby sync 0m0.512s 0 +node current globSync mjs 0m0.811s 200023 +node current glob syncStream 0m0.773s 200023 +~~ async ~~ +node fast-glob async 0m0.280s 0 +node globby async 0m0.299s 0 +node current glob async mjs 0m0.617s 200023 +node current glob stream 0m0.568s 200023 + +--- pattern: './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.485s 0 +node globby sync 0m0.507s 0 +node current globSync mjs 0m0.759s 200023 +node current glob syncStream 0m0.740s 200023 +~~ async ~~ +node fast-glob async 0m0.281s 0 +node globby async 0m0.297s 0 +node current glob async mjs 0m0.544s 200023 +node current glob stream 0m0.464s 200023 + +--- pattern: './*/**/../*/**/../*/**/../*/**/../*/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.486s 0 +node globby sync 0m0.513s 0 +node current globSync mjs 0m0.734s 200023 +node current glob syncStream 0m0.696s 200023 +~~ async ~~ +node fast-glob async 0m0.286s 0 +node globby async 0m0.296s 0 +node current glob async mjs 0m0.506s 200023 +node current glob stream 0m0.483s 200023 + +--- pattern: './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.060s 0 +node globby sync 0m0.074s 0 +node current globSync mjs 0m0.067s 0 +node current glob syncStream 0m0.066s 0 +~~ async ~~ +node fast-glob async 0m0.060s 0 +node globby async 0m0.075s 0 +node current glob async mjs 0m0.066s 0 +node current glob stream 0m0.067s 0 + +--- pattern: './**/?/**/?/**/?/**/?/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.568s 100000 +node globby sync 0m0.651s 100000 +node current globSync mjs 0m0.619s 100000 +node current glob syncStream 0m0.617s 100000 +~~ async ~~ +node fast-glob async 0m0.332s 100000 +node globby async 0m0.409s 100000 +node current glob async mjs 0m0.372s 100000 +node current glob stream 0m0.351s 100000 + +--- pattern: '**/*/**/*/**/*/**/*/**' --- +~~ sync ~~ +node fast-glob sync 0m0.603s 200113 +node globby sync 0m0.798s 200113 +node current globSync mjs 0m0.730s 222137 +node current glob syncStream 0m0.693s 222137 +~~ async ~~ +node fast-glob async 0m0.356s 200113 +node globby async 0m0.525s 200113 +node current glob async mjs 0m0.508s 222137 +node current glob stream 0m0.455s 222137 + +--- pattern: './**/*/**/*/**/*/**/*/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.622s 200000 +node globby sync 0m0.792s 200000 +node current globSync mjs 0m0.722s 200000 +node current glob syncStream 0m0.695s 200000 +~~ async ~~ +node fast-glob async 0m0.369s 200000 +node globby async 0m0.527s 200000 +node current glob async mjs 0m0.502s 200000 +node current glob stream 0m0.481s 200000 + +--- pattern: '**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.588s 200023 +node globby sync 0m0.771s 200023 +node current globSync mjs 0m0.684s 200023 +node current glob syncStream 0m0.658s 200023 +~~ async ~~ +node fast-glob async 0m0.352s 200023 +node globby async 0m0.516s 200023 +node current glob async mjs 0m0.432s 200023 +node current glob stream 0m0.384s 200023 + +--- pattern: './**/**/**/**/**/**/**/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.589s 200023 +node globby sync 0m0.766s 200023 +node current globSync mjs 0m0.682s 200023 +node current glob syncStream 0m0.652s 200023 +~~ async ~~ +node fast-glob async 0m0.352s 200023 +node globby async 0m0.523s 200023 +node current glob async mjs 0m0.436s 200023 +node current glob stream 0m0.380s 200023 + +--- pattern: '**/*/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.592s 200023 +node globby sync 0m0.776s 200023 +node current globSync mjs 0m0.691s 200023 +node current glob syncStream 0m0.659s 200023 +~~ async ~~ +node fast-glob async 0m0.357s 200023 +node globby async 0m0.513s 200023 +node current glob async mjs 0m0.471s 200023 +node current glob stream 0m0.424s 200023 + +--- pattern: '**/*/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.585s 200023 +node globby sync 0m0.766s 200023 +node current globSync mjs 0m0.694s 200023 +node current glob syncStream 0m0.664s 200023 +~~ async ~~ +node fast-glob async 0m0.350s 200023 +node globby async 0m0.514s 200023 +node current glob async mjs 0m0.472s 200023 +node current glob stream 0m0.424s 200023 + +--- pattern: '**/[0-9]/**/*.txt' --- +~~ sync ~~ +node fast-glob sync 0m0.544s 100000 +node globby sync 0m0.636s 100000 +node current globSync mjs 0m0.626s 100000 +node current glob syncStream 0m0.621s 100000 +~~ async ~~ +node fast-glob async 0m0.322s 100000 +node globby async 0m0.404s 100000 +node current glob async mjs 0m0.360s 100000 +node current glob stream 0m0.352s 100000 +``` diff --git a/libs/events/node_modules/glob/package.json b/libs/events/node_modules/glob/package.json new file mode 100644 index 000000000..bbf1e98a0 --- /dev/null +++ b/libs/events/node_modules/glob/package.json @@ -0,0 +1,97 @@ +{ + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "name": "glob", + "description": "the most correct and second fastest glob implementation in JavaScript", + "version": "9.3.5", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "main": "./dist/cjs/index-cjs.js", + "module": "./dist/mjs/index.js", + "types": "./dist/mjs/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index-cjs.js" + } + } + }, + "files": [ + "dist" + ], + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "preprepare": "rm -rf dist", + "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json", + "postprepare": "bash fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts", + "prepublish": "npm run benchclean", + "profclean": "rm -f v8.log profile.txt", + "test-regen": "npm run profclean && TEST_REGEN=1 node --no-warnings --loader ts-node/esm test/00-setup.ts", + "prebench": "npm run prepare", + "bench": "bash benchmark.sh", + "preprof": "npm run prepare", + "prof": "bash prof.sh", + "benchclean": "node benchclean.js" + }, + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "devDependencies": { + "@types/node": "^18.11.18", + "@types/tap": "^15.0.7", + "c8": "^7.12.0", + "memfs": "^3.4.13", + "mkdirp": "^2.1.4", + "prettier": "^2.8.3", + "rimraf": "^4.1.3", + "tap": "^16.3.4", + "ts-node": "^10.9.1", + "typedoc": "^0.23.24", + "typescript": "^4.9.4" + }, + "tap": { + "before": "test/00-setup.ts", + "coverage": false, + "node-arg": [ + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false + }, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } +} diff --git a/libs/events/node_modules/handlebars/LICENSE b/libs/events/node_modules/handlebars/LICENSE new file mode 100644 index 000000000..4d9d5806f --- /dev/null +++ b/libs/events/node_modules/handlebars/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2011-2019 by Yehuda Katz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/handlebars/README.markdown b/libs/events/node_modules/handlebars/README.markdown new file mode 100644 index 000000000..a62ce1c1a --- /dev/null +++ b/libs/events/node_modules/handlebars/README.markdown @@ -0,0 +1,169 @@ +[![CI Build Status](https://github.com/handlebars-lang/handlebars.js/actions/workflows/ci.yml/badge.svg)](https://github.com/handlebars-lang/handlebars.js/actions/workflows/ci.yml) +[![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/handlebars/badge?style=rounded)](https://www.jsdelivr.com/package/npm/handlebars) +[![npm downloads](https://badgen.net/npm/dm/handlebars)](https://www.npmjs.com/package/handlebars) +[![npm version](https://badgen.net/npm/v/handlebars)](https://www.npmjs.com/package/handlebars) +[![Bundle size](https://badgen.net/bundlephobia/minzip/handlebars?label=minified%20%2B%20gzipped)](https://bundlephobia.com/package/handlebars) +[![Install size](https://packagephobia.com/badge?p=handlebars)](https://packagephobia.com/result?p=handlebars) + +Handlebars.js +============= + +Handlebars.js is an extension to the [Mustache templating +language](https://mustache.github.io/) created by Chris Wanstrath. +Handlebars.js and Mustache are both logicless templating languages that +keep the view and the code separated like we all know they should be. + +Checkout the official Handlebars docs site at +[https://handlebarsjs.com/](https://handlebarsjs.com) and the live demo at [http://tryhandlebarsjs.com/](http://tryhandlebarsjs.com/). + +Installing +---------- + +See our [installation documentation](https://handlebarsjs.com/installation/). + +Usage +----- +In general, the syntax of Handlebars.js templates is a superset +of Mustache templates. For basic syntax, check out the [Mustache +manpage](https://mustache.github.io/mustache.5.html). + +Once you have a template, use the `Handlebars.compile` method to compile +the template into a function. The generated function takes a context +argument, which will be used to render the template. + +```js +var source = "

Hello, my name is {{name}}. I am from {{hometown}}. I have " + + "{{kids.length}} kids:

" + + "
    {{#kids}}
  • {{name}} is {{age}}
  • {{/kids}}
"; +var template = Handlebars.compile(source); + +var data = { "name": "Alan", "hometown": "Somewhere, TX", + "kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]}; +var result = template(data); + +// Would render: +//

Hello, my name is Alan. I am from Somewhere, TX. I have 2 kids:

+//
    +//
  • Jimmy is 12
  • +//
  • Sally is 4
  • +//
+``` + +Full documentation and more examples are at [handlebarsjs.com](https://handlebarsjs.com/). + +Precompiling Templates +---------------------- + +Handlebars allows templates to be precompiled and included as javascript code rather than the handlebars template allowing for faster startup time. Full details are located [here](https://handlebarsjs.com/installation/precompilation.html). + +Differences Between Handlebars.js and Mustache +---------------------------------------------- +Handlebars.js adds a couple of additional features to make writing +templates easier and also changes a tiny detail of how partials work. + +- [Nested Paths](https://handlebarsjs.com/guide/expressions.html#path-expressions) +- [Helpers](https://handlebarsjs.com/guide/expressions.html#helpers) +- [Block Expressions](https://handlebarsjs.com/guide/block-helpers.html#basic-blocks) +- [Literal Values](https://handlebarsjs.com/guide/expressions.html#literal-segments) +- [Delimited Comments](https://handlebarsjs.com/guide/#template-comments) + +Block expressions have the same syntax as mustache sections but should not be confused with one another. Sections are akin to an implicit `each` or `with` statement depending on the input data and helpers are explicit pieces of code that are free to implement whatever behavior they like. The [mustache spec](https://mustache.github.io/mustache.5.html) defines the exact behavior of sections. In the case of name conflicts, helpers are given priority. + +### Compatibility + +There are a few Mustache behaviors that Handlebars does not implement. +- Handlebars deviates from Mustache slightly in that it does not perform recursive lookup by default. The compile time `compat` flag must be set to enable this functionality. Users should note that there is a performance cost for enabling this flag. The exact cost varies by template, but it's recommended that performance sensitive operations should avoid this mode and instead opt for explicit path references. +- The optional Mustache-style lambdas are not supported. Instead Handlebars provides its own lambda resolution that follows the behaviors of helpers. +- Alternative delimiters are not supported. + + +Supported Environments +---------------------- + +Handlebars has been designed to work in any ECMAScript 3 environment. This includes + +- Node.js +- Chrome +- Firefox +- Safari 5+ +- Opera 11+ +- IE 6+ + +Older versions and other runtimes are likely to work but have not been formally +tested. The compiler requires `JSON.stringify` to be implemented natively or via a polyfill. If using the precompiler this is not necessary. + +Performance +----------- + +In a rough performance test, precompiled Handlebars.js templates (in +the original version of Handlebars.js) rendered in about half the +time of Mustache templates. It would be a shame if it were any other +way, since they were precompiled, but the difference in architecture +does have some big performance advantages. Justin Marney, a.k.a. +[gotascii](http://github.com/gotascii), confirmed that with an +[independent test](http://sorescode.com/2010/09/12/benchmarks.html). The +rewritten Handlebars (current version) is faster than the old version, +with many performance tests being 5 to 7 times faster than the Mustache equivalent. + + +Upgrading +--------- + +See [release-notes.md](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md) for upgrade notes. + +Known Issues +------------ + +See [FAQ.md](https://github.com/handlebars-lang/handlebars.js/blob/master/FAQ.md) for known issues and common pitfalls. + + +Handlebars in the Wild +---------------------- + +* [Assemble](http://assemble.io), by [@jonschlinkert](https://github.com/jonschlinkert) + and [@doowb](https://github.com/doowb), is a static site generator that uses Handlebars.js + as its template engine. +* [Cory](https://github.com/leo/cory), by [@leo](https://github.com/leo), is another tiny static site generator +* [CoSchedule](http://coschedule.com) An editorial calendar for WordPress that uses Handlebars.js +* [dashbars](https://github.com/pismute/dashbars) A modern helper library for Handlebars.js. +* [Ember.js](http://www.emberjs.com) makes Handlebars.js the primary way to + structure your views, also with automatic data binding support. +* [Ghost](https://ghost.org/) Just a blogging platform. +* [handlebars_assets](http://github.com/leshill/handlebars_assets): A Rails Asset Pipeline gem + from Les Hill (@leshill). +* [handlebars-helpers](https://github.com/assemble/handlebars-helpers) is an extensive library + with 100+ handlebars helpers. +* [handlebars-layouts](https://github.com/shannonmoeller/handlebars-layouts) is a set of helpers which implement extendible and embeddable layout blocks as seen in other popular templating languages. +* [hbs](http://github.com/donpark/hbs): An Express.js view engine adapter for Handlebars.js, + from Don Park. +* [koa-hbs](https://github.com/jwilm/koa-hbs): [koa](https://github.com/koajs/koa) generator based + renderer for Handlebars.js. +* [jblotus](http://github.com/jblotus) created [http://tryhandlebarsjs.com](http://tryhandlebarsjs.com) + for anyone who would like to try out Handlebars.js in their browser. +* [jQuery plugin](http://71104.github.io/jquery-handlebars/): allows you to use + Handlebars.js with [jQuery](http://jquery.com/). +* [Lumbar](http://walmartlabs.github.io/lumbar) provides easy module-based template management for + handlebars projects. +* [Marionette.Handlebars](https://github.com/hashchange/marionette.handlebars) adds support for Handlebars and Mustache templates to Marionette. +* [sammy.js](http://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey, + supports Handlebars.js as one of its template plugins. +* [SproutCore](http://www.sproutcore.com) uses Handlebars.js as its main + templating engine, extending it with automatic data binding support. +* [YUI](http://yuilibrary.com/yui/docs/handlebars/) implements a port of handlebars +* [Swag](https://github.com/elving/swag) by [@elving](https://github.com/elving) is a growing collection of helpers for handlebars.js. Give your handlebars.js templates some swag son! +* [DOMBars](https://github.com/blakeembrey/dombars) is a DOM-based templating engine built on the Handlebars parser and runtime **DEPRECATED** +* [promised-handlebars](https://github.com/nknapp/promised-handlebars) is a wrapper for Handlebars that allows helpers to return Promises. +* [just-handlebars-helpers](https://github.com/leapfrogtechnology/just-handlebars-helpers) A fully tested lightweight package with common Handlebars helpers. + +External Resources +------------------ + +* [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070) + +Have a project using Handlebars? Send us a [pull request][pull-request]! + +License +------- +Handlebars.js is released under the MIT license. + +[pull-request]: https://github.com/handlebars-lang/handlebars.js/pull/new/master diff --git a/libs/events/node_modules/handlebars/bin/.eslintrc.js b/libs/events/node_modules/handlebars/bin/.eslintrc.js new file mode 100644 index 000000000..ad6e812aa --- /dev/null +++ b/libs/events/node_modules/handlebars/bin/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + rules: { + 'no-console': 0, + 'no-var': 0 + } +}; diff --git a/libs/events/node_modules/handlebars/bin/handlebars b/libs/events/node_modules/handlebars/bin/handlebars new file mode 100755 index 000000000..7749121d3 --- /dev/null +++ b/libs/events/node_modules/handlebars/bin/handlebars @@ -0,0 +1,176 @@ +#!/usr/bin/env node + +var argv = parseArgs({ + 'f': { + 'type': 'string', + 'description': 'Output File', + 'alias': 'output' + }, + 'map': { + 'type': 'string', + 'description': 'Source Map File' + }, + 'a': { + 'type': 'boolean', + 'description': 'Exports amd style (require.js)', + 'alias': 'amd' + }, + 'c': { + 'type': 'string', + 'description': 'Exports CommonJS style, path to Handlebars module', + 'alias': 'commonjs', + 'default': null + }, + 'h': { + 'type': 'string', + 'description': 'Path to handlebar.js (only valid for amd-style)', + 'alias': 'handlebarPath', + 'default': '' + }, + 'k': { + 'type': 'string', + 'description': 'Known helpers', + 'alias': 'known' + }, + 'o': { + 'type': 'boolean', + 'description': 'Known helpers only', + 'alias': 'knownOnly' + }, + 'm': { + 'type': 'boolean', + 'description': 'Minimize output', + 'alias': 'min' + }, + 'n': { + 'type': 'string', + 'description': 'Template namespace', + 'alias': 'namespace', + 'default': 'Handlebars.templates' + }, + 's': { + 'type': 'boolean', + 'description': 'Output template function only.', + 'alias': 'simple' + }, + 'N': { + 'type': 'string', + 'description': 'Name of passed string templates. Optional if running in a simple mode. Required when operating on multiple templates.', + 'alias': 'name' + }, + 'i': { + 'type': 'string', + 'description': 'Generates a template from the passed CLI argument.\n"-" is treated as a special value and causes stdin to be read for the template value.', + 'alias': 'string' + }, + 'r': { + 'type': 'string', + 'description': 'Template root. Base value that will be stripped from template names.', + 'alias': 'root' + }, + 'p': { + 'type': 'boolean', + 'description': 'Compiling a partial template', + 'alias': 'partial' + }, + 'd': { + 'type': 'boolean', + 'description': 'Include data when compiling', + 'alias': 'data' + }, + 'e': { + 'type': 'string', + 'description': 'Template extension.', + 'alias': 'extension', + 'default': 'handlebars' + }, + 'b': { + 'type': 'boolean', + 'description': 'Removes the BOM (Byte Order Mark) from the beginning of the templates.', + 'alias': 'bom' + }, + 'v': { + 'type': 'boolean', + 'description': 'Prints the current compiler version', + 'alias': 'version' + }, + 'help': { + 'type': 'boolean', + 'description': 'Outputs this message' + } +}); + +argv.files = argv._; +delete argv._; + +var Precompiler = require('../dist/cjs/precompiler'); +Precompiler.loadTemplates(argv, function(err, opts) { + + if (err) { + throw err; + } + + if (opts.help || (!opts.templates.length && !opts.version)) { + printUsage(argv._spec, 120); + } else { + Precompiler.cli(opts); + } +}); + +function pad(n) { + var str = ''; + while (str.length < n) { + str += ' '; + } + return str; +} + +function parseArgs(spec) { + var opts = { alias: {}, boolean: [], default: {}, string: [] }; + + Object.keys(spec).forEach(function (arg) { + var opt = spec[arg]; + opts[opt.type].push(arg); + if ('alias' in opt) opts.alias[arg] = opt.alias; + if ('default' in opt) opts.default[arg] = opt.default; + }); + + var argv = require('minimist')(process.argv.slice(2), opts); + argv._spec = spec; + return argv; +} + +function printUsage(spec, wrap) { + var wordwrap = require('wordwrap'); + + console.log('Precompile handlebar templates.'); + console.log('Usage: handlebars [template|directory]...'); + + var opts = []; + var width = 0; + Object.keys(spec).forEach(function (arg) { + var opt = spec[arg]; + + var name = (arg.length === 1 ? '-' : '--') + arg; + if ('alias' in opt) name += ', --' + opt.alias; + + var meta = '[' + opt.type + ']'; + if ('default' in opt) meta += ' [default: ' + JSON.stringify(opt.default) + ']'; + + opts.push({ name: name, desc: opt.description, meta: meta }); + if (name.length > width) width = name.length; + }); + + console.log('Options:'); + opts.forEach(function (opt) { + var desc = wordwrap(width + 4, wrap + 1)(opt.desc); + + console.log(' %s%s%s%s%s', + opt.name, + pad(width - opt.name.length + 2), + desc.slice(width + 4), + pad(wrap - opt.meta.length - desc.split(/\n/).pop().length), + opt.meta + ); + }); +} diff --git a/libs/events/node_modules/handlebars/lib/.eslintrc.js b/libs/events/node_modules/handlebars/lib/.eslintrc.js new file mode 100644 index 000000000..e55ad83c9 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + env: { + // Handlebars should not use node or browser-specific APIs + 'shared-node-browser': true, + node: false, + browser: false + } +}; diff --git a/libs/events/node_modules/handlebars/lib/handlebars.js b/libs/events/node_modules/handlebars/lib/handlebars.js new file mode 100644 index 000000000..c4f8fc781 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars.js @@ -0,0 +1,46 @@ +import runtime from './handlebars.runtime'; + +// Compiler imports +import AST from './handlebars/compiler/ast'; +import { + parser as Parser, + parse, + parseWithoutProcessing +} from './handlebars/compiler/base'; +import { Compiler, compile, precompile } from './handlebars/compiler/compiler'; +import JavaScriptCompiler from './handlebars/compiler/javascript-compiler'; +import Visitor from './handlebars/compiler/visitor'; + +import noConflict from './handlebars/no-conflict'; + +let _create = runtime.create; +function create() { + let hb = _create(); + + hb.compile = function(input, options) { + return compile(input, options, hb); + }; + hb.precompile = function(input, options) { + return precompile(input, options, hb); + }; + + hb.AST = AST; + hb.Compiler = Compiler; + hb.JavaScriptCompiler = JavaScriptCompiler; + hb.Parser = Parser; + hb.parse = parse; + hb.parseWithoutProcessing = parseWithoutProcessing; + + return hb; +} + +let inst = create(); +inst.create = create; + +noConflict(inst); + +inst.Visitor = Visitor; + +inst['default'] = inst; + +export default inst; diff --git a/libs/events/node_modules/handlebars/lib/handlebars.runtime.js b/libs/events/node_modules/handlebars/lib/handlebars.runtime.js new file mode 100644 index 000000000..3d05b5448 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars.runtime.js @@ -0,0 +1,37 @@ +import * as base from './handlebars/base'; + +// Each of these augment the Handlebars object. No need to setup here. +// (This is done to easily share code between commonjs and browse envs) +import SafeString from './handlebars/safe-string'; +import Exception from './handlebars/exception'; +import * as Utils from './handlebars/utils'; +import * as runtime from './handlebars/runtime'; + +import noConflict from './handlebars/no-conflict'; + +// For compatibility and usage outside of module systems, make the Handlebars object a namespace +function create() { + let hb = new base.HandlebarsEnvironment(); + + Utils.extend(hb, base); + hb.SafeString = SafeString; + hb.Exception = Exception; + hb.Utils = Utils; + hb.escapeExpression = Utils.escapeExpression; + + hb.VM = runtime; + hb.template = function(spec) { + return runtime.template(spec, hb); + }; + + return hb; +} + +let inst = create(); +inst.create = create; + +noConflict(inst); + +inst['default'] = inst; + +export default inst; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/base.js b/libs/events/node_modules/handlebars/lib/handlebars/base.js new file mode 100644 index 000000000..d6afe331d --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/base.js @@ -0,0 +1,94 @@ +import { createFrame, extend, toString } from './utils'; +import Exception from './exception'; +import { registerDefaultHelpers } from './helpers'; +import { registerDefaultDecorators } from './decorators'; +import logger from './logger'; +import { resetLoggedProperties } from './internal/proto-access'; + +export const VERSION = '4.7.8'; +export const COMPILER_REVISION = 8; +export const LAST_COMPATIBLE_COMPILER_REVISION = 7; + +export const REVISION_CHANGES = { + 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it + 2: '== 1.0.0-rc.3', + 3: '== 1.0.0-rc.4', + 4: '== 1.x.x', + 5: '== 2.0.0-alpha.x', + 6: '>= 2.0.0-beta.1', + 7: '>= 4.0.0 <4.3.0', + 8: '>= 4.3.0' +}; + +const objectType = '[object Object]'; + +export function HandlebarsEnvironment(helpers, partials, decorators) { + this.helpers = helpers || {}; + this.partials = partials || {}; + this.decorators = decorators || {}; + + registerDefaultHelpers(this); + registerDefaultDecorators(this); +} + +HandlebarsEnvironment.prototype = { + constructor: HandlebarsEnvironment, + + logger: logger, + log: logger.log, + + registerHelper: function(name, fn) { + if (toString.call(name) === objectType) { + if (fn) { + throw new Exception('Arg not supported with multiple helpers'); + } + extend(this.helpers, name); + } else { + this.helpers[name] = fn; + } + }, + unregisterHelper: function(name) { + delete this.helpers[name]; + }, + + registerPartial: function(name, partial) { + if (toString.call(name) === objectType) { + extend(this.partials, name); + } else { + if (typeof partial === 'undefined') { + throw new Exception( + `Attempting to register a partial called "${name}" as undefined` + ); + } + this.partials[name] = partial; + } + }, + unregisterPartial: function(name) { + delete this.partials[name]; + }, + + registerDecorator: function(name, fn) { + if (toString.call(name) === objectType) { + if (fn) { + throw new Exception('Arg not supported with multiple decorators'); + } + extend(this.decorators, name); + } else { + this.decorators[name] = fn; + } + }, + unregisterDecorator: function(name) { + delete this.decorators[name]; + }, + /** + * Reset the memory of illegal property accesses that have already been logged. + * @deprecated should only be used in handlebars test-cases + */ + resetLoggedPropertyAccesses() { + resetLoggedProperties(); + } +}; + +export let log = logger.log; + +export { createFrame, logger }; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/ast.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/ast.js new file mode 100644 index 000000000..d77629a52 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/ast.js @@ -0,0 +1,32 @@ +let AST = { + // Public API used to evaluate derived attributes regarding AST nodes + helpers: { + // a mustache is definitely a helper if: + // * it is an eligible helper, and + // * it has at least one parameter or hash segment + helperExpression: function(node) { + return ( + node.type === 'SubExpression' || + ((node.type === 'MustacheStatement' || + node.type === 'BlockStatement') && + !!((node.params && node.params.length) || node.hash)) + ); + }, + + scopedId: function(path) { + return /^\.|this\b/.test(path.original); + }, + + // an ID is simple if it only has one part, and that part is not + // `..` or `this`. + simpleId: function(path) { + return ( + path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth + ); + } + } +}; + +// Must be exported as an object rather than the root of the module as the jison lexer +// must modify the object to operate properly. +export default AST; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/base.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/base.js new file mode 100644 index 000000000..1dd5af1a4 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/base.js @@ -0,0 +1,34 @@ +import parser from './parser'; +import WhitespaceControl from './whitespace-control'; +import * as Helpers from './helpers'; +import { extend } from '../utils'; + +export { parser }; + +let yy = {}; +extend(yy, Helpers); + +export function parseWithoutProcessing(input, options) { + // Just return if an already-compiled AST was passed in. + if (input.type === 'Program') { + return input; + } + + parser.yy = yy; + + // Altering the shared object here, but this is ok as parser is a sync operation + yy.locInfo = function(locInfo) { + return new yy.SourceLocation(options && options.srcName, locInfo); + }; + + let ast = parser.parse(input); + + return ast; +} + +export function parse(input, options) { + let ast = parseWithoutProcessing(input, options); + let strip = new WhitespaceControl(options); + + return strip.accept(ast); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/code-gen.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/code-gen.js new file mode 100644 index 000000000..0ac38990e --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/code-gen.js @@ -0,0 +1,171 @@ +/* global define, require */ +import { isArray } from '../utils'; + +let SourceNode; + +try { + /* istanbul ignore next */ + if (typeof define !== 'function' || !define.amd) { + // We don't support this in AMD environments. For these environments, we assume that + // they are running on the browser and thus have no need for the source-map library. + let SourceMap = require('source-map'); + SourceNode = SourceMap.SourceNode; + } +} catch (err) { + /* NOP */ +} + +/* istanbul ignore if: tested but not covered in istanbul due to dist build */ +if (!SourceNode) { + SourceNode = function(line, column, srcFile, chunks) { + this.src = ''; + if (chunks) { + this.add(chunks); + } + }; + /* istanbul ignore next */ + SourceNode.prototype = { + add: function(chunks) { + if (isArray(chunks)) { + chunks = chunks.join(''); + } + this.src += chunks; + }, + prepend: function(chunks) { + if (isArray(chunks)) { + chunks = chunks.join(''); + } + this.src = chunks + this.src; + }, + toStringWithSourceMap: function() { + return { code: this.toString() }; + }, + toString: function() { + return this.src; + } + }; +} + +function castChunk(chunk, codeGen, loc) { + if (isArray(chunk)) { + let ret = []; + + for (let i = 0, len = chunk.length; i < len; i++) { + ret.push(codeGen.wrap(chunk[i], loc)); + } + return ret; + } else if (typeof chunk === 'boolean' || typeof chunk === 'number') { + // Handle primitives that the SourceNode will throw up on + return chunk + ''; + } + return chunk; +} + +function CodeGen(srcFile) { + this.srcFile = srcFile; + this.source = []; +} + +CodeGen.prototype = { + isEmpty() { + return !this.source.length; + }, + prepend: function(source, loc) { + this.source.unshift(this.wrap(source, loc)); + }, + push: function(source, loc) { + this.source.push(this.wrap(source, loc)); + }, + + merge: function() { + let source = this.empty(); + this.each(function(line) { + source.add([' ', line, '\n']); + }); + return source; + }, + + each: function(iter) { + for (let i = 0, len = this.source.length; i < len; i++) { + iter(this.source[i]); + } + }, + + empty: function() { + let loc = this.currentLocation || { start: {} }; + return new SourceNode(loc.start.line, loc.start.column, this.srcFile); + }, + wrap: function(chunk, loc = this.currentLocation || { start: {} }) { + if (chunk instanceof SourceNode) { + return chunk; + } + + chunk = castChunk(chunk, this, loc); + + return new SourceNode( + loc.start.line, + loc.start.column, + this.srcFile, + chunk + ); + }, + + functionCall: function(fn, type, params) { + params = this.generateList(params); + return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']); + }, + + quotedString: function(str) { + return ( + '"' + + (str + '') + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 + .replace(/\u2029/g, '\\u2029') + + '"' + ); + }, + + objectLiteral: function(obj) { + let pairs = []; + + Object.keys(obj).forEach(key => { + let value = castChunk(obj[key], this); + if (value !== 'undefined') { + pairs.push([this.quotedString(key), ':', value]); + } + }); + + let ret = this.generateList(pairs); + ret.prepend('{'); + ret.add('}'); + return ret; + }, + + generateList: function(entries) { + let ret = this.empty(); + + for (let i = 0, len = entries.length; i < len; i++) { + if (i) { + ret.add(','); + } + + ret.add(castChunk(entries[i], this)); + } + + return ret; + }, + + generateArray: function(entries) { + let ret = this.generateList(entries); + ret.prepend('['); + ret.add(']'); + + return ret; + } +}; + +export default CodeGen; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/compiler.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/compiler.js new file mode 100644 index 000000000..33bd2b11a --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/compiler.js @@ -0,0 +1,594 @@ +/* eslint-disable new-cap */ + +import Exception from '../exception'; +import { isArray, indexOf, extend } from '../utils'; +import AST from './ast'; + +const slice = [].slice; + +export function Compiler() {} + +// the foundHelper register will disambiguate helper lookup from finding a +// function in a context. This is necessary for mustache compatibility, which +// requires that context functions in blocks are evaluated by blockHelperMissing, +// and then proceed as if the resulting value was provided to blockHelperMissing. + +Compiler.prototype = { + compiler: Compiler, + + equals: function(other) { + let len = this.opcodes.length; + if (other.opcodes.length !== len) { + return false; + } + + for (let i = 0; i < len; i++) { + let opcode = this.opcodes[i], + otherOpcode = other.opcodes[i]; + if ( + opcode.opcode !== otherOpcode.opcode || + !argEquals(opcode.args, otherOpcode.args) + ) { + return false; + } + } + + // We know that length is the same between the two arrays because they are directly tied + // to the opcode behavior above. + len = this.children.length; + for (let i = 0; i < len; i++) { + if (!this.children[i].equals(other.children[i])) { + return false; + } + } + + return true; + }, + + guid: 0, + + compile: function(program, options) { + this.sourceNode = []; + this.opcodes = []; + this.children = []; + this.options = options; + this.stringParams = options.stringParams; + this.trackIds = options.trackIds; + + options.blockParams = options.blockParams || []; + + options.knownHelpers = extend( + Object.create(null), + { + helperMissing: true, + blockHelperMissing: true, + each: true, + if: true, + unless: true, + with: true, + log: true, + lookup: true + }, + options.knownHelpers + ); + + return this.accept(program); + }, + + compileProgram: function(program) { + let childCompiler = new this.compiler(), // eslint-disable-line new-cap + result = childCompiler.compile(program, this.options), + guid = this.guid++; + + this.usePartial = this.usePartial || result.usePartial; + + this.children[guid] = result; + this.useDepths = this.useDepths || result.useDepths; + + return guid; + }, + + accept: function(node) { + /* istanbul ignore next: Sanity code */ + if (!this[node.type]) { + throw new Exception('Unknown type: ' + node.type, node); + } + + this.sourceNode.unshift(node); + let ret = this[node.type](node); + this.sourceNode.shift(); + return ret; + }, + + Program: function(program) { + this.options.blockParams.unshift(program.blockParams); + + let body = program.body, + bodyLength = body.length; + for (let i = 0; i < bodyLength; i++) { + this.accept(body[i]); + } + + this.options.blockParams.shift(); + + this.isSimple = bodyLength === 1; + this.blockParams = program.blockParams ? program.blockParams.length : 0; + + return this; + }, + + BlockStatement: function(block) { + transformLiteralToPath(block); + + let program = block.program, + inverse = block.inverse; + + program = program && this.compileProgram(program); + inverse = inverse && this.compileProgram(inverse); + + let type = this.classifySexpr(block); + + if (type === 'helper') { + this.helperSexpr(block, program, inverse); + } else if (type === 'simple') { + this.simpleSexpr(block); + + // now that the simple mustache is resolved, we need to + // evaluate it by executing `blockHelperMissing` + this.opcode('pushProgram', program); + this.opcode('pushProgram', inverse); + this.opcode('emptyHash'); + this.opcode('blockValue', block.path.original); + } else { + this.ambiguousSexpr(block, program, inverse); + + // now that the simple mustache is resolved, we need to + // evaluate it by executing `blockHelperMissing` + this.opcode('pushProgram', program); + this.opcode('pushProgram', inverse); + this.opcode('emptyHash'); + this.opcode('ambiguousBlockValue'); + } + + this.opcode('append'); + }, + + DecoratorBlock(decorator) { + let program = decorator.program && this.compileProgram(decorator.program); + let params = this.setupFullMustacheParams(decorator, program, undefined), + path = decorator.path; + + this.useDecorators = true; + this.opcode('registerDecorator', params.length, path.original); + }, + + PartialStatement: function(partial) { + this.usePartial = true; + + let program = partial.program; + if (program) { + program = this.compileProgram(partial.program); + } + + let params = partial.params; + if (params.length > 1) { + throw new Exception( + 'Unsupported number of partial arguments: ' + params.length, + partial + ); + } else if (!params.length) { + if (this.options.explicitPartialContext) { + this.opcode('pushLiteral', 'undefined'); + } else { + params.push({ type: 'PathExpression', parts: [], depth: 0 }); + } + } + + let partialName = partial.name.original, + isDynamic = partial.name.type === 'SubExpression'; + if (isDynamic) { + this.accept(partial.name); + } + + this.setupFullMustacheParams(partial, program, undefined, true); + + let indent = partial.indent || ''; + if (this.options.preventIndent && indent) { + this.opcode('appendContent', indent); + indent = ''; + } + + this.opcode('invokePartial', isDynamic, partialName, indent); + this.opcode('append'); + }, + PartialBlockStatement: function(partialBlock) { + this.PartialStatement(partialBlock); + }, + + MustacheStatement: function(mustache) { + this.SubExpression(mustache); + + if (mustache.escaped && !this.options.noEscape) { + this.opcode('appendEscaped'); + } else { + this.opcode('append'); + } + }, + Decorator(decorator) { + this.DecoratorBlock(decorator); + }, + + ContentStatement: function(content) { + if (content.value) { + this.opcode('appendContent', content.value); + } + }, + + CommentStatement: function() {}, + + SubExpression: function(sexpr) { + transformLiteralToPath(sexpr); + let type = this.classifySexpr(sexpr); + + if (type === 'simple') { + this.simpleSexpr(sexpr); + } else if (type === 'helper') { + this.helperSexpr(sexpr); + } else { + this.ambiguousSexpr(sexpr); + } + }, + ambiguousSexpr: function(sexpr, program, inverse) { + let path = sexpr.path, + name = path.parts[0], + isBlock = program != null || inverse != null; + + this.opcode('getContext', path.depth); + + this.opcode('pushProgram', program); + this.opcode('pushProgram', inverse); + + path.strict = true; + this.accept(path); + + this.opcode('invokeAmbiguous', name, isBlock); + }, + + simpleSexpr: function(sexpr) { + let path = sexpr.path; + path.strict = true; + this.accept(path); + this.opcode('resolvePossibleLambda'); + }, + + helperSexpr: function(sexpr, program, inverse) { + let params = this.setupFullMustacheParams(sexpr, program, inverse), + path = sexpr.path, + name = path.parts[0]; + + if (this.options.knownHelpers[name]) { + this.opcode('invokeKnownHelper', params.length, name); + } else if (this.options.knownHelpersOnly) { + throw new Exception( + 'You specified knownHelpersOnly, but used the unknown helper ' + name, + sexpr + ); + } else { + path.strict = true; + path.falsy = true; + + this.accept(path); + this.opcode( + 'invokeHelper', + params.length, + path.original, + AST.helpers.simpleId(path) + ); + } + }, + + PathExpression: function(path) { + this.addDepth(path.depth); + this.opcode('getContext', path.depth); + + let name = path.parts[0], + scoped = AST.helpers.scopedId(path), + blockParamId = !path.depth && !scoped && this.blockParamIndex(name); + + if (blockParamId) { + this.opcode('lookupBlockParam', blockParamId, path.parts); + } else if (!name) { + // Context reference, i.e. `{{foo .}}` or `{{foo ..}}` + this.opcode('pushContext'); + } else if (path.data) { + this.options.data = true; + this.opcode('lookupData', path.depth, path.parts, path.strict); + } else { + this.opcode( + 'lookupOnContext', + path.parts, + path.falsy, + path.strict, + scoped + ); + } + }, + + StringLiteral: function(string) { + this.opcode('pushString', string.value); + }, + + NumberLiteral: function(number) { + this.opcode('pushLiteral', number.value); + }, + + BooleanLiteral: function(bool) { + this.opcode('pushLiteral', bool.value); + }, + + UndefinedLiteral: function() { + this.opcode('pushLiteral', 'undefined'); + }, + + NullLiteral: function() { + this.opcode('pushLiteral', 'null'); + }, + + Hash: function(hash) { + let pairs = hash.pairs, + i = 0, + l = pairs.length; + + this.opcode('pushHash'); + + for (; i < l; i++) { + this.pushParam(pairs[i].value); + } + while (i--) { + this.opcode('assignToHash', pairs[i].key); + } + this.opcode('popHash'); + }, + + // HELPERS + opcode: function(name) { + this.opcodes.push({ + opcode: name, + args: slice.call(arguments, 1), + loc: this.sourceNode[0].loc + }); + }, + + addDepth: function(depth) { + if (!depth) { + return; + } + + this.useDepths = true; + }, + + classifySexpr: function(sexpr) { + let isSimple = AST.helpers.simpleId(sexpr.path); + + let isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]); + + // a mustache is an eligible helper if: + // * its id is simple (a single part, not `this` or `..`) + let isHelper = !isBlockParam && AST.helpers.helperExpression(sexpr); + + // if a mustache is an eligible helper but not a definite + // helper, it is ambiguous, and will be resolved in a later + // pass or at runtime. + let isEligible = !isBlockParam && (isHelper || isSimple); + + // if ambiguous, we can possibly resolve the ambiguity now + // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc. + if (isEligible && !isHelper) { + let name = sexpr.path.parts[0], + options = this.options; + if (options.knownHelpers[name]) { + isHelper = true; + } else if (options.knownHelpersOnly) { + isEligible = false; + } + } + + if (isHelper) { + return 'helper'; + } else if (isEligible) { + return 'ambiguous'; + } else { + return 'simple'; + } + }, + + pushParams: function(params) { + for (let i = 0, l = params.length; i < l; i++) { + this.pushParam(params[i]); + } + }, + + pushParam: function(val) { + let value = val.value != null ? val.value : val.original || ''; + + if (this.stringParams) { + if (value.replace) { + value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.'); + } + + if (val.depth) { + this.addDepth(val.depth); + } + this.opcode('getContext', val.depth || 0); + this.opcode('pushStringParam', value, val.type); + + if (val.type === 'SubExpression') { + // SubExpressions get evaluated and passed in + // in string params mode. + this.accept(val); + } + } else { + if (this.trackIds) { + let blockParamIndex; + if (val.parts && !AST.helpers.scopedId(val) && !val.depth) { + blockParamIndex = this.blockParamIndex(val.parts[0]); + } + if (blockParamIndex) { + let blockParamChild = val.parts.slice(1).join('.'); + this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild); + } else { + value = val.original || value; + if (value.replace) { + value = value + .replace(/^this(?:\.|$)/, '') + .replace(/^\.\//, '') + .replace(/^\.$/, ''); + } + + this.opcode('pushId', val.type, value); + } + } + this.accept(val); + } + }, + + setupFullMustacheParams: function(sexpr, program, inverse, omitEmpty) { + let params = sexpr.params; + this.pushParams(params); + + this.opcode('pushProgram', program); + this.opcode('pushProgram', inverse); + + if (sexpr.hash) { + this.accept(sexpr.hash); + } else { + this.opcode('emptyHash', omitEmpty); + } + + return params; + }, + + blockParamIndex: function(name) { + for ( + let depth = 0, len = this.options.blockParams.length; + depth < len; + depth++ + ) { + let blockParams = this.options.blockParams[depth], + param = blockParams && indexOf(blockParams, name); + if (blockParams && param >= 0) { + return [depth, param]; + } + } + } +}; + +export function precompile(input, options, env) { + if ( + input == null || + (typeof input !== 'string' && input.type !== 'Program') + ) { + throw new Exception( + 'You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + + input + ); + } + + options = options || {}; + if (!('data' in options)) { + options.data = true; + } + if (options.compat) { + options.useDepths = true; + } + + let ast = env.parse(input, options), + environment = new env.Compiler().compile(ast, options); + return new env.JavaScriptCompiler().compile(environment, options); +} + +export function compile(input, options = {}, env) { + if ( + input == null || + (typeof input !== 'string' && input.type !== 'Program') + ) { + throw new Exception( + 'You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + + input + ); + } + + options = extend({}, options); + if (!('data' in options)) { + options.data = true; + } + if (options.compat) { + options.useDepths = true; + } + + let compiled; + + function compileInput() { + let ast = env.parse(input, options), + environment = new env.Compiler().compile(ast, options), + templateSpec = new env.JavaScriptCompiler().compile( + environment, + options, + undefined, + true + ); + return env.template(templateSpec); + } + + // Template is only compiled on first use and cached after that point. + function ret(context, execOptions) { + if (!compiled) { + compiled = compileInput(); + } + return compiled.call(this, context, execOptions); + } + ret._setup = function(setupOptions) { + if (!compiled) { + compiled = compileInput(); + } + return compiled._setup(setupOptions); + }; + ret._child = function(i, data, blockParams, depths) { + if (!compiled) { + compiled = compileInput(); + } + return compiled._child(i, data, blockParams, depths); + }; + return ret; +} + +function argEquals(a, b) { + if (a === b) { + return true; + } + + if (isArray(a) && isArray(b) && a.length === b.length) { + for (let i = 0; i < a.length; i++) { + if (!argEquals(a[i], b[i])) { + return false; + } + } + return true; + } +} + +function transformLiteralToPath(sexpr) { + if (!sexpr.path.parts) { + let literal = sexpr.path; + // Casting to string here to make false and 0 literal values play nicely with the rest + // of the system. + sexpr.path = { + type: 'PathExpression', + data: false, + depth: 0, + parts: [literal.original + ''], + original: literal.original + '', + loc: literal.loc + }; + } +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/helpers.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/helpers.js new file mode 100644 index 000000000..27033a1d5 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/helpers.js @@ -0,0 +1,219 @@ +import Exception from '../exception'; + +function validateClose(open, close) { + close = close.path ? close.path.original : close; + + if (open.path.original !== close) { + let errorNode = { loc: open.path.loc }; + + throw new Exception( + open.path.original + " doesn't match " + close, + errorNode + ); + } +} + +export function SourceLocation(source, locInfo) { + this.source = source; + this.start = { + line: locInfo.first_line, + column: locInfo.first_column + }; + this.end = { + line: locInfo.last_line, + column: locInfo.last_column + }; +} + +export function id(token) { + if (/^\[.*\]$/.test(token)) { + return token.substring(1, token.length - 1); + } else { + return token; + } +} + +export function stripFlags(open, close) { + return { + open: open.charAt(2) === '~', + close: close.charAt(close.length - 3) === '~' + }; +} + +export function stripComment(comment) { + return comment.replace(/^\{\{~?!-?-?/, '').replace(/-?-?~?\}\}$/, ''); +} + +export function preparePath(data, parts, loc) { + loc = this.locInfo(loc); + + let original = data ? '@' : '', + dig = [], + depth = 0; + + for (let i = 0, l = parts.length; i < l; i++) { + let part = parts[i].part, + // If we have [] syntax then we do not treat path references as operators, + // i.e. foo.[this] resolves to approximately context.foo['this'] + isLiteral = parts[i].original !== part; + original += (parts[i].separator || '') + part; + + if (!isLiteral && (part === '..' || part === '.' || part === 'this')) { + if (dig.length > 0) { + throw new Exception('Invalid path: ' + original, { loc }); + } else if (part === '..') { + depth++; + } + } else { + dig.push(part); + } + } + + return { + type: 'PathExpression', + data, + depth, + parts: dig, + original, + loc + }; +} + +export function prepareMustache(path, params, hash, open, strip, locInfo) { + // Must use charAt to support IE pre-10 + let escapeFlag = open.charAt(3) || open.charAt(2), + escaped = escapeFlag !== '{' && escapeFlag !== '&'; + + let decorator = /\*/.test(open); + return { + type: decorator ? 'Decorator' : 'MustacheStatement', + path, + params, + hash, + escaped, + strip, + loc: this.locInfo(locInfo) + }; +} + +export function prepareRawBlock(openRawBlock, contents, close, locInfo) { + validateClose(openRawBlock, close); + + locInfo = this.locInfo(locInfo); + let program = { + type: 'Program', + body: contents, + strip: {}, + loc: locInfo + }; + + return { + type: 'BlockStatement', + path: openRawBlock.path, + params: openRawBlock.params, + hash: openRawBlock.hash, + program, + openStrip: {}, + inverseStrip: {}, + closeStrip: {}, + loc: locInfo + }; +} + +export function prepareBlock( + openBlock, + program, + inverseAndProgram, + close, + inverted, + locInfo +) { + if (close && close.path) { + validateClose(openBlock, close); + } + + let decorator = /\*/.test(openBlock.open); + + program.blockParams = openBlock.blockParams; + + let inverse, inverseStrip; + + if (inverseAndProgram) { + if (decorator) { + throw new Exception( + 'Unexpected inverse block on decorator', + inverseAndProgram + ); + } + + if (inverseAndProgram.chain) { + inverseAndProgram.program.body[0].closeStrip = close.strip; + } + + inverseStrip = inverseAndProgram.strip; + inverse = inverseAndProgram.program; + } + + if (inverted) { + inverted = inverse; + inverse = program; + program = inverted; + } + + return { + type: decorator ? 'DecoratorBlock' : 'BlockStatement', + path: openBlock.path, + params: openBlock.params, + hash: openBlock.hash, + program, + inverse, + openStrip: openBlock.strip, + inverseStrip, + closeStrip: close && close.strip, + loc: this.locInfo(locInfo) + }; +} + +export function prepareProgram(statements, loc) { + if (!loc && statements.length) { + const firstLoc = statements[0].loc, + lastLoc = statements[statements.length - 1].loc; + + /* istanbul ignore else */ + if (firstLoc && lastLoc) { + loc = { + source: firstLoc.source, + start: { + line: firstLoc.start.line, + column: firstLoc.start.column + }, + end: { + line: lastLoc.end.line, + column: lastLoc.end.column + } + }; + } + } + + return { + type: 'Program', + body: statements, + strip: {}, + loc: loc + }; +} + +export function preparePartialBlock(open, program, close, locInfo) { + validateClose(open, close); + + return { + type: 'PartialBlockStatement', + name: open.path, + params: open.params, + hash: open.hash, + program, + openStrip: open.strip, + closeStrip: close && close.strip, + loc: this.locInfo(locInfo) + }; +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js new file mode 100644 index 000000000..7762412ef --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js @@ -0,0 +1,1293 @@ +import { COMPILER_REVISION, REVISION_CHANGES } from '../base'; +import Exception from '../exception'; +import { isArray } from '../utils'; +import CodeGen from './code-gen'; + +function Literal(value) { + this.value = value; +} + +function JavaScriptCompiler() {} + +JavaScriptCompiler.prototype = { + // PUBLIC API: You can override these methods in a subclass to provide + // alternative compiled forms for name lookup and buffering semantics + nameLookup: function(parent, name /*, type */) { + return this.internalNameLookup(parent, name); + }, + depthedLookup: function(name) { + return [ + this.aliasable('container.lookup'), + '(depths, ', + JSON.stringify(name), + ')' + ]; + }, + + compilerInfo: function() { + const revision = COMPILER_REVISION, + versions = REVISION_CHANGES[revision]; + return [revision, versions]; + }, + + appendToBuffer: function(source, location, explicit) { + // Force a source as this simplifies the merge logic. + if (!isArray(source)) { + source = [source]; + } + source = this.source.wrap(source, location); + + if (this.environment.isSimple) { + return ['return ', source, ';']; + } else if (explicit) { + // This is a case where the buffer operation occurs as a child of another + // construct, generally braces. We have to explicitly output these buffer + // operations to ensure that the emitted code goes in the correct location. + return ['buffer += ', source, ';']; + } else { + source.appendToBuffer = true; + return source; + } + }, + + initializeBuffer: function() { + return this.quotedString(''); + }, + // END PUBLIC API + internalNameLookup: function(parent, name) { + this.lookupPropertyFunctionIsUsed = true; + return ['lookupProperty(', parent, ',', JSON.stringify(name), ')']; + }, + + lookupPropertyFunctionIsUsed: false, + + compile: function(environment, options, context, asObject) { + this.environment = environment; + this.options = options; + this.stringParams = this.options.stringParams; + this.trackIds = this.options.trackIds; + this.precompile = !asObject; + + this.name = this.environment.name; + this.isChild = !!context; + this.context = context || { + decorators: [], + programs: [], + environments: [] + }; + + this.preamble(); + + this.stackSlot = 0; + this.stackVars = []; + this.aliases = {}; + this.registers = { list: [] }; + this.hashes = []; + this.compileStack = []; + this.inlineStack = []; + this.blockParams = []; + + this.compileChildren(environment, options); + + this.useDepths = + this.useDepths || + environment.useDepths || + environment.useDecorators || + this.options.compat; + this.useBlockParams = this.useBlockParams || environment.useBlockParams; + + let opcodes = environment.opcodes, + opcode, + firstLoc, + i, + l; + + for (i = 0, l = opcodes.length; i < l; i++) { + opcode = opcodes[i]; + + this.source.currentLocation = opcode.loc; + firstLoc = firstLoc || opcode.loc; + this[opcode.opcode].apply(this, opcode.args); + } + + // Flush any trailing content that might be pending. + this.source.currentLocation = firstLoc; + this.pushSource(''); + + /* istanbul ignore next */ + if (this.stackSlot || this.inlineStack.length || this.compileStack.length) { + throw new Exception('Compile completed with content left on stack'); + } + + if (!this.decorators.isEmpty()) { + this.useDecorators = true; + + this.decorators.prepend([ + 'var decorators = container.decorators, ', + this.lookupPropertyFunctionVarDeclaration(), + ';\n' + ]); + this.decorators.push('return fn;'); + + if (asObject) { + this.decorators = Function.apply(this, [ + 'fn', + 'props', + 'container', + 'depth0', + 'data', + 'blockParams', + 'depths', + this.decorators.merge() + ]); + } else { + this.decorators.prepend( + 'function(fn, props, container, depth0, data, blockParams, depths) {\n' + ); + this.decorators.push('}\n'); + this.decorators = this.decorators.merge(); + } + } else { + this.decorators = undefined; + } + + let fn = this.createFunctionContext(asObject); + if (!this.isChild) { + let ret = { + compiler: this.compilerInfo(), + main: fn + }; + + if (this.decorators) { + ret.main_d = this.decorators; // eslint-disable-line camelcase + ret.useDecorators = true; + } + + let { programs, decorators } = this.context; + for (i = 0, l = programs.length; i < l; i++) { + if (programs[i]) { + ret[i] = programs[i]; + if (decorators[i]) { + ret[i + '_d'] = decorators[i]; + ret.useDecorators = true; + } + } + } + + if (this.environment.usePartial) { + ret.usePartial = true; + } + if (this.options.data) { + ret.useData = true; + } + if (this.useDepths) { + ret.useDepths = true; + } + if (this.useBlockParams) { + ret.useBlockParams = true; + } + if (this.options.compat) { + ret.compat = true; + } + + if (!asObject) { + ret.compiler = JSON.stringify(ret.compiler); + + this.source.currentLocation = { start: { line: 1, column: 0 } }; + ret = this.objectLiteral(ret); + + if (options.srcName) { + ret = ret.toStringWithSourceMap({ file: options.destName }); + ret.map = ret.map && ret.map.toString(); + } else { + ret = ret.toString(); + } + } else { + ret.compilerOptions = this.options; + } + + return ret; + } else { + return fn; + } + }, + + preamble: function() { + // track the last context pushed into place to allow skipping the + // getContext opcode when it would be a noop + this.lastContext = 0; + this.source = new CodeGen(this.options.srcName); + this.decorators = new CodeGen(this.options.srcName); + }, + + createFunctionContext: function(asObject) { + let varDeclarations = ''; + + let locals = this.stackVars.concat(this.registers.list); + if (locals.length > 0) { + varDeclarations += ', ' + locals.join(', '); + } + + // Generate minimizer alias mappings + // + // When using true SourceNodes, this will update all references to the given alias + // as the source nodes are reused in situ. For the non-source node compilation mode, + // aliases will not be used, but this case is already being run on the client and + // we aren't concern about minimizing the template size. + let aliasCount = 0; + Object.keys(this.aliases).forEach(alias => { + let node = this.aliases[alias]; + if (node.children && node.referenceCount > 1) { + varDeclarations += ', alias' + ++aliasCount + '=' + alias; + node.children[0] = 'alias' + aliasCount; + } + }); + + if (this.lookupPropertyFunctionIsUsed) { + varDeclarations += ', ' + this.lookupPropertyFunctionVarDeclaration(); + } + + let params = ['container', 'depth0', 'helpers', 'partials', 'data']; + + if (this.useBlockParams || this.useDepths) { + params.push('blockParams'); + } + if (this.useDepths) { + params.push('depths'); + } + + // Perform a second pass over the output to merge content when possible + let source = this.mergeSource(varDeclarations); + + if (asObject) { + params.push(source); + + return Function.apply(this, params); + } else { + return this.source.wrap([ + 'function(', + params.join(','), + ') {\n ', + source, + '}' + ]); + } + }, + mergeSource: function(varDeclarations) { + let isSimple = this.environment.isSimple, + appendOnly = !this.forceBuffer, + appendFirst, + sourceSeen, + bufferStart, + bufferEnd; + this.source.each(line => { + if (line.appendToBuffer) { + if (bufferStart) { + line.prepend(' + '); + } else { + bufferStart = line; + } + bufferEnd = line; + } else { + if (bufferStart) { + if (!sourceSeen) { + appendFirst = true; + } else { + bufferStart.prepend('buffer += '); + } + bufferEnd.add(';'); + bufferStart = bufferEnd = undefined; + } + + sourceSeen = true; + if (!isSimple) { + appendOnly = false; + } + } + }); + + if (appendOnly) { + if (bufferStart) { + bufferStart.prepend('return '); + bufferEnd.add(';'); + } else if (!sourceSeen) { + this.source.push('return "";'); + } + } else { + varDeclarations += + ', buffer = ' + (appendFirst ? '' : this.initializeBuffer()); + + if (bufferStart) { + bufferStart.prepend('return buffer + '); + bufferEnd.add(';'); + } else { + this.source.push('return buffer;'); + } + } + + if (varDeclarations) { + this.source.prepend( + 'var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n') + ); + } + + return this.source.merge(); + }, + + lookupPropertyFunctionVarDeclaration: function() { + return ` + lookupProperty = container.lookupProperty || function(parent, propertyName) { + if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { + return parent[propertyName]; + } + return undefined + } + `.trim(); + }, + + // [blockValue] + // + // On stack, before: hash, inverse, program, value + // On stack, after: return value of blockHelperMissing + // + // The purpose of this opcode is to take a block of the form + // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and + // replace it on the stack with the result of properly + // invoking blockHelperMissing. + blockValue: function(name) { + let blockHelperMissing = this.aliasable( + 'container.hooks.blockHelperMissing' + ), + params = [this.contextName(0)]; + this.setupHelperArgs(name, 0, params); + + let blockName = this.popStack(); + params.splice(1, 0, blockName); + + this.push(this.source.functionCall(blockHelperMissing, 'call', params)); + }, + + // [ambiguousBlockValue] + // + // On stack, before: hash, inverse, program, value + // Compiler value, before: lastHelper=value of last found helper, if any + // On stack, after, if no lastHelper: same as [blockValue] + // On stack, after, if lastHelper: value + ambiguousBlockValue: function() { + // We're being a bit cheeky and reusing the options value from the prior exec + let blockHelperMissing = this.aliasable( + 'container.hooks.blockHelperMissing' + ), + params = [this.contextName(0)]; + this.setupHelperArgs('', 0, params, true); + + this.flushInline(); + + let current = this.topStack(); + params.splice(1, 0, current); + + this.pushSource([ + 'if (!', + this.lastHelper, + ') { ', + current, + ' = ', + this.source.functionCall(blockHelperMissing, 'call', params), + '}' + ]); + }, + + // [appendContent] + // + // On stack, before: ... + // On stack, after: ... + // + // Appends the string value of `content` to the current buffer + appendContent: function(content) { + if (this.pendingContent) { + content = this.pendingContent + content; + } else { + this.pendingLocation = this.source.currentLocation; + } + + this.pendingContent = content; + }, + + // [append] + // + // On stack, before: value, ... + // On stack, after: ... + // + // Coerces `value` to a String and appends it to the current buffer. + // + // If `value` is truthy, or 0, it is coerced into a string and appended + // Otherwise, the empty string is appended + append: function() { + if (this.isInline()) { + this.replaceStack(current => [' != null ? ', current, ' : ""']); + + this.pushSource(this.appendToBuffer(this.popStack())); + } else { + let local = this.popStack(); + this.pushSource([ + 'if (', + local, + ' != null) { ', + this.appendToBuffer(local, undefined, true), + ' }' + ]); + if (this.environment.isSimple) { + this.pushSource([ + 'else { ', + this.appendToBuffer("''", undefined, true), + ' }' + ]); + } + } + }, + + // [appendEscaped] + // + // On stack, before: value, ... + // On stack, after: ... + // + // Escape `value` and append it to the buffer + appendEscaped: function() { + this.pushSource( + this.appendToBuffer([ + this.aliasable('container.escapeExpression'), + '(', + this.popStack(), + ')' + ]) + ); + }, + + // [getContext] + // + // On stack, before: ... + // On stack, after: ... + // Compiler value, after: lastContext=depth + // + // Set the value of the `lastContext` compiler value to the depth + getContext: function(depth) { + this.lastContext = depth; + }, + + // [pushContext] + // + // On stack, before: ... + // On stack, after: currentContext, ... + // + // Pushes the value of the current context onto the stack. + pushContext: function() { + this.pushStackLiteral(this.contextName(this.lastContext)); + }, + + // [lookupOnContext] + // + // On stack, before: ... + // On stack, after: currentContext[name], ... + // + // Looks up the value of `name` on the current context and pushes + // it onto the stack. + lookupOnContext: function(parts, falsy, strict, scoped) { + let i = 0; + + if (!scoped && this.options.compat && !this.lastContext) { + // The depthed query is expected to handle the undefined logic for the root level that + // is implemented below, so we evaluate that directly in compat mode + this.push(this.depthedLookup(parts[i++])); + } else { + this.pushContext(); + } + + this.resolvePath('context', parts, i, falsy, strict); + }, + + // [lookupBlockParam] + // + // On stack, before: ... + // On stack, after: blockParam[name], ... + // + // Looks up the value of `parts` on the given block param and pushes + // it onto the stack. + lookupBlockParam: function(blockParamId, parts) { + this.useBlockParams = true; + + this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']); + this.resolvePath('context', parts, 1); + }, + + // [lookupData] + // + // On stack, before: ... + // On stack, after: data, ... + // + // Push the data lookup operator + lookupData: function(depth, parts, strict) { + if (!depth) { + this.pushStackLiteral('data'); + } else { + this.pushStackLiteral('container.data(data, ' + depth + ')'); + } + + this.resolvePath('data', parts, 0, true, strict); + }, + + resolvePath: function(type, parts, i, falsy, strict) { + if (this.options.strict || this.options.assumeObjects) { + this.push( + strictLookup(this.options.strict && strict, this, parts, i, type) + ); + return; + } + + let len = parts.length; + for (; i < len; i++) { + /* eslint-disable no-loop-func */ + this.replaceStack(current => { + let lookup = this.nameLookup(current, parts[i], type); + // We want to ensure that zero and false are handled properly if the context (falsy flag) + // needs to have the special handling for these values. + if (!falsy) { + return [' != null ? ', lookup, ' : ', current]; + } else { + // Otherwise we can use generic falsy handling + return [' && ', lookup]; + } + }); + /* eslint-enable no-loop-func */ + } + }, + + // [resolvePossibleLambda] + // + // On stack, before: value, ... + // On stack, after: resolved value, ... + // + // If the `value` is a lambda, replace it on the stack by + // the return value of the lambda + resolvePossibleLambda: function() { + this.push([ + this.aliasable('container.lambda'), + '(', + this.popStack(), + ', ', + this.contextName(0), + ')' + ]); + }, + + // [pushStringParam] + // + // On stack, before: ... + // On stack, after: string, currentContext, ... + // + // This opcode is designed for use in string mode, which + // provides the string value of a parameter along with its + // depth rather than resolving it immediately. + pushStringParam: function(string, type) { + this.pushContext(); + this.pushString(type); + + // If it's a subexpression, the string result + // will be pushed after this opcode. + if (type !== 'SubExpression') { + if (typeof string === 'string') { + this.pushString(string); + } else { + this.pushStackLiteral(string); + } + } + }, + + emptyHash: function(omitEmpty) { + if (this.trackIds) { + this.push('{}'); // hashIds + } + if (this.stringParams) { + this.push('{}'); // hashContexts + this.push('{}'); // hashTypes + } + this.pushStackLiteral(omitEmpty ? 'undefined' : '{}'); + }, + pushHash: function() { + if (this.hash) { + this.hashes.push(this.hash); + } + this.hash = { values: {}, types: [], contexts: [], ids: [] }; + }, + popHash: function() { + let hash = this.hash; + this.hash = this.hashes.pop(); + + if (this.trackIds) { + this.push(this.objectLiteral(hash.ids)); + } + if (this.stringParams) { + this.push(this.objectLiteral(hash.contexts)); + this.push(this.objectLiteral(hash.types)); + } + + this.push(this.objectLiteral(hash.values)); + }, + + // [pushString] + // + // On stack, before: ... + // On stack, after: quotedString(string), ... + // + // Push a quoted version of `string` onto the stack + pushString: function(string) { + this.pushStackLiteral(this.quotedString(string)); + }, + + // [pushLiteral] + // + // On stack, before: ... + // On stack, after: value, ... + // + // Pushes a value onto the stack. This operation prevents + // the compiler from creating a temporary variable to hold + // it. + pushLiteral: function(value) { + this.pushStackLiteral(value); + }, + + // [pushProgram] + // + // On stack, before: ... + // On stack, after: program(guid), ... + // + // Push a program expression onto the stack. This takes + // a compile-time guid and converts it into a runtime-accessible + // expression. + pushProgram: function(guid) { + if (guid != null) { + this.pushStackLiteral(this.programExpression(guid)); + } else { + this.pushStackLiteral(null); + } + }, + + // [registerDecorator] + // + // On stack, before: hash, program, params..., ... + // On stack, after: ... + // + // Pops off the decorator's parameters, invokes the decorator, + // and inserts the decorator into the decorators list. + registerDecorator(paramSize, name) { + let foundDecorator = this.nameLookup('decorators', name, 'decorator'), + options = this.setupHelperArgs(name, paramSize); + + this.decorators.push([ + 'fn = ', + this.decorators.functionCall(foundDecorator, '', [ + 'fn', + 'props', + 'container', + options + ]), + ' || fn;' + ]); + }, + + // [invokeHelper] + // + // On stack, before: hash, inverse, program, params..., ... + // On stack, after: result of helper invocation + // + // Pops off the helper's parameters, invokes the helper, + // and pushes the helper's return value onto the stack. + // + // If the helper is not found, `helperMissing` is called. + invokeHelper: function(paramSize, name, isSimple) { + let nonHelper = this.popStack(), + helper = this.setupHelper(paramSize, name); + + let possibleFunctionCalls = []; + + if (isSimple) { + // direct call to helper + possibleFunctionCalls.push(helper.name); + } + // call a function from the input object + possibleFunctionCalls.push(nonHelper); + if (!this.options.strict) { + possibleFunctionCalls.push( + this.aliasable('container.hooks.helperMissing') + ); + } + + let functionLookupCode = [ + '(', + this.itemsSeparatedBy(possibleFunctionCalls, '||'), + ')' + ]; + let functionCall = this.source.functionCall( + functionLookupCode, + 'call', + helper.callParams + ); + this.push(functionCall); + }, + + itemsSeparatedBy: function(items, separator) { + let result = []; + result.push(items[0]); + for (let i = 1; i < items.length; i++) { + result.push(separator, items[i]); + } + return result; + }, + // [invokeKnownHelper] + // + // On stack, before: hash, inverse, program, params..., ... + // On stack, after: result of helper invocation + // + // This operation is used when the helper is known to exist, + // so a `helperMissing` fallback is not required. + invokeKnownHelper: function(paramSize, name) { + let helper = this.setupHelper(paramSize, name); + this.push(this.source.functionCall(helper.name, 'call', helper.callParams)); + }, + + // [invokeAmbiguous] + // + // On stack, before: hash, inverse, program, params..., ... + // On stack, after: result of disambiguation + // + // This operation is used when an expression like `{{foo}}` + // is provided, but we don't know at compile-time whether it + // is a helper or a path. + // + // This operation emits more code than the other options, + // and can be avoided by passing the `knownHelpers` and + // `knownHelpersOnly` flags at compile-time. + invokeAmbiguous: function(name, helperCall) { + this.useRegister('helper'); + + let nonHelper = this.popStack(); + + this.emptyHash(); + let helper = this.setupHelper(0, name, helperCall); + + let helperName = (this.lastHelper = this.nameLookup( + 'helpers', + name, + 'helper' + )); + + let lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')']; + if (!this.options.strict) { + lookup[0] = '(helper = '; + lookup.push( + ' != null ? helper : ', + this.aliasable('container.hooks.helperMissing') + ); + } + + this.push([ + '(', + lookup, + helper.paramsInit ? ['),(', helper.paramsInit] : [], + '),', + '(typeof helper === ', + this.aliasable('"function"'), + ' ? ', + this.source.functionCall('helper', 'call', helper.callParams), + ' : helper))' + ]); + }, + + // [invokePartial] + // + // On stack, before: context, ... + // On stack after: result of partial invocation + // + // This operation pops off a context, invokes a partial with that context, + // and pushes the result of the invocation back. + invokePartial: function(isDynamic, name, indent) { + let params = [], + options = this.setupParams(name, 1, params); + + if (isDynamic) { + name = this.popStack(); + delete options.name; + } + + if (indent) { + options.indent = JSON.stringify(indent); + } + options.helpers = 'helpers'; + options.partials = 'partials'; + options.decorators = 'container.decorators'; + + if (!isDynamic) { + params.unshift(this.nameLookup('partials', name, 'partial')); + } else { + params.unshift(name); + } + + if (this.options.compat) { + options.depths = 'depths'; + } + options = this.objectLiteral(options); + params.push(options); + + this.push(this.source.functionCall('container.invokePartial', '', params)); + }, + + // [assignToHash] + // + // On stack, before: value, ..., hash, ... + // On stack, after: ..., hash, ... + // + // Pops a value off the stack and assigns it to the current hash + assignToHash: function(key) { + let value = this.popStack(), + context, + type, + id; + + if (this.trackIds) { + id = this.popStack(); + } + if (this.stringParams) { + type = this.popStack(); + context = this.popStack(); + } + + let hash = this.hash; + if (context) { + hash.contexts[key] = context; + } + if (type) { + hash.types[key] = type; + } + if (id) { + hash.ids[key] = id; + } + hash.values[key] = value; + }, + + pushId: function(type, name, child) { + if (type === 'BlockParam') { + this.pushStackLiteral( + 'blockParams[' + + name[0] + + '].path[' + + name[1] + + ']' + + (child ? ' + ' + JSON.stringify('.' + child) : '') + ); + } else if (type === 'PathExpression') { + this.pushString(name); + } else if (type === 'SubExpression') { + this.pushStackLiteral('true'); + } else { + this.pushStackLiteral('null'); + } + }, + + // HELPERS + + compiler: JavaScriptCompiler, + + compileChildren: function(environment, options) { + let children = environment.children, + child, + compiler; + + for (let i = 0, l = children.length; i < l; i++) { + child = children[i]; + compiler = new this.compiler(); // eslint-disable-line new-cap + + let existing = this.matchExistingProgram(child); + + if (existing == null) { + this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children + let index = this.context.programs.length; + child.index = index; + child.name = 'program' + index; + this.context.programs[index] = compiler.compile( + child, + options, + this.context, + !this.precompile + ); + this.context.decorators[index] = compiler.decorators; + this.context.environments[index] = child; + + this.useDepths = this.useDepths || compiler.useDepths; + this.useBlockParams = this.useBlockParams || compiler.useBlockParams; + child.useDepths = this.useDepths; + child.useBlockParams = this.useBlockParams; + } else { + child.index = existing.index; + child.name = 'program' + existing.index; + + this.useDepths = this.useDepths || existing.useDepths; + this.useBlockParams = this.useBlockParams || existing.useBlockParams; + } + } + }, + matchExistingProgram: function(child) { + for (let i = 0, len = this.context.environments.length; i < len; i++) { + let environment = this.context.environments[i]; + if (environment && environment.equals(child)) { + return environment; + } + } + }, + + programExpression: function(guid) { + let child = this.environment.children[guid], + programParams = [child.index, 'data', child.blockParams]; + + if (this.useBlockParams || this.useDepths) { + programParams.push('blockParams'); + } + if (this.useDepths) { + programParams.push('depths'); + } + + return 'container.program(' + programParams.join(', ') + ')'; + }, + + useRegister: function(name) { + if (!this.registers[name]) { + this.registers[name] = true; + this.registers.list.push(name); + } + }, + + push: function(expr) { + if (!(expr instanceof Literal)) { + expr = this.source.wrap(expr); + } + + this.inlineStack.push(expr); + return expr; + }, + + pushStackLiteral: function(item) { + this.push(new Literal(item)); + }, + + pushSource: function(source) { + if (this.pendingContent) { + this.source.push( + this.appendToBuffer( + this.source.quotedString(this.pendingContent), + this.pendingLocation + ) + ); + this.pendingContent = undefined; + } + + if (source) { + this.source.push(source); + } + }, + + replaceStack: function(callback) { + let prefix = ['('], + stack, + createdStack, + usedLiteral; + + /* istanbul ignore next */ + if (!this.isInline()) { + throw new Exception('replaceStack on non-inline'); + } + + // We want to merge the inline statement into the replacement statement via ',' + let top = this.popStack(true); + + if (top instanceof Literal) { + // Literals do not need to be inlined + stack = [top.value]; + prefix = ['(', stack]; + usedLiteral = true; + } else { + // Get or create the current stack name for use by the inline + createdStack = true; + let name = this.incrStack(); + + prefix = ['((', this.push(name), ' = ', top, ')']; + stack = this.topStack(); + } + + let item = callback.call(this, stack); + + if (!usedLiteral) { + this.popStack(); + } + if (createdStack) { + this.stackSlot--; + } + this.push(prefix.concat(item, ')')); + }, + + incrStack: function() { + this.stackSlot++; + if (this.stackSlot > this.stackVars.length) { + this.stackVars.push('stack' + this.stackSlot); + } + return this.topStackName(); + }, + topStackName: function() { + return 'stack' + this.stackSlot; + }, + flushInline: function() { + let inlineStack = this.inlineStack; + this.inlineStack = []; + for (let i = 0, len = inlineStack.length; i < len; i++) { + let entry = inlineStack[i]; + /* istanbul ignore if */ + if (entry instanceof Literal) { + this.compileStack.push(entry); + } else { + let stack = this.incrStack(); + this.pushSource([stack, ' = ', entry, ';']); + this.compileStack.push(stack); + } + } + }, + isInline: function() { + return this.inlineStack.length; + }, + + popStack: function(wrapped) { + let inline = this.isInline(), + item = (inline ? this.inlineStack : this.compileStack).pop(); + + if (!wrapped && item instanceof Literal) { + return item.value; + } else { + if (!inline) { + /* istanbul ignore next */ + if (!this.stackSlot) { + throw new Exception('Invalid stack pop'); + } + this.stackSlot--; + } + return item; + } + }, + + topStack: function() { + let stack = this.isInline() ? this.inlineStack : this.compileStack, + item = stack[stack.length - 1]; + + /* istanbul ignore if */ + if (item instanceof Literal) { + return item.value; + } else { + return item; + } + }, + + contextName: function(context) { + if (this.useDepths && context) { + return 'depths[' + context + ']'; + } else { + return 'depth' + context; + } + }, + + quotedString: function(str) { + return this.source.quotedString(str); + }, + + objectLiteral: function(obj) { + return this.source.objectLiteral(obj); + }, + + aliasable: function(name) { + let ret = this.aliases[name]; + if (ret) { + ret.referenceCount++; + return ret; + } + + ret = this.aliases[name] = this.source.wrap(name); + ret.aliasable = true; + ret.referenceCount = 1; + + return ret; + }, + + setupHelper: function(paramSize, name, blockHelper) { + let params = [], + paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper); + let foundHelper = this.nameLookup('helpers', name, 'helper'), + callContext = this.aliasable( + `${this.contextName(0)} != null ? ${this.contextName( + 0 + )} : (container.nullContext || {})` + ); + + return { + params: params, + paramsInit: paramsInit, + name: foundHelper, + callParams: [callContext].concat(params) + }; + }, + + setupParams: function(helper, paramSize, params) { + let options = {}, + contexts = [], + types = [], + ids = [], + objectArgs = !params, + param; + + if (objectArgs) { + params = []; + } + + options.name = this.quotedString(helper); + options.hash = this.popStack(); + + if (this.trackIds) { + options.hashIds = this.popStack(); + } + if (this.stringParams) { + options.hashTypes = this.popStack(); + options.hashContexts = this.popStack(); + } + + let inverse = this.popStack(), + program = this.popStack(); + + // Avoid setting fn and inverse if neither are set. This allows + // helpers to do a check for `if (options.fn)` + if (program || inverse) { + options.fn = program || 'container.noop'; + options.inverse = inverse || 'container.noop'; + } + + // The parameters go on to the stack in order (making sure that they are evaluated in order) + // so we need to pop them off the stack in reverse order + let i = paramSize; + while (i--) { + param = this.popStack(); + params[i] = param; + + if (this.trackIds) { + ids[i] = this.popStack(); + } + if (this.stringParams) { + types[i] = this.popStack(); + contexts[i] = this.popStack(); + } + } + + if (objectArgs) { + options.args = this.source.generateArray(params); + } + + if (this.trackIds) { + options.ids = this.source.generateArray(ids); + } + if (this.stringParams) { + options.types = this.source.generateArray(types); + options.contexts = this.source.generateArray(contexts); + } + + if (this.options.data) { + options.data = 'data'; + } + if (this.useBlockParams) { + options.blockParams = 'blockParams'; + } + return options; + }, + + setupHelperArgs: function(helper, paramSize, params, useRegister) { + let options = this.setupParams(helper, paramSize, params); + options.loc = JSON.stringify(this.source.currentLocation); + options = this.objectLiteral(options); + if (useRegister) { + this.useRegister('options'); + params.push('options'); + return ['options=', options]; + } else if (params) { + params.push(options); + return ''; + } else { + return options; + } + } +}; + +(function() { + const reservedWords = ( + 'break else new var' + + ' case finally return void' + + ' catch for switch while' + + ' continue function this with' + + ' default if throw' + + ' delete in try' + + ' do instanceof typeof' + + ' abstract enum int short' + + ' boolean export interface static' + + ' byte extends long super' + + ' char final native synchronized' + + ' class float package throws' + + ' const goto private transient' + + ' debugger implements protected volatile' + + ' double import public let yield await' + + ' null true false' + ).split(' '); + + const compilerWords = (JavaScriptCompiler.RESERVED_WORDS = {}); + + for (let i = 0, l = reservedWords.length; i < l; i++) { + compilerWords[reservedWords[i]] = true; + } +})(); + +/** + * @deprecated May be removed in the next major version + */ +JavaScriptCompiler.isValidJavaScriptVariableName = function(name) { + return ( + !JavaScriptCompiler.RESERVED_WORDS[name] && + /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name) + ); +}; + +function strictLookup(requireTerminal, compiler, parts, i, type) { + let stack = compiler.popStack(), + len = parts.length; + if (requireTerminal) { + len--; + } + + for (; i < len; i++) { + stack = compiler.nameLookup(stack, parts[i], type); + } + + if (requireTerminal) { + return [ + compiler.aliasable('container.strict'), + '(', + stack, + ', ', + compiler.quotedString(parts[i]), + ', ', + JSON.stringify(compiler.source.currentLocation), + ' )' + ]; + } else { + return stack; + } +} + +export default JavaScriptCompiler; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/parser.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/parser.js new file mode 100644 index 000000000..c990f8042 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/parser.js @@ -0,0 +1,622 @@ +// File ignored in coverage tests via setting in .istanbul.yml +/* Jison generated parser */ +var handlebars = (function(){ +var parser = {trace: function trace () { }, +yy: {}, +symbols_: {"error":2,"root":3,"program":4,"EOF":5,"program_repetition0":6,"statement":7,"mustache":8,"block":9,"rawBlock":10,"partial":11,"partialBlock":12,"content":13,"COMMENT":14,"CONTENT":15,"openRawBlock":16,"rawBlock_repetition0":17,"END_RAW_BLOCK":18,"OPEN_RAW_BLOCK":19,"helperName":20,"openRawBlock_repetition0":21,"openRawBlock_option0":22,"CLOSE_RAW_BLOCK":23,"openBlock":24,"block_option0":25,"closeBlock":26,"openInverse":27,"block_option1":28,"OPEN_BLOCK":29,"openBlock_repetition0":30,"openBlock_option0":31,"openBlock_option1":32,"CLOSE":33,"OPEN_INVERSE":34,"openInverse_repetition0":35,"openInverse_option0":36,"openInverse_option1":37,"openInverseChain":38,"OPEN_INVERSE_CHAIN":39,"openInverseChain_repetition0":40,"openInverseChain_option0":41,"openInverseChain_option1":42,"inverseAndProgram":43,"INVERSE":44,"inverseChain":45,"inverseChain_option0":46,"OPEN_ENDBLOCK":47,"OPEN":48,"mustache_repetition0":49,"mustache_option0":50,"OPEN_UNESCAPED":51,"mustache_repetition1":52,"mustache_option1":53,"CLOSE_UNESCAPED":54,"OPEN_PARTIAL":55,"partialName":56,"partial_repetition0":57,"partial_option0":58,"openPartialBlock":59,"OPEN_PARTIAL_BLOCK":60,"openPartialBlock_repetition0":61,"openPartialBlock_option0":62,"param":63,"sexpr":64,"OPEN_SEXPR":65,"sexpr_repetition0":66,"sexpr_option0":67,"CLOSE_SEXPR":68,"hash":69,"hash_repetition_plus0":70,"hashSegment":71,"ID":72,"EQUALS":73,"blockParams":74,"OPEN_BLOCK_PARAMS":75,"blockParams_repetition_plus0":76,"CLOSE_BLOCK_PARAMS":77,"path":78,"dataName":79,"STRING":80,"NUMBER":81,"BOOLEAN":82,"UNDEFINED":83,"NULL":84,"DATA":85,"pathSegments":86,"SEP":87,"$accept":0,"$end":1}, +terminals_: {2:"error",5:"EOF",14:"COMMENT",15:"CONTENT",18:"END_RAW_BLOCK",19:"OPEN_RAW_BLOCK",23:"CLOSE_RAW_BLOCK",29:"OPEN_BLOCK",33:"CLOSE",34:"OPEN_INVERSE",39:"OPEN_INVERSE_CHAIN",44:"INVERSE",47:"OPEN_ENDBLOCK",48:"OPEN",51:"OPEN_UNESCAPED",54:"CLOSE_UNESCAPED",55:"OPEN_PARTIAL",60:"OPEN_PARTIAL_BLOCK",65:"OPEN_SEXPR",68:"CLOSE_SEXPR",72:"ID",73:"EQUALS",75:"OPEN_BLOCK_PARAMS",77:"CLOSE_BLOCK_PARAMS",80:"STRING",81:"NUMBER",82:"BOOLEAN",83:"UNDEFINED",84:"NULL",85:"DATA",87:"SEP"}, +productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[13,1],[10,3],[16,5],[9,4],[9,4],[24,6],[27,6],[38,6],[43,2],[45,3],[45,1],[26,3],[8,5],[8,5],[11,5],[12,3],[59,5],[63,1],[63,1],[64,5],[69,1],[71,3],[74,3],[20,1],[20,1],[20,1],[20,1],[20,1],[20,1],[20,1],[56,1],[56,1],[79,2],[78,1],[86,3],[86,1],[6,0],[6,2],[17,0],[17,2],[21,0],[21,2],[22,0],[22,1],[25,0],[25,1],[28,0],[28,1],[30,0],[30,2],[31,0],[31,1],[32,0],[32,1],[35,0],[35,2],[36,0],[36,1],[37,0],[37,1],[40,0],[40,2],[41,0],[41,1],[42,0],[42,1],[46,0],[46,1],[49,0],[49,2],[50,0],[50,1],[52,0],[52,2],[53,0],[53,1],[57,0],[57,2],[58,0],[58,1],[61,0],[61,2],[62,0],[62,1],[66,0],[66,2],[67,0],[67,1],[70,1],[70,2],[76,1],[76,2]], +performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$ +) { + +var $0 = $$.length - 1; +switch (yystate) { +case 1: return $$[$0-1]; +break; +case 2:this.$ = yy.prepareProgram($$[$0]); +break; +case 3:this.$ = $$[$0]; +break; +case 4:this.$ = $$[$0]; +break; +case 5:this.$ = $$[$0]; +break; +case 6:this.$ = $$[$0]; +break; +case 7:this.$ = $$[$0]; +break; +case 8:this.$ = $$[$0]; +break; +case 9: + this.$ = { + type: 'CommentStatement', + value: yy.stripComment($$[$0]), + strip: yy.stripFlags($$[$0], $$[$0]), + loc: yy.locInfo(this._$) + }; + +break; +case 10: + this.$ = { + type: 'ContentStatement', + original: $$[$0], + value: $$[$0], + loc: yy.locInfo(this._$) + }; + +break; +case 11:this.$ = yy.prepareRawBlock($$[$0-2], $$[$0-1], $$[$0], this._$); +break; +case 12:this.$ = { path: $$[$0-3], params: $$[$0-2], hash: $$[$0-1] }; +break; +case 13:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], false, this._$); +break; +case 14:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], true, this._$); +break; +case 15:this.$ = { open: $$[$0-5], path: $$[$0-4], params: $$[$0-3], hash: $$[$0-2], blockParams: $$[$0-1], strip: yy.stripFlags($$[$0-5], $$[$0]) }; +break; +case 16:this.$ = { path: $$[$0-4], params: $$[$0-3], hash: $$[$0-2], blockParams: $$[$0-1], strip: yy.stripFlags($$[$0-5], $$[$0]) }; +break; +case 17:this.$ = { path: $$[$0-4], params: $$[$0-3], hash: $$[$0-2], blockParams: $$[$0-1], strip: yy.stripFlags($$[$0-5], $$[$0]) }; +break; +case 18:this.$ = { strip: yy.stripFlags($$[$0-1], $$[$0-1]), program: $$[$0] }; +break; +case 19: + var inverse = yy.prepareBlock($$[$0-2], $$[$0-1], $$[$0], $$[$0], false, this._$), + program = yy.prepareProgram([inverse], $$[$0-1].loc); + program.chained = true; + + this.$ = { strip: $$[$0-2].strip, program: program, chain: true }; + +break; +case 20:this.$ = $$[$0]; +break; +case 21:this.$ = {path: $$[$0-1], strip: yy.stripFlags($$[$0-2], $$[$0])}; +break; +case 22:this.$ = yy.prepareMustache($$[$0-3], $$[$0-2], $$[$0-1], $$[$0-4], yy.stripFlags($$[$0-4], $$[$0]), this._$); +break; +case 23:this.$ = yy.prepareMustache($$[$0-3], $$[$0-2], $$[$0-1], $$[$0-4], yy.stripFlags($$[$0-4], $$[$0]), this._$); +break; +case 24: + this.$ = { + type: 'PartialStatement', + name: $$[$0-3], + params: $$[$0-2], + hash: $$[$0-1], + indent: '', + strip: yy.stripFlags($$[$0-4], $$[$0]), + loc: yy.locInfo(this._$) + }; + +break; +case 25:this.$ = yy.preparePartialBlock($$[$0-2], $$[$0-1], $$[$0], this._$); +break; +case 26:this.$ = { path: $$[$0-3], params: $$[$0-2], hash: $$[$0-1], strip: yy.stripFlags($$[$0-4], $$[$0]) }; +break; +case 27:this.$ = $$[$0]; +break; +case 28:this.$ = $$[$0]; +break; +case 29: + this.$ = { + type: 'SubExpression', + path: $$[$0-3], + params: $$[$0-2], + hash: $$[$0-1], + loc: yy.locInfo(this._$) + }; + +break; +case 30:this.$ = {type: 'Hash', pairs: $$[$0], loc: yy.locInfo(this._$)}; +break; +case 31:this.$ = {type: 'HashPair', key: yy.id($$[$0-2]), value: $$[$0], loc: yy.locInfo(this._$)}; +break; +case 32:this.$ = yy.id($$[$0-1]); +break; +case 33:this.$ = $$[$0]; +break; +case 34:this.$ = $$[$0]; +break; +case 35:this.$ = {type: 'StringLiteral', value: $$[$0], original: $$[$0], loc: yy.locInfo(this._$)}; +break; +case 36:this.$ = {type: 'NumberLiteral', value: Number($$[$0]), original: Number($$[$0]), loc: yy.locInfo(this._$)}; +break; +case 37:this.$ = {type: 'BooleanLiteral', value: $$[$0] === 'true', original: $$[$0] === 'true', loc: yy.locInfo(this._$)}; +break; +case 38:this.$ = {type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(this._$)}; +break; +case 39:this.$ = {type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(this._$)}; +break; +case 40:this.$ = $$[$0]; +break; +case 41:this.$ = $$[$0]; +break; +case 42:this.$ = yy.preparePath(true, $$[$0], this._$); +break; +case 43:this.$ = yy.preparePath(false, $$[$0], this._$); +break; +case 44: $$[$0-2].push({part: yy.id($$[$0]), original: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2]; +break; +case 45:this.$ = [{part: yy.id($$[$0]), original: $$[$0]}]; +break; +case 46:this.$ = []; +break; +case 47:$$[$0-1].push($$[$0]); +break; +case 48:this.$ = []; +break; +case 49:$$[$0-1].push($$[$0]); +break; +case 50:this.$ = []; +break; +case 51:$$[$0-1].push($$[$0]); +break; +case 58:this.$ = []; +break; +case 59:$$[$0-1].push($$[$0]); +break; +case 64:this.$ = []; +break; +case 65:$$[$0-1].push($$[$0]); +break; +case 70:this.$ = []; +break; +case 71:$$[$0-1].push($$[$0]); +break; +case 78:this.$ = []; +break; +case 79:$$[$0-1].push($$[$0]); +break; +case 82:this.$ = []; +break; +case 83:$$[$0-1].push($$[$0]); +break; +case 86:this.$ = []; +break; +case 87:$$[$0-1].push($$[$0]); +break; +case 90:this.$ = []; +break; +case 91:$$[$0-1].push($$[$0]); +break; +case 94:this.$ = []; +break; +case 95:$$[$0-1].push($$[$0]); +break; +case 98:this.$ = [$$[$0]]; +break; +case 99:$$[$0-1].push($$[$0]); +break; +case 100:this.$ = [$$[$0]]; +break; +case 101:$$[$0-1].push($$[$0]); +break; +} +}, +table: [{3:1,4:2,5:[2,46],6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:10,13:11,14:[1,12],15:[1,20],16:17,19:[1,23],24:15,27:16,29:[1,21],34:[1,22],39:[2,2],44:[2,2],47:[2,2],48:[1,13],51:[1,14],55:[1,18],59:19,60:[1,24]},{1:[2,1]},{5:[2,47],14:[2,47],15:[2,47],19:[2,47],29:[2,47],34:[2,47],39:[2,47],44:[2,47],47:[2,47],48:[2,47],51:[2,47],55:[2,47],60:[2,47]},{5:[2,3],14:[2,3],15:[2,3],19:[2,3],29:[2,3],34:[2,3],39:[2,3],44:[2,3],47:[2,3],48:[2,3],51:[2,3],55:[2,3],60:[2,3]},{5:[2,4],14:[2,4],15:[2,4],19:[2,4],29:[2,4],34:[2,4],39:[2,4],44:[2,4],47:[2,4],48:[2,4],51:[2,4],55:[2,4],60:[2,4]},{5:[2,5],14:[2,5],15:[2,5],19:[2,5],29:[2,5],34:[2,5],39:[2,5],44:[2,5],47:[2,5],48:[2,5],51:[2,5],55:[2,5],60:[2,5]},{5:[2,6],14:[2,6],15:[2,6],19:[2,6],29:[2,6],34:[2,6],39:[2,6],44:[2,6],47:[2,6],48:[2,6],51:[2,6],55:[2,6],60:[2,6]},{5:[2,7],14:[2,7],15:[2,7],19:[2,7],29:[2,7],34:[2,7],39:[2,7],44:[2,7],47:[2,7],48:[2,7],51:[2,7],55:[2,7],60:[2,7]},{5:[2,8],14:[2,8],15:[2,8],19:[2,8],29:[2,8],34:[2,8],39:[2,8],44:[2,8],47:[2,8],48:[2,8],51:[2,8],55:[2,8],60:[2,8]},{5:[2,9],14:[2,9],15:[2,9],19:[2,9],29:[2,9],34:[2,9],39:[2,9],44:[2,9],47:[2,9],48:[2,9],51:[2,9],55:[2,9],60:[2,9]},{20:25,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:36,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{4:37,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],39:[2,46],44:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{4:38,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],44:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{15:[2,48],17:39,18:[2,48]},{20:41,56:40,64:42,65:[1,43],72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{4:44,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{5:[2,10],14:[2,10],15:[2,10],18:[2,10],19:[2,10],29:[2,10],34:[2,10],39:[2,10],44:[2,10],47:[2,10],48:[2,10],51:[2,10],55:[2,10],60:[2,10]},{20:45,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:46,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:47,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:41,56:48,64:42,65:[1,43],72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{33:[2,78],49:49,65:[2,78],72:[2,78],80:[2,78],81:[2,78],82:[2,78],83:[2,78],84:[2,78],85:[2,78]},{23:[2,33],33:[2,33],54:[2,33],65:[2,33],68:[2,33],72:[2,33],75:[2,33],80:[2,33],81:[2,33],82:[2,33],83:[2,33],84:[2,33],85:[2,33]},{23:[2,34],33:[2,34],54:[2,34],65:[2,34],68:[2,34],72:[2,34],75:[2,34],80:[2,34],81:[2,34],82:[2,34],83:[2,34],84:[2,34],85:[2,34]},{23:[2,35],33:[2,35],54:[2,35],65:[2,35],68:[2,35],72:[2,35],75:[2,35],80:[2,35],81:[2,35],82:[2,35],83:[2,35],84:[2,35],85:[2,35]},{23:[2,36],33:[2,36],54:[2,36],65:[2,36],68:[2,36],72:[2,36],75:[2,36],80:[2,36],81:[2,36],82:[2,36],83:[2,36],84:[2,36],85:[2,36]},{23:[2,37],33:[2,37],54:[2,37],65:[2,37],68:[2,37],72:[2,37],75:[2,37],80:[2,37],81:[2,37],82:[2,37],83:[2,37],84:[2,37],85:[2,37]},{23:[2,38],33:[2,38],54:[2,38],65:[2,38],68:[2,38],72:[2,38],75:[2,38],80:[2,38],81:[2,38],82:[2,38],83:[2,38],84:[2,38],85:[2,38]},{23:[2,39],33:[2,39],54:[2,39],65:[2,39],68:[2,39],72:[2,39],75:[2,39],80:[2,39],81:[2,39],82:[2,39],83:[2,39],84:[2,39],85:[2,39]},{23:[2,43],33:[2,43],54:[2,43],65:[2,43],68:[2,43],72:[2,43],75:[2,43],80:[2,43],81:[2,43],82:[2,43],83:[2,43],84:[2,43],85:[2,43],87:[1,50]},{72:[1,35],86:51},{23:[2,45],33:[2,45],54:[2,45],65:[2,45],68:[2,45],72:[2,45],75:[2,45],80:[2,45],81:[2,45],82:[2,45],83:[2,45],84:[2,45],85:[2,45],87:[2,45]},{52:52,54:[2,82],65:[2,82],72:[2,82],80:[2,82],81:[2,82],82:[2,82],83:[2,82],84:[2,82],85:[2,82]},{25:53,38:55,39:[1,57],43:56,44:[1,58],45:54,47:[2,54]},{28:59,43:60,44:[1,58],47:[2,56]},{13:62,15:[1,20],18:[1,61]},{33:[2,86],57:63,65:[2,86],72:[2,86],80:[2,86],81:[2,86],82:[2,86],83:[2,86],84:[2,86],85:[2,86]},{33:[2,40],65:[2,40],72:[2,40],80:[2,40],81:[2,40],82:[2,40],83:[2,40],84:[2,40],85:[2,40]},{33:[2,41],65:[2,41],72:[2,41],80:[2,41],81:[2,41],82:[2,41],83:[2,41],84:[2,41],85:[2,41]},{20:64,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{26:65,47:[1,66]},{30:67,33:[2,58],65:[2,58],72:[2,58],75:[2,58],80:[2,58],81:[2,58],82:[2,58],83:[2,58],84:[2,58],85:[2,58]},{33:[2,64],35:68,65:[2,64],72:[2,64],75:[2,64],80:[2,64],81:[2,64],82:[2,64],83:[2,64],84:[2,64],85:[2,64]},{21:69,23:[2,50],65:[2,50],72:[2,50],80:[2,50],81:[2,50],82:[2,50],83:[2,50],84:[2,50],85:[2,50]},{33:[2,90],61:70,65:[2,90],72:[2,90],80:[2,90],81:[2,90],82:[2,90],83:[2,90],84:[2,90],85:[2,90]},{20:74,33:[2,80],50:71,63:72,64:75,65:[1,43],69:73,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{72:[1,79]},{23:[2,42],33:[2,42],54:[2,42],65:[2,42],68:[2,42],72:[2,42],75:[2,42],80:[2,42],81:[2,42],82:[2,42],83:[2,42],84:[2,42],85:[2,42],87:[1,50]},{20:74,53:80,54:[2,84],63:81,64:75,65:[1,43],69:82,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{26:83,47:[1,66]},{47:[2,55]},{4:84,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],39:[2,46],44:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{47:[2,20]},{20:85,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{4:86,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{26:87,47:[1,66]},{47:[2,57]},{5:[2,11],14:[2,11],15:[2,11],19:[2,11],29:[2,11],34:[2,11],39:[2,11],44:[2,11],47:[2,11],48:[2,11],51:[2,11],55:[2,11],60:[2,11]},{15:[2,49],18:[2,49]},{20:74,33:[2,88],58:88,63:89,64:75,65:[1,43],69:90,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{65:[2,94],66:91,68:[2,94],72:[2,94],80:[2,94],81:[2,94],82:[2,94],83:[2,94],84:[2,94],85:[2,94]},{5:[2,25],14:[2,25],15:[2,25],19:[2,25],29:[2,25],34:[2,25],39:[2,25],44:[2,25],47:[2,25],48:[2,25],51:[2,25],55:[2,25],60:[2,25]},{20:92,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:74,31:93,33:[2,60],63:94,64:75,65:[1,43],69:95,70:76,71:77,72:[1,78],75:[2,60],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:74,33:[2,66],36:96,63:97,64:75,65:[1,43],69:98,70:76,71:77,72:[1,78],75:[2,66],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:74,22:99,23:[2,52],63:100,64:75,65:[1,43],69:101,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:74,33:[2,92],62:102,63:103,64:75,65:[1,43],69:104,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{33:[1,105]},{33:[2,79],65:[2,79],72:[2,79],80:[2,79],81:[2,79],82:[2,79],83:[2,79],84:[2,79],85:[2,79]},{33:[2,81]},{23:[2,27],33:[2,27],54:[2,27],65:[2,27],68:[2,27],72:[2,27],75:[2,27],80:[2,27],81:[2,27],82:[2,27],83:[2,27],84:[2,27],85:[2,27]},{23:[2,28],33:[2,28],54:[2,28],65:[2,28],68:[2,28],72:[2,28],75:[2,28],80:[2,28],81:[2,28],82:[2,28],83:[2,28],84:[2,28],85:[2,28]},{23:[2,30],33:[2,30],54:[2,30],68:[2,30],71:106,72:[1,107],75:[2,30]},{23:[2,98],33:[2,98],54:[2,98],68:[2,98],72:[2,98],75:[2,98]},{23:[2,45],33:[2,45],54:[2,45],65:[2,45],68:[2,45],72:[2,45],73:[1,108],75:[2,45],80:[2,45],81:[2,45],82:[2,45],83:[2,45],84:[2,45],85:[2,45],87:[2,45]},{23:[2,44],33:[2,44],54:[2,44],65:[2,44],68:[2,44],72:[2,44],75:[2,44],80:[2,44],81:[2,44],82:[2,44],83:[2,44],84:[2,44],85:[2,44],87:[2,44]},{54:[1,109]},{54:[2,83],65:[2,83],72:[2,83],80:[2,83],81:[2,83],82:[2,83],83:[2,83],84:[2,83],85:[2,83]},{54:[2,85]},{5:[2,13],14:[2,13],15:[2,13],19:[2,13],29:[2,13],34:[2,13],39:[2,13],44:[2,13],47:[2,13],48:[2,13],51:[2,13],55:[2,13],60:[2,13]},{38:55,39:[1,57],43:56,44:[1,58],45:111,46:110,47:[2,76]},{33:[2,70],40:112,65:[2,70],72:[2,70],75:[2,70],80:[2,70],81:[2,70],82:[2,70],83:[2,70],84:[2,70],85:[2,70]},{47:[2,18]},{5:[2,14],14:[2,14],15:[2,14],19:[2,14],29:[2,14],34:[2,14],39:[2,14],44:[2,14],47:[2,14],48:[2,14],51:[2,14],55:[2,14],60:[2,14]},{33:[1,113]},{33:[2,87],65:[2,87],72:[2,87],80:[2,87],81:[2,87],82:[2,87],83:[2,87],84:[2,87],85:[2,87]},{33:[2,89]},{20:74,63:115,64:75,65:[1,43],67:114,68:[2,96],69:116,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{33:[1,117]},{32:118,33:[2,62],74:119,75:[1,120]},{33:[2,59],65:[2,59],72:[2,59],75:[2,59],80:[2,59],81:[2,59],82:[2,59],83:[2,59],84:[2,59],85:[2,59]},{33:[2,61],75:[2,61]},{33:[2,68],37:121,74:122,75:[1,120]},{33:[2,65],65:[2,65],72:[2,65],75:[2,65],80:[2,65],81:[2,65],82:[2,65],83:[2,65],84:[2,65],85:[2,65]},{33:[2,67],75:[2,67]},{23:[1,123]},{23:[2,51],65:[2,51],72:[2,51],80:[2,51],81:[2,51],82:[2,51],83:[2,51],84:[2,51],85:[2,51]},{23:[2,53]},{33:[1,124]},{33:[2,91],65:[2,91],72:[2,91],80:[2,91],81:[2,91],82:[2,91],83:[2,91],84:[2,91],85:[2,91]},{33:[2,93]},{5:[2,22],14:[2,22],15:[2,22],19:[2,22],29:[2,22],34:[2,22],39:[2,22],44:[2,22],47:[2,22],48:[2,22],51:[2,22],55:[2,22],60:[2,22]},{23:[2,99],33:[2,99],54:[2,99],68:[2,99],72:[2,99],75:[2,99]},{73:[1,108]},{20:74,63:125,64:75,65:[1,43],72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{5:[2,23],14:[2,23],15:[2,23],19:[2,23],29:[2,23],34:[2,23],39:[2,23],44:[2,23],47:[2,23],48:[2,23],51:[2,23],55:[2,23],60:[2,23]},{47:[2,19]},{47:[2,77]},{20:74,33:[2,72],41:126,63:127,64:75,65:[1,43],69:128,70:76,71:77,72:[1,78],75:[2,72],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{5:[2,24],14:[2,24],15:[2,24],19:[2,24],29:[2,24],34:[2,24],39:[2,24],44:[2,24],47:[2,24],48:[2,24],51:[2,24],55:[2,24],60:[2,24]},{68:[1,129]},{65:[2,95],68:[2,95],72:[2,95],80:[2,95],81:[2,95],82:[2,95],83:[2,95],84:[2,95],85:[2,95]},{68:[2,97]},{5:[2,21],14:[2,21],15:[2,21],19:[2,21],29:[2,21],34:[2,21],39:[2,21],44:[2,21],47:[2,21],48:[2,21],51:[2,21],55:[2,21],60:[2,21]},{33:[1,130]},{33:[2,63]},{72:[1,132],76:131},{33:[1,133]},{33:[2,69]},{15:[2,12],18:[2,12]},{14:[2,26],15:[2,26],19:[2,26],29:[2,26],34:[2,26],47:[2,26],48:[2,26],51:[2,26],55:[2,26],60:[2,26]},{23:[2,31],33:[2,31],54:[2,31],68:[2,31],72:[2,31],75:[2,31]},{33:[2,74],42:134,74:135,75:[1,120]},{33:[2,71],65:[2,71],72:[2,71],75:[2,71],80:[2,71],81:[2,71],82:[2,71],83:[2,71],84:[2,71],85:[2,71]},{33:[2,73],75:[2,73]},{23:[2,29],33:[2,29],54:[2,29],65:[2,29],68:[2,29],72:[2,29],75:[2,29],80:[2,29],81:[2,29],82:[2,29],83:[2,29],84:[2,29],85:[2,29]},{14:[2,15],15:[2,15],19:[2,15],29:[2,15],34:[2,15],39:[2,15],44:[2,15],47:[2,15],48:[2,15],51:[2,15],55:[2,15],60:[2,15]},{72:[1,137],77:[1,136]},{72:[2,100],77:[2,100]},{14:[2,16],15:[2,16],19:[2,16],29:[2,16],34:[2,16],44:[2,16],47:[2,16],48:[2,16],51:[2,16],55:[2,16],60:[2,16]},{33:[1,138]},{33:[2,75]},{33:[2,32]},{72:[2,101],77:[2,101]},{14:[2,17],15:[2,17],19:[2,17],29:[2,17],34:[2,17],39:[2,17],44:[2,17],47:[2,17],48:[2,17],51:[2,17],55:[2,17],60:[2,17]}], +defaultActions: {4:[2,1],54:[2,55],56:[2,20],60:[2,57],73:[2,81],82:[2,85],86:[2,18],90:[2,89],101:[2,53],104:[2,93],110:[2,19],111:[2,77],116:[2,97],119:[2,63],122:[2,69],135:[2,75],136:[2,32]}, +parseError: function parseError (str, hash) { + throw new Error(str); +}, +parse: function parse(input) { + var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + this.lexer.setInput(input); + this.lexer.yy = this.yy; + this.yy.lexer = this.lexer; + this.yy.parser = this; + if (typeof this.lexer.yylloc == "undefined") + this.lexer.yylloc = {}; + var yyloc = this.lexer.yylloc; + lstack.push(yyloc); + var ranges = this.lexer.options && this.lexer.options.ranges; + if (typeof this.yy.parseError === "function") + this.parseError = this.yy.parseError; + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + function lex() { + var token; + token = self.lexer.lex() || 1; + if (typeof token !== "number") { + token = self.symbols_[token] || token; + } + return token; + } + var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + if (!recovering) { + expected = []; + for (p in table[state]) + if (this.terminals_[p] && p > 2) { + expected.push("'" + this.terminals_[p] + "'"); + } + if (this.lexer.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected}); + } + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(this.lexer.yytext); + lstack.push(this.lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + if (recovering > 0) + recovering--; + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column}; + if (ranges) { + yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]]; + } + r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; +} +}; +/* Jison generated lexer */ +var lexer = (function(){ +var lexer = ({EOF:1, +parseError:function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, +setInput:function (input) { + this._input = input; + this._more = this._less = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0}; + if (this.options.ranges) this.yylloc.range = [0,0]; + this.offset = 0; + return this; + }, +input:function () { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) this.yylloc.range[1]++; + + this._input = this._input.slice(1); + return ch; + }, +unput:function (ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length-len-1); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length-1); + this.matched = this.matched.substr(0, this.matched.length-1); + + if (lines.length-1) this.yylineno -= lines.length-1; + var r = this.yylloc.range; + + this.yylloc = {first_line: this.yylloc.first_line, + last_line: this.yylineno+1, + first_column: this.yylloc.first_column, + last_column: lines ? + (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length: + this.yylloc.first_column - len + }; + + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + return this; + }, +more:function () { + this._more = true; + return this; + }, +less:function (n) { + this.unput(this.match.slice(n)); + }, +pastInput:function () { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); + }, +upcomingInput:function () { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20-next.length); + } + return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, ""); + }, +showPosition:function () { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c+"^"; + }, +next:function () { + if (this.done) { + return this.EOF; + } + if (!this._input) this.done = true; + + var token, + match, + tempMatch, + index, + col, + lines; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i=0;i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (!this.options.flex) break; + } + } + if (match) { + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) this.yylineno += lines.length; + this.yylloc = {first_line: this.yylloc.last_line, + last_line: this.yylineno+1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length}; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]); + if (this.done && this._input) this.done = false; + if (token) return token; + else return; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(), + {text: "", token: null, line: this.yylineno}); + } + }, +lex:function lex () { + var r = this.next(); + if (typeof r !== 'undefined') { + return r; + } else { + return this.lex(); + } + }, +begin:function begin (condition) { + this.conditionStack.push(condition); + }, +popState:function popState () { + return this.conditionStack.pop(); + }, +_currentRules:function _currentRules () { + return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules; + }, +topState:function () { + return this.conditionStack[this.conditionStack.length-2]; + }, +pushState:function begin (condition) { + this.begin(condition); + }}); +lexer.options = {}; +lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START +) { + + +function strip(start, end) { + return yy_.yytext = yy_.yytext.substring(start, yy_.yyleng - end + start); +} + + +var YYSTATE=YY_START +switch($avoiding_name_collisions) { +case 0: + if(yy_.yytext.slice(-2) === "\\\\") { + strip(0,1); + this.begin("mu"); + } else if(yy_.yytext.slice(-1) === "\\") { + strip(0,1); + this.begin("emu"); + } else { + this.begin("mu"); + } + if(yy_.yytext) return 15; + +break; +case 1:return 15; +break; +case 2: + this.popState(); + return 15; + +break; +case 3:this.begin('raw'); return 15; +break; +case 4: + this.popState(); + // Should be using `this.topState()` below, but it currently + // returns the second top instead of the first top. Opened an + // issue about it at https://github.com/zaach/jison/issues/291 + if (this.conditionStack[this.conditionStack.length-1] === 'raw') { + return 15; + } else { + strip(5, 9); + return 'END_RAW_BLOCK'; + } + +break; +case 5: return 15; +break; +case 6: + this.popState(); + return 14; + +break; +case 7:return 65; +break; +case 8:return 68; +break; +case 9: return 19; +break; +case 10: + this.popState(); + this.begin('raw'); + return 23; + +break; +case 11:return 55; +break; +case 12:return 60; +break; +case 13:return 29; +break; +case 14:return 47; +break; +case 15:this.popState(); return 44; +break; +case 16:this.popState(); return 44; +break; +case 17:return 34; +break; +case 18:return 39; +break; +case 19:return 51; +break; +case 20:return 48; +break; +case 21: + this.unput(yy_.yytext); + this.popState(); + this.begin('com'); + +break; +case 22: + this.popState(); + return 14; + +break; +case 23:return 48; +break; +case 24:return 73; +break; +case 25:return 72; +break; +case 26:return 72; +break; +case 27:return 87; +break; +case 28:// ignore whitespace +break; +case 29:this.popState(); return 54; +break; +case 30:this.popState(); return 33; +break; +case 31:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 80; +break; +case 32:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 80; +break; +case 33:return 85; +break; +case 34:return 82; +break; +case 35:return 82; +break; +case 36:return 83; +break; +case 37:return 84; +break; +case 38:return 81; +break; +case 39:return 75; +break; +case 40:return 77; +break; +case 41:return 72; +break; +case 42:yy_.yytext = yy_.yytext.replace(/\\([\\\]])/g,'$1'); return 72; +break; +case 43:return 'INVALID'; +break; +case 44:return 5; +break; +} +}; +lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{(?=[^/]))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]+?(?=(\{\{\{\{)))/,/^(?:[\s\S]*?--(~)?\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#>)/,/^(?:\{\{(~)?#\*?)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{(~)?!--)/,/^(?:\{\{(~)?![\s\S]*?\}\})/,/^(?:\{\{(~)?\*?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)|])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:undefined(?=([~}\s)])))/,/^(?:null(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:as\s+\|)/,/^(?:\|)/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/,/^(?:\[(\\\]|[^\]])*\])/,/^(?:.)/,/^(?:$)/]; +lexer.conditions = {"mu":{"rules":[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[6],"inclusive":false},"raw":{"rules":[3,4,5],"inclusive":false},"INITIAL":{"rules":[0,1,44],"inclusive":true}}; +return lexer;})() +parser.lexer = lexer; +function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser; +return new Parser; +})();export default handlebars; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/printer.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/printer.js new file mode 100644 index 000000000..e087806cd --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/printer.js @@ -0,0 +1,178 @@ +/* eslint-disable new-cap */ +import Visitor from './visitor'; + +export function print(ast) { + return new PrintVisitor().accept(ast); +} + +export function PrintVisitor() { + this.padding = 0; +} + +PrintVisitor.prototype = new Visitor(); + +PrintVisitor.prototype.pad = function(string) { + let out = ''; + + for (let i = 0, l = this.padding; i < l; i++) { + out += ' '; + } + + out += string + '\n'; + return out; +}; + +PrintVisitor.prototype.Program = function(program) { + let out = '', + body = program.body, + i, + l; + + if (program.blockParams) { + let blockParams = 'BLOCK PARAMS: ['; + for (i = 0, l = program.blockParams.length; i < l; i++) { + blockParams += ' ' + program.blockParams[i]; + } + blockParams += ' ]'; + out += this.pad(blockParams); + } + + for (i = 0, l = body.length; i < l; i++) { + out += this.accept(body[i]); + } + + this.padding--; + + return out; +}; + +PrintVisitor.prototype.MustacheStatement = function(mustache) { + return this.pad('{{ ' + this.SubExpression(mustache) + ' }}'); +}; +PrintVisitor.prototype.Decorator = function(mustache) { + return this.pad('{{ DIRECTIVE ' + this.SubExpression(mustache) + ' }}'); +}; + +PrintVisitor.prototype.BlockStatement = PrintVisitor.prototype.DecoratorBlock = function( + block +) { + let out = ''; + + out += this.pad( + (block.type === 'DecoratorBlock' ? 'DIRECTIVE ' : '') + 'BLOCK:' + ); + this.padding++; + out += this.pad(this.SubExpression(block)); + if (block.program) { + out += this.pad('PROGRAM:'); + this.padding++; + out += this.accept(block.program); + this.padding--; + } + if (block.inverse) { + if (block.program) { + this.padding++; + } + out += this.pad('{{^}}'); + this.padding++; + out += this.accept(block.inverse); + this.padding--; + if (block.program) { + this.padding--; + } + } + this.padding--; + + return out; +}; + +PrintVisitor.prototype.PartialStatement = function(partial) { + let content = 'PARTIAL:' + partial.name.original; + if (partial.params[0]) { + content += ' ' + this.accept(partial.params[0]); + } + if (partial.hash) { + content += ' ' + this.accept(partial.hash); + } + return this.pad('{{> ' + content + ' }}'); +}; +PrintVisitor.prototype.PartialBlockStatement = function(partial) { + let content = 'PARTIAL BLOCK:' + partial.name.original; + if (partial.params[0]) { + content += ' ' + this.accept(partial.params[0]); + } + if (partial.hash) { + content += ' ' + this.accept(partial.hash); + } + + content += ' ' + this.pad('PROGRAM:'); + this.padding++; + content += this.accept(partial.program); + this.padding--; + + return this.pad('{{> ' + content + ' }}'); +}; + +PrintVisitor.prototype.ContentStatement = function(content) { + return this.pad("CONTENT[ '" + content.value + "' ]"); +}; + +PrintVisitor.prototype.CommentStatement = function(comment) { + return this.pad("{{! '" + comment.value + "' }}"); +}; + +PrintVisitor.prototype.SubExpression = function(sexpr) { + let params = sexpr.params, + paramStrings = [], + hash; + + for (let i = 0, l = params.length; i < l; i++) { + paramStrings.push(this.accept(params[i])); + } + + params = '[' + paramStrings.join(', ') + ']'; + + hash = sexpr.hash ? ' ' + this.accept(sexpr.hash) : ''; + + return this.accept(sexpr.path) + ' ' + params + hash; +}; + +PrintVisitor.prototype.PathExpression = function(id) { + let path = id.parts.join('/'); + return (id.data ? '@' : '') + 'PATH:' + path; +}; + +PrintVisitor.prototype.StringLiteral = function(string) { + return '"' + string.value + '"'; +}; + +PrintVisitor.prototype.NumberLiteral = function(number) { + return 'NUMBER{' + number.value + '}'; +}; + +PrintVisitor.prototype.BooleanLiteral = function(bool) { + return 'BOOLEAN{' + bool.value + '}'; +}; + +PrintVisitor.prototype.UndefinedLiteral = function() { + return 'UNDEFINED'; +}; + +PrintVisitor.prototype.NullLiteral = function() { + return 'NULL'; +}; + +PrintVisitor.prototype.Hash = function(hash) { + let pairs = hash.pairs, + joinedPairs = []; + + for (let i = 0, l = pairs.length; i < l; i++) { + joinedPairs.push(this.accept(pairs[i])); + } + + return 'HASH{' + joinedPairs.join(', ') + '}'; +}; +PrintVisitor.prototype.HashPair = function(pair) { + return pair.key + '=' + this.accept(pair.value); +}; +/* eslint-enable new-cap */ diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/visitor.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/visitor.js new file mode 100644 index 000000000..76bb01f12 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/visitor.js @@ -0,0 +1,136 @@ +import Exception from '../exception'; + +function Visitor() { + this.parents = []; +} + +Visitor.prototype = { + constructor: Visitor, + mutating: false, + + // Visits a given value. If mutating, will replace the value if necessary. + acceptKey: function(node, name) { + let value = this.accept(node[name]); + if (this.mutating) { + // Hacky sanity check: This may have a few false positives for type for the helper + // methods but will generally do the right thing without a lot of overhead. + if (value && !Visitor.prototype[value.type]) { + throw new Exception( + 'Unexpected node type "' + + value.type + + '" found when accepting ' + + name + + ' on ' + + node.type + ); + } + node[name] = value; + } + }, + + // Performs an accept operation with added sanity check to ensure + // required keys are not removed. + acceptRequired: function(node, name) { + this.acceptKey(node, name); + + if (!node[name]) { + throw new Exception(node.type + ' requires ' + name); + } + }, + + // Traverses a given array. If mutating, empty respnses will be removed + // for child elements. + acceptArray: function(array) { + for (let i = 0, l = array.length; i < l; i++) { + this.acceptKey(array, i); + + if (!array[i]) { + array.splice(i, 1); + i--; + l--; + } + } + }, + + accept: function(object) { + if (!object) { + return; + } + + /* istanbul ignore next: Sanity code */ + if (!this[object.type]) { + throw new Exception('Unknown type: ' + object.type, object); + } + + if (this.current) { + this.parents.unshift(this.current); + } + this.current = object; + + let ret = this[object.type](object); + + this.current = this.parents.shift(); + + if (!this.mutating || ret) { + return ret; + } else if (ret !== false) { + return object; + } + }, + + Program: function(program) { + this.acceptArray(program.body); + }, + + MustacheStatement: visitSubExpression, + Decorator: visitSubExpression, + + BlockStatement: visitBlock, + DecoratorBlock: visitBlock, + + PartialStatement: visitPartial, + PartialBlockStatement: function(partial) { + visitPartial.call(this, partial); + + this.acceptKey(partial, 'program'); + }, + + ContentStatement: function(/* content */) {}, + CommentStatement: function(/* comment */) {}, + + SubExpression: visitSubExpression, + + PathExpression: function(/* path */) {}, + + StringLiteral: function(/* string */) {}, + NumberLiteral: function(/* number */) {}, + BooleanLiteral: function(/* bool */) {}, + UndefinedLiteral: function(/* literal */) {}, + NullLiteral: function(/* literal */) {}, + + Hash: function(hash) { + this.acceptArray(hash.pairs); + }, + HashPair: function(pair) { + this.acceptRequired(pair, 'value'); + } +}; + +function visitSubExpression(mustache) { + this.acceptRequired(mustache, 'path'); + this.acceptArray(mustache.params); + this.acceptKey(mustache, 'hash'); +} +function visitBlock(block) { + visitSubExpression.call(this, block); + + this.acceptKey(block, 'program'); + this.acceptKey(block, 'inverse'); +} +function visitPartial(partial) { + this.acceptRequired(partial, 'name'); + this.acceptArray(partial.params); + this.acceptKey(partial, 'hash'); +} + +export default Visitor; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/compiler/whitespace-control.js b/libs/events/node_modules/handlebars/lib/handlebars/compiler/whitespace-control.js new file mode 100644 index 000000000..7db683983 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/compiler/whitespace-control.js @@ -0,0 +1,234 @@ +import Visitor from './visitor'; + +function WhitespaceControl(options = {}) { + this.options = options; +} +WhitespaceControl.prototype = new Visitor(); + +WhitespaceControl.prototype.Program = function(program) { + const doStandalone = !this.options.ignoreStandalone; + + let isRoot = !this.isRootSeen; + this.isRootSeen = true; + + let body = program.body; + for (let i = 0, l = body.length; i < l; i++) { + let current = body[i], + strip = this.accept(current); + + if (!strip) { + continue; + } + + let _isPrevWhitespace = isPrevWhitespace(body, i, isRoot), + _isNextWhitespace = isNextWhitespace(body, i, isRoot), + openStandalone = strip.openStandalone && _isPrevWhitespace, + closeStandalone = strip.closeStandalone && _isNextWhitespace, + inlineStandalone = + strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; + + if (strip.close) { + omitRight(body, i, true); + } + if (strip.open) { + omitLeft(body, i, true); + } + + if (doStandalone && inlineStandalone) { + omitRight(body, i); + + if (omitLeft(body, i)) { + // If we are on a standalone node, save the indent info for partials + if (current.type === 'PartialStatement') { + // Pull out the whitespace from the final line + current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1]; + } + } + } + if (doStandalone && openStandalone) { + omitRight((current.program || current.inverse).body); + + // Strip out the previous content node if it's whitespace only + omitLeft(body, i); + } + if (doStandalone && closeStandalone) { + // Always strip the next node + omitRight(body, i); + + omitLeft((current.inverse || current.program).body); + } + } + + return program; +}; + +WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function( + block +) { + this.accept(block.program); + this.accept(block.inverse); + + // Find the inverse program that is involed with whitespace stripping. + let program = block.program || block.inverse, + inverse = block.program && block.inverse, + firstInverse = inverse, + lastInverse = inverse; + + if (inverse && inverse.chained) { + firstInverse = inverse.body[0].program; + + // Walk the inverse chain to find the last inverse that is actually in the chain. + while (lastInverse.chained) { + lastInverse = lastInverse.body[lastInverse.body.length - 1].program; + } + } + + let strip = { + open: block.openStrip.open, + close: block.closeStrip.close, + + // Determine the standalone candiacy. Basically flag our content as being possibly standalone + // so our parent can determine if we actually are standalone + openStandalone: isNextWhitespace(program.body), + closeStandalone: isPrevWhitespace((firstInverse || program).body) + }; + + if (block.openStrip.close) { + omitRight(program.body, null, true); + } + + if (inverse) { + let inverseStrip = block.inverseStrip; + + if (inverseStrip.open) { + omitLeft(program.body, null, true); + } + + if (inverseStrip.close) { + omitRight(firstInverse.body, null, true); + } + if (block.closeStrip.open) { + omitLeft(lastInverse.body, null, true); + } + + // Find standalone else statments + if ( + !this.options.ignoreStandalone && + isPrevWhitespace(program.body) && + isNextWhitespace(firstInverse.body) + ) { + omitLeft(program.body); + omitRight(firstInverse.body); + } + } else if (block.closeStrip.open) { + omitLeft(program.body, null, true); + } + + return strip; +}; + +WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function( + mustache +) { + return mustache.strip; +}; + +WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function( + node +) { + /* istanbul ignore next */ + let strip = node.strip || {}; + return { + inlineStandalone: true, + open: strip.open, + close: strip.close + }; +}; + +function isPrevWhitespace(body, i, isRoot) { + if (i === undefined) { + i = body.length; + } + + // Nodes that end with newlines are considered whitespace (but are special + // cased for strip operations) + let prev = body[i - 1], + sibling = body[i - 2]; + if (!prev) { + return isRoot; + } + + if (prev.type === 'ContentStatement') { + return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test( + prev.original + ); + } +} +function isNextWhitespace(body, i, isRoot) { + if (i === undefined) { + i = -1; + } + + let next = body[i + 1], + sibling = body[i + 2]; + if (!next) { + return isRoot; + } + + if (next.type === 'ContentStatement') { + return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test( + next.original + ); + } +} + +// Marks the node to the right of the position as omitted. +// I.e. {{foo}}' ' will mark the ' ' node as omitted. +// +// If i is undefined, then the first child will be marked as such. +// +// If mulitple is truthy then all whitespace will be stripped out until non-whitespace +// content is met. +function omitRight(body, i, multiple) { + let current = body[i == null ? 0 : i + 1]; + if ( + !current || + current.type !== 'ContentStatement' || + (!multiple && current.rightStripped) + ) { + return; + } + + let original = current.value; + current.value = current.value.replace( + multiple ? /^\s+/ : /^[ \t]*\r?\n?/, + '' + ); + current.rightStripped = current.value !== original; +} + +// Marks the node to the left of the position as omitted. +// I.e. ' '{{foo}} will mark the ' ' node as omitted. +// +// If i is undefined then the last child will be marked as such. +// +// If mulitple is truthy then all whitespace will be stripped out until non-whitespace +// content is met. +function omitLeft(body, i, multiple) { + let current = body[i == null ? body.length - 1 : i - 1]; + if ( + !current || + current.type !== 'ContentStatement' || + (!multiple && current.leftStripped) + ) { + return; + } + + // We omit the last node if it's whitespace only and not preceded by a non-content node. + let original = current.value; + current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, ''); + current.leftStripped = current.value !== original; + return current.leftStripped; +} + +export default WhitespaceControl; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/decorators.js b/libs/events/node_modules/handlebars/lib/handlebars/decorators.js new file mode 100644 index 000000000..d9d5e8a96 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/decorators.js @@ -0,0 +1,5 @@ +import registerInline from './decorators/inline'; + +export function registerDefaultDecorators(instance) { + registerInline(instance); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/decorators/inline.js b/libs/events/node_modules/handlebars/lib/handlebars/decorators/inline.js new file mode 100644 index 000000000..02f5be7b5 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/decorators/inline.js @@ -0,0 +1,22 @@ +import { extend } from '../utils'; + +export default function(instance) { + instance.registerDecorator('inline', function(fn, props, container, options) { + let ret = fn; + if (!props.partials) { + props.partials = {}; + ret = function(context, options) { + // Create a new partials stack frame prior to exec. + let original = container.partials; + container.partials = extend({}, original, props.partials); + let ret = fn(context, options); + container.partials = original; + return ret; + }; + } + + props.partials[options.args[0]] = options.fn; + + return ret; + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/exception.js b/libs/events/node_modules/handlebars/lib/handlebars/exception.js new file mode 100644 index 000000000..b2fdc00bc --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/exception.js @@ -0,0 +1,68 @@ +const errorProps = [ + 'description', + 'fileName', + 'lineNumber', + 'endLineNumber', + 'message', + 'name', + 'number', + 'stack' +]; + +function Exception(message, node) { + let loc = node && node.loc, + line, + endLineNumber, + column, + endColumn; + + if (loc) { + line = loc.start.line; + endLineNumber = loc.end.line; + column = loc.start.column; + endColumn = loc.end.column; + + message += ' - ' + line + ':' + column; + } + + let tmp = Error.prototype.constructor.call(this, message); + + // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. + for (let idx = 0; idx < errorProps.length; idx++) { + this[errorProps[idx]] = tmp[errorProps[idx]]; + } + + /* istanbul ignore else */ + if (Error.captureStackTrace) { + Error.captureStackTrace(this, Exception); + } + + try { + if (loc) { + this.lineNumber = line; + this.endLineNumber = endLineNumber; + + // Work around issue under safari where we can't directly set the column value + /* istanbul ignore next */ + if (Object.defineProperty) { + Object.defineProperty(this, 'column', { + value: column, + enumerable: true + }); + Object.defineProperty(this, 'endColumn', { + value: endColumn, + enumerable: true + }); + } else { + this.column = column; + this.endColumn = endColumn; + } + } + } catch (nop) { + /* Ignore if the browser is very particular */ + } +} + +Exception.prototype = new Error(); + +export default Exception; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/helpers.js b/libs/events/node_modules/handlebars/lib/handlebars/helpers.js new file mode 100644 index 000000000..804796820 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/helpers.js @@ -0,0 +1,26 @@ +import registerBlockHelperMissing from './helpers/block-helper-missing'; +import registerEach from './helpers/each'; +import registerHelperMissing from './helpers/helper-missing'; +import registerIf from './helpers/if'; +import registerLog from './helpers/log'; +import registerLookup from './helpers/lookup'; +import registerWith from './helpers/with'; + +export function registerDefaultHelpers(instance) { + registerBlockHelperMissing(instance); + registerEach(instance); + registerHelperMissing(instance); + registerIf(instance); + registerLog(instance); + registerLookup(instance); + registerWith(instance); +} + +export function moveHelperToHooks(instance, helperName, keepHelper) { + if (instance.helpers[helperName]) { + instance.hooks[helperName] = instance.helpers[helperName]; + if (!keepHelper) { + delete instance.helpers[helperName]; + } + } +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/helpers/block-helper-missing.js b/libs/events/node_modules/handlebars/lib/handlebars/helpers/block-helper-missing.js new file mode 100644 index 000000000..9aeea9b97 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/helpers/block-helper-missing.js @@ -0,0 +1,35 @@ +import { appendContextPath, createFrame, isArray } from '../utils'; + +export default function(instance) { + instance.registerHelper('blockHelperMissing', function(context, options) { + let inverse = options.inverse, + fn = options.fn; + + if (context === true) { + return fn(this); + } else if (context === false || context == null) { + return inverse(this); + } else if (isArray(context)) { + if (context.length > 0) { + if (options.ids) { + options.ids = [options.name]; + } + + return instance.helpers.each(context, options); + } else { + return inverse(this); + } + } else { + if (options.data && options.ids) { + let data = createFrame(options.data); + data.contextPath = appendContextPath( + options.data.contextPath, + options.name + ); + options = { data: data }; + } + + return fn(context, options); + } + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/helpers/each.js b/libs/events/node_modules/handlebars/lib/handlebars/helpers/each.js new file mode 100644 index 000000000..511d36675 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/helpers/each.js @@ -0,0 +1,101 @@ +import { + appendContextPath, + blockParams, + createFrame, + isArray, + isFunction +} from '../utils'; +import Exception from '../exception'; + +export default function(instance) { + instance.registerHelper('each', function(context, options) { + if (!options) { + throw new Exception('Must pass iterator to #each'); + } + + let fn = options.fn, + inverse = options.inverse, + i = 0, + ret = '', + data, + contextPath; + + if (options.data && options.ids) { + contextPath = + appendContextPath(options.data.contextPath, options.ids[0]) + '.'; + } + + if (isFunction(context)) { + context = context.call(this); + } + + if (options.data) { + data = createFrame(options.data); + } + + function execIteration(field, index, last) { + if (data) { + data.key = field; + data.index = index; + data.first = index === 0; + data.last = !!last; + + if (contextPath) { + data.contextPath = contextPath + field; + } + } + + ret = + ret + + fn(context[field], { + data: data, + blockParams: blockParams( + [context[field], field], + [contextPath + field, null] + ) + }); + } + + if (context && typeof context === 'object') { + if (isArray(context)) { + for (let j = context.length; i < j; i++) { + if (i in context) { + execIteration(i, i, i === context.length - 1); + } + } + } else if (typeof Symbol === 'function' && context[Symbol.iterator]) { + const newContext = []; + const iterator = context[Symbol.iterator](); + for (let it = iterator.next(); !it.done; it = iterator.next()) { + newContext.push(it.value); + } + context = newContext; + for (let j = context.length; i < j; i++) { + execIteration(i, i, i === context.length - 1); + } + } else { + let priorKey; + + Object.keys(context).forEach(key => { + // We're running the iterations one step out of sync so we can detect + // the last iteration without have to scan the object twice and create + // an itermediate keys array. + if (priorKey !== undefined) { + execIteration(priorKey, i - 1); + } + priorKey = key; + i++; + }); + if (priorKey !== undefined) { + execIteration(priorKey, i - 1, true); + } + } + } + + if (i === 0) { + ret = inverse(this); + } + + return ret; + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/helpers/helper-missing.js b/libs/events/node_modules/handlebars/lib/handlebars/helpers/helper-missing.js new file mode 100644 index 000000000..f8869e9c9 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/helpers/helper-missing.js @@ -0,0 +1,15 @@ +import Exception from '../exception'; + +export default function(instance) { + instance.registerHelper('helperMissing', function(/* [args, ]options */) { + if (arguments.length === 1) { + // A missing field in a {{foo}} construct. + return undefined; + } else { + // Someone is actually trying to call something, blow up. + throw new Exception( + 'Missing helper: "' + arguments[arguments.length - 1].name + '"' + ); + } + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/helpers/if.js b/libs/events/node_modules/handlebars/lib/handlebars/helpers/if.js new file mode 100644 index 000000000..55241ecb7 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/helpers/if.js @@ -0,0 +1,33 @@ +import { isEmpty, isFunction } from '../utils'; +import Exception from '../exception'; + +export default function(instance) { + instance.registerHelper('if', function(conditional, options) { + if (arguments.length != 2) { + throw new Exception('#if requires exactly one argument'); + } + if (isFunction(conditional)) { + conditional = conditional.call(this); + } + + // Default behavior is to render the positive path if the value is truthy and not empty. + // The `includeZero` option may be set to treat the condtional as purely not empty based on the + // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative. + if ((!options.hash.includeZero && !conditional) || isEmpty(conditional)) { + return options.inverse(this); + } else { + return options.fn(this); + } + }); + + instance.registerHelper('unless', function(conditional, options) { + if (arguments.length != 2) { + throw new Exception('#unless requires exactly one argument'); + } + return instance.helpers['if'].call(this, conditional, { + fn: options.inverse, + inverse: options.fn, + hash: options.hash + }); + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/helpers/log.js b/libs/events/node_modules/handlebars/lib/handlebars/helpers/log.js new file mode 100644 index 000000000..ab0d73646 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/helpers/log.js @@ -0,0 +1,19 @@ +export default function(instance) { + instance.registerHelper('log', function(/* message, options */) { + let args = [undefined], + options = arguments[arguments.length - 1]; + for (let i = 0; i < arguments.length - 1; i++) { + args.push(arguments[i]); + } + + let level = 1; + if (options.hash.level != null) { + level = options.hash.level; + } else if (options.data && options.data.level != null) { + level = options.data.level; + } + args[0] = level; + + instance.log(...args); + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/helpers/lookup.js b/libs/events/node_modules/handlebars/lib/handlebars/helpers/lookup.js new file mode 100644 index 000000000..5620aba32 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/helpers/lookup.js @@ -0,0 +1,9 @@ +export default function(instance) { + instance.registerHelper('lookup', function(obj, field, options) { + if (!obj) { + // Note for 5.0: Change to "obj == null" in 5.0 + return obj; + } + return options.lookupProperty(obj, field); + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/helpers/with.js b/libs/events/node_modules/handlebars/lib/handlebars/helpers/with.js new file mode 100644 index 000000000..eb1cf1a90 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/helpers/with.js @@ -0,0 +1,39 @@ +import { + appendContextPath, + blockParams, + createFrame, + isEmpty, + isFunction +} from '../utils'; +import Exception from '../exception'; + +export default function(instance) { + instance.registerHelper('with', function(context, options) { + if (arguments.length != 2) { + throw new Exception('#with requires exactly one argument'); + } + if (isFunction(context)) { + context = context.call(this); + } + + let fn = options.fn; + + if (!isEmpty(context)) { + let data = options.data; + if (options.data && options.ids) { + data = createFrame(options.data); + data.contextPath = appendContextPath( + options.data.contextPath, + options.ids[0] + ); + } + + return fn(context, { + data: data, + blockParams: blockParams([context], [data && data.contextPath]) + }); + } else { + return options.inverse(this); + } + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/internal/create-new-lookup-object.js b/libs/events/node_modules/handlebars/lib/handlebars/internal/create-new-lookup-object.js new file mode 100644 index 000000000..256f1eca1 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/internal/create-new-lookup-object.js @@ -0,0 +1,11 @@ +import { extend } from '../utils'; + +/** + * Create a new object with "null"-prototype to avoid truthy results on prototype properties. + * The resulting object can be used with "object[property]" to check if a property exists + * @param {...object} sources a varargs parameter of source objects that will be merged + * @returns {object} + */ +export function createNewLookupObject(...sources) { + return extend(Object.create(null), ...sources); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/internal/proto-access.js b/libs/events/node_modules/handlebars/lib/handlebars/internal/proto-access.js new file mode 100644 index 000000000..424e0a714 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/internal/proto-access.js @@ -0,0 +1,70 @@ +import { createNewLookupObject } from './create-new-lookup-object'; +import logger from '../logger'; + +const loggedProperties = Object.create(null); + +export function createProtoAccessControl(runtimeOptions) { + let defaultMethodWhiteList = Object.create(null); + defaultMethodWhiteList['constructor'] = false; + defaultMethodWhiteList['__defineGetter__'] = false; + defaultMethodWhiteList['__defineSetter__'] = false; + defaultMethodWhiteList['__lookupGetter__'] = false; + + let defaultPropertyWhiteList = Object.create(null); + // eslint-disable-next-line no-proto + defaultPropertyWhiteList['__proto__'] = false; + + return { + properties: { + whitelist: createNewLookupObject( + defaultPropertyWhiteList, + runtimeOptions.allowedProtoProperties + ), + defaultValue: runtimeOptions.allowProtoPropertiesByDefault + }, + methods: { + whitelist: createNewLookupObject( + defaultMethodWhiteList, + runtimeOptions.allowedProtoMethods + ), + defaultValue: runtimeOptions.allowProtoMethodsByDefault + } + }; +} + +export function resultIsAllowed(result, protoAccessControl, propertyName) { + if (typeof result === 'function') { + return checkWhiteList(protoAccessControl.methods, propertyName); + } else { + return checkWhiteList(protoAccessControl.properties, propertyName); + } +} + +function checkWhiteList(protoAccessControlForType, propertyName) { + if (protoAccessControlForType.whitelist[propertyName] !== undefined) { + return protoAccessControlForType.whitelist[propertyName] === true; + } + if (protoAccessControlForType.defaultValue !== undefined) { + return protoAccessControlForType.defaultValue; + } + logUnexpecedPropertyAccessOnce(propertyName); + return false; +} + +function logUnexpecedPropertyAccessOnce(propertyName) { + if (loggedProperties[propertyName] !== true) { + loggedProperties[propertyName] = true; + logger.log( + 'error', + `Handlebars: Access has been denied to resolve the property "${propertyName}" because it is not an "own property" of its parent.\n` + + `You can add a runtime option to disable the check or this warning:\n` + + `See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details` + ); + } +} + +export function resetLoggedProperties() { + Object.keys(loggedProperties).forEach(propertyName => { + delete loggedProperties[propertyName]; + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/internal/wrapHelper.js b/libs/events/node_modules/handlebars/lib/handlebars/internal/wrapHelper.js new file mode 100644 index 000000000..29d65b033 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/internal/wrapHelper.js @@ -0,0 +1,13 @@ +export function wrapHelper(helper, transformOptionsFn) { + if (typeof helper !== 'function') { + // This should not happen, but apparently it does in https://github.com/wycats/handlebars.js/issues/1639 + // We try to make the wrapper least-invasive by not wrapping it, if the helper is not a function. + return helper; + } + let wrapper = function(/* dynamic arguments */) { + const options = arguments[arguments.length - 1]; + arguments[arguments.length - 1] = transformOptionsFn(options); + return helper.apply(this, arguments); + }; + return wrapper; +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/logger.js b/libs/events/node_modules/handlebars/lib/handlebars/logger.js new file mode 100644 index 000000000..bc411b250 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/logger.js @@ -0,0 +1,39 @@ +import { indexOf } from './utils'; + +let logger = { + methodMap: ['debug', 'info', 'warn', 'error'], + level: 'info', + + // Maps a given level value to the `methodMap` indexes above. + lookupLevel: function(level) { + if (typeof level === 'string') { + let levelMap = indexOf(logger.methodMap, level.toLowerCase()); + if (levelMap >= 0) { + level = levelMap; + } else { + level = parseInt(level, 10); + } + } + + return level; + }, + + // Can be overridden in the host environment + log: function(level, ...message) { + level = logger.lookupLevel(level); + + if ( + typeof console !== 'undefined' && + logger.lookupLevel(logger.level) <= level + ) { + let method = logger.methodMap[level]; + // eslint-disable-next-line no-console + if (!console[method]) { + method = 'log'; + } + console[method](...message); // eslint-disable-line no-console + } + } +}; + +export default logger; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/no-conflict.js b/libs/events/node_modules/handlebars/lib/handlebars/no-conflict.js new file mode 100644 index 000000000..91ef1da59 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/no-conflict.js @@ -0,0 +1,23 @@ +/* global globalThis */ +export default function(Handlebars) { + /* istanbul ignore next */ + // https://mathiasbynens.be/notes/globalthis + (function() { + if (typeof globalThis === 'object') return; + Object.prototype.__defineGetter__('__magic__', function() { + return this; + }); + __magic__.globalThis = __magic__; // eslint-disable-line no-undef + delete Object.prototype.__magic__; + })(); + + const $Handlebars = globalThis.Handlebars; + + /* istanbul ignore next */ + Handlebars.noConflict = function() { + if (globalThis.Handlebars === Handlebars) { + globalThis.Handlebars = $Handlebars; + } + return Handlebars; + }; +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/runtime.js b/libs/events/node_modules/handlebars/lib/handlebars/runtime.js new file mode 100644 index 000000000..36bf6c94d --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/runtime.js @@ -0,0 +1,450 @@ +import * as Utils from './utils'; +import Exception from './exception'; +import { + COMPILER_REVISION, + createFrame, + LAST_COMPATIBLE_COMPILER_REVISION, + REVISION_CHANGES +} from './base'; +import { moveHelperToHooks } from './helpers'; +import { wrapHelper } from './internal/wrapHelper'; +import { + createProtoAccessControl, + resultIsAllowed +} from './internal/proto-access'; + +export function checkRevision(compilerInfo) { + const compilerRevision = (compilerInfo && compilerInfo[0]) || 1, + currentRevision = COMPILER_REVISION; + + if ( + compilerRevision >= LAST_COMPATIBLE_COMPILER_REVISION && + compilerRevision <= COMPILER_REVISION + ) { + return; + } + + if (compilerRevision < LAST_COMPATIBLE_COMPILER_REVISION) { + const runtimeVersions = REVISION_CHANGES[currentRevision], + compilerVersions = REVISION_CHANGES[compilerRevision]; + throw new Exception( + 'Template was precompiled with an older version of Handlebars than the current runtime. ' + + 'Please update your precompiler to a newer version (' + + runtimeVersions + + ') or downgrade your runtime to an older version (' + + compilerVersions + + ').' + ); + } else { + // Use the embedded version info since the runtime doesn't know about this revision yet + throw new Exception( + 'Template was precompiled with a newer version of Handlebars than the current runtime. ' + + 'Please update your runtime to a newer version (' + + compilerInfo[1] + + ').' + ); + } +} + +export function template(templateSpec, env) { + /* istanbul ignore next */ + if (!env) { + throw new Exception('No environment passed to template'); + } + if (!templateSpec || !templateSpec.main) { + throw new Exception('Unknown template object: ' + typeof templateSpec); + } + + templateSpec.main.decorator = templateSpec.main_d; + + // Note: Using env.VM references rather than local var references throughout this section to allow + // for external users to override these as pseudo-supported APIs. + env.VM.checkRevision(templateSpec.compiler); + + // backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0) + const templateWasPrecompiledWithCompilerV7 = + templateSpec.compiler && templateSpec.compiler[0] === 7; + + function invokePartialWrapper(partial, context, options) { + if (options.hash) { + context = Utils.extend({}, context, options.hash); + if (options.ids) { + options.ids[0] = true; + } + } + partial = env.VM.resolvePartial.call(this, partial, context, options); + + let extendedOptions = Utils.extend({}, options, { + hooks: this.hooks, + protoAccessControl: this.protoAccessControl + }); + + let result = env.VM.invokePartial.call( + this, + partial, + context, + extendedOptions + ); + + if (result == null && env.compile) { + options.partials[options.name] = env.compile( + partial, + templateSpec.compilerOptions, + env + ); + result = options.partials[options.name](context, extendedOptions); + } + if (result != null) { + if (options.indent) { + let lines = result.split('\n'); + for (let i = 0, l = lines.length; i < l; i++) { + if (!lines[i] && i + 1 === l) { + break; + } + + lines[i] = options.indent + lines[i]; + } + result = lines.join('\n'); + } + return result; + } else { + throw new Exception( + 'The partial ' + + options.name + + ' could not be compiled when running in runtime-only mode' + ); + } + } + + // Just add water + let container = { + strict: function(obj, name, loc) { + if (!obj || !(name in obj)) { + throw new Exception('"' + name + '" not defined in ' + obj, { + loc: loc + }); + } + return container.lookupProperty(obj, name); + }, + lookupProperty: function(parent, propertyName) { + let result = parent[propertyName]; + if (result == null) { + return result; + } + if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { + return result; + } + + if (resultIsAllowed(result, container.protoAccessControl, propertyName)) { + return result; + } + return undefined; + }, + lookup: function(depths, name) { + const len = depths.length; + for (let i = 0; i < len; i++) { + let result = depths[i] && container.lookupProperty(depths[i], name); + if (result != null) { + return depths[i][name]; + } + } + }, + lambda: function(current, context) { + return typeof current === 'function' ? current.call(context) : current; + }, + + escapeExpression: Utils.escapeExpression, + invokePartial: invokePartialWrapper, + + fn: function(i) { + let ret = templateSpec[i]; + ret.decorator = templateSpec[i + '_d']; + return ret; + }, + + programs: [], + program: function(i, data, declaredBlockParams, blockParams, depths) { + let programWrapper = this.programs[i], + fn = this.fn(i); + if (data || depths || blockParams || declaredBlockParams) { + programWrapper = wrapProgram( + this, + i, + fn, + data, + declaredBlockParams, + blockParams, + depths + ); + } else if (!programWrapper) { + programWrapper = this.programs[i] = wrapProgram(this, i, fn); + } + return programWrapper; + }, + + data: function(value, depth) { + while (value && depth--) { + value = value._parent; + } + return value; + }, + mergeIfNeeded: function(param, common) { + let obj = param || common; + + if (param && common && param !== common) { + obj = Utils.extend({}, common, param); + } + + return obj; + }, + // An empty object to use as replacement for null-contexts + nullContext: Object.seal({}), + + noop: env.VM.noop, + compilerInfo: templateSpec.compiler + }; + + function ret(context, options = {}) { + let data = options.data; + + ret._setup(options); + if (!options.partial && templateSpec.useData) { + data = initData(context, data); + } + let depths, + blockParams = templateSpec.useBlockParams ? [] : undefined; + if (templateSpec.useDepths) { + if (options.depths) { + depths = + context != options.depths[0] + ? [context].concat(options.depths) + : options.depths; + } else { + depths = [context]; + } + } + + function main(context /*, options*/) { + return ( + '' + + templateSpec.main( + container, + context, + container.helpers, + container.partials, + data, + blockParams, + depths + ) + ); + } + + main = executeDecorators( + templateSpec.main, + main, + container, + options.depths || [], + data, + blockParams + ); + return main(context, options); + } + + ret.isTop = true; + + ret._setup = function(options) { + if (!options.partial) { + let mergedHelpers = Utils.extend({}, env.helpers, options.helpers); + wrapHelpersToPassLookupProperty(mergedHelpers, container); + container.helpers = mergedHelpers; + + if (templateSpec.usePartial) { + // Use mergeIfNeeded here to prevent compiling global partials multiple times + container.partials = container.mergeIfNeeded( + options.partials, + env.partials + ); + } + if (templateSpec.usePartial || templateSpec.useDecorators) { + container.decorators = Utils.extend( + {}, + env.decorators, + options.decorators + ); + } + + container.hooks = {}; + container.protoAccessControl = createProtoAccessControl(options); + + let keepHelperInHelpers = + options.allowCallsToHelperMissing || + templateWasPrecompiledWithCompilerV7; + moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers); + moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers); + } else { + container.protoAccessControl = options.protoAccessControl; // internal option + container.helpers = options.helpers; + container.partials = options.partials; + container.decorators = options.decorators; + container.hooks = options.hooks; + } + }; + + ret._child = function(i, data, blockParams, depths) { + if (templateSpec.useBlockParams && !blockParams) { + throw new Exception('must pass block params'); + } + if (templateSpec.useDepths && !depths) { + throw new Exception('must pass parent depths'); + } + + return wrapProgram( + container, + i, + templateSpec[i], + data, + 0, + blockParams, + depths + ); + }; + return ret; +} + +export function wrapProgram( + container, + i, + fn, + data, + declaredBlockParams, + blockParams, + depths +) { + function prog(context, options = {}) { + let currentDepths = depths; + if ( + depths && + context != depths[0] && + !(context === container.nullContext && depths[0] === null) + ) { + currentDepths = [context].concat(depths); + } + + return fn( + container, + context, + container.helpers, + container.partials, + options.data || data, + blockParams && [options.blockParams].concat(blockParams), + currentDepths + ); + } + + prog = executeDecorators(fn, prog, container, depths, data, blockParams); + + prog.program = i; + prog.depth = depths ? depths.length : 0; + prog.blockParams = declaredBlockParams || 0; + return prog; +} + +/** + * This is currently part of the official API, therefore implementation details should not be changed. + */ +export function resolvePartial(partial, context, options) { + if (!partial) { + if (options.name === '@partial-block') { + partial = options.data['partial-block']; + } else { + partial = options.partials[options.name]; + } + } else if (!partial.call && !options.name) { + // This is a dynamic partial that returned a string + options.name = partial; + partial = options.partials[partial]; + } + return partial; +} + +export function invokePartial(partial, context, options) { + // Use the current closure context to save the partial-block if this partial + const currentPartialBlock = options.data && options.data['partial-block']; + options.partial = true; + if (options.ids) { + options.data.contextPath = options.ids[0] || options.data.contextPath; + } + + let partialBlock; + if (options.fn && options.fn !== noop) { + options.data = createFrame(options.data); + // Wrapper function to get access to currentPartialBlock from the closure + let fn = options.fn; + partialBlock = options.data['partial-block'] = function partialBlockWrapper( + context, + options = {} + ) { + // Restore the partial-block from the closure for the execution of the block + // i.e. the part inside the block of the partial call. + options.data = createFrame(options.data); + options.data['partial-block'] = currentPartialBlock; + return fn(context, options); + }; + if (fn.partials) { + options.partials = Utils.extend({}, options.partials, fn.partials); + } + } + + if (partial === undefined && partialBlock) { + partial = partialBlock; + } + + if (partial === undefined) { + throw new Exception('The partial ' + options.name + ' could not be found'); + } else if (partial instanceof Function) { + return partial(context, options); + } +} + +export function noop() { + return ''; +} + +function initData(context, data) { + if (!data || !('root' in data)) { + data = data ? createFrame(data) : {}; + data.root = context; + } + return data; +} + +function executeDecorators(fn, prog, container, depths, data, blockParams) { + if (fn.decorator) { + let props = {}; + prog = fn.decorator( + prog, + props, + container, + depths && depths[0], + data, + blockParams, + depths + ); + Utils.extend(prog, props); + } + return prog; +} + +function wrapHelpersToPassLookupProperty(mergedHelpers, container) { + Object.keys(mergedHelpers).forEach(helperName => { + let helper = mergedHelpers[helperName]; + mergedHelpers[helperName] = passLookupPropertyOption(helper, container); + }); +} + +function passLookupPropertyOption(helper, container) { + const lookupProperty = container.lookupProperty; + return wrapHelper(helper, options => { + return Utils.extend({ lookupProperty }, options); + }); +} diff --git a/libs/events/node_modules/handlebars/lib/handlebars/safe-string.js b/libs/events/node_modules/handlebars/lib/handlebars/safe-string.js new file mode 100644 index 000000000..468019421 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/safe-string.js @@ -0,0 +1,10 @@ +// Build out our basic SafeString type +function SafeString(string) { + this.string = string; +} + +SafeString.prototype.toString = SafeString.prototype.toHTML = function() { + return '' + this.string; +}; + +export default SafeString; diff --git a/libs/events/node_modules/handlebars/lib/handlebars/utils.js b/libs/events/node_modules/handlebars/lib/handlebars/utils.js new file mode 100644 index 000000000..6fa43b23c --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/handlebars/utils.js @@ -0,0 +1,116 @@ +const escape = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`', + '=': '=' +}; + +const badChars = /[&<>"'`=]/g, + possible = /[&<>"'`=]/; + +function escapeChar(chr) { + return escape[chr]; +} + +export function extend(obj /* , ...source */) { + for (let i = 1; i < arguments.length; i++) { + for (let key in arguments[i]) { + if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { + obj[key] = arguments[i][key]; + } + } + } + + return obj; +} + +export let toString = Object.prototype.toString; + +// Sourced from lodash +// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt +/* eslint-disable func-style */ +let isFunction = function(value) { + return typeof value === 'function'; +}; +// fallback for older versions of Chrome and Safari +/* istanbul ignore next */ +if (isFunction(/x/)) { + isFunction = function(value) { + return ( + typeof value === 'function' && + toString.call(value) === '[object Function]' + ); + }; +} +export { isFunction }; +/* eslint-enable func-style */ + +/* istanbul ignore next */ +export const isArray = + Array.isArray || + function(value) { + return value && typeof value === 'object' + ? toString.call(value) === '[object Array]' + : false; + }; + +// Older IE versions do not directly support indexOf so we must implement our own, sadly. +export function indexOf(array, value) { + for (let i = 0, len = array.length; i < len; i++) { + if (array[i] === value) { + return i; + } + } + return -1; +} + +export function escapeExpression(string) { + if (typeof string !== 'string') { + // don't escape SafeStrings, since they're already safe + if (string && string.toHTML) { + return string.toHTML(); + } else if (string == null) { + return ''; + } else if (!string) { + return string + ''; + } + + // Force a string conversion as this will be done by the append regardless and + // the regex test will do this transparently behind the scenes, causing issues if + // an object's to string has escaped characters in it. + string = '' + string; + } + + if (!possible.test(string)) { + return string; + } + return string.replace(badChars, escapeChar); +} + +export function isEmpty(value) { + if (!value && value !== 0) { + return true; + } else if (isArray(value) && value.length === 0) { + return true; + } else { + return false; + } +} + +export function createFrame(object) { + let frame = extend({}, object); + frame._parent = object; + return frame; +} + +export function blockParams(params, ids) { + params.path = ids; + return params; +} + +export function appendContextPath(contextPath, id) { + return (contextPath ? contextPath + '.' : '') + id; +} diff --git a/libs/events/node_modules/handlebars/lib/index.js b/libs/events/node_modules/handlebars/lib/index.js new file mode 100644 index 000000000..3071b22a4 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/index.js @@ -0,0 +1,26 @@ +// USAGE: +// var handlebars = require('handlebars'); +/* eslint-env node */ +/* eslint-disable no-var */ + +// var local = handlebars.create(); + +var handlebars = require('../dist/cjs/handlebars')['default']; + +var printer = require('../dist/cjs/handlebars/compiler/printer'); +handlebars.PrintVisitor = printer.PrintVisitor; +handlebars.print = printer.print; + +module.exports = handlebars; + +// Publish a Node.js require() handler for .handlebars and .hbs files +function extension(module, filename) { + var fs = require('fs'); + var templateString = fs.readFileSync(filename, 'utf8'); + module.exports = handlebars.compile(templateString); +} +/* istanbul ignore else */ +if (typeof require !== 'undefined' && require.extensions) { + require.extensions['.handlebars'] = extension; + require.extensions['.hbs'] = extension; +} diff --git a/libs/events/node_modules/handlebars/lib/precompiler.js b/libs/events/node_modules/handlebars/lib/precompiler.js new file mode 100644 index 000000000..ab6056932 --- /dev/null +++ b/libs/events/node_modules/handlebars/lib/precompiler.js @@ -0,0 +1,341 @@ +/* eslint-env node */ +/* eslint-disable no-console */ +import Async from 'neo-async'; +import fs from 'fs'; +import * as Handlebars from './handlebars'; +import { basename } from 'path'; +import { SourceMapConsumer, SourceNode } from 'source-map'; + +module.exports.loadTemplates = function(opts, callback) { + loadStrings(opts, function(err, strings) { + if (err) { + callback(err); + } else { + loadFiles(opts, function(err, files) { + if (err) { + callback(err); + } else { + opts.templates = strings.concat(files); + callback(undefined, opts); + } + }); + } + }); +}; + +function loadStrings(opts, callback) { + let strings = arrayCast(opts.string), + names = arrayCast(opts.name); + + if (names.length !== strings.length && strings.length > 1) { + return callback( + new Handlebars.Exception( + 'Number of names did not match the number of string inputs' + ) + ); + } + + Async.map( + strings, + function(string, callback) { + if (string !== '-') { + callback(undefined, string); + } else { + // Load from stdin + let buffer = ''; + process.stdin.setEncoding('utf8'); + + process.stdin.on('data', function(chunk) { + buffer += chunk; + }); + process.stdin.on('end', function() { + callback(undefined, buffer); + }); + } + }, + function(err, strings) { + strings = strings.map((string, index) => ({ + name: names[index], + path: names[index], + source: string + })); + callback(err, strings); + } + ); +} + +function loadFiles(opts, callback) { + // Build file extension pattern + let extension = (opts.extension || 'handlebars').replace( + /[\\^$*+?.():=!|{}\-[\]]/g, + function(arg) { + return '\\' + arg; + } + ); + extension = new RegExp('\\.' + extension + '$'); + + let ret = [], + queue = (opts.files || []).map(template => ({ template, root: opts.root })); + Async.whilst( + () => queue.length, + function(callback) { + let { template: path, root } = queue.shift(); + + fs.stat(path, function(err, stat) { + if (err) { + return callback( + new Handlebars.Exception(`Unable to open template file "${path}"`) + ); + } + + if (stat.isDirectory()) { + opts.hasDirectory = true; + + fs.readdir(path, function(err, children) { + /* istanbul ignore next : Race condition that being too lazy to test */ + if (err) { + return callback(err); + } + children.forEach(function(file) { + let childPath = path + '/' + file; + + if ( + extension.test(childPath) || + fs.statSync(childPath).isDirectory() + ) { + queue.push({ template: childPath, root: root || path }); + } + }); + + callback(); + }); + } else { + fs.readFile(path, 'utf8', function(err, data) { + /* istanbul ignore next : Race condition that being too lazy to test */ + if (err) { + return callback(err); + } + + if (opts.bom && data.indexOf('\uFEFF') === 0) { + data = data.substring(1); + } + + // Clean the template name + let name = path; + if (!root) { + name = basename(name); + } else if (name.indexOf(root) === 0) { + name = name.substring(root.length + 1); + } + name = name.replace(extension, ''); + + ret.push({ + path: path, + name: name, + source: data + }); + + callback(); + }); + } + }); + }, + function(err) { + if (err) { + callback(err); + } else { + callback(undefined, ret); + } + } + ); +} + +module.exports.cli = function(opts) { + if (opts.version) { + console.log(Handlebars.VERSION); + return; + } + + if (!opts.templates.length && !opts.hasDirectory) { + throw new Handlebars.Exception( + 'Must define at least one template or directory.' + ); + } + + if (opts.simple && opts.min) { + throw new Handlebars.Exception('Unable to minimize simple output'); + } + + const multiple = opts.templates.length !== 1 || opts.hasDirectory; + if (opts.simple && multiple) { + throw new Handlebars.Exception( + 'Unable to output multiple templates in simple mode' + ); + } + + // Force simple mode if we have only one template and it's unnamed. + if ( + !opts.amd && + !opts.commonjs && + opts.templates.length === 1 && + !opts.templates[0].name + ) { + opts.simple = true; + } + + // Convert the known list into a hash + let known = {}; + if (opts.known && !Array.isArray(opts.known)) { + opts.known = [opts.known]; + } + if (opts.known) { + for (let i = 0, len = opts.known.length; i < len; i++) { + known[opts.known[i]] = true; + } + } + + const objectName = opts.partial ? 'Handlebars.partials' : 'templates'; + + let output = new SourceNode(); + if (!opts.simple) { + if (opts.amd) { + output.add( + "define(['" + + opts.handlebarPath + + 'handlebars.runtime\'], function(Handlebars) {\n Handlebars = Handlebars["default"];' + ); + } else if (opts.commonjs) { + output.add('var Handlebars = require("' + opts.commonjs + '");'); + } else { + output.add('(function() {\n'); + } + output.add(' var template = Handlebars.template, templates = '); + if (opts.namespace) { + output.add(opts.namespace); + output.add(' = '); + output.add(opts.namespace); + output.add(' || '); + } + output.add('{};\n'); + } + + opts.templates.forEach(function(template) { + let options = { + knownHelpers: known, + knownHelpersOnly: opts.o + }; + + if (opts.map) { + options.srcName = template.path; + } + if (opts.data) { + options.data = true; + } + + let precompiled = Handlebars.precompile(template.source, options); + + // If we are generating a source map, we have to reconstruct the SourceNode object + if (opts.map) { + let consumer = new SourceMapConsumer(precompiled.map); + precompiled = SourceNode.fromStringWithSourceMap( + precompiled.code, + consumer + ); + } + + if (opts.simple) { + output.add([precompiled, '\n']); + } else { + if (!template.name) { + throw new Handlebars.Exception('Name missing for template'); + } + + if (opts.amd && !multiple) { + output.add('return '); + } + output.add([ + objectName, + "['", + template.name, + "'] = template(", + precompiled, + ');\n' + ]); + } + }); + + // Output the content + if (!opts.simple) { + if (opts.amd) { + if (multiple) { + output.add(['return ', objectName, ';\n']); + } + output.add('});'); + } else if (!opts.commonjs) { + output.add('})();'); + } + } + + if (opts.map) { + output.add('\n//# sourceMappingURL=' + opts.map + '\n'); + } + + output = output.toStringWithSourceMap(); + output.map = output.map + ''; + + if (opts.min) { + output = minify(output, opts.map); + } + + if (opts.map) { + fs.writeFileSync(opts.map, output.map, 'utf8'); + } + output = output.code; + + if (opts.output) { + fs.writeFileSync(opts.output, output, 'utf8'); + } else { + console.log(output); + } +}; + +function arrayCast(value) { + value = value != null ? value : []; + if (!Array.isArray(value)) { + value = [value]; + } + return value; +} + +/** + * Run uglify to minify the compiled template, if uglify exists in the dependencies. + * + * We are using `require` instead of `import` here, because es6-modules do not allow + * dynamic imports and uglify-js is an optional dependency. Since we are inside NodeJS here, this + * should not be a problem. + * + * @param {string} output the compiled template + * @param {string} sourceMapFile the file to write the source map to. + */ +function minify(output, sourceMapFile) { + try { + // Try to resolve uglify-js in order to see if it does exist + require.resolve('uglify-js'); + } catch (e) { + if (e.code !== 'MODULE_NOT_FOUND') { + // Something else seems to be wrong + throw e; + } + // it does not exist! + console.error( + 'Code minimization is disabled due to missing uglify-js dependency' + ); + return output; + } + return require('uglify-js').minify(output.code, { + sourceMap: { + content: output.map, + url: sourceMapFile + } + }); +} diff --git a/libs/events/node_modules/handlebars/package.json b/libs/events/node_modules/handlebars/package.json new file mode 100644 index 000000000..fc8bfa666 --- /dev/null +++ b/libs/events/node_modules/handlebars/package.json @@ -0,0 +1,135 @@ +{ + "name": "handlebars", + "barename": "handlebars", + "version": "4.7.8", + "description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration", + "homepage": "https://www.handlebarsjs.com/", + "keywords": [ + "handlebars", + "mustache", + "template", + "html" + ], + "repository": { + "type": "git", + "url": "https://github.com/handlebars-lang/handlebars.js.git" + }, + "author": "Yehuda Katz", + "license": "MIT", + "readmeFilename": "README.md", + "engines": { + "node": ">=0.4.7" + }, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + }, + "devDependencies": { + "@playwright/test": "^1.17.1", + "aws-sdk": "^2.1.49", + "babel-loader": "^5.0.0", + "babel-runtime": "^5.1.10", + "benchmark": "~1.0", + "chai": "^4.2.0", + "chai-diff": "^1.0.1", + "concurrently": "^5.0.0", + "dirty-chai": "^2.0.1", + "dtslint": "^0.5.5", + "dustjs-linkedin": "^2.0.2", + "eco": "~1.1.0-rc-3", + "eslint": "^6.7.2", + "eslint-config-prettier": "^6.7.0", + "eslint-plugin-compat": "^3.13.0", + "eslint-plugin-es5": "^1.4.1", + "fs-extra": "^8.1.0", + "grunt": "^1.0.4", + "grunt-babel": "^5.0.0", + "grunt-cli": "^1", + "grunt-contrib-clean": "^1", + "grunt-contrib-concat": "^1", + "grunt-contrib-connect": "^1", + "grunt-contrib-copy": "^1", + "grunt-contrib-requirejs": "^1", + "grunt-contrib-uglify": "^1", + "grunt-contrib-watch": "^1.1.0", + "grunt-shell": "^4.0.0", + "grunt-webpack": "^1.0.8", + "husky": "^3.1.0", + "jison": "~0.3.0", + "lint-staged": "^9.5.0", + "mocha": "^5", + "mock-stdin": "^0.3.0", + "mustache": "^2.1.3", + "nyc": "^14.1.1", + "prettier": "^1.19.1", + "semver": "^5.0.1", + "sinon": "^7.5.0", + "typescript": "^3.4.3", + "underscore": "^1.5.1", + "webpack": "^1.12.6", + "webpack-dev-server": "^1.12.1" + }, + "main": "lib/index.js", + "types": "types/index.d.ts", + "browser": "./dist/cjs/handlebars.js", + "bin": { + "handlebars": "bin/handlebars" + }, + "scripts": { + "build": "grunt build", + "release": "npm run build && grunt release", + "format": "prettier --write '**/*.js' && eslint --fix .", + "lint": "npm run lint:eslint && npm run lint:prettier && npm run lint:types", + "lint:eslint": "eslint --max-warnings 0 .", + "lint:prettier": "prettier --check '**/*.js'", + "lint:types": "dtslint types", + "test": "npm run test:mocha", + "test:mocha": "grunt build && grunt test", + "test:browser": "playwright test --config tests/browser/playwright.config.js tests/browser/spec.js", + "test:integration": "grunt integration-tests", + "test:serve": "grunt connect:server:keepalive", + "extensive-tests-and-publish-to-aws": "npx mocha tasks/tests/ && grunt --stack extensive-tests-and-publish-to-aws", + "--- combined tasks ---": "", + "check-before-pull-request": "concurrently --kill-others-on-fail npm:lint npm:test" + }, + "jspm": { + "main": "handlebars", + "directories": { + "lib": "dist/amd" + }, + "buildConfig": { + "minify": true + } + }, + "files": [ + "bin", + "dist/*.js", + "dist/amd/**/*.js", + "dist/cjs/**/*.js", + "lib", + "release-notes.md", + "runtime.js", + "types/*.d.ts", + "runtime.d.ts" + ], + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{js,css,json}": [ + "prettier --write", + "git add" + ], + "*.js": [ + "eslint --fix", + "git add" + ] + } +} diff --git a/libs/events/node_modules/handlebars/release-notes.md b/libs/events/node_modules/handlebars/release-notes.md new file mode 100644 index 000000000..0668bcc1b --- /dev/null +++ b/libs/events/node_modules/handlebars/release-notes.md @@ -0,0 +1,1102 @@ +# Release Notes + +## Development + +[Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.8...master) + +## v4.7.8 - July 27th, 2023 + +- Make library compatible with workers (#1894) - 3d3796c +- Don't rely on Node.js global object (#1776) - 2954e7e +- Fix compiling of each block params in strict mode (#1855) - 30dbf04 +- Fix rollup warning when importing Handlebars as ESM - 03d387b +- Fix bundler issue with webpack 5 (#1862) - c6c6bbb +- Use https instead of git for mustache submodule - 88ac068 + +[Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.7...v4.7.8) + +## v4.7.7 - February 15th, 2021 + +- fix weird error in integration tests - eb860c0 +- fix: check prototype property access in strict-mode (#1736) - b6d3de7 +- fix: escape property names in compat mode (#1736) - f058970 +- refactor: In spec tests, use expectTemplate over equals and shouldThrow (#1683) - 77825f8 +- chore: start testing on Node.js 12 and 13 - 3789a30 + +(POSSIBLY) BREAKING CHANGES: + +- the changes from version [4.6.0](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md#v460---january-8th-2020) now also apply + in when using the compile-option "strict: true". Access to prototype properties is forbidden completely by default, specific properties or methods + can be allowed via runtime-options. See #1633 for details. If you are using Handlebars as documented, you should not be accessing prototype properties + from your template anyway, so the changes should not be a problem for you. Only the use of undocumented features can break your build. + +That is why we only bump the patch version despite mentioning breaking changes. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.7.6...v4.7.7) + +## v4.7.6 - April 3rd, 2020 + +Chore/Housekeeping: + +- [#1672](https://github.com/wycats/handlebars.js/issues/1672) - Switch cmd parser to latest minimist ([@dougwilson](https://api.github.com/users/dougwilson) + +Compatibility notes: + +- Restored Node.js compatibility + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.7.5...v4.7.6) + +## v4.7.5 - April 2nd, 2020 + +Chore/Housekeeping: + +- ~Node.js version support has been changed to v6+~ Reverted in 4.7.6 + +Compatibility notes: + +- ~Node.js < v6 is no longer supported~ Reverted in 4.7.6 + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.7.4...v4.7.5) + +## v4.7.4 - April 1st, 2020 + +Chore/Housekeeping: + +- [#1666](https://github.com/wycats/handlebars.js/issues/1666) - Replaced minimist with yargs for handlebars CLI ([@aorinevo](https://api.github.com/users/aorinevo), [@AviVahl](https://api.github.com/users/AviVahl) & [@fabb](https://api.github.com/users/fabb)) + +Compatibility notes: + +- No incompatibilities are to be expected + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.7.3...v4.7.4) + +## v4.7.3 - February 5th, 2020 + +Chore/Housekeeping: + +- [#1644](https://github.com/wycats/handlebars.js/issues/1644) - Download links to aws broken on handlebarsjs.com - access denied ([@Tea56](https://api.github.com/users/Tea56)) +- Fix spelling and punctuation in changelog - d78cc73 + +Bugfixes: + +- Add Type Definition for Handlebars.VERSION, Fixes #1647 - 4de51fe +- Include Type Definition for runtime.js in Package - a32d05f + +Compatibility notes: + +- No incompatibilities are to be expected + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.7.2...v4.7.3) + +## v4.7.2 - January 13th, 2020 + +Bugfixes: + +- fix: don't wrap helpers that are not functions - 9d5aa36, #1639 + +Chore/Build: + +- chore: execute saucelabs-task only if access-key exists - a4fd391 + +Compatibility notes: + +- No breaking changes are to be expected + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.7.1...v4.7.2) + +## v4.7.1 - January 12th, 2020 + +Bugfixes: + +- fix: fix log output in case of illegal property access - f152dfc +- fix: log error for illegal property access only once per property - 3c1e252 + +Compatibility notes: + +- no incompatibilities are to be expected. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.7.0...v4.7.1) + +## v4.7.0 - January 10th, 2020 + +Features: + +- feat: default options for controlling proto access - 7af1c12, #1635 + - This makes it possible to disable the prototype access restrictions added in 4.6.0 + - an error is logged in the console, if access to prototype properties is attempted and denied + and no explicit configuration has taken place. + +Compatibility notes: + +- no compatibilities are expected + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.6.0...v4.7.0) + +## v4.6.0 - January 8th, 2020 + +Features: + +- feat: access control to prototype properties via whitelist (#1633)- d03b6ec + +Bugfixes: + +- fix(runtime.js): partials compile not caching (#1600) - 23d58e7 + +Chores, docs: + +- various refactorings and improvements to tests - d7f0dcf, 187d611, d337f40 +- modernize the build-setup + - use prettier to format and eslint to verify - c40d9f3, 8901c28, e97685e, 1f61f21 + - use nyc instead of istanbul to collect coverage - 164b7ff, 1ebce2b + - update build code to use modern javascript and make it cleaner - 14b621c, 1ec1737, 3a5b65e, dde108e, 04b1984, 587e7a3 + - restructur build commands - e913dc5, +- eslint rule changes - ac4655e, dc54952 +- Update (C) year in the LICENSE file - d1fb07b +- chore: try to fix saucelabs credentials (#1627) - +- Update readme.md with updated links (#1620) - edcc84f + +BREAKING CHANGES: + +- access to prototype properties is forbidden completely by default, + specific properties or methods can be allowed via runtime-options. + See #1633 for details. + If you are using Handlebars as documented, you should not be accessing prototype + properties from your template anyway, so the changes should not be a problem + for you. Only the use of undocumented features can break your build. + + That is why we only bump the minor version despite mentioning breaking changes. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.3...v4.6.0) + +## v4.5.3 - November 18th, 2019 + +Bugfixes: + +- fix: add "no-prototype-builtins" eslint-rule and fix all occurences - f7f05d7 +- fix: add more properties required to be enumerable - 1988878 + +Chores / Build: + +- fix: use !== 0 instead of != 0 - c02b05f +- add chai and dirty-chai and sinon, for cleaner test-assertions and spies, + deprecate old assertion-methods - 93e284e, 886ba86, 0817dad, 93516a0 + +Security: + +- The properties `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__` + have been added to the list of "properties that must be enumerable". + If a property by that name is found and not enumerable on its parent, + it will silently evaluate to `undefined`. This is done in both the compiled template and the "lookup"-helper. + This will prevent new Remote-Code-Execution exploits that have been + published recently. + +Compatibility notes: + +- Due to the security-fixes. The semantics of the templates using + `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__` in the respect that those expression now return + `undefined` rather than their actual value from the proto. +- The semantics have not changed in cases where the properties are enumerable, as in: + +```js +{ + __proto__: 'some string'; +} +``` + +- The change may be breaking in that respect, but we still only + increase the patch-version, because the incompatible use-cases + are not intended, undocumented and far less important than fixing + Remote-Code-Execution exploits on existing systems. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.2...v4.5.3) + +## v4.5.2 - November 13th, 2019 + +# Bugfixes + +- fix: use String(field) in lookup when checking for "constructor" - d541378 +- test: add fluent API for testing Handlebars - c2ac79c + +Compatibility notes: + +- no incompatibility are to be expected + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.1...v4.5.2) + +## v4.5.1 - October 29th, 2019 + +Bugfixs + +- fix: move "eslint-plugin-compat" to devDependencies - 5e9d17f (#1589) + +Compatibility notes: + +- No compatibility issues are to be expected + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.0...v4.5.1) + +## v4.5.0 - October 28th, 2019 + +Features / Improvements + +- Add method Handlebars.parseWithoutProcessing (#1584) - 62ed3c2 +- add guard to if & unless helpers (#1549) +- show source location for the strict lookup exceptions - feb60f8 + +Bugfixes: + +- Use objects for hash value tracking - 7fcf9d2 + +Chore: + +- Resolve deprecation warning message from eslint while running eslint (#1586) - 7052e88 +- chore: add eslint-plugin-compat and eslint-plugin-es5 - 088e618 + +Compatibility notes: + +- No compatibility issues are to be expected + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.5...v4.5.0) + +## v4.4.5 - October 20th, 2019 + +Bugfixes: + +- Contents of raw-blocks must be matched with non-eager regex-matching - 8d5530e, #1579 + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.4...v4.4.5) + +## v4.4.4 - October 20th, 2019 + +Bugfixes: + +- fix: prevent zero length tokens in raw-blocks (#1577, #1578) - f1752fe + +Chore: + +- chore: link to s3 bucket with https, add "npm ci" to build instructions - 0b593bf + +Compatibility notes: + +- no compatibility issues are expected + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.3...v4.4.4) + +## v4.4.3 - October 8th, 2019 + +Bugfixes + +Typings: + +- add missing type fields to AST typings and add tests for them - 0440af2 + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.2...v4.4.3) + +## v4.4.2 - October 2nd, 2019 + +- chore: fix grunt-saucelabs dependency - b7eada0 + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.1...v4.4.2) + +## v4.4.1 - October 2nd, 2019 + +- [#1562](https://github.com/wycats/handlebars.js/issues/1562) - Error message for syntax error missing location in 4.2.1+ + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.0...v4.4.1) + +## v4.4.0 - September 29th, 2019 + +- Added support for iterable objects in {{#each}} helper (#1557) - cf7545e + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.4...v4.4.0) + +## v4.3.4 - September 28th, 2019 + +- fix: harden "propertyIsEnumerable"-check - ff4d827 + +Compatibility notes: + +- No incompatibilities are known. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.3...v4.3.4) + +## v4.3.3 - September 27th, 2019 + +- fix test case for browsers that do not support **defineGetter** - 8742bde + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.2...v4.3.3) + +## v4.3.2 - September 26th, 2019 + +- Use Object.prototype.propertyIsEnumerable to check for constructors - 213c0bb, #1563 + +Compatibility notes: + +- There are no breaking changes + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.1...v4.3.2) + +## v4.3.1 - September 25th, 2019 + +Fixes: + +- do not break on precompiled templates from Handlebars >=4.0.0 <4.3.0 - 1266838, #1561 +- Ensure allowCallsToHelperMissing runtime option is optional in typings - 93444c5, 64ecb9e, #1560 + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.0...v4.3.1) + +## v4.3.0 - September 24th, 2019 + +Fixes: + +- Security: Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72 +- Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72 + +Features: + +- Add new runtime option `allowCallsToHelperMissing` to allow calling `blockHelperMissing` and `helperMissing`. + +Breaking changes: + +Compatibility notes: + +- Compiler revision increased - 06b7224 + + - This means that template compiled with versions prior to 4.3.0 will not work with runtimes >= 4.3.0 + The increase was done because the "helperMissing" and "blockHelperMissing" are now moved from the helpers + to the internal "container.hooks" object, so old templates will not be able to call them anymore. We suggest + that you always recompile your templates with the latest compiler in your build pipelines. + +- Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72 + - Calling "helperMissing" and "blockHelperMissing" directly from a template (like in `{{blockHelperMissing}}` was + never intended and was part of the exploits that have been revealed early in 2019 + (see https://github.com/wycats/handlebars.js/issues/1495). _It is also part of a new exploit that + is not captured by the earlier fix._ In order to harden Handlebars against such exploits, calling thos helpers + is now not possible anymore. _Overriding_ those helpers is still possible. + - If you really need this behavior, you can set the runtime option `allowCallsToHelperMissing` to `true` and the + calls will again be possible + +Both bullet points imly that Handlebars is not 100% percent compatible to 4.2.0, despite the minor version bump. + +We consider it more important to resolve a major security issue than to maintain 100% compatibility. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.2.1...v4.3.0) + +## v4.2.1 - September 20th, 2019 + +Bugfixes: + +- The "browser" property in the package.json has been updated to use the common-js builds instead of the minified UMD - c55a7be, #1553 + +Compatibility notes: + +- No compatibility issues should arise + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.2.0...v4.2.1) + +## v4.2.0 - September 3rd, 2019 + +Chore/Test: + +- Use custom `grunt-saucelab` with current sauce-connect proxy - f119497 +- Add framework for various integration tests - f9cce4d +- Add integration test for webpack - a57b682 + +Bugfixes: + +- [#1544](https://github.com/wycats/handlebars.js/issues/1544) - Typescript types: `knownHelpers` doesnt allow for custom helpers ([@NickCis](https://api.github.com/users/NickCis)) +- [#1534](https://github.com/wycats/handlebars.js/pull/1534) - Add typings for "Handlebars.VM.resolvePartial ([@AndrewLeedham](https://api.github.com/users/AndrewLeedham)) + +Features: + +- [#1540](https://github.com/wycats/handlebars.js/pull/1540) - added "browser"-property to package.json, resolves #1102 ([@ouijan](https://api.github.com/users/ouijan)) + +Compatibility notes: + +- The new "browser"-property should not break anything, but you can never be sure. The integration test for webpack + shows that it works, but if it doesn't please open an issue. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2-0...v4.2.0) + +## v4.1.2-0 - August 25th, 2019 + +[#1540](https://github.com/wycats/handlebars.js/pull/1540) - added browser to package.json, resolves #1102 ([@ouijan](https://api.github.com/users/ouijan)) + +Compatibility notes: + +- We are not sure if imports via webpack are still working, which is why this release is a pre-release + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.1.2-0) + +## v4.1.2 - April 13th, 2019 + +Chore/Test: + +- [#1515](https://github.com/wycats/handlebars.js/pull/1515) - Port over linting and test for typings ([@zimmi88](https://api.github.com/users/zimmi88)) +- chore: add missing typescript dependency, add package-lock.json - 594f1e3 +- test: remove safari from saucelabs - 871accc + +Bugfixes: + +- fix: prevent RCE through the "lookup"-helper - cd38583 + +Compatibility notes: + +Access to the constructor of a class thought `{{lookup obj "constructor" }}` is now prohibited. This closes +a leak that only half closed in versions 4.0.13 and 4.1.0, but it is a slight incompatibility. + +This kind of access is not the intended use of Handlebars and leads to the vulnerability described +in #1495. We will **not** increase the major version, because such use is not intended or documented, +and because of the potential impact of the issue (we fear that most people won't use a new major version +and the issue may not be resolved on many systems). + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.1.1...v4.1.2) + +## v4.1.1 - March 16th, 2019 + +Bugfixes: + +- fix: add "runtime.d.ts" to allow "require('handlebars/runtime')" in TypeScript - 5cedd62 + +Refactorings: + +- replace "async" with "neo-async" - 048f2ce +- use "substring"-function instead of "substr" - 445ae12 + +Compatibility notes: + +- This is a bugfix release. There are no breaking change and no new features. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.1.0...v4.1.1) + +## v4.1.0 - February 7th, 2019 + +New Features + +- import TypeScript typings - 27ac1ee + +Security fixes: + +- disallow access to the constructor in templates to prevent RCE - 42841c4, #1495 + +Housekeeping + +- chore: fix components/handlebars package.json and auto-update on release - bacd473 +- chore: Use node 10 to build handlebars - 78dd89c +- chore/doc: Add more release docs - 6b87c21 + +Compatibility notes: + +Access to class constructors (i.e. `({}).constructor`) is now prohibited to prevent +Remote Code Execution. This means that following construct will no work anymore: + +``` +class SomeClass { +} + +SomeClass.staticProperty = 'static' + +var template = Handlebars.compile('{{constructor.staticProperty}}'); +document.getElementById('output').innerHTML = template(new SomeClass()); +// expected: 'static', but now this is empty. +``` + +This kind of access is not the intended use of Handlebars and leads to the vulnerability described in #1495. We will **not** increase the major version, because such use is not intended or documented, and because of the potential impact of the issue (we fear that most people won't use a new major version and the issue may not be resolved on many systems). + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.12...v4.1.0) + +## v4.0.12 - September 4th, 2018 + +New features: + +- none + +Various dependency updates + +- [#1464](https://github.com/wycats/handlebars.js/pull/1464) - Bump versions of grunt-plugins to 1.x +- [#1398](https://github.com/wycats/handlebars.js/pull/1398) - Chore: updated various dev dependencies +- upgrade uglify-js - d3d3942 +- Update grunt-eslint to 20.1.0 - 7729aa9 +- Update dependencies "async" to 2.5.0 and "source-map" to 0.6.1 (73d5637) + +Bugfixes: + +- [components/handlebars.js#24](https://github.com/components/handlebars.js#24) Add package.json to components shim +- Updated `source-map`-package should work better with `rollup`[#1463](https://github.com/wycats/handlebars.js/issues/1463) + +Removed obsolete code: + +- unnecessary check - 0ddff8b +- Use `files` field - 69c6ca5 +- Update jsfiddle to 4.0.11 - 8947dd0 + +Compatibility notes: + +- No compatibility issues are to be expected + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.11...v4.0.12) + +## v4.0.11 - October 17th, 2017 + +- [#1391](https://github.com/wycats/handlebars.js/issues/1391) - `uglify-js` is unconditionally imported, but only listed as optional dependency ([@Turbo87](https://github.com/Turbo87)) +- [#1233](https://github.com/wycats/handlebars.js/issues/1233) - Unable to build under windows - error at test:bin task ([@blikblum](https://github.com/blikblum)) +- Update (C) year in the LICENSE file - 21386b6 + +Compatibility notes: + +- This is a bugfix release. There are no breaking change and no new features. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.10...v4.0.11) + +## v4.0.10 - May 21st, 2017 + +- Fix regression in 4.0.9: Replace "Object.assign" (not support in IE) by "util/extend" - 0e953d1 + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.9...v4.0.10) + +## v4.0.9 - May 21st, 2017 + +- [#1327](https://github.com/wycats/handlebars.js/issues/1327) Handlebars.compile() does not modify "options" anymore +- pending [#1331](https://github.com/wycats/handlebars.js/issues/1331) Attempts to build Handlebars in a Windows environment + - Fix build in windows - cc554a5 + - Ensure LF line-edings in handlebars-template fixtures (\*.hbs) - ed879a6 + - Run integration test with `node handlebars -a ...` on Windows - 2e21e2b + - Ensure LF line-edings in lexer-files (\*.l) - bdfdbea + - Force LF line-endings for spec/artifacts - b50ef03 + - Use istanbul/lib/cli.js instead of node_modules/.bin/istanbul - 6e6269f +- TravisCI: Publish valid semver tags independently of the branch - 7378f85 + +Compatibility notes: + +- No compatibility issues are expected. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.8...v4.0.9) + +## v4.0.8 - May 2nd, 2017 + +- [#1341](https://github.com/wycats/handlebars.js/issues/1341) [#1342](https://github.com/wycats/handlebars.js/issues/1342) Allow partial-blocks to be executed without "options" ([@nknapp](https://github.com/nknapp)) - a00c598 + +Compatibility notes: + +- No breaking changes + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.7...v4.0.8) + +## v4.0.7 - April 29th, 2017 + +- [#1319](https://github.com/wycats/handlebars.js/issues/1319): Fix context-stack when calling block-helpers on null values ([@nknapp](https://github.com/nknapp)) - c8f4b57 +- [#1315](https://github.com/wycats/handlebars.js/pull/1315) Parser: Change suffix to use ES6 default module export ([@Turbo87](https://github.com/Turbo87))- b617375 +- [#1290](https://github.com/wycats/handlebars.js/pull/1290) [#1252](https://github.com/wycats/handlebars.js/issue/1290) Add more tests for partial-blocks and inline partials ([@nknapp](https://github.com/nknapp)) - 63a8e0c +- [#1252](https://github.com/wycats/handlebars.js/issue/1290) Using @partial-block twice in a template not possible ([@nknapp](https://github.com/nknapp)) - 5a164d0 +- [#1310](https://github.com/wycats/handlebars.js/pull/1310) Avoid duplicate "sourceMappingURL=" lines. ([@joonas-lahtinen](https://github.com/joonas-lahtinen)) - 01b0f65 +- [#1275](https://github.com/wycats/handlebars.js/pull/1275) require('sys') is deprecated, using 'util' instead ([@travnels](https://github.com/travnels)) - 406f2ee +- [#1285](https://github.com/wycats/handlebars.js/pull/1285) [#1284](https://github.com/wycats/handlebars.js/issues/1284) Make "column"-property of Errors enumerable ([@nknapp](https://github.com/nknapp)) - a023cb4 +- [#1285](https://github.com/wycats/handlebars.js/pull/1285) Testcase to verify that compile-errors have a column-property ([@nknapp](https://github.com/nknapp)) - c7dc353 + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.6...v4.0.7) + +## v4.0.6 - November 12th, 2016 + +- [#1243](https://github.com/wycats/handlebars.js/pull/1243) - Walk up data frames for nested @partial-block ([@lawnsea](https://github.com/lawnsea)) +- [#1210](https://github.com/wycats/handlebars.js/pull/1210) - Add a new lightweight package based on handlebars in the README ([@kabirbaidhya](https://github.com/kabirbaidhya)) +- [#1187](https://github.com/wycats/handlebars.js/pull/1187) - Ensure that existing blockParams and depths are respected on dupe programs ([@charleso](https://github.com/charleso)) +- [#1191](https://github.com/wycats/handlebars.js/pull/1191) - Added cory ([@leo](https://github.com/leo)) +- [#1177](https://github.com/wycats/handlebars.js/pull/1177) - Preserve License info in Closure Compiler ([@gennadiylitvinyuk](https://github.com/gennadiylitvinyuk)) +- [#1171](https://github.com/wycats/handlebars.js/pull/1171) - Contributing doc fix: failing thats -> failing tests ([@paulfalgout](https://github.com/paulfalgout)) +- [#1166](https://github.com/wycats/handlebars.js/pull/1166) - Update license date ([@timwangdev](https://github.com/timwangdev)) +- Update jsfiddle to point to latest - 959ee55 (originally dfc7554 by [@kpdecker](https://github.com/kpdecker)) +- [#1163](https://github.com/wycats/handlebars.js/pull/1163) - Fix typos on decorators-api.md. ([@adjohnson916](https://github.com/adjohnson916)) +- Drop extra Error params - 8c19874 (originally 63fdb92 by [@kpdecker](https://github.com/kpdecker)) +- [#1153](https://github.com/wycats/handlebars.js/pull/1153) - Add documentation for running tests to contributing.md ([@ryanmurakami](https://github.com/ryanmurakami)) +- Avoid error in older browsers in test - 400916c (originally a6121ca by [@kpdecker](https://github.com/kpdecker)) +- Update target browser test versions - fee2334 (originally 871c32a by [@kpdecker](https://github.com/kpdecker)) +- Exclude coverage check in exception conditional - 32d6363 (originally 326734b by [@kpdecker](https://github.com/kpdecker)) +- Fix throw when creating exception object in Safari - 20c965c (originally 2ea6119 by [@kpdecker](https://github.com/kpdecker)) +- Update build for modern node versions - 6c9f98c (originally 8289c0b by [@kpdecker](https://github.com/kpdecker)) +- [#1135](https://github.com/wycats/handlebars.js/issues/1135) - Relax depth check for context push - c393c81 (originally 25458fd by [@kpdecker](https://github.com/kpdecker)) + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.5...v4.0.6) + +## v4.0.5 - November 19th, 2015 + +- [#1132](https://github.com/wycats/handlebars.js/pull/1132) - Update uglify-js to avoid vulnerability ([@plynchnlm](https://github.com/plynchnlm)) +- [#1129](https://github.com/wycats/handlebars.js/issues/1129) - Minified lib returns an empty string ([@bricss](https://github.com/bricss)) +- Return current handlebars instance from noConflict - 685cf92 +- Add webpack to dev dependency to support npm 3 - 7a6c228 +- Further relax uglify dependency - 0a3b3c2 +- Include tests for minimized artifacts - c21118d +- Fix lint errors under latest eslint - 9f59de9 +- Add print-script helper script - 98a6717 + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.4...v4.0.5) + +## v4.0.4 - October 29th, 2015 + +- [#1121](https://github.com/wycats/handlebars.js/pull/1121) - Include partial name in 'undefined partial' exception message ([@shinypb](https://github.com/shinypb)) +- [#1125](https://github.com/wycats/handlebars.js/pull/1125) - Add promised-handlebars to "in-the-wild"-list ([@nknapp](https://github.com/nknapp)) + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.3...v4.0.4) + +## v4.0.3 - September 23rd, 2015 + +- [#1099](https://github.com/wycats/handlebars.js/issues/1099) - @partial-block is overridden ([@btmorex](https://github.com/btmorex)) +- [#1093](https://github.com/wycats/handlebars.js/issues/1093) - #each skips iteration on undefined values ([@florianpilz](https://github.com/florianpilz)) +- [#1092](https://github.com/wycats/handlebars.js/issues/1092) - Square braces in key name ([@distantnative](https://github.com/distantnative)) +- [#1091](https://github.com/wycats/handlebars.js/pull/1091) - fix typo in release notes ([@nikolas](https://github.com/nikolas)) +- [#1090](https://github.com/wycats/handlebars.js/pull/1090) - grammar fixes in 4.0.0 release notes ([@nikolas](https://github.com/nikolas)) + +Compatibility notes: + +- `each` iteration with `undefined` values has been restored to the 3.0 behaviors. Helper calls with undefined context values will now execute against an arbitrary empty object to avoid executing against global object in non-strict mode. +- `]` can now be included in `[]` wrapped identifiers by escaping with `\`. Any `[]` identifiers that include `\` will now have to properly escape these values. + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.2...v4.0.3) + +## v4.0.2 - September 4th, 2015 + +- [#1089](https://github.com/wycats/handlebars.js/issues/1089) - "Failover content" not working in multiple levels of inline partials ([@michaellopez](https://github.com/michaellopez)) + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.1...v4.0.2) + +## v4.0.1 - September 2nd, 2015 + +- Fix failure when using decorators in partials - 05b82a2 + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.0...v4.0.1) + +## v4.0.0 - September 1st, 2015 + +- [#1082](https://github.com/wycats/handlebars.js/pull/1082) - Decorators and Inline Partials ([@kpdecker](https://github.com/kpdecker)) +- [#1076](https://github.com/wycats/handlebars.js/pull/1076) - Implement partial blocks ([@kpdecker](https://github.com/kpdecker)) +- [#1087](https://github.com/wycats/handlebars.js/pull/1087) - Fix #each when last object entry has empty key ([@denniskuczynski](https://github.com/denniskuczynski)) +- [#1084](https://github.com/wycats/handlebars.js/pull/1084) - Bump uglify version to fix vulnerability ([@John-Steidley](https://github.com/John-Steidley)) +- [#1068](https://github.com/wycats/handlebars.js/pull/1068) - Fix typo ([@0xack13](https://github.com/0xack13)) +- [#1060](https://github.com/wycats/handlebars.js/pull/1060) - #1056 Fixed grammar for nested raw blocks ([@ericbn](https://github.com/ericbn)) +- [#1052](https://github.com/wycats/handlebars.js/pull/1052) - Updated year in License ([@maqnouch](https://github.com/maqnouch)) +- [#1037](https://github.com/wycats/handlebars.js/pull/1037) - Fix minor typos in README ([@tomxtobin](https://github.com/tomxtobin)) +- [#1032](https://github.com/wycats/handlebars.js/issues/1032) - Is it possible to render a partial without the parent scope? ([@aputinski](https://github.com/aputinski)) +- [#1019](https://github.com/wycats/handlebars.js/pull/1019) - Fixes typo in tests ([@aymerick](https://github.com/aymerick)) +- [#1016](https://github.com/wycats/handlebars.js/issues/1016) - Version mis-match ([@mayankdedhia](https://github.com/mayankdedhia)) +- [#1023](https://github.com/wycats/handlebars.js/issues/1023) - is it possible for nested custom helpers to communicate between each other? +- [#893](https://github.com/wycats/handlebars.js/issues/893) - [Proposal] Section blocks. +- [#792](https://github.com/wycats/handlebars.js/issues/792) - feature request: inline partial definitions +- [#583](https://github.com/wycats/handlebars.js/issues/583) - Parent path continues to drill down depth with multiple conditionals +- [#404](https://github.com/wycats/handlebars.js/issues/404) - Add named child helpers that can be referenced by block helpers +- Escape = in HTML content - [83b8e84](https://github.com/wycats/handlebars.js/commit/83b8e84) +- Drop AST constructors in favor of JSON - [95d84ba](https://github.com/wycats/handlebars.js/commit/95d84ba) +- Pass container rather than exec as context - [9a2d1d6](https://github.com/wycats/handlebars.js/commit/9a2d1d6) +- Add ignoreStandalone compiler option - [ea3a5a1](https://github.com/wycats/handlebars.js/commit/ea3a5a1) +- Ignore empty when iterating on sparse arrays - [06d515a](https://github.com/wycats/handlebars.js/commit/06d515a) +- Add support for string and stdin precompilation - [0de8dac](https://github.com/wycats/handlebars.js/commit/0de8dac) +- Simplify object assignment generation logic - [77e6bfc](https://github.com/wycats/handlebars.js/commit/77e6bfc) +- Bulletproof AST.helpers.helperExpression - [93b0760](https://github.com/wycats/handlebars.js/commit/93b0760) +- Always return string responses - [8e868ab](https://github.com/wycats/handlebars.js/commit/8e868ab) +- Pass undefined fields to helpers in strict mode - [5d4b8da](https://github.com/wycats/handlebars.js/commit/5d4b8da) +- Avoid depth creation when context remains the same - [279e038](https://github.com/wycats/handlebars.js/commit/279e038) +- Improve logging API - [9a49d35](https://github.com/wycats/handlebars.js/commit/9a49d35) +- Fix with operator in no @data mode - [231a8d7](https://github.com/wycats/handlebars.js/commit/231a8d7) +- Allow empty key name in each iteration - [1bb640b](https://github.com/wycats/handlebars.js/commit/1bb640b) +- Add with block parameter support - [2a85106](https://github.com/wycats/handlebars.js/commit/2a85106) +- Fix escaping of non-javascript identifiers - [410141c](https://github.com/wycats/handlebars.js/commit/410141c) +- Fix location information for programs - [93faffa](https://github.com/wycats/handlebars.js/commit/93faffa) + +Compatibility notes: + +- Depthed paths are now conditionally pushed on to the stack. If the helper uses the same context, then a new stack is not created. This leads to behavior that better matches expectations for helpers like `if` that do not seem to alter the context. Any instances of `../` in templates will need to be checked for the correct behavior under 4.0.0. In general templates will either reduce the number of `../` instances or leave them as is. See [#1028](https://github.com/wycats/handlebars.js/issues/1028). +- The `=` character is now HTML escaped. This closes a potential exploit case when using unquoted attributes, i.e. `
`. In general it's recommended that attributes always be quoted when their values are generated from a mustache to avoid any potential exploit surfaces. +- AST constructors have been dropped in favor of plain old javascript objects +- The runtime version has been increased. Precompiled templates will need to use runtime of at least 4.0.0. + +[Commits](https://github.com/wycats/handlebars.js/compare/v3.0.3...v4.0.0) + +## v3.0.3 - April 28th, 2015 + +- [#1004](https://github.com/wycats/handlebars.js/issues/1004) - Latest version breaks with RequireJS (global is undefined) ([@boskee](https://github.com/boskee)) + +[Commits](https://github.com/wycats/handlebars.js/compare/v3.0.2...v3.0.3) + +## v3.0.2 - April 20th, 2015 + +- [#998](https://github.com/wycats/handlebars.js/pull/998) - Add full support for es6 ([@kpdecker](https://github.com/kpdecker)) +- [#994](https://github.com/wycats/handlebars.js/issues/994) - Access Handlebars.Visitor in browser ([@tamlyn](https://github.com/tamlyn)) +- [#990](https://github.com/wycats/handlebars.js/issues/990) - Allow passing null/undefined literals subexpressions ([@blimmer](https://github.com/blimmer)) +- [#989](https://github.com/wycats/handlebars.js/issues/989) - Source-map error with requirejs ([@SteppeEagle](https://github.com/SteppeEagle)) +- [#967](https://github.com/wycats/handlebars.js/issues/967) - can't access "this" property ([@75lb](https://github.com/75lb)) +- Use captureStackTrace for error handler - a009a97 +- Ignore branches tested without coverage monitoring - 37a664b + +[Commits](https://github.com/wycats/handlebars.js/compare/v3.0.1...v3.0.2) + +## v3.0.1 - March 24th, 2015 + +- [#984](https://github.com/wycats/handlebars.js/pull/984) - Adding documentation for passing arguments into partials ([@johneke](https://github.com/johneke)) +- [#973](https://github.com/wycats/handlebars.js/issues/973) - version 3 is slower than version 2 ([@elover](https://github.com/elover)) +- [#966](https://github.com/wycats/handlebars.js/issues/966) - "handlebars --version" does not work with v3.0.0 ([@abloomston](https://github.com/abloomston)) +- [#964](https://github.com/wycats/handlebars.js/pull/964) - default is a reserved word ([@grassick](https://github.com/grassick)) +- [#962](https://github.com/wycats/handlebars.js/pull/962) - Add dashbars' link on README. ([@pismute](https://github.com/pismute)) + +[Commits](https://github.com/wycats/handlebars.js/compare/v3.0.0...v3.0.1) + +## v3.0.0 - February 10th, 2015 + +- [#941](https://github.com/wycats/handlebars.js/pull/941) - Add support for dynamic partial names ([@kpdecker](https://github.com/kpdecker)) +- [#940](https://github.com/wycats/handlebars.js/pull/940) - Add missing reserved words so compiler knows to use array syntax: ([@mattflaschen](https://github.com/mattflaschen)) +- [#938](https://github.com/wycats/handlebars.js/pull/938) - Fix example using #with helper ([@diwo](https://github.com/diwo)) +- [#930](https://github.com/wycats/handlebars.js/pull/930) - Add parent tracking and mutation to AST visitors ([@kpdecker](https://github.com/kpdecker)) +- [#926](https://github.com/wycats/handlebars.js/issues/926) - Depthed lookups fail when program duplicator runs ([@kpdecker](https://github.com/kpdecker)) +- [#918](https://github.com/wycats/handlebars.js/pull/918) - Add instructions for 'spec/mustache' to CONTRIBUTING.md, fix a few typos ([@oneeman](https://github.com/oneeman)) +- [#915](https://github.com/wycats/handlebars.js/pull/915) - Ast update ([@kpdecker](https://github.com/kpdecker)) +- [#910](https://github.com/wycats/handlebars.js/issues/910) - Different behavior of {{@last}} when {{#each}} in {{#each}} ([@zordius](https://github.com/zordius)) +- [#907](https://github.com/wycats/handlebars.js/issues/907) - Implement named helper variable references ([@kpdecker](https://github.com/kpdecker)) +- [#906](https://github.com/wycats/handlebars.js/pull/906) - Add parser support for block params ([@mmun](https://github.com/mmun)) +- [#903](https://github.com/wycats/handlebars.js/issues/903) - Only provide aliases for multiple use calls ([@kpdecker](https://github.com/kpdecker)) +- [#902](https://github.com/wycats/handlebars.js/pull/902) - Generate Source Maps ([@kpdecker](https://github.com/kpdecker)) +- [#901](https://github.com/wycats/handlebars.js/issues/901) - Still escapes with noEscape enabled on isolated Handlebars environment ([@zedknight](https://github.com/zedknight)) +- [#896](https://github.com/wycats/handlebars.js/pull/896) - Simplify BlockNode by removing intermediate MustacheNode ([@mmun](https://github.com/mmun)) +- [#892](https://github.com/wycats/handlebars.js/pull/892) - Implement parser for else chaining of helpers ([@kpdecker](https://github.com/kpdecker)) +- [#889](https://github.com/wycats/handlebars.js/issues/889) - Consider extensible parser API ([@kpdecker](https://github.com/kpdecker)) +- [#887](https://github.com/wycats/handlebars.js/issues/887) - Handlebars.noConflict() option? ([@bradvogel](https://github.com/bradvogel)) +- [#886](https://github.com/wycats/handlebars.js/issues/886) - Add SafeString to context (or use duck-typing) ([@dominicbarnes](https://github.com/dominicbarnes)) +- [#870](https://github.com/wycats/handlebars.js/pull/870) - Registering undefined partial throws exception. ([@max-b](https://github.com/max-b)) +- [#866](https://github.com/wycats/handlebars.js/issues/866) - comments don't respect whitespace control ([@75lb](https://github.com/75lb)) +- [#863](https://github.com/wycats/handlebars.js/pull/863) - + jsDelivr CDN info ([@tomByrer](https://github.com/tomByrer)) +- [#858](https://github.com/wycats/handlebars.js/issues/858) - Disable new default auto-indent at included partials ([@majodev](https://github.com/majodev)) +- [#856](https://github.com/wycats/handlebars.js/pull/856) - jspm compatibility ([@MajorBreakfast](https://github.com/MajorBreakfast)) +- [#805](https://github.com/wycats/handlebars.js/issues/805) - Request: "strict" lookups ([@nzakas](https://github.com/nzakas)) + +- Export the default object for handlebars/runtime - 5594416 +- Lookup partials when undefined - 617dd57 + +Compatibility notes: + +- Runtime breaking changes. Must match 3.x runtime and precompiler. +- The AST has been upgraded to a public API. + - There are a number of changes to this, but the format is now documented in docs/compiler-api.md + - The Visitor API has been expanded to support mutation and provide a base implementation +- The `JavaScriptCompiler` APIs have been formalized and documented. As part of the sourcemap handling these should be updated to return arrays for concatenation. +- `JavaScriptCompiler.namespace` has been removed as it was unused. +- `SafeString` is now duck typed on `toHTML` + +New Features: + +- noConflict +- Source Maps +- Block Params +- Strict Mode +- @last and other each changes +- Chained else blocks +- @data methods can now have helper parameters passed to them +- Dynamic partials + +[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0...v3.0.0) + +## v2.0.0 - September 1st, 2014 + +- Update jsfiddle to 2.0.0-beta.1 - 0670f65 +- Add contrib note regarding handlebarsjs.com docs - 4d17e3c +- Play nice with gemspec version numbers - 64d5481 + +[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-beta.1...v2.0.0) + +## v2.0.0-beta.1 - August 26th, 2014 + +- [#787](https://github.com/wycats/handlebars.js/pull/787) - Remove whitespace surrounding standalone statements ([@kpdecker](https://github.com/kpdecker)) +- [#827](https://github.com/wycats/handlebars.js/issues/827) - Render false literal as “false” ([@scoot557](https://github.com/scoot557)) +- [#767](https://github.com/wycats/handlebars.js/issues/767) - Subexpressions bug with hash and context ([@evensoul](https://github.com/evensoul)) +- Changes to 0/undefined handling + - [#731](https://github.com/wycats/handlebars.js/pull/731) - Strange behavior for {{#foo}} {{bar}} {{/foo}} when foo is 0 ([@kpdecker](https://github.com/kpdecker)) + - [#820](https://github.com/wycats/handlebars.js/issues/820) - strange behavior for {{foo.bar}} when foo is 0 or null or false ([@zordius](https://github.com/zordius)) + - [#837](https://github.com/wycats/handlebars.js/issues/837) - Strange input for custom helper ( foo.bar == false when foo is undefined ) ([@zordius](https://github.com/zordius)) +- [#819](https://github.com/wycats/handlebars.js/pull/819) - Implement recursive field lookup ([@kpdecker](https://github.com/kpdecker)) +- [#764](https://github.com/wycats/handlebars.js/issues/764) - This reference not working for helpers ([@kpdecker](https://github.com/kpdecker)) +- [#773](https://github.com/wycats/handlebars.js/issues/773) - Implicit parameters in {{#each}} introduces a peculiarity in helpers calling convention ([@Bertrand](https://github.com/Bertrand)) +- [#783](https://github.com/wycats/handlebars.js/issues/783) - helperMissing and consistency for different expression types ([@ErisDS](https://github.com/ErisDS)) +- [#795](https://github.com/wycats/handlebars.js/pull/795) - Turn the precompile script into a wrapper around a module. ([@jwietelmann](https://github.com/jwietelmann)) +- [#823](https://github.com/wycats/handlebars.js/pull/823) - Support inverse sections on the with helper ([@dan-manges](https://github.com/dan-manges)) +- [#834](https://github.com/wycats/handlebars.js/pull/834) - Refactor blocks, programs and inverses ([@mmun](https://github.com/mmun)) +- [#852](https://github.com/wycats/handlebars.js/issues/852) - {{foo~}} space control behavior is different from older version ([@zordius](https://github.com/zordius)) +- [#835](https://github.com/wycats/handlebars.js/issues/835) - Templates overwritten if file is loaded twice + +- Expose escapeExpression on the root object - 980c38c +- Remove nested function eval in blockHelperMissing - 6f22ec1 +- Fix compiler program de-duping - 9e3f824 + +Compatibility notes: + +- The default build now outputs a generic UMD wrapper. This should be transparent change but may cause issues in some environments. +- Runtime compatibility breaks in both directions. Ensure that both compiler and client are upgraded to 2.0.0-beta.1 or higher at the same time. + - `programWithDepth` has been removed an instead an array of context values is passed to fields needing depth lookups. +- `false` values are now printed to output rather than silently dropped +- Lines containing only block statements and whitespace are now removed. This matches the Mustache spec but may cause issues with code that expects whitespace to exist but would not otherwise. +- Partials that are standalone will now indent their rendered content +- `AST.ProgramNode`'s signature has changed. +- Numerious methods/features removed from pseudo-API classes + - `JavaScriptCompiler.register` + - `JavaScriptCompiler.replaceStack` no longer supports non-inline replace + - `Compiler.disassemble` + - `DECLARE` opcode + - `strip` opcode + - `lookup` opcode + - Content nodes may have their `string` values mutated over time. `original` field provides the unmodified value. +- Removed unused `Handlebars.registerHelper` `inverse` parameter +- `each` helper requires iterator parameter + +[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.4...v2.0.0-beta.1) + +## v2.0.0-alpha.4 - May 19th, 2014 + +- Expose setup wrappers for compiled templates - 3638874 + +[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.3...v2.0.0-alpha.4) + +## v2.0.0-alpha.3 - May 19th, 2014 + +- [#797](https://github.com/wycats/handlebars.js/pull/797) - Pass full helper ID to helperMissing when options are provided ([@tomdale](https://github.com/tomdale)) +- [#793](https://github.com/wycats/handlebars.js/pull/793) - Ensure isHelper is coerced to a boolean ([@mmun](https://github.com/mmun)) +- Refactor template init logic - 085e5e1 + +[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.2...v2.0.0-alpha.3) + +## v2.0.0-alpha.2 - March 6th, 2014 + +- [#756](https://github.com/wycats/handlebars.js/pull/756) - fix bug in IE<=8 (no Array::map), closes #751 ([@jenseng](https://github.com/jenseng)) +- [#749](https://github.com/wycats/handlebars.js/pull/749) - properly handle multiple subexpressions in the same hash, fixes #748 ([@jenseng](https://github.com/jenseng)) +- [#743](https://github.com/wycats/handlebars.js/issues/743) - subexpression confusion/problem? ([@waynedpj](https://github.com/waynedpj)) +- [#746](https://github.com/wycats/handlebars.js/issues/746) - [CLI] support `handlebars --version` ([@apfelbox](https://github.com/apfelbox)) +- [#747](https://github.com/wycats/handlebars.js/pull/747) - updated grunt-saucelabs, failing tests revealed ([@Jonahss](https://github.com/Jonahss)) +- Make JSON a requirement for the compiler. - 058c0fb +- Temporarily kill the AWS publish CI step - 8347ee2 + +Compatibility notes: + +- A JSON polyfill is required to run the compiler under IE8 and below. It's recommended that the precompiler be used in lieu of running the compiler on these legacy environments. + +[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) + +## v2.0.0-alpha.1 - February 10th, 2014 + +- [#182](https://github.com/wycats/handlebars.js/pull/182) - Allow passing hash parameters to partials ([@kpdecker](https://github.com/kpdecker)) +- [#392](https://github.com/wycats/handlebars.js/pull/392) - Access to root context in partials and helpers ([@kpdecker](https://github.com/kpdecker)) +- [#472](https://github.com/wycats/handlebars.js/issues/472) - Helpers cannot have decimal parameters ([@kayleg](https://github.com/kayleg)) +- [#569](https://github.com/wycats/handlebars.js/pull/569) - Unable to lookup array values using @index ([@kpdecker](https://github.com/kpdecker)) +- [#491](https://github.com/wycats/handlebars.js/pull/491) - For nested helpers: get the @ variables of the outer helper from the inner one ([@kpdecker](https://github.com/kpdecker)) +- [#669](https://github.com/wycats/handlebars.js/issues/669) - Ability to unregister a helper ([@dbachrach](https://github.com/dbachrach)) +- [#730](https://github.com/wycats/handlebars.js/pull/730) - Raw block helpers ([@kpdecker](https://github.com/kpdecker)) +- [#634](https://github.com/wycats/handlebars.js/pull/634) - It would be great to have the helper name passed to `blockHelperMissing` ([@kpdecker](https://github.com/kpdecker)) +- [#729](https://github.com/wycats/handlebars.js/pull/729) - Convert template spec to object literal ([@kpdecker](https://github.com/kpdecker)) + +- [#658](https://github.com/wycats/handlebars.js/issues/658) - Depthed helpers do not work after an upgrade from 1.0.0 ([@xibxor](https://github.com/xibxor)) +- [#671](https://github.com/wycats/handlebars.js/issues/671) - Crashes on no-parameter {{#each}} ([@stepancheg](https://github.com/stepancheg)) +- [#689](https://github.com/wycats/handlebars.js/issues/689) - broken template precompilation ([@AAS](https://github.com/AAS)) +- [#698](https://github.com/wycats/handlebars.js/pull/698) - Fix parser generation under windows ([@osiris43](https://github.com/osiris43)) +- [#699](https://github.com/wycats/handlebars.js/issues/699) - @DATA not compiles to invalid JS in stringParams mode ([@kpdecker](https://github.com/kpdecker)) +- [#705](https://github.com/wycats/handlebars.js/issues/705) - 1.3.0 can not be wrapped in an IIFE ([@craigteegarden](https://github.com/craigteegarden)) +- [#706](https://github.com/wycats/handlebars.js/pull/706) - README: Use with helper instead of relying on blockHelperMissing ([@scottgonzalez](https://github.com/scottgonzalez)) + +- [#700](https://github.com/wycats/handlebars.js/pull/700) - Remove redundant conditions ([@blakeembrey](https://github.com/blakeembrey)) +- [#704](https://github.com/wycats/handlebars.js/pull/704) - JavaScript Compiler Cleanup ([@blakeembrey](https://github.com/blakeembrey)) + +Compatibility notes: + +- `helperMissing` helper no longer has the indexed name argument. Helper name is now available via `options.name`. +- Precompiler output has changed, which breaks compatibility with prior versions of the runtime and precompiled output. +- `JavaScriptCompiler.compilerInfo` now returns generic objects rather than javascript source. +- AST changes + - INTEGER -> NUMBER + - Additional PartialNode hash parameter + - New RawBlockNode type +- Data frames now have a `_parent` field. This is internal but is enumerable for performance/compatibility reasons. + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.3.0...v2.0.0-alpha.1) + +## v1.3.0 - January 1st, 2014 + +- [#690](https://github.com/wycats/handlebars.js/pull/690) - Added support for subexpressions ([@machty](https://github.com/machty)) +- [#696](https://github.com/wycats/handlebars.js/pull/696) - Fix for reserved keyword "default" ([@nateirwin](https://github.com/nateirwin)) +- [#692](https://github.com/wycats/handlebars.js/pull/692) - add line numbers to nodes when parsing ([@fivetanley](https://github.com/fivetanley)) +- [#695](https://github.com/wycats/handlebars.js/pull/695) - Pull options out from param setup to allow easier extension ([@blakeembrey](https://github.com/blakeembrey)) +- [#694](https://github.com/wycats/handlebars.js/pull/694) - Make the environment reusable ([@blakeembrey](https://github.com/blakeembrey)) +- [#636](https://github.com/wycats/handlebars.js/issues/636) - Print line and column of errors ([@sgronblo](https://github.com/sgronblo)) +- Use literal for data lookup - c1a93d3 +- Add stack handling sanity checks - cd885bf +- Fix stack id "leak" on replaceStack - ddfe457 +- Fix incorrect stack pop when replacing literals - f4d337d + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.2.1...v1.3.0) + +## v1.2.1 - December 26th, 2013 + +- [#684](https://github.com/wycats/handlebars.js/pull/684) - Allow any number of trailing characters for valid JavaScript variable ([@blakeembrey](https://github.com/blakeembrey)) +- [#686](https://github.com/wycats/handlebars.js/pull/686) - Falsy AMD module names in version 1.2.0 ([@kpdecker](https://github.com/kpdecker)) + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.2.0...v1.2.1) + +## v1.2.0 - December 23rd, 2013 + +- [#675](https://github.com/wycats/handlebars.js/issues/675) - Cannot compile empty template for partial ([@erwinw](https://github.com/erwinw)) +- [#677](https://github.com/wycats/handlebars.js/issues/677) - Triple brace statements fail under IE ([@hamzaCM](https://github.com/hamzaCM)) +- [#655](https://github.com/wycats/handlebars.js/issues/655) - Loading Handlebars using bower ([@niki4810](https://github.com/niki4810)) +- [#657](https://github.com/wycats/handlebars.js/pull/657) - Fixes issue where cli compiles non handlebars templates ([@chrishoage](https://github.com/chrishoage)) +- [#681](https://github.com/wycats/handlebars.js/pull/681) - Adds in-browser testing and Saucelabs CI ([@kpdecker](https://github.com/kpdecker)) +- [#661](https://github.com/wycats/handlebars.js/pull/661) - Add @first and @index to #each object iteration ([@cgp](https://github.com/cgp)) +- [#650](https://github.com/wycats/handlebars.js/pull/650) - Handlebars is MIT-licensed ([@thomasboyt](https://github.com/thomasboyt)) +- [#641](https://github.com/wycats/handlebars.js/pull/641) - Document ember testing process ([@kpdecker](https://github.com/kpdecker)) +- [#662](https://github.com/wycats/handlebars.js/issues/662) - handlebars-source 1.1.2 is missing from RubyGems. +- [#656](https://github.com/wycats/handlebars.js/issues/656) - Expose COMPILER_REVISION checks as a hook ([@machty](https://github.com/machty)) +- [#668](https://github.com/wycats/handlebars.js/issues/668) - Consider publishing handlebars-runtime as a separate module on npm ([@dlmanning](https://github.com/dlmanning)) +- [#679](https://github.com/wycats/handlebars.js/issues/679) - Unable to override invokePartial ([@mattbrailsford](https://github.com/mattbrailsford)) +- [#646](https://github.com/wycats/handlebars.js/pull/646) - Fix "\\{{" immediately following "\{{" ([@dmarcotte](https://github.com/dmarcotte)) +- Allow extend to work with non-prototyped objects - eb53f2e +- Add JavascriptCompiler public API tests - 1a751b2 +- Add AST test coverage for more complex paths - ddea5be +- Fix handling of boolean escape in MustacheNode - b4968bb + +Compatibility notes: + +- `@index` and `@first` are now supported for `each` iteration on objects +- `Handlebars.VM.checkRevision` and `Handlebars.JavaScriptCompiler.prototype.compilerInfo` now available to modify the version checking behavior. +- Browserify users may link to the runtime library via `require('handlebars/runtime')` + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.1.2...v1.2.0) + +## v1.1.2 - November 5th, 2013 + +- [#645](https://github.com/wycats/handlebars.js/issues/645) - 1.1.1 fails under IE8 ([@kpdecker](https://github.com/kpdecker)) +- [#644](https://github.com/wycats/handlebars.js/issues/644) - Using precompiled templates (AMD mode) with handlebars.runtime 1.1.1 ([@fddima](https://github.com/fddima)) + +- Add simple binary utility tests - 96a45a4 +- Fix empty string compilation - eea708a + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.1.1...v1.1.2) + +## v1.1.1 - November 4th, 2013 + +- [#642](https://github.com/wycats/handlebars.js/issues/642) - handlebars 1.1.0 are broken with nodejs + +- Fix release notes link - 17ba258 + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.1.0...v1.1.1) + +## v1.1.0 - November 3rd, 2013 + +- [#628](https://github.com/wycats/handlebars.js/pull/628) - Convert code to ES6 modules ([@kpdecker](https://github.com/kpdecker)) +- [#336](https://github.com/wycats/handlebars.js/pull/336) - Add whitespace control syntax ([@kpdecker](https://github.com/kpdecker)) +- [#535](https://github.com/wycats/handlebars.js/pull/535) - Fix for probable JIT error under Safari ([@sorentwo](https://github.com/sorentwo)) +- [#483](https://github.com/wycats/handlebars.js/issues/483) - Add first and last @ vars to each helper ([@denniskuczynski](https://github.com/denniskuczynski)) +- [#557](https://github.com/wycats/handlebars.js/pull/557) - `\\{{foo}}` escaping only works in some situations ([@dmarcotte](https://github.com/dmarcotte)) +- [#552](https://github.com/wycats/handlebars.js/pull/552) - Added BOM removal flag. ([@blessenm](https://github.com/blessenm)) +- [#543](https://github.com/wycats/handlebars.js/pull/543) - publish passing master builds to s3 ([@fivetanley](https://github.com/fivetanley)) + +- [#608](https://github.com/wycats/handlebars.js/issues/608) - Add `includeZero` flag to `if` conditional +- [#498](https://github.com/wycats/handlebars.js/issues/498) - `Handlebars.compile` fails on empty string although a single blank works fine +- [#599](https://github.com/wycats/handlebars.js/issues/599) - lambda helpers only receive options if used with arguments +- [#592](https://github.com/wycats/handlebars.js/issues/592) - Optimize array and subprogram performance +- [#571](https://github.com/wycats/handlebars.js/issues/571) - uglify upgrade breaks compatibility with older versions of node +- [#587](https://github.com/wycats/handlebars.js/issues/587) - Partial inside partial breaks? + +Compatibility notes: + +- The project now includes separate artifacts for AMD, CommonJS, and global objects. + - AMD: Users may load the bundled `handlebars.amd.js` or `handlebars.runtime.amd.js` files or load individual modules directly. AMD users should also note that the handlebars object is exposed via the `default` field on the imported object. This [gist](https://gist.github.com/wycats/7417be0dc361a69d5916) provides some discussion of possible compatibility shims. + - CommonJS/Node: Node loading occurs as normal via `require` + - Globals: The `handlebars.js` and `handlebars.runtime.js` files should behave in the same manner as the v1.0.12 / 1.0.0 release. +- Build artifacts have been removed from the repository. [npm][npm], [components/handlebars.js][components], [cdnjs][cdnjs], or the [builds page][builds-page] should now be used as the source of built artifacts. +- Context-stored helpers are now always passed the `options` hash. Previously no-argument helpers did not have this argument. + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.0.12...v1.1.0) + +## v1.0.12 / 1.0.0 - May 31 2013 + +- [#515](https://github.com/wycats/handlebars.js/issues/515) - Add node require extensions support ([@jjclark1982](https://github.com/jjclark1982)) +- [#517](https://github.com/wycats/handlebars.js/issues/517) - Fix amd precompiler output with directories ([@blessenm](https://github.com/blessenm)) +- [#433](https://github.com/wycats/handlebars.js/issues/433) - Add support for unicode ids +- [#469](https://github.com/wycats/handlebars.js/issues/469) - Add support for `?` in ids +- [#534](https://github.com/wycats/handlebars.js/issues/534) - Protect from object prototype modifications +- [#519](https://github.com/wycats/handlebars.js/issues/519) - Fix partials with . name ([@jamesgorrie](https://github.com/jamesgorrie)) +- [#519](https://github.com/wycats/handlebars.js/issues/519) - Allow ID or strings in partial names +- [#437](https://github.com/wycats/handlebars.js/issues/437) - Require matching brace counts in escaped expressions +- Merge passed partials and helpers with global namespace values +- Add support for complex ids in @data references +- Docs updates + +Compatibility notes: + +- The parser is now stricter on `{{{`, requiring that the end token be `}}}`. Templates that do not + follow this convention should add the additional brace value. +- Code that relies on global the namespace being muted when custom helpers or partials are passed will need to explicitly pass an `undefined` value for any helpers that should not be available. +- The compiler version has changed. Precompiled templates with 1.0.12 or higher must use the 1.0.0 or higher runtime. + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.0.11...v1.0.12) + +## v1.0.11 / 1.0.0-rc4 - May 13 2013 + +- [#458](https://github.com/wycats/handlebars.js/issues/458) - Fix `./foo` syntax ([@jpfiset](https://github.com/jpfiset)) +- [#460](https://github.com/wycats/handlebars.js/issues/460) - Allow `:` in unescaped identifiers ([@jpfiset](https://github.com/jpfiset)) +- [#471](https://github.com/wycats/handlebars.js/issues/471) - Create release notes (These!) +- [#456](https://github.com/wycats/handlebars.js/issues/456) - Allow escaping of `\\` +- [#211](https://github.com/wycats/handlebars.js/issues/211) - Fix exception in `escapeExpression` +- [#375](https://github.com/wycats/handlebars.js/issues/375) - Escape unicode newlines +- [#461](https://github.com/wycats/handlebars.js/issues/461) - Do not fail when compiling `""` +- [#302](https://github.com/wycats/handlebars.js/issues/302) - Fix sanity check in knownHelpersOnly mode +- [#369](https://github.com/wycats/handlebars.js/issues/369) - Allow registration of multiple helpers and partial by passing definition object +- Add bower package declaration ([@DevinClark](https://github.com/DevinClark)) +- Add NuSpec package declaration ([@MikeMayer](https://github.com/MikeMayer)) +- Handle empty context in `with` ([@thejohnfreeman](https://github.com/thejohnfreeman)) +- Support custom template extensions in CLI ([@matteoagosti](https://github.com/matteoagosti)) +- Fix Rhino support ([@broady](https://github.com/broady)) +- Include contexts in string mode ([@leshill](https://github.com/leshill)) +- Return precompiled scripts when compiling to AMD ([@JamesMaroney](https://github.com/JamesMaroney)) +- Docs updates ([@iangreenleaf](https://github.com/iangreenleaf), [@gilesbowkett](https://github.com/gilesbowkett), [@utkarsh2012](https://github.com/utkarsh2012)) +- Fix `toString` handling under IE and browserify ([@tommydudebreaux](https://github.com/tommydudebreaux)) +- Add program metadata + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.0.10...v1.0.11) + +## v1.0.10 - Node - Feb 27 2013 + +- [#428](https://github.com/wycats/handlebars.js/issues/428) - Fix incorrect rendering of nested programs +- Fix exception message ([@tricknotes](https://github.com/tricknotes)) +- Added negative number literal support +- Concert library to single IIFE +- Add handlebars-source gemspec ([@machty](https://github.com/machty)) + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.0.9...v1.0.10) + +## v1.0.9 - Node - Feb 15 2013 + +- Added `Handlebars.create` API in node module for sandboxed instances ([@tommydudebreaux](https://github.com/tommydudebreaux)) + +[Commits](https://github.com/wycats/handlebars.js/compare/1.0.0-rc.3...v1.0.9) + +## 1.0.0-rc3 - Browser - Feb 14 2013 + +- Prevent use of `this` or `..` in illogical place ([@leshill](https://github.com/leshill)) +- Allow AST passing for `parse`/`compile`/`precompile` ([@machty](https://github.com/machty)) +- Optimize generated output by inlining statements where possible +- Check compiler version when evaluating templates +- Package browser dist in npm package + +[Commits](https://github.com/wycats/handlebars.js/compare/v1.0.8...1.0.0-rc.3) + +## Prior Versions + +When upgrading from the Handlebars 0.9 series, be aware that the +signature for passing custom helpers or partials to templates has +changed. + +Instead of: + +```js +template(context, helpers, partials, [data]); +``` + +Use: + +```js +template(context, { helpers: helpers, partials: partials, data: data }); +``` + +[builds-page]: http://builds.handlebarsjs.com.s3.amazonaws.com/index.html +[cdnjs]: http://cdnjs.com/libraries/handlebars.js/ +[components]: https://github.com/components/handlebars.js +[npm]: https://npmjs.org/package/handlebars diff --git a/libs/events/node_modules/handlebars/runtime.d.ts b/libs/events/node_modules/handlebars/runtime.d.ts new file mode 100644 index 000000000..0d5105eb7 --- /dev/null +++ b/libs/events/node_modules/handlebars/runtime.d.ts @@ -0,0 +1,5 @@ +import Handlebars = require('handlebars') + +declare module "handlebars/runtime" { + +} \ No newline at end of file diff --git a/libs/events/node_modules/handlebars/runtime.js b/libs/events/node_modules/handlebars/runtime.js new file mode 100644 index 000000000..306207cd2 --- /dev/null +++ b/libs/events/node_modules/handlebars/runtime.js @@ -0,0 +1,3 @@ +// Create a simple path alias to allow browserify to resolve +// the runtime on a supported path. +module.exports = require('./dist/cjs/handlebars.runtime')['default']; diff --git a/libs/events/node_modules/handlebars/types/index.d.ts b/libs/events/node_modules/handlebars/types/index.d.ts new file mode 100644 index 000000000..3f2f8b792 --- /dev/null +++ b/libs/events/node_modules/handlebars/types/index.d.ts @@ -0,0 +1,422 @@ +/* These definitions were imported from https://github.com/DefinitelyTyped/DefinitelyTyped + * and includes previous contributions from the DefinitelyTyped community by: + * - Albert Willemsen + * - Boris Yankov + * - Jessica Franco + * - Masahiro Wakame + * - Raanan Weber + * - Sergei Dorogin + * - webbiesdk + * - Andrew Leedham + * - Nils Knappmeier + * For full history prior to their migration to handlebars.js, please see: + * https://github.com/DefinitelyTyped/DefinitelyTyped/commits/1ce60bdc07f10e0b076778c6c953271c072bc894/types/handlebars/index.d.ts + */ +// TypeScript Version: 2.3 + +declare namespace Handlebars { + export interface TemplateDelegate { + (context: T, options?: RuntimeOptions): string; + } + + export type Template = TemplateDelegate|string; + + export interface RuntimeOptions { + partial?: boolean; + depths?: any[]; + helpers?: { [name: string]: Function }; + partials?: { [name: string]: HandlebarsTemplateDelegate }; + decorators?: { [name: string]: Function }; + data?: any; + blockParams?: any[]; + allowCallsToHelperMissing?: boolean; + allowedProtoProperties?: { [name: string]: boolean }; + allowedProtoMethods?: { [name: string]: boolean }; + allowProtoPropertiesByDefault?: boolean; + allowProtoMethodsByDefault?: boolean; + } + + export interface HelperOptions { + fn: TemplateDelegate; + inverse: TemplateDelegate; + hash: any; + data?: any; + } + + export interface HelperDelegate { + (context?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, options?: HelperOptions): any; + } + export interface HelperDeclareSpec { + [key: string]: HelperDelegate; + } + + export interface ParseOptions { + srcName?: string; + ignoreStandalone?: boolean; + } + + export function registerHelper(name: string, fn: HelperDelegate): void; + export function registerHelper(name: HelperDeclareSpec): void; + export function unregisterHelper(name: string): void; + + export function registerPartial(name: string, fn: Template): void; + export function registerPartial(spec: { [name: string]: HandlebarsTemplateDelegate }): void; + export function unregisterPartial(name: string): void; + + // TODO: replace Function with actual signature + export function registerDecorator(name: string, fn: Function): void; + export function unregisterDecorator(name: string): void; + + export function K(): void; + export function createFrame(object: any): any; + export function blockParams(obj: any[], ids: any[]): any[]; + export function log(level: number, obj: any): void; + export function parse(input: string, options?: ParseOptions): hbs.AST.Program; + export function parseWithoutProcessing(input: string, options?: ParseOptions): hbs.AST.Program; + export function compile(input: any, options?: CompileOptions): HandlebarsTemplateDelegate; + export function precompile(input: any, options?: PrecompileOptions): TemplateSpecification; + export function template(precompilation: TemplateSpecification): HandlebarsTemplateDelegate; + + export function create(): typeof Handlebars; + + export const escapeExpression: typeof Utils.escapeExpression; + //export const Utils: typeof hbs.Utils; + export const logger: Logger; + export const templates: HandlebarsTemplates; + export const helpers: { [name: string]: HelperDelegate }; + export const partials: { [name: string]: any }; + // TODO: replace Function with actual signature + export const decorators: { [name: string]: Function }; + + export const VERSION: string; + + export function noConflict(): typeof Handlebars; + + export class Exception { + constructor(message: string, node?: hbs.AST.Node); + description: string; + fileName: string; + lineNumber?: any; + endLineNumber?: any; + message: string; + name: string; + number: number; + stack?: string; + column?: any; + endColumn?: any; + } + + export class SafeString { + constructor(str: string); + toString(): string; + toHTML(): string; + } + + export namespace Utils { + export function escapeExpression(str: string): string; + export function createFrame(object: any): any; + export function blockParams(obj: any[], ids: any[]): any[]; + export function isEmpty(obj: any) : boolean; + export function extend(obj: any, ...source: any[]): any; + export function toString(obj: any): string; + export function isArray(obj: any): boolean; + export function isFunction(obj: any): boolean; + } + + export namespace AST { + export const helpers: hbs.AST.helpers; + } + + interface ICompiler { + accept(node: hbs.AST.Node): void; + Program(program: hbs.AST.Program): void; + BlockStatement(block: hbs.AST.BlockStatement): void; + PartialStatement(partial: hbs.AST.PartialStatement): void; + PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; + DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; + Decorator(decorator: hbs.AST.Decorator): void; + MustacheStatement(mustache: hbs.AST.MustacheStatement): void; + ContentStatement(content: hbs.AST.ContentStatement): void; + CommentStatement(comment?: hbs.AST.CommentStatement): void; + SubExpression(sexpr: hbs.AST.SubExpression): void; + PathExpression(path: hbs.AST.PathExpression): void; + StringLiteral(str: hbs.AST.StringLiteral): void; + NumberLiteral(num: hbs.AST.NumberLiteral): void; + BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; + UndefinedLiteral(): void; + NullLiteral(): void; + Hash(hash: hbs.AST.Hash): void; + } + + export class Visitor implements ICompiler { + accept(node: hbs.AST.Node): void; + acceptKey(node: hbs.AST.Node, name: string): void; + acceptArray(arr: hbs.AST.Expression[]): void; + Program(program: hbs.AST.Program): void; + BlockStatement(block: hbs.AST.BlockStatement): void; + PartialStatement(partial: hbs.AST.PartialStatement): void; + PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; + DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; + Decorator(decorator: hbs.AST.Decorator): void; + MustacheStatement(mustache: hbs.AST.MustacheStatement): void; + ContentStatement(content: hbs.AST.ContentStatement): void; + CommentStatement(comment?: hbs.AST.CommentStatement): void; + SubExpression(sexpr: hbs.AST.SubExpression): void; + PathExpression(path: hbs.AST.PathExpression): void; + StringLiteral(str: hbs.AST.StringLiteral): void; + NumberLiteral(num: hbs.AST.NumberLiteral): void; + BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; + UndefinedLiteral(): void; + NullLiteral(): void; + Hash(hash: hbs.AST.Hash): void; + } + + + export interface ResolvePartialOptions { + name: string; + helpers?: { [name: string]: Function }; + partials?: { [name: string]: HandlebarsTemplateDelegate }; + decorators?: { [name: string]: Function }; + data?: any; + } + + export namespace VM { + /** + * @deprecated + */ + export function resolvePartial(partial: HandlebarsTemplateDelegate | undefined, context: any, options: ResolvePartialOptions): HandlebarsTemplateDelegate; + } +} + +/** +* Implement this interface on your MVW/MVVM/MVC views such as Backbone.View +**/ +interface HandlebarsTemplatable { + template: HandlebarsTemplateDelegate; +} + +// NOTE: for backward compatibility of this typing +type HandlebarsTemplateDelegate = Handlebars.TemplateDelegate; + +interface HandlebarsTemplates { + [index: string]: HandlebarsTemplateDelegate; +} + +interface TemplateSpecification { + +} + +// for backward compatibility of this typing +type RuntimeOptions = Handlebars.RuntimeOptions; + +interface CompileOptions { + data?: boolean; + compat?: boolean; + knownHelpers?: KnownHelpers; + knownHelpersOnly?: boolean; + noEscape?: boolean; + strict?: boolean; + assumeObjects?: boolean; + preventIndent?: boolean; + ignoreStandalone?: boolean; + explicitPartialContext?: boolean; +} + +type KnownHelpers = { + [name in BuiltinHelperName | CustomHelperName]: boolean; +}; + +type BuiltinHelperName = + "helperMissing"| + "blockHelperMissing"| + "each"| + "if"| + "unless"| + "with"| + "log"| + "lookup"; + +type CustomHelperName = string; + +interface PrecompileOptions extends CompileOptions { + srcName?: string; + destName?: string; +} + +declare namespace hbs { + // for backward compatibility of this typing + type SafeString = Handlebars.SafeString; + + type Utils = typeof Handlebars.Utils; +} + +interface Logger { + DEBUG: number; + INFO: number; + WARN: number; + ERROR: number; + level: number; + + methodMap: { [level: number]: string }; + + log(level: number, obj: string): void; +} + +type CompilerInfo = [number/* revision */, string /* versions */]; + +declare namespace hbs { + namespace AST { + interface Node { + type: string; + loc: SourceLocation; + } + + interface SourceLocation { + source: string; + start: Position; + end: Position; + } + + interface Position { + line: number; + column: number; + } + + interface Program extends Node { + body: Statement[]; + blockParams: string[]; + } + + interface Statement extends Node {} + + interface MustacheStatement extends Statement { + type: 'MustacheStatement'; + path: PathExpression | Literal; + params: Expression[]; + hash: Hash; + escaped: boolean; + strip: StripFlags; + } + + interface Decorator extends MustacheStatement { } + + interface BlockStatement extends Statement { + type: 'BlockStatement'; + path: PathExpression; + params: Expression[]; + hash: Hash; + program: Program; + inverse: Program; + openStrip: StripFlags; + inverseStrip: StripFlags; + closeStrip: StripFlags; + } + + interface DecoratorBlock extends BlockStatement { } + + interface PartialStatement extends Statement { + type: 'PartialStatement'; + name: PathExpression | SubExpression; + params: Expression[]; + hash: Hash; + indent: string; + strip: StripFlags; + } + + interface PartialBlockStatement extends Statement { + type: 'PartialBlockStatement'; + name: PathExpression | SubExpression; + params: Expression[]; + hash: Hash; + program: Program; + openStrip: StripFlags; + closeStrip: StripFlags; + } + + interface ContentStatement extends Statement { + type: 'ContentStatement'; + value: string; + original: StripFlags; + } + + interface CommentStatement extends Statement { + type: 'CommentStatement'; + value: string; + strip: StripFlags; + } + + interface Expression extends Node {} + + interface SubExpression extends Expression { + type: 'SubExpression'; + path: PathExpression; + params: Expression[]; + hash: Hash; + } + + interface PathExpression extends Expression { + type: 'PathExpression'; + data: boolean; + depth: number; + parts: string[]; + original: string; + } + + interface Literal extends Expression {} + interface StringLiteral extends Literal { + type: 'StringLiteral'; + value: string; + original: string; + } + + interface BooleanLiteral extends Literal { + type: 'BooleanLiteral'; + value: boolean; + original: boolean; + } + + interface NumberLiteral extends Literal { + type: 'NumberLiteral'; + value: number; + original: number; + } + + interface UndefinedLiteral extends Literal { + type: 'UndefinedLiteral'; + } + + interface NullLiteral extends Literal { + type: 'NullLiteral'; + } + + interface Hash extends Node { + type: 'Hash'; + pairs: HashPair[]; + } + + interface HashPair extends Node { + type: 'HashPair'; + key: string; + value: Expression; + } + + interface StripFlags { + open: boolean; + close: boolean; + } + + interface helpers { + helperExpression(node: Node): boolean; + scopeId(path: PathExpression): boolean; + simpleId(path: PathExpression): boolean; + } + } +} + +declare module "handlebars" { + export = Handlebars; +} + +declare module "handlebars/runtime" { + export = Handlebars; +} diff --git a/libs/events/node_modules/is-extglob/LICENSE b/libs/events/node_modules/is-extglob/LICENSE new file mode 100644 index 000000000..842218cf0 --- /dev/null +++ b/libs/events/node_modules/is-extglob/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/is-extglob/README.md b/libs/events/node_modules/is-extglob/README.md new file mode 100644 index 000000000..0416af5c3 --- /dev/null +++ b/libs/events/node_modules/is-extglob/README.md @@ -0,0 +1,107 @@ +# is-extglob [![NPM version](https://img.shields.io/npm/v/is-extglob.svg?style=flat)](https://www.npmjs.com/package/is-extglob) [![NPM downloads](https://img.shields.io/npm/dm/is-extglob.svg?style=flat)](https://npmjs.org/package/is-extglob) [![Build Status](https://img.shields.io/travis/jonschlinkert/is-extglob.svg?style=flat)](https://travis-ci.org/jonschlinkert/is-extglob) + +> Returns true if a string has an extglob. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save is-extglob +``` + +## Usage + +```js +var isExtglob = require('is-extglob'); +``` + +**True** + +```js +isExtglob('?(abc)'); +isExtglob('@(abc)'); +isExtglob('!(abc)'); +isExtglob('*(abc)'); +isExtglob('+(abc)'); +``` + +**False** + +Escaped extglobs: + +```js +isExtglob('\\?(abc)'); +isExtglob('\\@(abc)'); +isExtglob('\\!(abc)'); +isExtglob('\\*(abc)'); +isExtglob('\\+(abc)'); +``` + +Everything else... + +```js +isExtglob('foo.js'); +isExtglob('!foo.js'); +isExtglob('*.js'); +isExtglob('**/abc.js'); +isExtglob('abc/*.js'); +isExtglob('abc/(aaa|bbb).js'); +isExtglob('abc/[a-z].js'); +isExtglob('abc/{a,b}.js'); +isExtglob('abc/?.js'); +isExtglob('abc.js'); +isExtglob('abc/def/ghi.js'); +``` + +## History + +**v2.0** + +Adds support for escaping. Escaped exglobs no longer return true. + +## About + +### Related projects + +* [has-glob](https://www.npmjs.com/package/has-glob): Returns `true` if an array has a glob pattern. | [homepage](https://github.com/jonschlinkert/has-glob "Returns `true` if an array has a glob pattern.") +* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern… [more](https://github.com/jonschlinkert/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob "Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a bet") +* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/jonschlinkert/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.") + +### Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +### Building docs + +_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ + +To generate the readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install -g verb verb-generate-readme && verb +``` + +### Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +### Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +### License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/is-extglob/blob/master/LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.1.31, on October 12, 2016._ \ No newline at end of file diff --git a/libs/events/node_modules/is-extglob/index.js b/libs/events/node_modules/is-extglob/index.js new file mode 100644 index 000000000..c1d986fc5 --- /dev/null +++ b/libs/events/node_modules/is-extglob/index.js @@ -0,0 +1,20 @@ +/*! + * is-extglob + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ + +module.exports = function isExtglob(str) { + if (typeof str !== 'string' || str === '') { + return false; + } + + var match; + while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { + if (match[2]) return true; + str = str.slice(match.index + match[0].length); + } + + return false; +}; diff --git a/libs/events/node_modules/is-extglob/package.json b/libs/events/node_modules/is-extglob/package.json new file mode 100644 index 000000000..7a908369d --- /dev/null +++ b/libs/events/node_modules/is-extglob/package.json @@ -0,0 +1,69 @@ +{ + "name": "is-extglob", + "description": "Returns true if a string has an extglob.", + "version": "2.1.1", + "homepage": "https://github.com/jonschlinkert/is-extglob", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "repository": "jonschlinkert/is-extglob", + "bugs": { + "url": "https://github.com/jonschlinkert/is-extglob/issues" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "main": "index.js", + "engines": { + "node": ">=0.10.0" + }, + "scripts": { + "test": "mocha" + }, + "devDependencies": { + "gulp-format-md": "^0.1.10", + "mocha": "^3.0.2" + }, + "keywords": [ + "bash", + "braces", + "check", + "exec", + "expression", + "extglob", + "glob", + "globbing", + "globstar", + "is", + "match", + "matches", + "pattern", + "regex", + "regular", + "string", + "test" + ], + "verb": { + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "has-glob", + "is-glob", + "micromatch" + ] + }, + "reflinks": [ + "verb", + "verb-generate-readme" + ], + "lint": { + "reflinks": true + } + } +} diff --git a/libs/events/node_modules/is-glob/LICENSE b/libs/events/node_modules/is-glob/LICENSE new file mode 100644 index 000000000..3f2eca18f --- /dev/null +++ b/libs/events/node_modules/is-glob/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2017, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/is-glob/README.md b/libs/events/node_modules/is-glob/README.md new file mode 100644 index 000000000..740724b27 --- /dev/null +++ b/libs/events/node_modules/is-glob/README.md @@ -0,0 +1,206 @@ +# is-glob [![NPM version](https://img.shields.io/npm/v/is-glob.svg?style=flat)](https://www.npmjs.com/package/is-glob) [![NPM monthly downloads](https://img.shields.io/npm/dm/is-glob.svg?style=flat)](https://npmjs.org/package/is-glob) [![NPM total downloads](https://img.shields.io/npm/dt/is-glob.svg?style=flat)](https://npmjs.org/package/is-glob) [![Build Status](https://img.shields.io/github/workflow/status/micromatch/is-glob/dev)](https://github.com/micromatch/is-glob/actions) + +> Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a better user experience. + +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save is-glob +``` + +You might also be interested in [is-valid-glob](https://github.com/jonschlinkert/is-valid-glob) and [has-glob](https://github.com/jonschlinkert/has-glob). + +## Usage + +```js +var isGlob = require('is-glob'); +``` + +### Default behavior + +**True** + +Patterns that have glob characters or regex patterns will return `true`: + +```js +isGlob('!foo.js'); +isGlob('*.js'); +isGlob('**/abc.js'); +isGlob('abc/*.js'); +isGlob('abc/(aaa|bbb).js'); +isGlob('abc/[a-z].js'); +isGlob('abc/{a,b}.js'); +//=> true +``` + +Extglobs + +```js +isGlob('abc/@(a).js'); +isGlob('abc/!(a).js'); +isGlob('abc/+(a).js'); +isGlob('abc/*(a).js'); +isGlob('abc/?(a).js'); +//=> true +``` + +**False** + +Escaped globs or extglobs return `false`: + +```js +isGlob('abc/\\@(a).js'); +isGlob('abc/\\!(a).js'); +isGlob('abc/\\+(a).js'); +isGlob('abc/\\*(a).js'); +isGlob('abc/\\?(a).js'); +isGlob('\\!foo.js'); +isGlob('\\*.js'); +isGlob('\\*\\*/abc.js'); +isGlob('abc/\\*.js'); +isGlob('abc/\\(aaa|bbb).js'); +isGlob('abc/\\[a-z].js'); +isGlob('abc/\\{a,b}.js'); +//=> false +``` + +Patterns that do not have glob patterns return `false`: + +```js +isGlob('abc.js'); +isGlob('abc/def/ghi.js'); +isGlob('foo.js'); +isGlob('abc/@.js'); +isGlob('abc/+.js'); +isGlob('abc/?.js'); +isGlob(); +isGlob(null); +//=> false +``` + +Arrays are also `false` (If you want to check if an array has a glob pattern, use [has-glob](https://github.com/jonschlinkert/has-glob)): + +```js +isGlob(['**/*.js']); +isGlob(['foo.js']); +//=> false +``` + +### Option strict + +When `options.strict === false` the behavior is less strict in determining if a pattern is a glob. Meaning that +some patterns that would return `false` may return `true`. This is done so that matching libraries like [micromatch](https://github.com/micromatch/micromatch) have a chance at determining if the pattern is a glob or not. + +**True** + +Patterns that have glob characters or regex patterns will return `true`: + +```js +isGlob('!foo.js', {strict: false}); +isGlob('*.js', {strict: false}); +isGlob('**/abc.js', {strict: false}); +isGlob('abc/*.js', {strict: false}); +isGlob('abc/(aaa|bbb).js', {strict: false}); +isGlob('abc/[a-z].js', {strict: false}); +isGlob('abc/{a,b}.js', {strict: false}); +//=> true +``` + +Extglobs + +```js +isGlob('abc/@(a).js', {strict: false}); +isGlob('abc/!(a).js', {strict: false}); +isGlob('abc/+(a).js', {strict: false}); +isGlob('abc/*(a).js', {strict: false}); +isGlob('abc/?(a).js', {strict: false}); +//=> true +``` + +**False** + +Escaped globs or extglobs return `false`: + +```js +isGlob('\\!foo.js', {strict: false}); +isGlob('\\*.js', {strict: false}); +isGlob('\\*\\*/abc.js', {strict: false}); +isGlob('abc/\\*.js', {strict: false}); +isGlob('abc/\\(aaa|bbb).js', {strict: false}); +isGlob('abc/\\[a-z].js', {strict: false}); +isGlob('abc/\\{a,b}.js', {strict: false}); +//=> false +``` + +## About + +
+Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +
+ +
+Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` + +
+ +
+Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +$ npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
+ +### Related projects + +You might also be interested in these projects: + +* [assemble](https://www.npmjs.com/package/assemble): Get the rocks out of your socks! Assemble makes you fast at creating web projects… [more](https://github.com/assemble/assemble) | [homepage](https://github.com/assemble/assemble "Get the rocks out of your socks! Assemble makes you fast at creating web projects. Assemble is used by thousands of projects for rapid prototyping, creating themes, scaffolds, boilerplates, e-books, UI components, API documentation, blogs, building websit") +* [base](https://www.npmjs.com/package/base): Framework for rapidly creating high quality, server-side node.js applications, using plugins like building blocks | [homepage](https://github.com/node-base/base "Framework for rapidly creating high quality, server-side node.js applications, using plugins like building blocks") +* [update](https://www.npmjs.com/package/update): Be scalable! Update is a new, open source developer framework and CLI for automating updates… [more](https://github.com/update/update) | [homepage](https://github.com/update/update "Be scalable! Update is a new, open source developer framework and CLI for automating updates of any kind in code projects.") +* [verb](https://www.npmjs.com/package/verb): Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… [more](https://github.com/verbose/verb) | [homepage](https://github.com/verbose/verb "Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used on hundreds of projects of all sizes to generate everything from API docs to readmes.") + +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 47 | [jonschlinkert](https://github.com/jonschlinkert) | +| 5 | [doowb](https://github.com/doowb) | +| 1 | [phated](https://github.com/phated) | +| 1 | [danhper](https://github.com/danhper) | +| 1 | [paulmillr](https://github.com/paulmillr) | + +### Author + +**Jon Schlinkert** + +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +### License + +Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on March 27, 2019._ \ No newline at end of file diff --git a/libs/events/node_modules/is-glob/index.js b/libs/events/node_modules/is-glob/index.js new file mode 100644 index 000000000..620f563ec --- /dev/null +++ b/libs/events/node_modules/is-glob/index.js @@ -0,0 +1,150 @@ +/*! + * is-glob + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +var isExtglob = require('is-extglob'); +var chars = { '{': '}', '(': ')', '[': ']'}; +var strictCheck = function(str) { + if (str[0] === '!') { + return true; + } + var index = 0; + var pipeIndex = -2; + var closeSquareIndex = -2; + var closeCurlyIndex = -2; + var closeParenIndex = -2; + var backSlashIndex = -2; + while (index < str.length) { + if (str[index] === '*') { + return true; + } + + if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) { + return true; + } + + if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') { + if (closeSquareIndex < index) { + closeSquareIndex = str.indexOf(']', index); + } + if (closeSquareIndex > index) { + if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { + return true; + } + backSlashIndex = str.indexOf('\\', index); + if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { + return true; + } + } + } + + if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') { + closeCurlyIndex = str.indexOf('}', index); + if (closeCurlyIndex > index) { + backSlashIndex = str.indexOf('\\', index); + if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) { + return true; + } + } + } + + if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') { + closeParenIndex = str.indexOf(')', index); + if (closeParenIndex > index) { + backSlashIndex = str.indexOf('\\', index); + if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { + return true; + } + } + } + + if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') { + if (pipeIndex < index) { + pipeIndex = str.indexOf('|', index); + } + if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') { + closeParenIndex = str.indexOf(')', pipeIndex); + if (closeParenIndex > pipeIndex) { + backSlashIndex = str.indexOf('\\', pipeIndex); + if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { + return true; + } + } + } + } + + if (str[index] === '\\') { + var open = str[index + 1]; + index += 2; + var close = chars[open]; + + if (close) { + var n = str.indexOf(close, index); + if (n !== -1) { + index = n + 1; + } + } + + if (str[index] === '!') { + return true; + } + } else { + index++; + } + } + return false; +}; + +var relaxedCheck = function(str) { + if (str[0] === '!') { + return true; + } + var index = 0; + while (index < str.length) { + if (/[*?{}()[\]]/.test(str[index])) { + return true; + } + + if (str[index] === '\\') { + var open = str[index + 1]; + index += 2; + var close = chars[open]; + + if (close) { + var n = str.indexOf(close, index); + if (n !== -1) { + index = n + 1; + } + } + + if (str[index] === '!') { + return true; + } + } else { + index++; + } + } + return false; +}; + +module.exports = function isGlob(str, options) { + if (typeof str !== 'string' || str === '') { + return false; + } + + if (isExtglob(str)) { + return true; + } + + var check = strictCheck; + + // optionally relax check + if (options && options.strict === false) { + check = relaxedCheck; + } + + return check(str); +}; diff --git a/libs/events/node_modules/is-glob/package.json b/libs/events/node_modules/is-glob/package.json new file mode 100644 index 000000000..858af0378 --- /dev/null +++ b/libs/events/node_modules/is-glob/package.json @@ -0,0 +1,81 @@ +{ + "name": "is-glob", + "description": "Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a better user experience.", + "version": "4.0.3", + "homepage": "https://github.com/micromatch/is-glob", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "contributors": [ + "Brian Woodward (https://twitter.com/doowb)", + "Daniel Perez (https://tuvistavie.com)", + "Jon Schlinkert (http://twitter.com/jonschlinkert)" + ], + "repository": "micromatch/is-glob", + "bugs": { + "url": "https://github.com/micromatch/is-glob/issues" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "main": "index.js", + "engines": { + "node": ">=0.10.0" + }, + "scripts": { + "test": "mocha && node benchmark.js" + }, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "devDependencies": { + "gulp-format-md": "^0.1.10", + "mocha": "^3.0.2" + }, + "keywords": [ + "bash", + "braces", + "check", + "exec", + "expression", + "extglob", + "glob", + "globbing", + "globstar", + "is", + "match", + "matches", + "pattern", + "regex", + "regular", + "string", + "test" + ], + "verb": { + "layout": "default", + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "assemble", + "base", + "update", + "verb" + ] + }, + "reflinks": [ + "assemble", + "bach", + "base", + "composer", + "gulp", + "has-glob", + "is-valid-glob", + "micromatch", + "npm", + "scaffold", + "verb", + "vinyl" + ] + } +} diff --git a/libs/events/node_modules/is-number/LICENSE b/libs/events/node_modules/is-number/LICENSE new file mode 100644 index 000000000..9af4a67d2 --- /dev/null +++ b/libs/events/node_modules/is-number/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/is-number/README.md b/libs/events/node_modules/is-number/README.md new file mode 100644 index 000000000..eb8149e8c --- /dev/null +++ b/libs/events/node_modules/is-number/README.md @@ -0,0 +1,187 @@ +# is-number [![NPM version](https://img.shields.io/npm/v/is-number.svg?style=flat)](https://www.npmjs.com/package/is-number) [![NPM monthly downloads](https://img.shields.io/npm/dm/is-number.svg?style=flat)](https://npmjs.org/package/is-number) [![NPM total downloads](https://img.shields.io/npm/dt/is-number.svg?style=flat)](https://npmjs.org/package/is-number) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/is-number.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/is-number) + +> Returns true if the value is a finite number. + +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save is-number +``` + +## Why is this needed? + +In JavaScript, it's not always as straightforward as it should be to reliably check if a value is a number. It's common for devs to use `+`, `-`, or `Number()` to cast a string value to a number (for example, when values are returned from user input, regex matches, parsers, etc). But there are many non-intuitive edge cases that yield unexpected results: + +```js +console.log(+[]); //=> 0 +console.log(+''); //=> 0 +console.log(+' '); //=> 0 +console.log(typeof NaN); //=> 'number' +``` + +This library offers a performant way to smooth out edge cases like these. + +## Usage + +```js +const isNumber = require('is-number'); +``` + +See the [tests](./test.js) for more examples. + +### true + +```js +isNumber(5e3); // true +isNumber(0xff); // true +isNumber(-1.1); // true +isNumber(0); // true +isNumber(1); // true +isNumber(1.1); // true +isNumber(10); // true +isNumber(10.10); // true +isNumber(100); // true +isNumber('-1.1'); // true +isNumber('0'); // true +isNumber('012'); // true +isNumber('0xff'); // true +isNumber('1'); // true +isNumber('1.1'); // true +isNumber('10'); // true +isNumber('10.10'); // true +isNumber('100'); // true +isNumber('5e3'); // true +isNumber(parseInt('012')); // true +isNumber(parseFloat('012')); // true +``` + +### False + +Everything else is false, as you would expect: + +```js +isNumber(Infinity); // false +isNumber(NaN); // false +isNumber(null); // false +isNumber(undefined); // false +isNumber(''); // false +isNumber(' '); // false +isNumber('foo'); // false +isNumber([1]); // false +isNumber([]); // false +isNumber(function () {}); // false +isNumber({}); // false +``` + +## Release history + +### 7.0.0 + +* Refactor. Now uses `.isFinite` if it exists. +* Performance is about the same as v6.0 when the value is a string or number. But it's now 3x-4x faster when the value is not a string or number. + +### 6.0.0 + +* Optimizations, thanks to @benaadams. + +### 5.0.0 + +**Breaking changes** + +* removed support for `instanceof Number` and `instanceof String` + +## Benchmarks + +As with all benchmarks, take these with a grain of salt. See the [benchmarks](./benchmark/index.js) for more detail. + +``` +# all +v7.0 x 413,222 ops/sec ±2.02% (86 runs sampled) +v6.0 x 111,061 ops/sec ±1.29% (85 runs sampled) +parseFloat x 317,596 ops/sec ±1.36% (86 runs sampled) +fastest is 'v7.0' + +# string +v7.0 x 3,054,496 ops/sec ±1.05% (89 runs sampled) +v6.0 x 2,957,781 ops/sec ±0.98% (88 runs sampled) +parseFloat x 3,071,060 ops/sec ±1.13% (88 runs sampled) +fastest is 'parseFloat,v7.0' + +# number +v7.0 x 3,146,895 ops/sec ±0.89% (89 runs sampled) +v6.0 x 3,214,038 ops/sec ±1.07% (89 runs sampled) +parseFloat x 3,077,588 ops/sec ±1.07% (87 runs sampled) +fastest is 'v6.0' +``` + +## About + +
+Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +
+ +
+Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` + +
+ +
+Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +$ npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
+ +### Related projects + +You might also be interested in these projects: + +* [is-plain-object](https://www.npmjs.com/package/is-plain-object): Returns true if an object was created by the `Object` constructor. | [homepage](https://github.com/jonschlinkert/is-plain-object "Returns true if an object was created by the `Object` constructor.") +* [is-primitive](https://www.npmjs.com/package/is-primitive): Returns `true` if the value is a primitive. | [homepage](https://github.com/jonschlinkert/is-primitive "Returns `true` if the value is a primitive. ") +* [isobject](https://www.npmjs.com/package/isobject): Returns true if the value is an object and not an array or null. | [homepage](https://github.com/jonschlinkert/isobject "Returns true if the value is an object and not an array or null.") +* [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of "Get the native type of a value.") + +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 49 | [jonschlinkert](https://github.com/jonschlinkert) | +| 5 | [charlike-old](https://github.com/charlike-old) | +| 1 | [benaadams](https://github.com/benaadams) | +| 1 | [realityking](https://github.com/realityking) | + +### Author + +**Jon Schlinkert** + +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) + +### License + +Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on June 15, 2018._ \ No newline at end of file diff --git a/libs/events/node_modules/is-number/index.js b/libs/events/node_modules/is-number/index.js new file mode 100644 index 000000000..27f19b757 --- /dev/null +++ b/libs/events/node_modules/is-number/index.js @@ -0,0 +1,18 @@ +/*! + * is-number + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +module.exports = function(num) { + if (typeof num === 'number') { + return num - num === 0; + } + if (typeof num === 'string' && num.trim() !== '') { + return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); + } + return false; +}; diff --git a/libs/events/node_modules/is-number/package.json b/libs/events/node_modules/is-number/package.json new file mode 100644 index 000000000..371507260 --- /dev/null +++ b/libs/events/node_modules/is-number/package.json @@ -0,0 +1,82 @@ +{ + "name": "is-number", + "description": "Returns true if a number or string value is a finite number. Useful for regex matches, parsing, user input, etc.", + "version": "7.0.0", + "homepage": "https://github.com/jonschlinkert/is-number", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "contributors": [ + "Jon Schlinkert (http://twitter.com/jonschlinkert)", + "Olsten Larck (https://i.am.charlike.online)", + "Rouven Weßling (www.rouvenwessling.de)" + ], + "repository": "jonschlinkert/is-number", + "bugs": { + "url": "https://github.com/jonschlinkert/is-number/issues" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "main": "index.js", + "engines": { + "node": ">=0.12.0" + }, + "scripts": { + "test": "mocha" + }, + "devDependencies": { + "ansi": "^0.3.1", + "benchmark": "^2.1.4", + "gulp-format-md": "^1.0.0", + "mocha": "^3.5.3" + }, + "keywords": [ + "cast", + "check", + "coerce", + "coercion", + "finite", + "integer", + "is", + "isnan", + "is-nan", + "is-num", + "is-number", + "isnumber", + "isfinite", + "istype", + "kind", + "math", + "nan", + "num", + "number", + "numeric", + "parseFloat", + "parseInt", + "test", + "type", + "typeof", + "value" + ], + "verb": { + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "related": { + "list": [ + "is-plain-object", + "is-primitive", + "isobject", + "kind-of" + ] + }, + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + } + } +} diff --git a/libs/events/node_modules/js-yaml/CHANGELOG.md b/libs/events/node_modules/js-yaml/CHANGELOG.md new file mode 100644 index 000000000..ff2375e05 --- /dev/null +++ b/libs/events/node_modules/js-yaml/CHANGELOG.md @@ -0,0 +1,616 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [4.1.0] - 2021-04-15 +### Added +- Types are now exported as `yaml.types.XXX`. +- Every type now has `options` property with original arguments kept as they were + (see `yaml.types.int.options` as an example). + +### Changed +- `Schema.extend()` now keeps old type order in case of conflicts + (e.g. Schema.extend([ a, b, c ]).extend([ b, a, d ]) is now ordered as `abcd` instead of `cbad`). + + +## [4.0.0] - 2021-01-03 +### Changed +- Check [migration guide](migrate_v3_to_v4.md) to see details for all breaking changes. +- Breaking: "unsafe" tags `!!js/function`, `!!js/regexp`, `!!js/undefined` are + moved to [js-yaml-js-types](https://github.com/nodeca/js-yaml-js-types) package. +- Breaking: removed `safe*` functions. Use `load`, `loadAll`, `dump` + instead which are all now safe by default. +- `yaml.DEFAULT_SAFE_SCHEMA` and `yaml.DEFAULT_FULL_SCHEMA` are removed, use + `yaml.DEFAULT_SCHEMA` instead. +- `yaml.Schema.create(schema, tags)` is removed, use `schema.extend(tags)` instead. +- `!!binary` now always mapped to `Uint8Array` on load. +- Reduced nesting of `/lib` folder. +- Parse numbers according to YAML 1.2 instead of YAML 1.1 (`01234` is now decimal, + `0o1234` is octal, `1:23` is parsed as string instead of base60). +- `dump()` no longer quotes `:`, `[`, `]`, `(`, `)` except when necessary, #470, #557. +- Line and column in exceptions are now formatted as `(X:Y)` instead of + `at line X, column Y` (also present in compact format), #332. +- Code snippet created in exceptions now contains multiple lines with line numbers. +- `dump()` now serializes `undefined` as `null` in collections and removes keys with + `undefined` in mappings, #571. +- `dump()` with `skipInvalid=true` now serializes invalid items in collections as null. +- Custom tags starting with `!` are now dumped as `!tag` instead of `!`, #576. +- Custom tags starting with `tag:yaml.org,2002:` are now shorthanded using `!!`, #258. + +### Added +- Added `.mjs` (es modules) support. +- Added `quotingType` and `forceQuotes` options for dumper to configure + string literal style, #290, #529. +- Added `styles: { '!!null': 'empty' }` option for dumper + (serializes `{ foo: null }` as "`foo: `"), #570. +- Added `replacer` option (similar to option in JSON.stringify), #339. +- Custom `Tag` can now handle all tags or multiple tags with the same prefix, #385. + +### Fixed +- Astral characters are no longer encoded by `dump()`, #587. +- "duplicate mapping key" exception now points at the correct column, #452. +- Extra commas in flow collections (e.g. `[foo,,bar]`) now throw an exception + instead of producing null, #321. +- `__proto__` key no longer overrides object prototype, #164. +- Removed `bower.json`. +- Tags are now url-decoded in `load()` and url-encoded in `dump()` + (previously usage of custom non-ascii tags may have led to invalid YAML that can't be parsed). +- Anchors now work correctly with empty nodes, #301. +- Fix incorrect parsing of invalid block mapping syntax, #418. +- Throw an error if block sequence/mapping indent contains a tab, #80. + + +## [3.14.1] - 2020-12-07 +### Security +- Fix possible code execution in (already unsafe) `.load()` (in &anchor). + + +## [3.14.0] - 2020-05-22 +### Changed +- Support `safe/loadAll(input, options)` variant of call. +- CI: drop outdated nodejs versions. +- Dev deps bump. + +### Fixed +- Quote `=` in plain scalars #519. +- Check the node type for `!` tag in case user manually specifies it. +- Verify that there are no null-bytes in input. +- Fix wrong quote position when writing condensed flow, #526. + + +## [3.13.1] - 2019-04-05 +### Security +- Fix possible code execution in (already unsafe) `.load()`, #480. + + +## [3.13.0] - 2019-03-20 +### Security +- Security fix: `safeLoad()` can hang when arrays with nested refs + used as key. Now throws exception for nested arrays. #475. + + +## [3.12.2] - 2019-02-26 +### Fixed +- Fix `noArrayIndent` option for root level, #468. + + +## [3.12.1] - 2019-01-05 +### Added +- Added `noArrayIndent` option, #432. + + +## [3.12.0] - 2018-06-02 +### Changed +- Support arrow functions without a block statement, #421. + + +## [3.11.0] - 2018-03-05 +### Added +- Add arrow functions suport for `!!js/function`. + +### Fixed +- Fix dump in bin/octal/hex formats for negative integers, #399. + + +## [3.10.0] - 2017-09-10 +### Fixed +- Fix `condenseFlow` output (quote keys for sure, instead of spaces), #371, #370. +- Dump astrals as codepoints instead of surrogate pair, #368. + + +## [3.9.1] - 2017-07-08 +### Fixed +- Ensure stack is present for custom errors in node 7.+, #351. + + +## [3.9.0] - 2017-07-08 +### Added +- Add `condenseFlow` option (to create pretty URL query params), #346. + +### Fixed +- Support array return from safeLoadAll/loadAll, #350. + + +## [3.8.4] - 2017-05-08 +### Fixed +- Dumper: prevent space after dash for arrays that wrap, #343. + + +## [3.8.3] - 2017-04-05 +### Fixed +- Should not allow numbers to begin and end with underscore, #335. + + +## [3.8.2] - 2017-03-02 +### Fixed +- Fix `!!float 123` (integers) parse, #333. +- Don't allow leading zeros in floats (except 0, 0.xxx). +- Allow positive exponent without sign in floats. + + +## [3.8.1] - 2017-02-07 +### Changed +- Maintenance: update browserified build. + + +## [3.8.0] - 2017-02-07 +### Fixed +- Fix reported position for `duplicated mapping key` errors. + Now points to block start instead of block end. + (#243, thanks to @shockey). + + +## [3.7.0] - 2016-11-12 +### Added +- Support polymorphism for tags (#300, thanks to @monken). + +### Fixed +- Fix parsing of quotes followed by newlines (#304, thanks to @dplepage). + + +## [3.6.1] - 2016-05-11 +### Fixed +- Fix output cut on a pipe, #286. + + +## [3.6.0] - 2016-04-16 +### Fixed +- Dumper rewrite, fix multiple bugs with trailing `\n`. + Big thanks to @aepsilon! +- Loader: fix leading/trailing newlines in block scalars, @aepsilon. + + +## [3.5.5] - 2016-03-17 +### Fixed +- Date parse fix: don't allow dates with on digit in month and day, #268. + + +## [3.5.4] - 2016-03-09 +### Added +- `noCompatMode` for dumper, to disable quoting YAML 1.1 values. + + +## [3.5.3] - 2016-02-11 +### Changed +- Maintenance release. + + +## [3.5.2] - 2016-01-11 +### Changed +- Maintenance: missed comma in bower config. + + +## [3.5.1] - 2016-01-11 +### Changed +- Removed `inherit` dependency, #239. +- Better browserify workaround for esprima load. +- Demo rewrite. + + +## [3.5.0] - 2016-01-10 +### Fixed +- Dumper. Fold strings only, #217. +- Dumper. `norefs` option, to clone linked objects, #229. +- Loader. Throw a warning for duplicate keys, #166. +- Improved browserify support (mark `esprima` & `Buffer` excluded). + + +## [3.4.6] - 2015-11-26 +### Changed +- Use standalone `inherit` to keep browserified files clear. + + +## [3.4.5] - 2015-11-23 +### Added +- Added `lineWidth` option to dumper. + + +## [3.4.4] - 2015-11-21 +### Fixed +- Fixed floats dump (missed dot for scientific format), #220. +- Allow non-printable characters inside quoted scalars, #192. + + +## [3.4.3] - 2015-10-10 +### Changed +- Maintenance release - deps bump (esprima, argparse). + + +## [3.4.2] - 2015-09-09 +### Fixed +- Fixed serialization of duplicated entries in sequences, #205. + Thanks to @vogelsgesang. + + +## [3.4.1] - 2015-09-05 +### Fixed +- Fixed stacktrace handling in generated errors, for browsers (FF/IE). + + +## [3.4.0] - 2015-08-23 +### Changed +- Don't throw on warnings anymore. Use `onWarning` option to catch. +- Throw error on unknown tags (was warning before). +- Reworked internals of error class. + +### Fixed +- Fixed multiline keys dump, #197. Thanks to @tcr. +- Fixed heading line breaks in some scalars (regression). + + +## [3.3.1] - 2015-05-13 +### Added +- Added `.sortKeys` dumper option, thanks to @rjmunro. + +### Fixed +- Fixed astral characters support, #191. + + +## [3.3.0] - 2015-04-26 +### Changed +- Significantly improved long strings formatting in dumper, thanks to @isaacs. +- Strip BOM if exists. + + +## [3.2.7] - 2015-02-19 +### Changed +- Maintenance release. +- Updated dependencies. +- HISTORY.md -> CHANGELOG.md + + +## [3.2.6] - 2015-02-07 +### Fixed +- Fixed encoding of UTF-16 surrogate pairs. (e.g. "\U0001F431" CAT FACE). +- Fixed demo dates dump (#113, thanks to @Hypercubed). + + +## [3.2.5] - 2014-12-28 +### Fixed +- Fixed resolving of all built-in types on empty nodes. +- Fixed invalid warning on empty lines within quoted scalars and flow collections. +- Fixed bug: Tag on an empty node didn't resolve in some cases. + + +## [3.2.4] - 2014-12-19 +### Fixed +- Fixed resolving of !!null tag on an empty node. + + +## [3.2.3] - 2014-11-08 +### Fixed +- Implemented dumping of objects with circular and cross references. +- Partially fixed aliasing of constructed objects. (see issue #141 for details) + + +## [3.2.2] - 2014-09-07 +### Fixed +- Fixed infinite loop on unindented block scalars. +- Rewritten base64 encode/decode in binary type, to keep code licence clear. + + +## [3.2.1] - 2014-08-24 +### Fixed +- Nothig new. Just fix npm publish error. + + +## [3.2.0] - 2014-08-24 +### Added +- Added input piping support to CLI. + +### Fixed +- Fixed typo, that could cause hand on initial indent (#139). + + +## [3.1.0] - 2014-07-07 +### Changed +- 1.5x-2x speed boost. +- Removed deprecated `require('xxx.yml')` support. +- Significant code cleanup and refactoring. +- Internal API changed. If you used custom types - see updated examples. + Others are not affected. +- Even if the input string has no trailing line break character, + it will be parsed as if it has one. +- Added benchmark scripts. +- Moved bower files to /dist folder +- Bugfixes. + + +## [3.0.2] - 2014-02-27 +### Fixed +- Fixed bug: "constructor" string parsed as `null`. + + +## [3.0.1] - 2013-12-22 +### Fixed +- Fixed parsing of literal scalars. (issue #108) +- Prevented adding unnecessary spaces in object dumps. (issue #68) +- Fixed dumping of objects with very long (> 1024 in length) keys. + + +## [3.0.0] - 2013-12-16 +### Changed +- Refactored code. Changed API for custom types. +- Removed output colors in CLI, dump json by default. +- Removed big dependencies from browser version (esprima, buffer). Load `esprima` manually, if `!!js/function` needed. `!!bin` now returns Array in browser +- AMD support. +- Don't quote dumped strings because of `-` & `?` (if not first char). +- __Deprecated__ loading yaml files via `require()`, as not recommended + behaviour for node. + + +## [2.1.3] - 2013-10-16 +### Fixed +- Fix wrong loading of empty block scalars. + + +## [2.1.2] - 2013-10-07 +### Fixed +- Fix unwanted line breaks in folded scalars. + + +## [2.1.1] - 2013-10-02 +### Fixed +- Dumper now respects deprecated booleans syntax from YAML 1.0/1.1 +- Fixed reader bug in JSON-like sequences/mappings. + + +## [2.1.0] - 2013-06-05 +### Added +- Add standard YAML schemas: Failsafe (`FAILSAFE_SCHEMA`), + JSON (`JSON_SCHEMA`) and Core (`CORE_SCHEMA`). +- Add `skipInvalid` dumper option. + +### Changed +- Rename `DEFAULT_SCHEMA` to `DEFAULT_FULL_SCHEMA` + and `SAFE_SCHEMA` to `DEFAULT_SAFE_SCHEMA`. +- Use `safeLoad` for `require` extension. + +### Fixed +- Bug fix: export `NIL` constant from the public interface. + + +## [2.0.5] - 2013-04-26 +### Security +- Close security issue in !!js/function constructor. + Big thanks to @nealpoole for security audit. + + +## [2.0.4] - 2013-04-08 +### Changed +- Updated .npmignore to reduce package size + + +## [2.0.3] - 2013-02-26 +### Fixed +- Fixed dumping of empty arrays ans objects. ([] and {} instead of null) + + +## [2.0.2] - 2013-02-15 +### Fixed +- Fixed input validation: tabs are printable characters. + + +## [2.0.1] - 2013-02-09 +### Fixed +- Fixed error, when options not passed to function cass + + +## [2.0.0] - 2013-02-09 +### Changed +- Full rewrite. New architecture. Fast one-stage parsing. +- Changed custom types API. +- Added YAML dumper. + + +## [1.0.3] - 2012-11-05 +### Fixed +- Fixed utf-8 files loading. + + +## [1.0.2] - 2012-08-02 +### Fixed +- Pull out hand-written shims. Use ES5-Shims for old browsers support. See #44. +- Fix timstamps incorectly parsed in local time when no time part specified. + + +## [1.0.1] - 2012-07-07 +### Fixed +- Fixes `TypeError: 'undefined' is not an object` under Safari. Thanks Phuong. +- Fix timestamps incorrectly parsed in local time. Thanks @caolan. Closes #46. + + +## [1.0.0] - 2012-07-01 +### Changed +- `y`, `yes`, `n`, `no`, `on`, `off` are not converted to Booleans anymore. + Fixes #42. +- `require(filename)` now returns a single document and throws an Error if + file contains more than one document. +- CLI was merged back from js-yaml.bin + + +## [0.3.7] - 2012-02-28 +### Fixed +- Fix export of `addConstructor()`. Closes #39. + + +## [0.3.6] - 2012-02-22 +### Changed +- Removed AMD parts - too buggy to use. Need help to rewrite from scratch + +### Fixed +- Removed YUI compressor warning (renamed `double` variable). Closes #40. + + +## [0.3.5] - 2012-01-10 +### Fixed +- Workagound for .npmignore fuckup under windows. Thanks to airportyh. + + +## [0.3.4] - 2011-12-24 +### Fixed +- Fixes str[] for oldIEs support. +- Adds better has change support for browserified demo. +- improves compact output of Error. Closes #33. + + +## [0.3.3] - 2011-12-20 +### Added +- adds `compact` stringification of Errors. + +### Changed +- jsyaml executable moved to separate module. + + +## [0.3.2] - 2011-12-16 +### Added +- Added jsyaml executable. +- Added !!js/function support. Closes #12. + +### Fixed +- Fixes ug with block style scalars. Closes #26. +- All sources are passing JSLint now. +- Fixes bug in Safari. Closes #28. +- Fixes bug in Opers. Closes #29. +- Improves browser support. Closes #20. + + +## [0.3.1] - 2011-11-18 +### Added +- Added AMD support for browserified version. +- Added permalinks for online demo YAML snippets. Now we have YPaste service, lol. +- Added !!js/regexp and !!js/undefined types. Partially solves #12. + +### Changed +- Wrapped browserified js-yaml into closure. + +### Fixed +- Fixed the resolvement of non-specific tags. Closes #17. +- Fixed !!set mapping. +- Fixed month parse in dates. Closes #19. + + +## [0.3.0] - 2011-11-09 +### Added +- Added browserified version. Closes #13. +- Added live demo of browserified version. +- Ported some of the PyYAML tests. See #14. + +### Fixed +- Removed JS.Class dependency. Closes #3. +- Fixed timestamp bug when fraction was given. + + +## [0.2.2] - 2011-11-06 +### Fixed +- Fixed crash on docs without ---. Closes #8. +- Fixed multiline string parse +- Fixed tests/comments for using array as key + + +## [0.2.1] - 2011-11-02 +### Fixed +- Fixed short file read (<4k). Closes #9. + + +## [0.2.0] - 2011-11-02 +### Changed +- First public release + + +[4.1.0]: https://github.com/nodeca/js-yaml/compare/4.0.0...4.1.0 +[4.0.0]: https://github.com/nodeca/js-yaml/compare/3.14.0...4.0.0 +[3.14.0]: https://github.com/nodeca/js-yaml/compare/3.13.1...3.14.0 +[3.13.1]: https://github.com/nodeca/js-yaml/compare/3.13.0...3.13.1 +[3.13.0]: https://github.com/nodeca/js-yaml/compare/3.12.2...3.13.0 +[3.12.2]: https://github.com/nodeca/js-yaml/compare/3.12.1...3.12.2 +[3.12.1]: https://github.com/nodeca/js-yaml/compare/3.12.0...3.12.1 +[3.12.0]: https://github.com/nodeca/js-yaml/compare/3.11.0...3.12.0 +[3.11.0]: https://github.com/nodeca/js-yaml/compare/3.10.0...3.11.0 +[3.10.0]: https://github.com/nodeca/js-yaml/compare/3.9.1...3.10.0 +[3.9.1]: https://github.com/nodeca/js-yaml/compare/3.9.0...3.9.1 +[3.9.0]: https://github.com/nodeca/js-yaml/compare/3.8.4...3.9.0 +[3.8.4]: https://github.com/nodeca/js-yaml/compare/3.8.3...3.8.4 +[3.8.3]: https://github.com/nodeca/js-yaml/compare/3.8.2...3.8.3 +[3.8.2]: https://github.com/nodeca/js-yaml/compare/3.8.1...3.8.2 +[3.8.1]: https://github.com/nodeca/js-yaml/compare/3.8.0...3.8.1 +[3.8.0]: https://github.com/nodeca/js-yaml/compare/3.7.0...3.8.0 +[3.7.0]: https://github.com/nodeca/js-yaml/compare/3.6.1...3.7.0 +[3.6.1]: https://github.com/nodeca/js-yaml/compare/3.6.0...3.6.1 +[3.6.0]: https://github.com/nodeca/js-yaml/compare/3.5.5...3.6.0 +[3.5.5]: https://github.com/nodeca/js-yaml/compare/3.5.4...3.5.5 +[3.5.4]: https://github.com/nodeca/js-yaml/compare/3.5.3...3.5.4 +[3.5.3]: https://github.com/nodeca/js-yaml/compare/3.5.2...3.5.3 +[3.5.2]: https://github.com/nodeca/js-yaml/compare/3.5.1...3.5.2 +[3.5.1]: https://github.com/nodeca/js-yaml/compare/3.5.0...3.5.1 +[3.5.0]: https://github.com/nodeca/js-yaml/compare/3.4.6...3.5.0 +[3.4.6]: https://github.com/nodeca/js-yaml/compare/3.4.5...3.4.6 +[3.4.5]: https://github.com/nodeca/js-yaml/compare/3.4.4...3.4.5 +[3.4.4]: https://github.com/nodeca/js-yaml/compare/3.4.3...3.4.4 +[3.4.3]: https://github.com/nodeca/js-yaml/compare/3.4.2...3.4.3 +[3.4.2]: https://github.com/nodeca/js-yaml/compare/3.4.1...3.4.2 +[3.4.1]: https://github.com/nodeca/js-yaml/compare/3.4.0...3.4.1 +[3.4.0]: https://github.com/nodeca/js-yaml/compare/3.3.1...3.4.0 +[3.3.1]: https://github.com/nodeca/js-yaml/compare/3.3.0...3.3.1 +[3.3.0]: https://github.com/nodeca/js-yaml/compare/3.2.7...3.3.0 +[3.2.7]: https://github.com/nodeca/js-yaml/compare/3.2.6...3.2.7 +[3.2.6]: https://github.com/nodeca/js-yaml/compare/3.2.5...3.2.6 +[3.2.5]: https://github.com/nodeca/js-yaml/compare/3.2.4...3.2.5 +[3.2.4]: https://github.com/nodeca/js-yaml/compare/3.2.3...3.2.4 +[3.2.3]: https://github.com/nodeca/js-yaml/compare/3.2.2...3.2.3 +[3.2.2]: https://github.com/nodeca/js-yaml/compare/3.2.1...3.2.2 +[3.2.1]: https://github.com/nodeca/js-yaml/compare/3.2.0...3.2.1 +[3.2.0]: https://github.com/nodeca/js-yaml/compare/3.1.0...3.2.0 +[3.1.0]: https://github.com/nodeca/js-yaml/compare/3.0.2...3.1.0 +[3.0.2]: https://github.com/nodeca/js-yaml/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/nodeca/js-yaml/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/nodeca/js-yaml/compare/2.1.3...3.0.0 +[2.1.3]: https://github.com/nodeca/js-yaml/compare/2.1.2...2.1.3 +[2.1.2]: https://github.com/nodeca/js-yaml/compare/2.1.1...2.1.2 +[2.1.1]: https://github.com/nodeca/js-yaml/compare/2.1.0...2.1.1 +[2.1.0]: https://github.com/nodeca/js-yaml/compare/2.0.5...2.1.0 +[2.0.5]: https://github.com/nodeca/js-yaml/compare/2.0.4...2.0.5 +[2.0.4]: https://github.com/nodeca/js-yaml/compare/2.0.3...2.0.4 +[2.0.3]: https://github.com/nodeca/js-yaml/compare/2.0.2...2.0.3 +[2.0.2]: https://github.com/nodeca/js-yaml/compare/2.0.1...2.0.2 +[2.0.1]: https://github.com/nodeca/js-yaml/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/nodeca/js-yaml/compare/1.0.3...2.0.0 +[1.0.3]: https://github.com/nodeca/js-yaml/compare/1.0.2...1.0.3 +[1.0.2]: https://github.com/nodeca/js-yaml/compare/1.0.1...1.0.2 +[1.0.1]: https://github.com/nodeca/js-yaml/compare/1.0.0...1.0.1 +[1.0.0]: https://github.com/nodeca/js-yaml/compare/0.3.7...1.0.0 +[0.3.7]: https://github.com/nodeca/js-yaml/compare/0.3.6...0.3.7 +[0.3.6]: https://github.com/nodeca/js-yaml/compare/0.3.5...0.3.6 +[0.3.5]: https://github.com/nodeca/js-yaml/compare/0.3.4...0.3.5 +[0.3.4]: https://github.com/nodeca/js-yaml/compare/0.3.3...0.3.4 +[0.3.3]: https://github.com/nodeca/js-yaml/compare/0.3.2...0.3.3 +[0.3.2]: https://github.com/nodeca/js-yaml/compare/0.3.1...0.3.2 +[0.3.1]: https://github.com/nodeca/js-yaml/compare/0.3.0...0.3.1 +[0.3.0]: https://github.com/nodeca/js-yaml/compare/0.2.2...0.3.0 +[0.2.2]: https://github.com/nodeca/js-yaml/compare/0.2.1...0.2.2 +[0.2.1]: https://github.com/nodeca/js-yaml/compare/0.2.0...0.2.1 +[0.2.0]: https://github.com/nodeca/js-yaml/releases/tag/0.2.0 diff --git a/libs/events/node_modules/js-yaml/LICENSE b/libs/events/node_modules/js-yaml/LICENSE new file mode 100644 index 000000000..09d3a29e9 --- /dev/null +++ b/libs/events/node_modules/js-yaml/LICENSE @@ -0,0 +1,21 @@ +(The MIT License) + +Copyright (C) 2011-2015 by Vitaly Puzrin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/js-yaml/README.md b/libs/events/node_modules/js-yaml/README.md new file mode 100644 index 000000000..3cbc4bd2d --- /dev/null +++ b/libs/events/node_modules/js-yaml/README.md @@ -0,0 +1,246 @@ +JS-YAML - YAML 1.2 parser / writer for JavaScript +================================================= + +[![CI](https://github.com/nodeca/js-yaml/workflows/CI/badge.svg?branch=master)](https://github.com/nodeca/js-yaml/actions) +[![NPM version](https://img.shields.io/npm/v/js-yaml.svg)](https://www.npmjs.org/package/js-yaml) + +__[Online Demo](http://nodeca.github.com/js-yaml/)__ + + +This is an implementation of [YAML](http://yaml.org/), a human-friendly data +serialization language. Started as [PyYAML](http://pyyaml.org/) port, it was +completely rewritten from scratch. Now it's very fast, and supports 1.2 spec. + + +Installation +------------ + +### YAML module for node.js + +``` +npm install js-yaml +``` + + +### CLI executable + +If you want to inspect your YAML files from CLI, install js-yaml globally: + +``` +npm install -g js-yaml +``` + +#### Usage + +``` +usage: js-yaml [-h] [-v] [-c] [-t] file + +Positional arguments: + file File with YAML document(s) + +Optional arguments: + -h, --help Show this help message and exit. + -v, --version Show program's version number and exit. + -c, --compact Display errors in compact mode + -t, --trace Show stack trace on error +``` + + +API +--- + +Here we cover the most 'useful' methods. If you need advanced details (creating +your own tags), see [examples](https://github.com/nodeca/js-yaml/tree/master/examples) +for more info. + +``` javascript +const yaml = require('js-yaml'); +const fs = require('fs'); + +// Get document, or throw exception on error +try { + const doc = yaml.load(fs.readFileSync('/home/ixti/example.yml', 'utf8')); + console.log(doc); +} catch (e) { + console.log(e); +} +``` + + +### load (string [ , options ]) + +Parses `string` as single YAML document. Returns either a +plain object, a string, a number, `null` or `undefined`, or throws `YAMLException` on error. By default, does +not support regexps, functions and undefined. + +options: + +- `filename` _(default: null)_ - string to be used as a file path in + error/warning messages. +- `onWarning` _(default: null)_ - function to call on warning messages. + Loader will call this function with an instance of `YAMLException` for each warning. +- `schema` _(default: `DEFAULT_SCHEMA`)_ - specifies a schema to use. + - `FAILSAFE_SCHEMA` - only strings, arrays and plain objects: + http://www.yaml.org/spec/1.2/spec.html#id2802346 + - `JSON_SCHEMA` - all JSON-supported types: + http://www.yaml.org/spec/1.2/spec.html#id2803231 + - `CORE_SCHEMA` - same as `JSON_SCHEMA`: + http://www.yaml.org/spec/1.2/spec.html#id2804923 + - `DEFAULT_SCHEMA` - all supported YAML types. +- `json` _(default: false)_ - compatibility with JSON.parse behaviour. If true, then duplicate keys in a mapping will override values rather than throwing an error. + +NOTE: This function **does not** understand multi-document sources, it throws +exception on those. + +NOTE: JS-YAML **does not** support schema-specific tag resolution restrictions. +So, the JSON schema is not as strictly defined in the YAML specification. +It allows numbers in any notation, use `Null` and `NULL` as `null`, etc. +The core schema also has no such restrictions. It allows binary notation for integers. + + +### loadAll (string [, iterator] [, options ]) + +Same as `load()`, but understands multi-document sources. Applies +`iterator` to each document if specified, or returns array of documents. + +``` javascript +const yaml = require('js-yaml'); + +yaml.loadAll(data, function (doc) { + console.log(doc); +}); +``` + + +### dump (object [ , options ]) + +Serializes `object` as a YAML document. Uses `DEFAULT_SCHEMA`, so it will +throw an exception if you try to dump regexps or functions. However, you can +disable exceptions by setting the `skipInvalid` option to `true`. + +options: + +- `indent` _(default: 2)_ - indentation width to use (in spaces). +- `noArrayIndent` _(default: false)_ - when true, will not add an indentation level to array elements +- `skipInvalid` _(default: false)_ - do not throw on invalid types (like function + in the safe schema) and skip pairs and single values with such types. +- `flowLevel` _(default: -1)_ - specifies level of nesting, when to switch from + block to flow style for collections. -1 means block style everwhere +- `styles` - "tag" => "style" map. Each tag may have own set of styles. +- `schema` _(default: `DEFAULT_SCHEMA`)_ specifies a schema to use. +- `sortKeys` _(default: `false`)_ - if `true`, sort keys when dumping YAML. If a + function, use the function to sort the keys. +- `lineWidth` _(default: `80`)_ - set max line width. Set `-1` for unlimited width. +- `noRefs` _(default: `false`)_ - if `true`, don't convert duplicate objects into references +- `noCompatMode` _(default: `false`)_ - if `true` don't try to be compatible with older + yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1 +- `condenseFlow` _(default: `false`)_ - if `true` flow sequences will be condensed, omitting the space between `a, b`. Eg. `'[a,b]'`, and omitting the space between `key: value` and quoting the key. Eg. `'{"a":b}'` Can be useful when using yaml for pretty URL query params as spaces are %-encoded. +- `quotingType` _(`'` or `"`, default: `'`)_ - strings will be quoted using this quoting style. If you specify single quotes, double quotes will still be used for non-printable characters. +- `forceQuotes` _(default: `false`)_ - if `true`, all non-key strings will be quoted even if they normally don't need to. +- `replacer` - callback `function (key, value)` called recursively on each key/value in source object (see `replacer` docs for `JSON.stringify`). + +The following table show availlable styles (e.g. "canonical", +"binary"...) available for each tag (.e.g. !!null, !!int ...). Yaml +output is shown on the right side after `=>` (default setting) or `->`: + +``` none +!!null + "canonical" -> "~" + "lowercase" => "null" + "uppercase" -> "NULL" + "camelcase" -> "Null" + +!!int + "binary" -> "0b1", "0b101010", "0b1110001111010" + "octal" -> "0o1", "0o52", "0o16172" + "decimal" => "1", "42", "7290" + "hexadecimal" -> "0x1", "0x2A", "0x1C7A" + +!!bool + "lowercase" => "true", "false" + "uppercase" -> "TRUE", "FALSE" + "camelcase" -> "True", "False" + +!!float + "lowercase" => ".nan", '.inf' + "uppercase" -> ".NAN", '.INF' + "camelcase" -> ".NaN", '.Inf' +``` + +Example: + +``` javascript +dump(object, { + 'styles': { + '!!null': 'canonical' // dump null as ~ + }, + 'sortKeys': true // sort object keys +}); +``` + +Supported YAML types +-------------------- + +The list of standard YAML tags and corresponding JavaScript types. See also +[YAML tag discussion](http://pyyaml.org/wiki/YAMLTagDiscussion) and +[YAML types repository](http://yaml.org/type/). + +``` +!!null '' # null +!!bool 'yes' # bool +!!int '3...' # number +!!float '3.14...' # number +!!binary '...base64...' # buffer +!!timestamp 'YYYY-...' # date +!!omap [ ... ] # array of key-value pairs +!!pairs [ ... ] # array or array pairs +!!set { ... } # array of objects with given keys and null values +!!str '...' # string +!!seq [ ... ] # array +!!map { ... } # object +``` + +**JavaScript-specific tags** + +See [js-yaml-js-types](https://github.com/nodeca/js-yaml-js-types) for +extra types. + + +Caveats +------- + +Note, that you use arrays or objects as key in JS-YAML. JS does not allow objects +or arrays as keys, and stringifies (by calling `toString()` method) them at the +moment of adding them. + +``` yaml +--- +? [ foo, bar ] +: - baz +? { foo: bar } +: - baz + - baz +``` + +``` javascript +{ "foo,bar": ["baz"], "[object Object]": ["baz", "baz"] } +``` + +Also, reading of properties on implicit block mapping keys is not supported yet. +So, the following YAML document cannot be loaded. + +``` yaml +&anchor foo: + foo: bar + *anchor: duplicate key + baz: bat + *anchor: duplicate key +``` + + +js-yaml for enterprise +---------------------- + +Available as part of the Tidelift Subscription + +The maintainers of js-yaml and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-js-yaml?utm_source=npm-js-yaml&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) diff --git a/libs/events/node_modules/js-yaml/bin/js-yaml.js b/libs/events/node_modules/js-yaml/bin/js-yaml.js new file mode 100755 index 000000000..a182f1afb --- /dev/null +++ b/libs/events/node_modules/js-yaml/bin/js-yaml.js @@ -0,0 +1,126 @@ +#!/usr/bin/env node + + +'use strict'; + +/*eslint-disable no-console*/ + + +var fs = require('fs'); +var argparse = require('argparse'); +var yaml = require('..'); + + +//////////////////////////////////////////////////////////////////////////////// + + +var cli = new argparse.ArgumentParser({ + prog: 'js-yaml', + add_help: true +}); + +cli.add_argument('-v', '--version', { + action: 'version', + version: require('../package.json').version +}); + +cli.add_argument('-c', '--compact', { + help: 'Display errors in compact mode', + action: 'store_true' +}); + +// deprecated (not needed after we removed output colors) +// option suppressed, but not completely removed for compatibility +cli.add_argument('-j', '--to-json', { + help: argparse.SUPPRESS, + dest: 'json', + action: 'store_true' +}); + +cli.add_argument('-t', '--trace', { + help: 'Show stack trace on error', + action: 'store_true' +}); + +cli.add_argument('file', { + help: 'File to read, utf-8 encoded without BOM', + nargs: '?', + default: '-' +}); + + +//////////////////////////////////////////////////////////////////////////////// + + +var options = cli.parse_args(); + + +//////////////////////////////////////////////////////////////////////////////// + +function readFile(filename, encoding, callback) { + if (options.file === '-') { + // read from stdin + + var chunks = []; + + process.stdin.on('data', function (chunk) { + chunks.push(chunk); + }); + + process.stdin.on('end', function () { + return callback(null, Buffer.concat(chunks).toString(encoding)); + }); + } else { + fs.readFile(filename, encoding, callback); + } +} + +readFile(options.file, 'utf8', function (error, input) { + var output, isYaml; + + if (error) { + if (error.code === 'ENOENT') { + console.error('File not found: ' + options.file); + process.exit(2); + } + + console.error( + options.trace && error.stack || + error.message || + String(error)); + + process.exit(1); + } + + try { + output = JSON.parse(input); + isYaml = false; + } catch (err) { + if (err instanceof SyntaxError) { + try { + output = []; + yaml.loadAll(input, function (doc) { output.push(doc); }, {}); + isYaml = true; + + if (output.length === 0) output = null; + else if (output.length === 1) output = output[0]; + + } catch (e) { + if (options.trace && err.stack) console.error(e.stack); + else console.error(e.toString(options.compact)); + + process.exit(1); + } + } else { + console.error( + options.trace && err.stack || + err.message || + String(err)); + + process.exit(1); + } + } + + if (isYaml) console.log(JSON.stringify(output, null, ' ')); + else console.log(yaml.dump(output)); +}); diff --git a/libs/events/node_modules/js-yaml/index.js b/libs/events/node_modules/js-yaml/index.js new file mode 100644 index 000000000..bcb7eba7a --- /dev/null +++ b/libs/events/node_modules/js-yaml/index.js @@ -0,0 +1,47 @@ +'use strict'; + + +var loader = require('./lib/loader'); +var dumper = require('./lib/dumper'); + + +function renamed(from, to) { + return function () { + throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' + + 'Use yaml.' + to + ' instead, which is now safe by default.'); + }; +} + + +module.exports.Type = require('./lib/type'); +module.exports.Schema = require('./lib/schema'); +module.exports.FAILSAFE_SCHEMA = require('./lib/schema/failsafe'); +module.exports.JSON_SCHEMA = require('./lib/schema/json'); +module.exports.CORE_SCHEMA = require('./lib/schema/core'); +module.exports.DEFAULT_SCHEMA = require('./lib/schema/default'); +module.exports.load = loader.load; +module.exports.loadAll = loader.loadAll; +module.exports.dump = dumper.dump; +module.exports.YAMLException = require('./lib/exception'); + +// Re-export all types in case user wants to create custom schema +module.exports.types = { + binary: require('./lib/type/binary'), + float: require('./lib/type/float'), + map: require('./lib/type/map'), + null: require('./lib/type/null'), + pairs: require('./lib/type/pairs'), + set: require('./lib/type/set'), + timestamp: require('./lib/type/timestamp'), + bool: require('./lib/type/bool'), + int: require('./lib/type/int'), + merge: require('./lib/type/merge'), + omap: require('./lib/type/omap'), + seq: require('./lib/type/seq'), + str: require('./lib/type/str') +}; + +// Removed functions from JS-YAML 3.0.x +module.exports.safeLoad = renamed('safeLoad', 'load'); +module.exports.safeLoadAll = renamed('safeLoadAll', 'loadAll'); +module.exports.safeDump = renamed('safeDump', 'dump'); diff --git a/libs/events/node_modules/js-yaml/lib/common.js b/libs/events/node_modules/js-yaml/lib/common.js new file mode 100644 index 000000000..25ef7d8e4 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/common.js @@ -0,0 +1,59 @@ +'use strict'; + + +function isNothing(subject) { + return (typeof subject === 'undefined') || (subject === null); +} + + +function isObject(subject) { + return (typeof subject === 'object') && (subject !== null); +} + + +function toArray(sequence) { + if (Array.isArray(sequence)) return sequence; + else if (isNothing(sequence)) return []; + + return [ sequence ]; +} + + +function extend(target, source) { + var index, length, key, sourceKeys; + + if (source) { + sourceKeys = Object.keys(source); + + for (index = 0, length = sourceKeys.length; index < length; index += 1) { + key = sourceKeys[index]; + target[key] = source[key]; + } + } + + return target; +} + + +function repeat(string, count) { + var result = '', cycle; + + for (cycle = 0; cycle < count; cycle += 1) { + result += string; + } + + return result; +} + + +function isNegativeZero(number) { + return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); +} + + +module.exports.isNothing = isNothing; +module.exports.isObject = isObject; +module.exports.toArray = toArray; +module.exports.repeat = repeat; +module.exports.isNegativeZero = isNegativeZero; +module.exports.extend = extend; diff --git a/libs/events/node_modules/js-yaml/lib/dumper.js b/libs/events/node_modules/js-yaml/lib/dumper.js new file mode 100644 index 000000000..f357a6aee --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/dumper.js @@ -0,0 +1,965 @@ +'use strict'; + +/*eslint-disable no-use-before-define*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var DEFAULT_SCHEMA = require('./schema/default'); + +var _toString = Object.prototype.toString; +var _hasOwnProperty = Object.prototype.hasOwnProperty; + +var CHAR_BOM = 0xFEFF; +var CHAR_TAB = 0x09; /* Tab */ +var CHAR_LINE_FEED = 0x0A; /* LF */ +var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ +var CHAR_SPACE = 0x20; /* Space */ +var CHAR_EXCLAMATION = 0x21; /* ! */ +var CHAR_DOUBLE_QUOTE = 0x22; /* " */ +var CHAR_SHARP = 0x23; /* # */ +var CHAR_PERCENT = 0x25; /* % */ +var CHAR_AMPERSAND = 0x26; /* & */ +var CHAR_SINGLE_QUOTE = 0x27; /* ' */ +var CHAR_ASTERISK = 0x2A; /* * */ +var CHAR_COMMA = 0x2C; /* , */ +var CHAR_MINUS = 0x2D; /* - */ +var CHAR_COLON = 0x3A; /* : */ +var CHAR_EQUALS = 0x3D; /* = */ +var CHAR_GREATER_THAN = 0x3E; /* > */ +var CHAR_QUESTION = 0x3F; /* ? */ +var CHAR_COMMERCIAL_AT = 0x40; /* @ */ +var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ +var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ +var CHAR_GRAVE_ACCENT = 0x60; /* ` */ +var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ +var CHAR_VERTICAL_LINE = 0x7C; /* | */ +var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ + +var ESCAPE_SEQUENCES = {}; + +ESCAPE_SEQUENCES[0x00] = '\\0'; +ESCAPE_SEQUENCES[0x07] = '\\a'; +ESCAPE_SEQUENCES[0x08] = '\\b'; +ESCAPE_SEQUENCES[0x09] = '\\t'; +ESCAPE_SEQUENCES[0x0A] = '\\n'; +ESCAPE_SEQUENCES[0x0B] = '\\v'; +ESCAPE_SEQUENCES[0x0C] = '\\f'; +ESCAPE_SEQUENCES[0x0D] = '\\r'; +ESCAPE_SEQUENCES[0x1B] = '\\e'; +ESCAPE_SEQUENCES[0x22] = '\\"'; +ESCAPE_SEQUENCES[0x5C] = '\\\\'; +ESCAPE_SEQUENCES[0x85] = '\\N'; +ESCAPE_SEQUENCES[0xA0] = '\\_'; +ESCAPE_SEQUENCES[0x2028] = '\\L'; +ESCAPE_SEQUENCES[0x2029] = '\\P'; + +var DEPRECATED_BOOLEANS_SYNTAX = [ + 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', + 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' +]; + +var DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/; + +function compileStyleMap(schema, map) { + var result, keys, index, length, tag, style, type; + + if (map === null) return {}; + + result = {}; + keys = Object.keys(map); + + for (index = 0, length = keys.length; index < length; index += 1) { + tag = keys[index]; + style = String(map[tag]); + + if (tag.slice(0, 2) === '!!') { + tag = 'tag:yaml.org,2002:' + tag.slice(2); + } + type = schema.compiledTypeMap['fallback'][tag]; + + if (type && _hasOwnProperty.call(type.styleAliases, style)) { + style = type.styleAliases[style]; + } + + result[tag] = style; + } + + return result; +} + +function encodeHex(character) { + var string, handle, length; + + string = character.toString(16).toUpperCase(); + + if (character <= 0xFF) { + handle = 'x'; + length = 2; + } else if (character <= 0xFFFF) { + handle = 'u'; + length = 4; + } else if (character <= 0xFFFFFFFF) { + handle = 'U'; + length = 8; + } else { + throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); + } + + return '\\' + handle + common.repeat('0', length - string.length) + string; +} + + +var QUOTING_TYPE_SINGLE = 1, + QUOTING_TYPE_DOUBLE = 2; + +function State(options) { + this.schema = options['schema'] || DEFAULT_SCHEMA; + this.indent = Math.max(1, (options['indent'] || 2)); + this.noArrayIndent = options['noArrayIndent'] || false; + this.skipInvalid = options['skipInvalid'] || false; + this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); + this.styleMap = compileStyleMap(this.schema, options['styles'] || null); + this.sortKeys = options['sortKeys'] || false; + this.lineWidth = options['lineWidth'] || 80; + this.noRefs = options['noRefs'] || false; + this.noCompatMode = options['noCompatMode'] || false; + this.condenseFlow = options['condenseFlow'] || false; + this.quotingType = options['quotingType'] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE; + this.forceQuotes = options['forceQuotes'] || false; + this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null; + + this.implicitTypes = this.schema.compiledImplicit; + this.explicitTypes = this.schema.compiledExplicit; + + this.tag = null; + this.result = ''; + + this.duplicates = []; + this.usedDuplicates = null; +} + +// Indents every line in a string. Empty lines (\n only) are not indented. +function indentString(string, spaces) { + var ind = common.repeat(' ', spaces), + position = 0, + next = -1, + result = '', + line, + length = string.length; + + while (position < length) { + next = string.indexOf('\n', position); + if (next === -1) { + line = string.slice(position); + position = length; + } else { + line = string.slice(position, next + 1); + position = next + 1; + } + + if (line.length && line !== '\n') result += ind; + + result += line; + } + + return result; +} + +function generateNextLine(state, level) { + return '\n' + common.repeat(' ', state.indent * level); +} + +function testImplicitResolving(state, str) { + var index, length, type; + + for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { + type = state.implicitTypes[index]; + + if (type.resolve(str)) { + return true; + } + } + + return false; +} + +// [33] s-white ::= s-space | s-tab +function isWhitespace(c) { + return c === CHAR_SPACE || c === CHAR_TAB; +} + +// Returns true if the character can be printed without escaping. +// From YAML 1.2: "any allowed characters known to be non-printable +// should also be escaped. [However,] This isn’t mandatory" +// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. +function isPrintable(c) { + return (0x00020 <= c && c <= 0x00007E) + || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) + || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM) + || (0x10000 <= c && c <= 0x10FFFF); +} + +// [34] ns-char ::= nb-char - s-white +// [27] nb-char ::= c-printable - b-char - c-byte-order-mark +// [26] b-char ::= b-line-feed | b-carriage-return +// Including s-white (for some reason, examples doesn't match specs in this aspect) +// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark +function isNsCharOrWhitespace(c) { + return isPrintable(c) + && c !== CHAR_BOM + // - b-char + && c !== CHAR_CARRIAGE_RETURN + && c !== CHAR_LINE_FEED; +} + +// [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out +// c = flow-in ⇒ ns-plain-safe-in +// c = block-key ⇒ ns-plain-safe-out +// c = flow-key ⇒ ns-plain-safe-in +// [128] ns-plain-safe-out ::= ns-char +// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator +// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” ) +// | ( /* An ns-char preceding */ “#” ) +// | ( “:” /* Followed by an ns-plain-safe(c) */ ) +function isPlainSafe(c, prev, inblock) { + var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c); + var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c); + return ( + // ns-plain-safe + inblock ? // c = flow-in + cIsNsCharOrWhitespace + : cIsNsCharOrWhitespace + // - c-flow-indicator + && c !== CHAR_COMMA + && c !== CHAR_LEFT_SQUARE_BRACKET + && c !== CHAR_RIGHT_SQUARE_BRACKET + && c !== CHAR_LEFT_CURLY_BRACKET + && c !== CHAR_RIGHT_CURLY_BRACKET + ) + // ns-plain-char + && c !== CHAR_SHARP // false on '#' + && !(prev === CHAR_COLON && !cIsNsChar) // false on ': ' + || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#' + || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]' +} + +// Simplified test for values allowed as the first character in plain style. +function isPlainSafeFirst(c) { + // Uses a subset of ns-char - c-indicator + // where ns-char = nb-char - s-white. + // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part + return isPrintable(c) && c !== CHAR_BOM + && !isWhitespace(c) // - s-white + // - (c-indicator ::= + // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” + && c !== CHAR_MINUS + && c !== CHAR_QUESTION + && c !== CHAR_COLON + && c !== CHAR_COMMA + && c !== CHAR_LEFT_SQUARE_BRACKET + && c !== CHAR_RIGHT_SQUARE_BRACKET + && c !== CHAR_LEFT_CURLY_BRACKET + && c !== CHAR_RIGHT_CURLY_BRACKET + // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “"” + && c !== CHAR_SHARP + && c !== CHAR_AMPERSAND + && c !== CHAR_ASTERISK + && c !== CHAR_EXCLAMATION + && c !== CHAR_VERTICAL_LINE + && c !== CHAR_EQUALS + && c !== CHAR_GREATER_THAN + && c !== CHAR_SINGLE_QUOTE + && c !== CHAR_DOUBLE_QUOTE + // | “%” | “@” | “`”) + && c !== CHAR_PERCENT + && c !== CHAR_COMMERCIAL_AT + && c !== CHAR_GRAVE_ACCENT; +} + +// Simplified test for values allowed as the last character in plain style. +function isPlainSafeLast(c) { + // just not whitespace or colon, it will be checked to be plain character later + return !isWhitespace(c) && c !== CHAR_COLON; +} + +// Same as 'string'.codePointAt(pos), but works in older browsers. +function codePointAt(string, pos) { + var first = string.charCodeAt(pos), second; + if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) { + second = string.charCodeAt(pos + 1); + if (second >= 0xDC00 && second <= 0xDFFF) { + // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; + } + } + return first; +} + +// Determines whether block indentation indicator is required. +function needIndentIndicator(string) { + var leadingSpaceRe = /^\n* /; + return leadingSpaceRe.test(string); +} + +var STYLE_PLAIN = 1, + STYLE_SINGLE = 2, + STYLE_LITERAL = 3, + STYLE_FOLDED = 4, + STYLE_DOUBLE = 5; + +// Determines which scalar styles are possible and returns the preferred style. +// lineWidth = -1 => no limit. +// Pre-conditions: str.length > 0. +// Post-conditions: +// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. +// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). +// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). +function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, + testAmbiguousType, quotingType, forceQuotes, inblock) { + + var i; + var char = 0; + var prevChar = null; + var hasLineBreak = false; + var hasFoldableLine = false; // only checked if shouldTrackWidth + var shouldTrackWidth = lineWidth !== -1; + var previousLineBreak = -1; // count the first line correctly + var plain = isPlainSafeFirst(codePointAt(string, 0)) + && isPlainSafeLast(codePointAt(string, string.length - 1)); + + if (singleLineOnly || forceQuotes) { + // Case: no block styles. + // Check for disallowed characters to rule out plain and single. + for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { + char = codePointAt(string, i); + if (!isPrintable(char)) { + return STYLE_DOUBLE; + } + plain = plain && isPlainSafe(char, prevChar, inblock); + prevChar = char; + } + } else { + // Case: block styles permitted. + for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { + char = codePointAt(string, i); + if (char === CHAR_LINE_FEED) { + hasLineBreak = true; + // Check if any line can be folded. + if (shouldTrackWidth) { + hasFoldableLine = hasFoldableLine || + // Foldable line = too long, and not more-indented. + (i - previousLineBreak - 1 > lineWidth && + string[previousLineBreak + 1] !== ' '); + previousLineBreak = i; + } + } else if (!isPrintable(char)) { + return STYLE_DOUBLE; + } + plain = plain && isPlainSafe(char, prevChar, inblock); + prevChar = char; + } + // in case the end is missing a \n + hasFoldableLine = hasFoldableLine || (shouldTrackWidth && + (i - previousLineBreak - 1 > lineWidth && + string[previousLineBreak + 1] !== ' ')); + } + // Although every style can represent \n without escaping, prefer block styles + // for multiline, since they're more readable and they don't add empty lines. + // Also prefer folding a super-long line. + if (!hasLineBreak && !hasFoldableLine) { + // Strings interpretable as another type have to be quoted; + // e.g. the string 'true' vs. the boolean true. + if (plain && !forceQuotes && !testAmbiguousType(string)) { + return STYLE_PLAIN; + } + return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; + } + // Edge case: block indentation indicator can only have one digit. + if (indentPerLevel > 9 && needIndentIndicator(string)) { + return STYLE_DOUBLE; + } + // At this point we know block styles are valid. + // Prefer literal style unless we want to fold. + if (!forceQuotes) { + return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; + } + return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; +} + +// Note: line breaking/folding is implemented for only the folded style. +// NB. We drop the last trailing newline (if any) of a returned block scalar +// since the dumper adds its own newline. This always works: +// • No ending newline => unaffected; already using strip "-" chomping. +// • Ending newline => removed then restored. +// Importantly, this keeps the "+" chomp indicator from gaining an extra line. +function writeScalar(state, string, level, iskey, inblock) { + state.dump = (function () { + if (string.length === 0) { + return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''"; + } + if (!state.noCompatMode) { + if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) { + return state.quotingType === QUOTING_TYPE_DOUBLE ? ('"' + string + '"') : ("'" + string + "'"); + } + } + + var indent = state.indent * Math.max(1, level); // no 0-indent scalars + // As indentation gets deeper, let the width decrease monotonically + // to the lower bound min(state.lineWidth, 40). + // Note that this implies + // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. + // state.lineWidth > 40 + state.indent: width decreases until the lower bound. + // This behaves better than a constant minimum width which disallows narrower options, + // or an indent threshold which causes the width to suddenly increase. + var lineWidth = state.lineWidth === -1 + ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); + + // Without knowing if keys are implicit/explicit, assume implicit for safety. + var singleLineOnly = iskey + // No block styles in flow mode. + || (state.flowLevel > -1 && level >= state.flowLevel); + function testAmbiguity(string) { + return testImplicitResolving(state, string); + } + + switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, + testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) { + + case STYLE_PLAIN: + return string; + case STYLE_SINGLE: + return "'" + string.replace(/'/g, "''") + "'"; + case STYLE_LITERAL: + return '|' + blockHeader(string, state.indent) + + dropEndingNewline(indentString(string, indent)); + case STYLE_FOLDED: + return '>' + blockHeader(string, state.indent) + + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); + case STYLE_DOUBLE: + return '"' + escapeString(string, lineWidth) + '"'; + default: + throw new YAMLException('impossible error: invalid scalar style'); + } + }()); +} + +// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. +function blockHeader(string, indentPerLevel) { + var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ''; + + // note the special case: the string '\n' counts as a "trailing" empty line. + var clip = string[string.length - 1] === '\n'; + var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); + var chomp = keep ? '+' : (clip ? '' : '-'); + + return indentIndicator + chomp + '\n'; +} + +// (See the note for writeScalar.) +function dropEndingNewline(string) { + return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; +} + +// Note: a long line without a suitable break point will exceed the width limit. +// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. +function foldString(string, width) { + // In folded style, $k$ consecutive newlines output as $k+1$ newlines— + // unless they're before or after a more-indented line, or at the very + // beginning or end, in which case $k$ maps to $k$. + // Therefore, parse each chunk as newline(s) followed by a content line. + var lineRe = /(\n+)([^\n]*)/g; + + // first line (possibly an empty line) + var result = (function () { + var nextLF = string.indexOf('\n'); + nextLF = nextLF !== -1 ? nextLF : string.length; + lineRe.lastIndex = nextLF; + return foldLine(string.slice(0, nextLF), width); + }()); + // If we haven't reached the first content line yet, don't add an extra \n. + var prevMoreIndented = string[0] === '\n' || string[0] === ' '; + var moreIndented; + + // rest of the lines + var match; + while ((match = lineRe.exec(string))) { + var prefix = match[1], line = match[2]; + moreIndented = (line[0] === ' '); + result += prefix + + (!prevMoreIndented && !moreIndented && line !== '' + ? '\n' : '') + + foldLine(line, width); + prevMoreIndented = moreIndented; + } + + return result; +} + +// Greedy line breaking. +// Picks the longest line under the limit each time, +// otherwise settles for the shortest line over the limit. +// NB. More-indented lines *cannot* be folded, as that would add an extra \n. +function foldLine(line, width) { + if (line === '' || line[0] === ' ') return line; + + // Since a more-indented line adds a \n, breaks can't be followed by a space. + var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. + var match; + // start is an inclusive index. end, curr, and next are exclusive. + var start = 0, end, curr = 0, next = 0; + var result = ''; + + // Invariants: 0 <= start <= length-1. + // 0 <= curr <= next <= max(0, length-2). curr - start <= width. + // Inside the loop: + // A match implies length >= 2, so curr and next are <= length-2. + while ((match = breakRe.exec(line))) { + next = match.index; + // maintain invariant: curr - start <= width + if (next - start > width) { + end = (curr > start) ? curr : next; // derive end <= length-2 + result += '\n' + line.slice(start, end); + // skip the space that was output as \n + start = end + 1; // derive start <= length-1 + } + curr = next; + } + + // By the invariants, start <= length-1, so there is something left over. + // It is either the whole string or a part starting from non-whitespace. + result += '\n'; + // Insert a break if the remainder is too long and there is a break available. + if (line.length - start > width && curr > start) { + result += line.slice(start, curr) + '\n' + line.slice(curr + 1); + } else { + result += line.slice(start); + } + + return result.slice(1); // drop extra \n joiner +} + +// Escapes a double-quoted string. +function escapeString(string) { + var result = ''; + var char = 0; + var escapeSeq; + + for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { + char = codePointAt(string, i); + escapeSeq = ESCAPE_SEQUENCES[char]; + + if (!escapeSeq && isPrintable(char)) { + result += string[i]; + if (char >= 0x10000) result += string[i + 1]; + } else { + result += escapeSeq || encodeHex(char); + } + } + + return result; +} + +function writeFlowSequence(state, level, object) { + var _result = '', + _tag = state.tag, + index, + length, + value; + + for (index = 0, length = object.length; index < length; index += 1) { + value = object[index]; + + if (state.replacer) { + value = state.replacer.call(object, String(index), value); + } + + // Write only valid elements, put null instead of invalid elements. + if (writeNode(state, level, value, false, false) || + (typeof value === 'undefined' && + writeNode(state, level, null, false, false))) { + + if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : ''); + _result += state.dump; + } + } + + state.tag = _tag; + state.dump = '[' + _result + ']'; +} + +function writeBlockSequence(state, level, object, compact) { + var _result = '', + _tag = state.tag, + index, + length, + value; + + for (index = 0, length = object.length; index < length; index += 1) { + value = object[index]; + + if (state.replacer) { + value = state.replacer.call(object, String(index), value); + } + + // Write only valid elements, put null instead of invalid elements. + if (writeNode(state, level + 1, value, true, true, false, true) || + (typeof value === 'undefined' && + writeNode(state, level + 1, null, true, true, false, true))) { + + if (!compact || _result !== '') { + _result += generateNextLine(state, level); + } + + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + _result += '-'; + } else { + _result += '- '; + } + + _result += state.dump; + } + } + + state.tag = _tag; + state.dump = _result || '[]'; // Empty sequence if no valid values. +} + +function writeFlowMapping(state, level, object) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + pairBuffer; + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + + pairBuffer = ''; + if (_result !== '') pairBuffer += ', '; + + if (state.condenseFlow) pairBuffer += '"'; + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (state.replacer) { + objectValue = state.replacer.call(object, objectKey, objectValue); + } + + if (!writeNode(state, level, objectKey, false, false)) { + continue; // Skip this pair because of invalid key; + } + + if (state.dump.length > 1024) pairBuffer += '? '; + + pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' '); + + if (!writeNode(state, level, objectValue, false, false)) { + continue; // Skip this pair because of invalid value. + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = '{' + _result + '}'; +} + +function writeBlockMapping(state, level, object, compact) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + explicitPair, + pairBuffer; + + // Allow sorting keys so that the output file is deterministic + if (state.sortKeys === true) { + // Default sorting + objectKeyList.sort(); + } else if (typeof state.sortKeys === 'function') { + // Custom sort function + objectKeyList.sort(state.sortKeys); + } else if (state.sortKeys) { + // Something is wrong + throw new YAMLException('sortKeys must be a boolean or a function'); + } + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (!compact || _result !== '') { + pairBuffer += generateNextLine(state, level); + } + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (state.replacer) { + objectValue = state.replacer.call(object, objectKey, objectValue); + } + + if (!writeNode(state, level + 1, objectKey, true, true, true)) { + continue; // Skip this pair because of invalid key. + } + + explicitPair = (state.tag !== null && state.tag !== '?') || + (state.dump && state.dump.length > 1024); + + if (explicitPair) { + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += '?'; + } else { + pairBuffer += '? '; + } + } + + pairBuffer += state.dump; + + if (explicitPair) { + pairBuffer += generateNextLine(state, level); + } + + if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { + continue; // Skip this pair because of invalid value. + } + + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += ':'; + } else { + pairBuffer += ': '; + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = _result || '{}'; // Empty mapping if no valid pairs. +} + +function detectType(state, object, explicit) { + var _result, typeList, index, length, type, style; + + typeList = explicit ? state.explicitTypes : state.implicitTypes; + + for (index = 0, length = typeList.length; index < length; index += 1) { + type = typeList[index]; + + if ((type.instanceOf || type.predicate) && + (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && + (!type.predicate || type.predicate(object))) { + + if (explicit) { + if (type.multi && type.representName) { + state.tag = type.representName(object); + } else { + state.tag = type.tag; + } + } else { + state.tag = '?'; + } + + if (type.represent) { + style = state.styleMap[type.tag] || type.defaultStyle; + + if (_toString.call(type.represent) === '[object Function]') { + _result = type.represent(object, style); + } else if (_hasOwnProperty.call(type.represent, style)) { + _result = type.represent[style](object, style); + } else { + throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); + } + + state.dump = _result; + } + + return true; + } + } + + return false; +} + +// Serializes `object` and writes it to global `result`. +// Returns true on success, or false on invalid object. +// +function writeNode(state, level, object, block, compact, iskey, isblockseq) { + state.tag = null; + state.dump = object; + + if (!detectType(state, object, false)) { + detectType(state, object, true); + } + + var type = _toString.call(state.dump); + var inblock = block; + var tagStr; + + if (block) { + block = (state.flowLevel < 0 || state.flowLevel > level); + } + + var objectOrArray = type === '[object Object]' || type === '[object Array]', + duplicateIndex, + duplicate; + + if (objectOrArray) { + duplicateIndex = state.duplicates.indexOf(object); + duplicate = duplicateIndex !== -1; + } + + if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { + compact = false; + } + + if (duplicate && state.usedDuplicates[duplicateIndex]) { + state.dump = '*ref_' + duplicateIndex; + } else { + if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { + state.usedDuplicates[duplicateIndex] = true; + } + if (type === '[object Object]') { + if (block && (Object.keys(state.dump).length !== 0)) { + writeBlockMapping(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowMapping(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object Array]') { + if (block && (state.dump.length !== 0)) { + if (state.noArrayIndent && !isblockseq && level > 0) { + writeBlockSequence(state, level - 1, state.dump, compact); + } else { + writeBlockSequence(state, level, state.dump, compact); + } + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowSequence(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object String]') { + if (state.tag !== '?') { + writeScalar(state, state.dump, level, iskey, inblock); + } + } else if (type === '[object Undefined]') { + return false; + } else { + if (state.skipInvalid) return false; + throw new YAMLException('unacceptable kind of an object to dump ' + type); + } + + if (state.tag !== null && state.tag !== '?') { + // Need to encode all characters except those allowed by the spec: + // + // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */ + // [36] ns-hex-digit ::= ns-dec-digit + // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */ + // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */ + // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-” + // [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#” + // | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,” + // | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]” + // + // Also need to encode '!' because it has special meaning (end of tag prefix). + // + tagStr = encodeURI( + state.tag[0] === '!' ? state.tag.slice(1) : state.tag + ).replace(/!/g, '%21'); + + if (state.tag[0] === '!') { + tagStr = '!' + tagStr; + } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') { + tagStr = '!!' + tagStr.slice(18); + } else { + tagStr = '!<' + tagStr + '>'; + } + + state.dump = tagStr + ' ' + state.dump; + } + } + + return true; +} + +function getDuplicateReferences(object, state) { + var objects = [], + duplicatesIndexes = [], + index, + length; + + inspectNode(object, objects, duplicatesIndexes); + + for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { + state.duplicates.push(objects[duplicatesIndexes[index]]); + } + state.usedDuplicates = new Array(length); +} + +function inspectNode(object, objects, duplicatesIndexes) { + var objectKeyList, + index, + length; + + if (object !== null && typeof object === 'object') { + index = objects.indexOf(object); + if (index !== -1) { + if (duplicatesIndexes.indexOf(index) === -1) { + duplicatesIndexes.push(index); + } + } else { + objects.push(object); + + if (Array.isArray(object)) { + for (index = 0, length = object.length; index < length; index += 1) { + inspectNode(object[index], objects, duplicatesIndexes); + } + } else { + objectKeyList = Object.keys(object); + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); + } + } + } + } +} + +function dump(input, options) { + options = options || {}; + + var state = new State(options); + + if (!state.noRefs) getDuplicateReferences(input, state); + + var value = input; + + if (state.replacer) { + value = state.replacer.call({ '': value }, '', value); + } + + if (writeNode(state, 0, value, true, true)) return state.dump + '\n'; + + return ''; +} + +module.exports.dump = dump; diff --git a/libs/events/node_modules/js-yaml/lib/exception.js b/libs/events/node_modules/js-yaml/lib/exception.js new file mode 100644 index 000000000..7f62daaef --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/exception.js @@ -0,0 +1,55 @@ +// YAML error class. http://stackoverflow.com/questions/8458984 +// +'use strict'; + + +function formatError(exception, compact) { + var where = '', message = exception.reason || '(unknown reason)'; + + if (!exception.mark) return message; + + if (exception.mark.name) { + where += 'in "' + exception.mark.name + '" '; + } + + where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')'; + + if (!compact && exception.mark.snippet) { + where += '\n\n' + exception.mark.snippet; + } + + return message + ' ' + where; +} + + +function YAMLException(reason, mark) { + // Super constructor + Error.call(this); + + this.name = 'YAMLException'; + this.reason = reason; + this.mark = mark; + this.message = formatError(this, false); + + // Include stack trace in error object + if (Error.captureStackTrace) { + // Chrome and NodeJS + Error.captureStackTrace(this, this.constructor); + } else { + // FF, IE 10+ and Safari 6+. Fallback for others + this.stack = (new Error()).stack || ''; + } +} + + +// Inherit from Error +YAMLException.prototype = Object.create(Error.prototype); +YAMLException.prototype.constructor = YAMLException; + + +YAMLException.prototype.toString = function toString(compact) { + return this.name + ': ' + formatError(this, compact); +}; + + +module.exports = YAMLException; diff --git a/libs/events/node_modules/js-yaml/lib/loader.js b/libs/events/node_modules/js-yaml/lib/loader.js new file mode 100644 index 000000000..39f13f561 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/loader.js @@ -0,0 +1,1727 @@ +'use strict'; + +/*eslint-disable max-len,no-use-before-define*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var makeSnippet = require('./snippet'); +var DEFAULT_SCHEMA = require('./schema/default'); + + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + + +var CONTEXT_FLOW_IN = 1; +var CONTEXT_FLOW_OUT = 2; +var CONTEXT_BLOCK_IN = 3; +var CONTEXT_BLOCK_OUT = 4; + + +var CHOMPING_CLIP = 1; +var CHOMPING_STRIP = 2; +var CHOMPING_KEEP = 3; + + +var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; +var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; +var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; +var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; + + +function _class(obj) { return Object.prototype.toString.call(obj); } + +function is_EOL(c) { + return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); +} + +function is_WHITE_SPACE(c) { + return (c === 0x09/* Tab */) || (c === 0x20/* Space */); +} + +function is_WS_OR_EOL(c) { + return (c === 0x09/* Tab */) || + (c === 0x20/* Space */) || + (c === 0x0A/* LF */) || + (c === 0x0D/* CR */); +} + +function is_FLOW_INDICATOR(c) { + return c === 0x2C/* , */ || + c === 0x5B/* [ */ || + c === 0x5D/* ] */ || + c === 0x7B/* { */ || + c === 0x7D/* } */; +} + +function fromHexCode(c) { + var lc; + + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + /*eslint-disable no-bitwise*/ + lc = c | 0x20; + + if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { + return lc - 0x61 + 10; + } + + return -1; +} + +function escapedHexLen(c) { + if (c === 0x78/* x */) { return 2; } + if (c === 0x75/* u */) { return 4; } + if (c === 0x55/* U */) { return 8; } + return 0; +} + +function fromDecimalCode(c) { + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + return -1; +} + +function simpleEscapeSequence(c) { + /* eslint-disable indent */ + return (c === 0x30/* 0 */) ? '\x00' : + (c === 0x61/* a */) ? '\x07' : + (c === 0x62/* b */) ? '\x08' : + (c === 0x74/* t */) ? '\x09' : + (c === 0x09/* Tab */) ? '\x09' : + (c === 0x6E/* n */) ? '\x0A' : + (c === 0x76/* v */) ? '\x0B' : + (c === 0x66/* f */) ? '\x0C' : + (c === 0x72/* r */) ? '\x0D' : + (c === 0x65/* e */) ? '\x1B' : + (c === 0x20/* Space */) ? ' ' : + (c === 0x22/* " */) ? '\x22' : + (c === 0x2F/* / */) ? '/' : + (c === 0x5C/* \ */) ? '\x5C' : + (c === 0x4E/* N */) ? '\x85' : + (c === 0x5F/* _ */) ? '\xA0' : + (c === 0x4C/* L */) ? '\u2028' : + (c === 0x50/* P */) ? '\u2029' : ''; +} + +function charFromCodepoint(c) { + if (c <= 0xFFFF) { + return String.fromCharCode(c); + } + // Encode UTF-16 surrogate pair + // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF + return String.fromCharCode( + ((c - 0x010000) >> 10) + 0xD800, + ((c - 0x010000) & 0x03FF) + 0xDC00 + ); +} + +var simpleEscapeCheck = new Array(256); // integer, for fast access +var simpleEscapeMap = new Array(256); +for (var i = 0; i < 256; i++) { + simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; + simpleEscapeMap[i] = simpleEscapeSequence(i); +} + + +function State(input, options) { + this.input = input; + + this.filename = options['filename'] || null; + this.schema = options['schema'] || DEFAULT_SCHEMA; + this.onWarning = options['onWarning'] || null; + // (Hidden) Remove? makes the loader to expect YAML 1.1 documents + // if such documents have no explicit %YAML directive + this.legacy = options['legacy'] || false; + + this.json = options['json'] || false; + this.listener = options['listener'] || null; + + this.implicitTypes = this.schema.compiledImplicit; + this.typeMap = this.schema.compiledTypeMap; + + this.length = input.length; + this.position = 0; + this.line = 0; + this.lineStart = 0; + this.lineIndent = 0; + + // position of first leading tab in the current line, + // used to make sure there are no tabs in the indentation + this.firstTabInLine = -1; + + this.documents = []; + + /* + this.version; + this.checkLineBreaks; + this.tagMap; + this.anchorMap; + this.tag; + this.anchor; + this.kind; + this.result;*/ + +} + + +function generateError(state, message) { + var mark = { + name: state.filename, + buffer: state.input.slice(0, -1), // omit trailing \0 + position: state.position, + line: state.line, + column: state.position - state.lineStart + }; + + mark.snippet = makeSnippet(mark); + + return new YAMLException(message, mark); +} + +function throwError(state, message) { + throw generateError(state, message); +} + +function throwWarning(state, message) { + if (state.onWarning) { + state.onWarning.call(null, generateError(state, message)); + } +} + + +var directiveHandlers = { + + YAML: function handleYamlDirective(state, name, args) { + + var match, major, minor; + + if (state.version !== null) { + throwError(state, 'duplication of %YAML directive'); + } + + if (args.length !== 1) { + throwError(state, 'YAML directive accepts exactly one argument'); + } + + match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); + + if (match === null) { + throwError(state, 'ill-formed argument of the YAML directive'); + } + + major = parseInt(match[1], 10); + minor = parseInt(match[2], 10); + + if (major !== 1) { + throwError(state, 'unacceptable YAML version of the document'); + } + + state.version = args[0]; + state.checkLineBreaks = (minor < 2); + + if (minor !== 1 && minor !== 2) { + throwWarning(state, 'unsupported YAML version of the document'); + } + }, + + TAG: function handleTagDirective(state, name, args) { + + var handle, prefix; + + if (args.length !== 2) { + throwError(state, 'TAG directive accepts exactly two arguments'); + } + + handle = args[0]; + prefix = args[1]; + + if (!PATTERN_TAG_HANDLE.test(handle)) { + throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); + } + + if (_hasOwnProperty.call(state.tagMap, handle)) { + throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); + } + + if (!PATTERN_TAG_URI.test(prefix)) { + throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); + } + + try { + prefix = decodeURIComponent(prefix); + } catch (err) { + throwError(state, 'tag prefix is malformed: ' + prefix); + } + + state.tagMap[handle] = prefix; + } +}; + + +function captureSegment(state, start, end, checkJson) { + var _position, _length, _character, _result; + + if (start < end) { + _result = state.input.slice(start, end); + + if (checkJson) { + for (_position = 0, _length = _result.length; _position < _length; _position += 1) { + _character = _result.charCodeAt(_position); + if (!(_character === 0x09 || + (0x20 <= _character && _character <= 0x10FFFF))) { + throwError(state, 'expected valid JSON character'); + } + } + } else if (PATTERN_NON_PRINTABLE.test(_result)) { + throwError(state, 'the stream contains non-printable characters'); + } + + state.result += _result; + } +} + +function mergeMappings(state, destination, source, overridableKeys) { + var sourceKeys, key, index, quantity; + + if (!common.isObject(source)) { + throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); + } + + sourceKeys = Object.keys(source); + + for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { + key = sourceKeys[index]; + + if (!_hasOwnProperty.call(destination, key)) { + destination[key] = source[key]; + overridableKeys[key] = true; + } + } +} + +function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, + startLine, startLineStart, startPos) { + + var index, quantity; + + // The output is a plain object here, so keys can only be strings. + // We need to convert keyNode to a string, but doing so can hang the process + // (deeply nested arrays that explode exponentially using aliases). + if (Array.isArray(keyNode)) { + keyNode = Array.prototype.slice.call(keyNode); + + for (index = 0, quantity = keyNode.length; index < quantity; index += 1) { + if (Array.isArray(keyNode[index])) { + throwError(state, 'nested arrays are not supported inside keys'); + } + + if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') { + keyNode[index] = '[object Object]'; + } + } + } + + // Avoid code execution in load() via toString property + // (still use its own toString for arrays, timestamps, + // and whatever user schema extensions happen to have @@toStringTag) + if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') { + keyNode = '[object Object]'; + } + + + keyNode = String(keyNode); + + if (_result === null) { + _result = {}; + } + + if (keyTag === 'tag:yaml.org,2002:merge') { + if (Array.isArray(valueNode)) { + for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { + mergeMappings(state, _result, valueNode[index], overridableKeys); + } + } else { + mergeMappings(state, _result, valueNode, overridableKeys); + } + } else { + if (!state.json && + !_hasOwnProperty.call(overridableKeys, keyNode) && + _hasOwnProperty.call(_result, keyNode)) { + state.line = startLine || state.line; + state.lineStart = startLineStart || state.lineStart; + state.position = startPos || state.position; + throwError(state, 'duplicated mapping key'); + } + + // used for this specific key only because Object.defineProperty is slow + if (keyNode === '__proto__') { + Object.defineProperty(_result, keyNode, { + configurable: true, + enumerable: true, + writable: true, + value: valueNode + }); + } else { + _result[keyNode] = valueNode; + } + delete overridableKeys[keyNode]; + } + + return _result; +} + +function readLineBreak(state) { + var ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x0A/* LF */) { + state.position++; + } else if (ch === 0x0D/* CR */) { + state.position++; + if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { + state.position++; + } + } else { + throwError(state, 'a line break is expected'); + } + + state.line += 1; + state.lineStart = state.position; + state.firstTabInLine = -1; +} + +function skipSeparationSpace(state, allowComments, checkIndent) { + var lineBreaks = 0, + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) { + state.firstTabInLine = state.position; + } + ch = state.input.charCodeAt(++state.position); + } + + if (allowComments && ch === 0x23/* # */) { + do { + ch = state.input.charCodeAt(++state.position); + } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); + } + + if (is_EOL(ch)) { + readLineBreak(state); + + ch = state.input.charCodeAt(state.position); + lineBreaks++; + state.lineIndent = 0; + + while (ch === 0x20/* Space */) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + } else { + break; + } + } + + if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { + throwWarning(state, 'deficient indentation'); + } + + return lineBreaks; +} + +function testDocumentSeparator(state) { + var _position = state.position, + ch; + + ch = state.input.charCodeAt(_position); + + // Condition state.position === state.lineStart is tested + // in parent on each call, for efficiency. No needs to test here again. + if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && + ch === state.input.charCodeAt(_position + 1) && + ch === state.input.charCodeAt(_position + 2)) { + + _position += 3; + + ch = state.input.charCodeAt(_position); + + if (ch === 0 || is_WS_OR_EOL(ch)) { + return true; + } + } + + return false; +} + +function writeFoldedLines(state, count) { + if (count === 1) { + state.result += ' '; + } else if (count > 1) { + state.result += common.repeat('\n', count - 1); + } +} + + +function readPlainScalar(state, nodeIndent, withinFlowCollection) { + var preceding, + following, + captureStart, + captureEnd, + hasPendingContent, + _line, + _lineStart, + _lineIndent, + _kind = state.kind, + _result = state.result, + ch; + + ch = state.input.charCodeAt(state.position); + + if (is_WS_OR_EOL(ch) || + is_FLOW_INDICATOR(ch) || + ch === 0x23/* # */ || + ch === 0x26/* & */ || + ch === 0x2A/* * */ || + ch === 0x21/* ! */ || + ch === 0x7C/* | */ || + ch === 0x3E/* > */ || + ch === 0x27/* ' */ || + ch === 0x22/* " */ || + ch === 0x25/* % */ || + ch === 0x40/* @ */ || + ch === 0x60/* ` */) { + return false; + } + + if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + return false; + } + } + + state.kind = 'scalar'; + state.result = ''; + captureStart = captureEnd = state.position; + hasPendingContent = false; + + while (ch !== 0) { + if (ch === 0x3A/* : */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + break; + } + + } else if (ch === 0x23/* # */) { + preceding = state.input.charCodeAt(state.position - 1); + + if (is_WS_OR_EOL(preceding)) { + break; + } + + } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || + withinFlowCollection && is_FLOW_INDICATOR(ch)) { + break; + + } else if (is_EOL(ch)) { + _line = state.line; + _lineStart = state.lineStart; + _lineIndent = state.lineIndent; + skipSeparationSpace(state, false, -1); + + if (state.lineIndent >= nodeIndent) { + hasPendingContent = true; + ch = state.input.charCodeAt(state.position); + continue; + } else { + state.position = captureEnd; + state.line = _line; + state.lineStart = _lineStart; + state.lineIndent = _lineIndent; + break; + } + } + + if (hasPendingContent) { + captureSegment(state, captureStart, captureEnd, false); + writeFoldedLines(state, state.line - _line); + captureStart = captureEnd = state.position; + hasPendingContent = false; + } + + if (!is_WHITE_SPACE(ch)) { + captureEnd = state.position + 1; + } + + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, captureEnd, false); + + if (state.result) { + return true; + } + + state.kind = _kind; + state.result = _result; + return false; +} + +function readSingleQuotedScalar(state, nodeIndent) { + var ch, + captureStart, captureEnd; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x27/* ' */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x27/* ' */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x27/* ' */) { + captureStart = state.position; + state.position++; + captureEnd = state.position; + } else { + return true; + } + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a single quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a single quoted scalar'); +} + +function readDoubleQuotedScalar(state, nodeIndent) { + var captureStart, + captureEnd, + hexLength, + hexResult, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x22/* " */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x22/* " */) { + captureSegment(state, captureStart, state.position, true); + state.position++; + return true; + + } else if (ch === 0x5C/* \ */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (is_EOL(ch)) { + skipSeparationSpace(state, false, nodeIndent); + + // TODO: rework to inline fn with no type cast? + } else if (ch < 256 && simpleEscapeCheck[ch]) { + state.result += simpleEscapeMap[ch]; + state.position++; + + } else if ((tmp = escapedHexLen(ch)) > 0) { + hexLength = tmp; + hexResult = 0; + + for (; hexLength > 0; hexLength--) { + ch = state.input.charCodeAt(++state.position); + + if ((tmp = fromHexCode(ch)) >= 0) { + hexResult = (hexResult << 4) + tmp; + + } else { + throwError(state, 'expected hexadecimal character'); + } + } + + state.result += charFromCodepoint(hexResult); + + state.position++; + + } else { + throwError(state, 'unknown escape sequence'); + } + + captureStart = captureEnd = state.position; + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a double quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a double quoted scalar'); +} + +function readFlowCollection(state, nodeIndent) { + var readNext = true, + _line, + _lineStart, + _pos, + _tag = state.tag, + _result, + _anchor = state.anchor, + following, + terminator, + isPair, + isExplicitPair, + isMapping, + overridableKeys = Object.create(null), + keyNode, + keyTag, + valueNode, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x5B/* [ */) { + terminator = 0x5D;/* ] */ + isMapping = false; + _result = []; + } else if (ch === 0x7B/* { */) { + terminator = 0x7D;/* } */ + isMapping = true; + _result = {}; + } else { + return false; + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(++state.position); + + while (ch !== 0) { + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === terminator) { + state.position++; + state.tag = _tag; + state.anchor = _anchor; + state.kind = isMapping ? 'mapping' : 'sequence'; + state.result = _result; + return true; + } else if (!readNext) { + throwError(state, 'missed comma between flow collection entries'); + } else if (ch === 0x2C/* , */) { + // "flow collection entries can never be completely empty", as per YAML 1.2, section 7.4 + throwError(state, "expected the node content, but found ','"); + } + + keyTag = keyNode = valueNode = null; + isPair = isExplicitPair = false; + + if (ch === 0x3F/* ? */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following)) { + isPair = isExplicitPair = true; + state.position++; + skipSeparationSpace(state, true, nodeIndent); + } + } + + _line = state.line; // Save the current line. + _lineStart = state.lineStart; + _pos = state.position; + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + keyTag = state.tag; + keyNode = state.result; + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { + isPair = true; + ch = state.input.charCodeAt(++state.position); + skipSeparationSpace(state, true, nodeIndent); + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + valueNode = state.result; + } + + if (isMapping) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos); + } else if (isPair) { + _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos)); + } else { + _result.push(keyNode); + } + + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x2C/* , */) { + readNext = true; + ch = state.input.charCodeAt(++state.position); + } else { + readNext = false; + } + } + + throwError(state, 'unexpected end of the stream within a flow collection'); +} + +function readBlockScalar(state, nodeIndent) { + var captureStart, + folding, + chomping = CHOMPING_CLIP, + didReadContent = false, + detectedIndent = false, + textIndent = nodeIndent, + emptyLines = 0, + atMoreIndented = false, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x7C/* | */) { + folding = false; + } else if (ch === 0x3E/* > */) { + folding = true; + } else { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + + while (ch !== 0) { + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { + if (CHOMPING_CLIP === chomping) { + chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; + } else { + throwError(state, 'repeat of a chomping mode identifier'); + } + + } else if ((tmp = fromDecimalCode(ch)) >= 0) { + if (tmp === 0) { + throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); + } else if (!detectedIndent) { + textIndent = nodeIndent + tmp - 1; + detectedIndent = true; + } else { + throwError(state, 'repeat of an indentation width identifier'); + } + + } else { + break; + } + } + + if (is_WHITE_SPACE(ch)) { + do { ch = state.input.charCodeAt(++state.position); } + while (is_WHITE_SPACE(ch)); + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (!is_EOL(ch) && (ch !== 0)); + } + } + + while (ch !== 0) { + readLineBreak(state); + state.lineIndent = 0; + + ch = state.input.charCodeAt(state.position); + + while ((!detectedIndent || state.lineIndent < textIndent) && + (ch === 0x20/* Space */)) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + + if (!detectedIndent && state.lineIndent > textIndent) { + textIndent = state.lineIndent; + } + + if (is_EOL(ch)) { + emptyLines++; + continue; + } + + // End of the scalar. + if (state.lineIndent < textIndent) { + + // Perform the chomping. + if (chomping === CHOMPING_KEEP) { + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + } else if (chomping === CHOMPING_CLIP) { + if (didReadContent) { // i.e. only if the scalar is not empty. + state.result += '\n'; + } + } + + // Break this `while` cycle and go to the funciton's epilogue. + break; + } + + // Folded style: use fancy rules to handle line breaks. + if (folding) { + + // Lines starting with white space characters (more-indented lines) are not folded. + if (is_WHITE_SPACE(ch)) { + atMoreIndented = true; + // except for the first content line (cf. Example 8.1) + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + + // End of more-indented block. + } else if (atMoreIndented) { + atMoreIndented = false; + state.result += common.repeat('\n', emptyLines + 1); + + // Just one line break - perceive as the same line. + } else if (emptyLines === 0) { + if (didReadContent) { // i.e. only if we have already read some scalar content. + state.result += ' '; + } + + // Several line breaks - perceive as different lines. + } else { + state.result += common.repeat('\n', emptyLines); + } + + // Literal style: just add exact number of line breaks between content lines. + } else { + // Keep all line breaks except the header line break. + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + } + + didReadContent = true; + detectedIndent = true; + emptyLines = 0; + captureStart = state.position; + + while (!is_EOL(ch) && (ch !== 0)) { + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, state.position, false); + } + + return true; +} + +function readBlockSequence(state, nodeIndent) { + var _line, + _tag = state.tag, + _anchor = state.anchor, + _result = [], + following, + detected = false, + ch; + + // there is a leading tab before this token, so it can't be a block sequence/mapping; + // it can still be flow sequence/mapping or a scalar + if (state.firstTabInLine !== -1) return false; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + if (state.firstTabInLine !== -1) { + state.position = state.firstTabInLine; + throwError(state, 'tab characters must not be used in indentation'); + } + + if (ch !== 0x2D/* - */) { + break; + } + + following = state.input.charCodeAt(state.position + 1); + + if (!is_WS_OR_EOL(following)) { + break; + } + + detected = true; + state.position++; + + if (skipSeparationSpace(state, true, -1)) { + if (state.lineIndent <= nodeIndent) { + _result.push(null); + ch = state.input.charCodeAt(state.position); + continue; + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); + _result.push(state.result); + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { + throwError(state, 'bad indentation of a sequence entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'sequence'; + state.result = _result; + return true; + } + return false; +} + +function readBlockMapping(state, nodeIndent, flowIndent) { + var following, + allowCompact, + _line, + _keyLine, + _keyLineStart, + _keyPos, + _tag = state.tag, + _anchor = state.anchor, + _result = {}, + overridableKeys = Object.create(null), + keyTag = null, + keyNode = null, + valueNode = null, + atExplicitKey = false, + detected = false, + ch; + + // there is a leading tab before this token, so it can't be a block sequence/mapping; + // it can still be flow sequence/mapping or a scalar + if (state.firstTabInLine !== -1) return false; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + if (!atExplicitKey && state.firstTabInLine !== -1) { + state.position = state.firstTabInLine; + throwError(state, 'tab characters must not be used in indentation'); + } + + following = state.input.charCodeAt(state.position + 1); + _line = state.line; // Save the current line. + + // + // Explicit notation case. There are two separate blocks: + // first for the key (denoted by "?") and second for the value (denoted by ":") + // + if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { + + if (ch === 0x3F/* ? */) { + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = true; + allowCompact = true; + + } else if (atExplicitKey) { + // i.e. 0x3A/* : */ === character after the explicit key. + atExplicitKey = false; + allowCompact = true; + + } else { + throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line'); + } + + state.position += 1; + ch = following; + + // + // Implicit notation case. Flow-style node as the key first, then ":", and the value. + // + } else { + _keyLine = state.line; + _keyLineStart = state.lineStart; + _keyPos = state.position; + + if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { + // Neither implicit nor explicit notation. + // Reading is done. Go to the epilogue. + break; + } + + if (state.line === _line) { + ch = state.input.charCodeAt(state.position); + + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x3A/* : */) { + ch = state.input.charCodeAt(++state.position); + + if (!is_WS_OR_EOL(ch)) { + throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); + } + + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = false; + allowCompact = false; + keyTag = state.tag; + keyNode = state.result; + + } else if (detected) { + throwError(state, 'can not read an implicit mapping pair; a colon is missed'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else if (detected) { + throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + } + + // + // Common reading code for both explicit and implicit notations. + // + if (state.line === _line || state.lineIndent > nodeIndent) { + if (atExplicitKey) { + _keyLine = state.line; + _keyLineStart = state.lineStart; + _keyPos = state.position; + } + + if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { + if (atExplicitKey) { + keyNode = state.result; + } else { + valueNode = state.result; + } + } + + if (!atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos); + keyTag = keyNode = valueNode = null; + } + + skipSeparationSpace(state, true, -1); + ch = state.input.charCodeAt(state.position); + } + + if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { + throwError(state, 'bad indentation of a mapping entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + // + // Epilogue. + // + + // Special case: last mapping's node contains only the key in explicit notation. + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); + } + + // Expose the resulting mapping. + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'mapping'; + state.result = _result; + } + + return detected; +} + +function readTagProperty(state) { + var _position, + isVerbatim = false, + isNamed = false, + tagHandle, + tagName, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x21/* ! */) return false; + + if (state.tag !== null) { + throwError(state, 'duplication of a tag property'); + } + + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x3C/* < */) { + isVerbatim = true; + ch = state.input.charCodeAt(++state.position); + + } else if (ch === 0x21/* ! */) { + isNamed = true; + tagHandle = '!!'; + ch = state.input.charCodeAt(++state.position); + + } else { + tagHandle = '!'; + } + + _position = state.position; + + if (isVerbatim) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && ch !== 0x3E/* > */); + + if (state.position < state.length) { + tagName = state.input.slice(_position, state.position); + ch = state.input.charCodeAt(++state.position); + } else { + throwError(state, 'unexpected end of the stream within a verbatim tag'); + } + } else { + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + + if (ch === 0x21/* ! */) { + if (!isNamed) { + tagHandle = state.input.slice(_position - 1, state.position + 1); + + if (!PATTERN_TAG_HANDLE.test(tagHandle)) { + throwError(state, 'named tag handle cannot contain such characters'); + } + + isNamed = true; + _position = state.position + 1; + } else { + throwError(state, 'tag suffix cannot contain exclamation marks'); + } + } + + ch = state.input.charCodeAt(++state.position); + } + + tagName = state.input.slice(_position, state.position); + + if (PATTERN_FLOW_INDICATORS.test(tagName)) { + throwError(state, 'tag suffix cannot contain flow indicator characters'); + } + } + + if (tagName && !PATTERN_TAG_URI.test(tagName)) { + throwError(state, 'tag name cannot contain such characters: ' + tagName); + } + + try { + tagName = decodeURIComponent(tagName); + } catch (err) { + throwError(state, 'tag name is malformed: ' + tagName); + } + + if (isVerbatim) { + state.tag = tagName; + + } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) { + state.tag = state.tagMap[tagHandle] + tagName; + + } else if (tagHandle === '!') { + state.tag = '!' + tagName; + + } else if (tagHandle === '!!') { + state.tag = 'tag:yaml.org,2002:' + tagName; + + } else { + throwError(state, 'undeclared tag handle "' + tagHandle + '"'); + } + + return true; +} + +function readAnchorProperty(state) { + var _position, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x26/* & */) return false; + + if (state.anchor !== null) { + throwError(state, 'duplication of an anchor property'); + } + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an anchor node must contain at least one character'); + } + + state.anchor = state.input.slice(_position, state.position); + return true; +} + +function readAlias(state) { + var _position, alias, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x2A/* * */) return false; + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an alias node must contain at least one character'); + } + + alias = state.input.slice(_position, state.position); + + if (!_hasOwnProperty.call(state.anchorMap, alias)) { + throwError(state, 'unidentified alias "' + alias + '"'); + } + + state.result = state.anchorMap[alias]; + skipSeparationSpace(state, true, -1); + return true; +} + +function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { + var allowBlockStyles, + allowBlockScalars, + allowBlockCollections, + indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } + } + + if (indentStatus === 1) { + while (readTagProperty(state) || readAnchorProperty(state)) { + if (skipSeparationSpace(state, true, -1)) { + atNewLine = true; + allowBlockCollections = allowBlockStyles; + + if (state.lineIndent > parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } else { + allowBlockCollections = false; + } + } + } + + if (allowBlockCollections) { + allowBlockCollections = atNewLine || allowCompact; + } + + if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { + if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { + flowIndent = parentIndent; + } else { + flowIndent = parentIndent + 1; + } + + blockIndent = state.position - state.lineStart; + + if (indentStatus === 1) { + if (allowBlockCollections && + (readBlockSequence(state, blockIndent) || + readBlockMapping(state, blockIndent, flowIndent)) || + readFlowCollection(state, flowIndent)) { + hasContent = true; + } else { + if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || + readSingleQuotedScalar(state, flowIndent) || + readDoubleQuotedScalar(state, flowIndent)) { + hasContent = true; + + } else if (readAlias(state)) { + hasContent = true; + + if (state.tag !== null || state.anchor !== null) { + throwError(state, 'alias node should not have any properties'); + } + + } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { + hasContent = true; + + if (state.tag === null) { + state.tag = '?'; + } + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else if (indentStatus === 0) { + // Special case: block sequences are allowed to have same indentation level as the parent. + // http://www.yaml.org/spec/1.2/spec.html#id2799784 + hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); + } + } + + if (state.tag === null) { + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + + } else if (state.tag === '?') { + // Implicit resolving is not allowed for non-scalar types, and '?' + // non-specific tag is only automatically assigned to plain scalars. + // + // We only need to check kind conformity in case user explicitly assigns '?' + // tag, for example like this: "! [0]" + // + if (state.result !== null && state.kind !== 'scalar') { + throwError(state, 'unacceptable node kind for ! tag; it should be "scalar", not "' + state.kind + '"'); + } + + for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) { + type = state.implicitTypes[typeIndex]; + + if (type.resolve(state.result)) { // `state.result` updated in resolver if matched + state.result = type.construct(state.result); + state.tag = type.tag; + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + break; + } + } + } else if (state.tag !== '!') { + if (_hasOwnProperty.call(state.typeMap[state.kind || 'fallback'], state.tag)) { + type = state.typeMap[state.kind || 'fallback'][state.tag]; + } else { + // looking for multi type + type = null; + typeList = state.typeMap.multi[state.kind || 'fallback']; + + for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) { + if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) { + type = typeList[typeIndex]; + break; + } + } + } + + if (!type) { + throwError(state, 'unknown tag !<' + state.tag + '>'); + } + + if (state.result !== null && type.kind !== state.kind) { + throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); + } + + if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched + throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); + } else { + state.result = type.construct(state.result, state.tag); + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } + + if (state.listener !== null) { + state.listener('close', state); + } + return state.tag !== null || state.anchor !== null || hasContent; +} + +function readDocument(state) { + var documentStart = state.position, + _position, + directiveName, + directiveArgs, + hasDirectives = false, + ch; + + state.version = null; + state.checkLineBreaks = state.legacy; + state.tagMap = Object.create(null); + state.anchorMap = Object.create(null); + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if (state.lineIndent > 0 || ch !== 0x25/* % */) { + break; + } + + hasDirectives = true; + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveName = state.input.slice(_position, state.position); + directiveArgs = []; + + if (directiveName.length < 1) { + throwError(state, 'directive name must not be less than one character in length'); + } + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && !is_EOL(ch)); + break; + } + + if (is_EOL(ch)) break; + + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveArgs.push(state.input.slice(_position, state.position)); + } + + if (ch !== 0) readLineBreak(state); + + if (_hasOwnProperty.call(directiveHandlers, directiveName)) { + directiveHandlers[directiveName](state, directiveName, directiveArgs); + } else { + throwWarning(state, 'unknown document directive "' + directiveName + '"'); + } + } + + skipSeparationSpace(state, true, -1); + + if (state.lineIndent === 0 && + state.input.charCodeAt(state.position) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + + } else if (hasDirectives) { + throwError(state, 'directives end mark is expected'); + } + + composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); + skipSeparationSpace(state, true, -1); + + if (state.checkLineBreaks && + PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { + throwWarning(state, 'non-ASCII line breaks are interpreted as content'); + } + + state.documents.push(state.result); + + if (state.position === state.lineStart && testDocumentSeparator(state)) { + + if (state.input.charCodeAt(state.position) === 0x2E/* . */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + } + return; + } + + if (state.position < (state.length - 1)) { + throwError(state, 'end of the stream or a document separator is expected'); + } else { + return; + } +} + + +function loadDocuments(input, options) { + input = String(input); + options = options || {}; + + if (input.length !== 0) { + + // Add tailing `\n` if not exists + if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && + input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { + input += '\n'; + } + + // Strip BOM + if (input.charCodeAt(0) === 0xFEFF) { + input = input.slice(1); + } + } + + var state = new State(input, options); + + var nullpos = input.indexOf('\0'); + + if (nullpos !== -1) { + state.position = nullpos; + throwError(state, 'null byte is not allowed in input'); + } + + // Use 0 as string terminator. That significantly simplifies bounds check. + state.input += '\0'; + + while (state.input.charCodeAt(state.position) === 0x20/* Space */) { + state.lineIndent += 1; + state.position += 1; + } + + while (state.position < (state.length - 1)) { + readDocument(state); + } + + return state.documents; +} + + +function loadAll(input, iterator, options) { + if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') { + options = iterator; + iterator = null; + } + + var documents = loadDocuments(input, options); + + if (typeof iterator !== 'function') { + return documents; + } + + for (var index = 0, length = documents.length; index < length; index += 1) { + iterator(documents[index]); + } +} + + +function load(input, options) { + var documents = loadDocuments(input, options); + + if (documents.length === 0) { + /*eslint-disable no-undefined*/ + return undefined; + } else if (documents.length === 1) { + return documents[0]; + } + throw new YAMLException('expected a single document in the stream, but found more'); +} + + +module.exports.loadAll = loadAll; +module.exports.load = load; diff --git a/libs/events/node_modules/js-yaml/lib/schema.js b/libs/events/node_modules/js-yaml/lib/schema.js new file mode 100644 index 000000000..65b41f401 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/schema.js @@ -0,0 +1,121 @@ +'use strict'; + +/*eslint-disable max-len*/ + +var YAMLException = require('./exception'); +var Type = require('./type'); + + +function compileList(schema, name) { + var result = []; + + schema[name].forEach(function (currentType) { + var newIndex = result.length; + + result.forEach(function (previousType, previousIndex) { + if (previousType.tag === currentType.tag && + previousType.kind === currentType.kind && + previousType.multi === currentType.multi) { + + newIndex = previousIndex; + } + }); + + result[newIndex] = currentType; + }); + + return result; +} + + +function compileMap(/* lists... */) { + var result = { + scalar: {}, + sequence: {}, + mapping: {}, + fallback: {}, + multi: { + scalar: [], + sequence: [], + mapping: [], + fallback: [] + } + }, index, length; + + function collectType(type) { + if (type.multi) { + result.multi[type.kind].push(type); + result.multi['fallback'].push(type); + } else { + result[type.kind][type.tag] = result['fallback'][type.tag] = type; + } + } + + for (index = 0, length = arguments.length; index < length; index += 1) { + arguments[index].forEach(collectType); + } + return result; +} + + +function Schema(definition) { + return this.extend(definition); +} + + +Schema.prototype.extend = function extend(definition) { + var implicit = []; + var explicit = []; + + if (definition instanceof Type) { + // Schema.extend(type) + explicit.push(definition); + + } else if (Array.isArray(definition)) { + // Schema.extend([ type1, type2, ... ]) + explicit = explicit.concat(definition); + + } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) { + // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] }) + if (definition.implicit) implicit = implicit.concat(definition.implicit); + if (definition.explicit) explicit = explicit.concat(definition.explicit); + + } else { + throw new YAMLException('Schema.extend argument should be a Type, [ Type ], ' + + 'or a schema definition ({ implicit: [...], explicit: [...] })'); + } + + implicit.forEach(function (type) { + if (!(type instanceof Type)) { + throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); + } + + if (type.loadKind && type.loadKind !== 'scalar') { + throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); + } + + if (type.multi) { + throw new YAMLException('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.'); + } + }); + + explicit.forEach(function (type) { + if (!(type instanceof Type)) { + throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); + } + }); + + var result = Object.create(Schema.prototype); + + result.implicit = (this.implicit || []).concat(implicit); + result.explicit = (this.explicit || []).concat(explicit); + + result.compiledImplicit = compileList(result, 'implicit'); + result.compiledExplicit = compileList(result, 'explicit'); + result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit); + + return result; +}; + + +module.exports = Schema; diff --git a/libs/events/node_modules/js-yaml/lib/schema/core.js b/libs/events/node_modules/js-yaml/lib/schema/core.js new file mode 100644 index 000000000..608b26de2 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/schema/core.js @@ -0,0 +1,11 @@ +// Standard YAML's Core schema. +// http://www.yaml.org/spec/1.2/spec.html#id2804923 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, Core schema has no distinctions from JSON schema is JS-YAML. + + +'use strict'; + + +module.exports = require('./json'); diff --git a/libs/events/node_modules/js-yaml/lib/schema/default.js b/libs/events/node_modules/js-yaml/lib/schema/default.js new file mode 100644 index 000000000..3af0520d5 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/schema/default.js @@ -0,0 +1,22 @@ +// JS-YAML's default schema for `safeLoad` function. +// It is not described in the YAML specification. +// +// This schema is based on standard YAML's Core schema and includes most of +// extra types described at YAML tag repository. (http://yaml.org/type/) + + +'use strict'; + + +module.exports = require('./core').extend({ + implicit: [ + require('../type/timestamp'), + require('../type/merge') + ], + explicit: [ + require('../type/binary'), + require('../type/omap'), + require('../type/pairs'), + require('../type/set') + ] +}); diff --git a/libs/events/node_modules/js-yaml/lib/schema/failsafe.js b/libs/events/node_modules/js-yaml/lib/schema/failsafe.js new file mode 100644 index 000000000..b7a33eb7a --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/schema/failsafe.js @@ -0,0 +1,17 @@ +// Standard YAML's Failsafe schema. +// http://www.yaml.org/spec/1.2/spec.html#id2802346 + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + explicit: [ + require('../type/str'), + require('../type/seq'), + require('../type/map') + ] +}); diff --git a/libs/events/node_modules/js-yaml/lib/schema/json.js b/libs/events/node_modules/js-yaml/lib/schema/json.js new file mode 100644 index 000000000..b73df78e5 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/schema/json.js @@ -0,0 +1,19 @@ +// Standard YAML's JSON schema. +// http://www.yaml.org/spec/1.2/spec.html#id2803231 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, this schema is not such strict as defined in the YAML specification. +// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc. + + +'use strict'; + + +module.exports = require('./failsafe').extend({ + implicit: [ + require('../type/null'), + require('../type/bool'), + require('../type/int'), + require('../type/float') + ] +}); diff --git a/libs/events/node_modules/js-yaml/lib/snippet.js b/libs/events/node_modules/js-yaml/lib/snippet.js new file mode 100644 index 000000000..00e2133c0 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/snippet.js @@ -0,0 +1,101 @@ +'use strict'; + + +var common = require('./common'); + + +// get snippet for a single line, respecting maxLength +function getLine(buffer, lineStart, lineEnd, position, maxLineLength) { + var head = ''; + var tail = ''; + var maxHalfLength = Math.floor(maxLineLength / 2) - 1; + + if (position - lineStart > maxHalfLength) { + head = ' ... '; + lineStart = position - maxHalfLength + head.length; + } + + if (lineEnd - position > maxHalfLength) { + tail = ' ...'; + lineEnd = position + maxHalfLength - tail.length; + } + + return { + str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail, + pos: position - lineStart + head.length // relative position + }; +} + + +function padStart(string, max) { + return common.repeat(' ', max - string.length) + string; +} + + +function makeSnippet(mark, options) { + options = Object.create(options || null); + + if (!mark.buffer) return null; + + if (!options.maxLength) options.maxLength = 79; + if (typeof options.indent !== 'number') options.indent = 1; + if (typeof options.linesBefore !== 'number') options.linesBefore = 3; + if (typeof options.linesAfter !== 'number') options.linesAfter = 2; + + var re = /\r?\n|\r|\0/g; + var lineStarts = [ 0 ]; + var lineEnds = []; + var match; + var foundLineNo = -1; + + while ((match = re.exec(mark.buffer))) { + lineEnds.push(match.index); + lineStarts.push(match.index + match[0].length); + + if (mark.position <= match.index && foundLineNo < 0) { + foundLineNo = lineStarts.length - 2; + } + } + + if (foundLineNo < 0) foundLineNo = lineStarts.length - 1; + + var result = '', i, line; + var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length; + var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3); + + for (i = 1; i <= options.linesBefore; i++) { + if (foundLineNo - i < 0) break; + line = getLine( + mark.buffer, + lineStarts[foundLineNo - i], + lineEnds[foundLineNo - i], + mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), + maxLineLength + ); + result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + + ' | ' + line.str + '\n' + result; + } + + line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength); + result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + + ' | ' + line.str + '\n'; + result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n'; + + for (i = 1; i <= options.linesAfter; i++) { + if (foundLineNo + i >= lineEnds.length) break; + line = getLine( + mark.buffer, + lineStarts[foundLineNo + i], + lineEnds[foundLineNo + i], + mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), + maxLineLength + ); + result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + + ' | ' + line.str + '\n'; + } + + return result.replace(/\n$/, ''); +} + + +module.exports = makeSnippet; diff --git a/libs/events/node_modules/js-yaml/lib/type.js b/libs/events/node_modules/js-yaml/lib/type.js new file mode 100644 index 000000000..5e57877fe --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type.js @@ -0,0 +1,66 @@ +'use strict'; + +var YAMLException = require('./exception'); + +var TYPE_CONSTRUCTOR_OPTIONS = [ + 'kind', + 'multi', + 'resolve', + 'construct', + 'instanceOf', + 'predicate', + 'represent', + 'representName', + 'defaultStyle', + 'styleAliases' +]; + +var YAML_NODE_KINDS = [ + 'scalar', + 'sequence', + 'mapping' +]; + +function compileStyleAliases(map) { + var result = {}; + + if (map !== null) { + Object.keys(map).forEach(function (style) { + map[style].forEach(function (alias) { + result[String(alias)] = style; + }); + }); + } + + return result; +} + +function Type(tag, options) { + options = options || {}; + + Object.keys(options).forEach(function (name) { + if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { + throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); + } + }); + + // TODO: Add tag format check. + this.options = options; // keep original options in case user wants to extend this type later + this.tag = tag; + this.kind = options['kind'] || null; + this.resolve = options['resolve'] || function () { return true; }; + this.construct = options['construct'] || function (data) { return data; }; + this.instanceOf = options['instanceOf'] || null; + this.predicate = options['predicate'] || null; + this.represent = options['represent'] || null; + this.representName = options['representName'] || null; + this.defaultStyle = options['defaultStyle'] || null; + this.multi = options['multi'] || false; + this.styleAliases = compileStyleAliases(options['styleAliases'] || null); + + if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { + throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); + } +} + +module.exports = Type; diff --git a/libs/events/node_modules/js-yaml/lib/type/binary.js b/libs/events/node_modules/js-yaml/lib/type/binary.js new file mode 100644 index 000000000..e1523513d --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/binary.js @@ -0,0 +1,125 @@ +'use strict'; + +/*eslint-disable no-bitwise*/ + + +var Type = require('../type'); + + +// [ 64, 65, 66 ] -> [ padding, CR, LF ] +var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; + + +function resolveYamlBinary(data) { + if (data === null) return false; + + var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; + + // Convert one by one. + for (idx = 0; idx < max; idx++) { + code = map.indexOf(data.charAt(idx)); + + // Skip CR/LF + if (code > 64) continue; + + // Fail on illegal characters + if (code < 0) return false; + + bitlen += 6; + } + + // If there are any bits left, source was corrupted + return (bitlen % 8) === 0; +} + +function constructYamlBinary(data) { + var idx, tailbits, + input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan + max = input.length, + map = BASE64_MAP, + bits = 0, + result = []; + + // Collect by 6*4 bits (3 bytes) + + for (idx = 0; idx < max; idx++) { + if ((idx % 4 === 0) && idx) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } + + bits = (bits << 6) | map.indexOf(input.charAt(idx)); + } + + // Dump tail + + tailbits = (max % 4) * 6; + + if (tailbits === 0) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } else if (tailbits === 18) { + result.push((bits >> 10) & 0xFF); + result.push((bits >> 2) & 0xFF); + } else if (tailbits === 12) { + result.push((bits >> 4) & 0xFF); + } + + return new Uint8Array(result); +} + +function representYamlBinary(object /*, style*/) { + var result = '', bits = 0, idx, tail, + max = object.length, + map = BASE64_MAP; + + // Convert every three bytes to 4 ASCII characters. + + for (idx = 0; idx < max; idx++) { + if ((idx % 3 === 0) && idx) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } + + bits = (bits << 8) + object[idx]; + } + + // Dump tail + + tail = max % 3; + + if (tail === 0) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } else if (tail === 2) { + result += map[(bits >> 10) & 0x3F]; + result += map[(bits >> 4) & 0x3F]; + result += map[(bits << 2) & 0x3F]; + result += map[64]; + } else if (tail === 1) { + result += map[(bits >> 2) & 0x3F]; + result += map[(bits << 4) & 0x3F]; + result += map[64]; + result += map[64]; + } + + return result; +} + +function isBinary(obj) { + return Object.prototype.toString.call(obj) === '[object Uint8Array]'; +} + +module.exports = new Type('tag:yaml.org,2002:binary', { + kind: 'scalar', + resolve: resolveYamlBinary, + construct: constructYamlBinary, + predicate: isBinary, + represent: representYamlBinary +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/bool.js b/libs/events/node_modules/js-yaml/lib/type/bool.js new file mode 100644 index 000000000..cb7745930 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/bool.js @@ -0,0 +1,35 @@ +'use strict'; + +var Type = require('../type'); + +function resolveYamlBoolean(data) { + if (data === null) return false; + + var max = data.length; + + return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || + (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); +} + +function constructYamlBoolean(data) { + return data === 'true' || + data === 'True' || + data === 'TRUE'; +} + +function isBoolean(object) { + return Object.prototype.toString.call(object) === '[object Boolean]'; +} + +module.exports = new Type('tag:yaml.org,2002:bool', { + kind: 'scalar', + resolve: resolveYamlBoolean, + construct: constructYamlBoolean, + predicate: isBoolean, + represent: { + lowercase: function (object) { return object ? 'true' : 'false'; }, + uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, + camelcase: function (object) { return object ? 'True' : 'False'; } + }, + defaultStyle: 'lowercase' +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/float.js b/libs/events/node_modules/js-yaml/lib/type/float.js new file mode 100644 index 000000000..74d77ec2e --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/float.js @@ -0,0 +1,97 @@ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +var YAML_FLOAT_PATTERN = new RegExp( + // 2.5e4, 2.5 and integers + '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' + + // .2e4, .2 + // special case, seems not from spec + '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' + + // .inf + '|[-+]?\\.(?:inf|Inf|INF)' + + // .nan + '|\\.(?:nan|NaN|NAN))$'); + +function resolveYamlFloat(data) { + if (data === null) return false; + + if (!YAML_FLOAT_PATTERN.test(data) || + // Quick hack to not allow integers end with `_` + // Probably should update regexp & check speed + data[data.length - 1] === '_') { + return false; + } + + return true; +} + +function constructYamlFloat(data) { + var value, sign; + + value = data.replace(/_/g, '').toLowerCase(); + sign = value[0] === '-' ? -1 : 1; + + if ('+-'.indexOf(value[0]) >= 0) { + value = value.slice(1); + } + + if (value === '.inf') { + return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + + } else if (value === '.nan') { + return NaN; + } + return sign * parseFloat(value, 10); +} + + +var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; + +function representYamlFloat(object, style) { + var res; + + if (isNaN(object)) { + switch (style) { + case 'lowercase': return '.nan'; + case 'uppercase': return '.NAN'; + case 'camelcase': return '.NaN'; + } + } else if (Number.POSITIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '.inf'; + case 'uppercase': return '.INF'; + case 'camelcase': return '.Inf'; + } + } else if (Number.NEGATIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '-.inf'; + case 'uppercase': return '-.INF'; + case 'camelcase': return '-.Inf'; + } + } else if (common.isNegativeZero(object)) { + return '-0.0'; + } + + res = object.toString(10); + + // JS stringifier can build scientific format without dots: 5e-100, + // while YAML requres dot: 5.e-100. Fix it with simple hack + + return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; +} + +function isFloat(object) { + return (Object.prototype.toString.call(object) === '[object Number]') && + (object % 1 !== 0 || common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:float', { + kind: 'scalar', + resolve: resolveYamlFloat, + construct: constructYamlFloat, + predicate: isFloat, + represent: representYamlFloat, + defaultStyle: 'lowercase' +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/int.js b/libs/events/node_modules/js-yaml/lib/type/int.js new file mode 100644 index 000000000..3fe3a4437 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/int.js @@ -0,0 +1,156 @@ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +function isHexCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || + ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || + ((0x61/* a */ <= c) && (c <= 0x66/* f */)); +} + +function isOctCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); +} + +function isDecCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); +} + +function resolveYamlInteger(data) { + if (data === null) return false; + + var max = data.length, + index = 0, + hasDigits = false, + ch; + + if (!max) return false; + + ch = data[index]; + + // sign + if (ch === '-' || ch === '+') { + ch = data[++index]; + } + + if (ch === '0') { + // 0 + if (index + 1 === max) return true; + ch = data[++index]; + + // base 2, base 8, base 16 + + if (ch === 'b') { + // base 2 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch !== '0' && ch !== '1') return false; + hasDigits = true; + } + return hasDigits && ch !== '_'; + } + + + if (ch === 'x') { + // base 16 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isHexCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits && ch !== '_'; + } + + + if (ch === 'o') { + // base 8 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isOctCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits && ch !== '_'; + } + } + + // base 10 (except 0) + + // value should not start with `_`; + if (ch === '_') return false; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isDecCode(data.charCodeAt(index))) { + return false; + } + hasDigits = true; + } + + // Should have digits and should not end with `_` + if (!hasDigits || ch === '_') return false; + + return true; +} + +function constructYamlInteger(data) { + var value = data, sign = 1, ch; + + if (value.indexOf('_') !== -1) { + value = value.replace(/_/g, ''); + } + + ch = value[0]; + + if (ch === '-' || ch === '+') { + if (ch === '-') sign = -1; + value = value.slice(1); + ch = value[0]; + } + + if (value === '0') return 0; + + if (ch === '0') { + if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); + if (value[1] === 'x') return sign * parseInt(value.slice(2), 16); + if (value[1] === 'o') return sign * parseInt(value.slice(2), 8); + } + + return sign * parseInt(value, 10); +} + +function isInteger(object) { + return (Object.prototype.toString.call(object)) === '[object Number]' && + (object % 1 === 0 && !common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:int', { + kind: 'scalar', + resolve: resolveYamlInteger, + construct: constructYamlInteger, + predicate: isInteger, + represent: { + binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); }, + octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); }, + decimal: function (obj) { return obj.toString(10); }, + /* eslint-disable max-len */ + hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); } + }, + defaultStyle: 'decimal', + styleAliases: { + binary: [ 2, 'bin' ], + octal: [ 8, 'oct' ], + decimal: [ 10, 'dec' ], + hexadecimal: [ 16, 'hex' ] + } +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/map.js b/libs/events/node_modules/js-yaml/lib/type/map.js new file mode 100644 index 000000000..f327beebd --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/map.js @@ -0,0 +1,8 @@ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:map', { + kind: 'mapping', + construct: function (data) { return data !== null ? data : {}; } +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/merge.js b/libs/events/node_modules/js-yaml/lib/type/merge.js new file mode 100644 index 000000000..ae08a8644 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/merge.js @@ -0,0 +1,12 @@ +'use strict'; + +var Type = require('../type'); + +function resolveYamlMerge(data) { + return data === '<<' || data === null; +} + +module.exports = new Type('tag:yaml.org,2002:merge', { + kind: 'scalar', + resolve: resolveYamlMerge +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/null.js b/libs/events/node_modules/js-yaml/lib/type/null.js new file mode 100644 index 000000000..315ca4e23 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/null.js @@ -0,0 +1,35 @@ +'use strict'; + +var Type = require('../type'); + +function resolveYamlNull(data) { + if (data === null) return true; + + var max = data.length; + + return (max === 1 && data === '~') || + (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); +} + +function constructYamlNull() { + return null; +} + +function isNull(object) { + return object === null; +} + +module.exports = new Type('tag:yaml.org,2002:null', { + kind: 'scalar', + resolve: resolveYamlNull, + construct: constructYamlNull, + predicate: isNull, + represent: { + canonical: function () { return '~'; }, + lowercase: function () { return 'null'; }, + uppercase: function () { return 'NULL'; }, + camelcase: function () { return 'Null'; }, + empty: function () { return ''; } + }, + defaultStyle: 'lowercase' +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/omap.js b/libs/events/node_modules/js-yaml/lib/type/omap.js new file mode 100644 index 000000000..b2b5323bd --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/omap.js @@ -0,0 +1,44 @@ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; +var _toString = Object.prototype.toString; + +function resolveYamlOmap(data) { + if (data === null) return true; + + var objectKeys = [], index, length, pair, pairKey, pairHasKey, + object = data; + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + pairHasKey = false; + + if (_toString.call(pair) !== '[object Object]') return false; + + for (pairKey in pair) { + if (_hasOwnProperty.call(pair, pairKey)) { + if (!pairHasKey) pairHasKey = true; + else return false; + } + } + + if (!pairHasKey) return false; + + if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); + else return false; + } + + return true; +} + +function constructYamlOmap(data) { + return data !== null ? data : []; +} + +module.exports = new Type('tag:yaml.org,2002:omap', { + kind: 'sequence', + resolve: resolveYamlOmap, + construct: constructYamlOmap +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/pairs.js b/libs/events/node_modules/js-yaml/lib/type/pairs.js new file mode 100644 index 000000000..74b52403f --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/pairs.js @@ -0,0 +1,53 @@ +'use strict'; + +var Type = require('../type'); + +var _toString = Object.prototype.toString; + +function resolveYamlPairs(data) { + if (data === null) return true; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + if (_toString.call(pair) !== '[object Object]') return false; + + keys = Object.keys(pair); + + if (keys.length !== 1) return false; + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return true; +} + +function constructYamlPairs(data) { + if (data === null) return []; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + keys = Object.keys(pair); + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return result; +} + +module.exports = new Type('tag:yaml.org,2002:pairs', { + kind: 'sequence', + resolve: resolveYamlPairs, + construct: constructYamlPairs +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/seq.js b/libs/events/node_modules/js-yaml/lib/type/seq.js new file mode 100644 index 000000000..be8f77f28 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/seq.js @@ -0,0 +1,8 @@ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:seq', { + kind: 'sequence', + construct: function (data) { return data !== null ? data : []; } +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/set.js b/libs/events/node_modules/js-yaml/lib/type/set.js new file mode 100644 index 000000000..f885a329c --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/set.js @@ -0,0 +1,29 @@ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + +function resolveYamlSet(data) { + if (data === null) return true; + + var key, object = data; + + for (key in object) { + if (_hasOwnProperty.call(object, key)) { + if (object[key] !== null) return false; + } + } + + return true; +} + +function constructYamlSet(data) { + return data !== null ? data : {}; +} + +module.exports = new Type('tag:yaml.org,2002:set', { + kind: 'mapping', + resolve: resolveYamlSet, + construct: constructYamlSet +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/str.js b/libs/events/node_modules/js-yaml/lib/type/str.js new file mode 100644 index 000000000..27acc106c --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/str.js @@ -0,0 +1,8 @@ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:str', { + kind: 'scalar', + construct: function (data) { return data !== null ? data : ''; } +}); diff --git a/libs/events/node_modules/js-yaml/lib/type/timestamp.js b/libs/events/node_modules/js-yaml/lib/type/timestamp.js new file mode 100644 index 000000000..8fa9c5865 --- /dev/null +++ b/libs/events/node_modules/js-yaml/lib/type/timestamp.js @@ -0,0 +1,88 @@ +'use strict'; + +var Type = require('../type'); + +var YAML_DATE_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9])' + // [2] month + '-([0-9][0-9])$'); // [3] day + +var YAML_TIMESTAMP_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9]?)' + // [2] month + '-([0-9][0-9]?)' + // [3] day + '(?:[Tt]|[ \\t]+)' + // ... + '([0-9][0-9]?)' + // [4] hour + ':([0-9][0-9])' + // [5] minute + ':([0-9][0-9])' + // [6] second + '(?:\\.([0-9]*))?' + // [7] fraction + '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour + '(?::([0-9][0-9]))?))?$'); // [11] tz_minute + +function resolveYamlTimestamp(data) { + if (data === null) return false; + if (YAML_DATE_REGEXP.exec(data) !== null) return true; + if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; + return false; +} + +function constructYamlTimestamp(data) { + var match, year, month, day, hour, minute, second, fraction = 0, + delta = null, tz_hour, tz_minute, date; + + match = YAML_DATE_REGEXP.exec(data); + if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); + + if (match === null) throw new Error('Date resolve error'); + + // match: [1] year [2] month [3] day + + year = +(match[1]); + month = +(match[2]) - 1; // JS month starts with 0 + day = +(match[3]); + + if (!match[4]) { // no hour + return new Date(Date.UTC(year, month, day)); + } + + // match: [4] hour [5] minute [6] second [7] fraction + + hour = +(match[4]); + minute = +(match[5]); + second = +(match[6]); + + if (match[7]) { + fraction = match[7].slice(0, 3); + while (fraction.length < 3) { // milli-seconds + fraction += '0'; + } + fraction = +fraction; + } + + // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute + + if (match[9]) { + tz_hour = +(match[10]); + tz_minute = +(match[11] || 0); + delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds + if (match[9] === '-') delta = -delta; + } + + date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); + + if (delta) date.setTime(date.getTime() - delta); + + return date; +} + +function representYamlTimestamp(object /*, style*/) { + return object.toISOString(); +} + +module.exports = new Type('tag:yaml.org,2002:timestamp', { + kind: 'scalar', + resolve: resolveYamlTimestamp, + construct: constructYamlTimestamp, + instanceOf: Date, + represent: representYamlTimestamp +}); diff --git a/libs/events/node_modules/js-yaml/package.json b/libs/events/node_modules/js-yaml/package.json new file mode 100644 index 000000000..17574da80 --- /dev/null +++ b/libs/events/node_modules/js-yaml/package.json @@ -0,0 +1,66 @@ +{ + "name": "js-yaml", + "version": "4.1.0", + "description": "YAML 1.2 parser and serializer", + "keywords": [ + "yaml", + "parser", + "serializer", + "pyyaml" + ], + "author": "Vladimir Zapparov ", + "contributors": [ + "Aleksey V Zapparov (http://www.ixti.net/)", + "Vitaly Puzrin (https://github.com/puzrin)", + "Martin Grenfell (http://got-ravings.blogspot.com)" + ], + "license": "MIT", + "repository": "nodeca/js-yaml", + "files": [ + "index.js", + "lib/", + "bin/", + "dist/" + ], + "bin": { + "js-yaml": "bin/js-yaml.js" + }, + "module": "./dist/js-yaml.mjs", + "exports": { + ".": { + "import": "./dist/js-yaml.mjs", + "require": "./index.js" + }, + "./package.json": "./package.json" + }, + "scripts": { + "lint": "eslint .", + "test": "npm run lint && mocha", + "coverage": "npm run lint && nyc mocha && nyc report --reporter html", + "demo": "npm run lint && node support/build_demo.js", + "gh-demo": "npm run demo && gh-pages -d demo -f", + "browserify": "rollup -c support/rollup.config.js", + "prepublishOnly": "npm run gh-demo" + }, + "unpkg": "dist/js-yaml.min.js", + "jsdelivr": "dist/js-yaml.min.js", + "dependencies": { + "argparse": "^2.0.1" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.0.0", + "ansi": "^0.3.1", + "benchmark": "^2.1.4", + "codemirror": "^5.13.4", + "eslint": "^7.0.0", + "fast-check": "^2.8.0", + "gh-pages": "^3.1.0", + "mocha": "^8.2.1", + "nyc": "^15.1.0", + "rollup": "^2.34.1", + "rollup-plugin-node-polyfills": "^0.2.1", + "rollup-plugin-terser": "^7.0.2", + "shelljs": "^0.8.4" + } +} diff --git a/libs/events/node_modules/json-schema-static-docs/.circleci/config.yml b/libs/events/node_modules/json-schema-static-docs/.circleci/config.yml new file mode 100644 index 000000000..f67280db3 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/.circleci/config.yml @@ -0,0 +1,55 @@ +version: 2 + +defaults: &defaults + working_directory: ~/repo + docker: + - image: cimg/node:14.21.1 + +jobs: + test: + <<: *defaults + steps: + - checkout + - restore_cache: + keys: + - v1-dependencies-{{ checksum "package.json" }} + - v1-dependencies- + - run: npm install + - run: + name: Run tests + command: npm test + - save_cache: + paths: + - node_modules + key: v1-dependencies-{{ checksum "package.json" }} + - persist_to_workspace: + root: ~/repo + paths: . + deploy: + <<: *defaults + steps: + - attach_workspace: + at: ~/repo + - run: + name: Authenticate with registry + command: echo "//registry.npmjs.org/:_authToken=$npm_TOKEN" > ~/repo/.npmrc + - run: + name: Publish package + command: npm publish + +workflows: + version: 2 + test-deploy: + jobs: + - test: + filters: + tags: + only: /^v.*/ + - deploy: + requires: + - test + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ diff --git a/libs/events/node_modules/json-schema-static-docs/.github/workflows/jekyll-gh-pages.yml b/libs/events/node_modules/json-schema-static-docs/.github/workflows/jekyll-gh-pages.yml new file mode 100644 index 000000000..af61c8d3b --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/.github/workflows/jekyll-gh-pages.yml @@ -0,0 +1,50 @@ +# Sample workflow for building and deploying a Jekyll site to GitHub Pages +name: Deploy Jekyll with GitHub Pages dependencies preinstalled + +on: + # Runs on pushes targeting the default branch + push: + branches: ["master"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Pages + uses: actions/configure-pages@v2 + - name: Build with Jekyll + uses: actions/jekyll-build-pages@v1 + with: + source: ./gh-pages/ + destination: ./_site + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v1 diff --git a/libs/events/node_modules/json-schema-static-docs/LICENCE b/libs/events/node_modules/json-schema-static-docs/LICENCE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/LICENCE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/libs/events/node_modules/json-schema-static-docs/README.md b/libs/events/node_modules/json-schema-static-docs/README.md new file mode 100644 index 000000000..b30d3e0d6 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/README.md @@ -0,0 +1,40 @@ +# Json Schema Static Docs + +[![npm version](https://badge.fury.io/js/json-schema-static-docs.svg)](https://badge.fury.io/js/json-schema-static-docs) [![CircleCI](https://circleci.com/gh/tomcollins/json-schema-static-docs/tree/master.svg?style=svg)](https://circleci.com/gh/tomcollins/json-schema-static-docs/tree/master) + +## Description + +Generates static documentation for humans based on the contents of [JSON schema](https://json-schema.org/) files (yml or json). + +## Support for JSON schema specification versions + +Currently supports schema specified using the following [specification versions](https://json-schema.org/specification-links.html): +draft-06, draft-07 and draft-2019-09. + +For complete documentation, including examples and supported keywords, see [tomcollins.github.io/json-schema-static-docs](https://tomcollins.github.io/json-schema-static-docs/). + +## Installation + +```bash +npm install json-schema-static-docs +``` + +## Usage + +See [the docs](https://tomcollins.github.io/json-schema-static-docs/) for more details. + +```javascript +const JsonSchemaStaticDocs = require("json-schema-static-docs"); + +(async () => { + let jsonSchemaStaticDocs = new JsonSchemaStaticDocs({ + inputPath: "./schema", + outputPath: "./docs", + ajvOptions: { + allowUnionTypes: true, + }, + }); + await jsonSchemaStaticDocs.generate(); + console.log("Documents generated."); +})(); +``` diff --git a/libs/events/node_modules/json-schema-static-docs/cli.js b/libs/events/node_modules/json-schema-static-docs/cli.js new file mode 100755 index 000000000..e7b25b1fb --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/cli.js @@ -0,0 +1,30 @@ +#! /usr/bin/env node + +const fs = require('fs'); +const path = require('path'); +const JsonSchemaStaticDocs = require('./lib/json-schema-static-docs'); + +var argv = require('optimist') + .usage('Convert json schema into markdown docs.') + .demand('i') + .demand('o') + .alias('i', 'inputPath') + .describe('i', 'path to input directory') + .alias('o', 'outputPath') + .describe('o', 'path to output directory') + .check(function(args) { + if (!fs.existsSync(args.inputPath)) { + throw 'Input path "' + args.inputPath + '" does not exist.'; + } + }) + .argv; + +( async () => { + let jsonSchemaStaticDocs = new JsonSchemaStaticDocs({ + inputPath: argv.i, + outputPath: argv.o + }); + await jsonSchemaStaticDocs.generate(); + console.log('Documents generated into ' + argv.o); +})(); + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/Gemfile b/libs/events/node_modules/json-schema-static-docs/gh-pages/Gemfile new file mode 100644 index 000000000..49b38eb91 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/Gemfile @@ -0,0 +1,14 @@ +# Gemfile + +source 'https://rubygems.org' + +gem 'jekyll', '~> 3.9.2' + +# gem "minima" + +# group :jekyll_plugins do +# gem 'jekyll-timeago', '~> 0.13.1' +# end + +gem "github-pages", '>=227', group: :jekyll_plugins +gem "webrick", "~> 1.8" diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/Gemfile.lock b/libs/events/node_modules/json-schema-static-docs/gh-pages/Gemfile.lock new file mode 100644 index 000000000..8e7dbcaa8 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/Gemfile.lock @@ -0,0 +1,266 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (6.0.6.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + zeitwerk (~> 2.2, >= 2.2.2) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.11.1) + colorator (1.1.0) + commonmarker (0.23.9) + concurrent-ruby (1.2.0) + dnsruby (1.61.9) + simpleidn (~> 0.1) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + ethon (0.16.0) + ffi (>= 1.15.0) + eventmachine (1.2.7) + execjs (2.8.1) + faraday (2.7.3) + faraday-net_http (>= 2.0, < 3.1) + ruby2_keywords (>= 0.0.4) + faraday-net_http (3.0.2) + ffi (1.15.5) + forwardable-extended (2.6.0) + gemoji (3.0.1) + github-pages (227) + github-pages-health-check (= 1.17.9) + jekyll (= 3.9.2) + jekyll-avatar (= 0.7.0) + jekyll-coffeescript (= 1.1.1) + jekyll-commonmark-ghpages (= 0.2.0) + jekyll-default-layout (= 0.1.4) + jekyll-feed (= 0.15.1) + jekyll-gist (= 1.5.0) + jekyll-github-metadata (= 2.13.0) + jekyll-include-cache (= 0.2.1) + jekyll-mentions (= 1.6.0) + jekyll-optional-front-matter (= 0.3.2) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.3.0) + jekyll-redirect-from (= 0.16.0) + jekyll-relative-links (= 0.6.1) + jekyll-remote-theme (= 0.4.3) + jekyll-sass-converter (= 1.5.2) + jekyll-seo-tag (= 2.8.0) + jekyll-sitemap (= 1.4.0) + jekyll-swiss (= 1.0.0) + jekyll-theme-architect (= 0.2.0) + jekyll-theme-cayman (= 0.2.0) + jekyll-theme-dinky (= 0.2.0) + jekyll-theme-hacker (= 0.2.0) + jekyll-theme-leap-day (= 0.2.0) + jekyll-theme-merlot (= 0.2.0) + jekyll-theme-midnight (= 0.2.0) + jekyll-theme-minimal (= 0.2.0) + jekyll-theme-modernist (= 0.2.0) + jekyll-theme-primer (= 0.6.0) + jekyll-theme-slate (= 0.2.0) + jekyll-theme-tactile (= 0.2.0) + jekyll-theme-time-machine (= 0.2.0) + jekyll-titles-from-headings (= 0.5.3) + jemoji (= 0.12.0) + kramdown (= 2.3.2) + kramdown-parser-gfm (= 1.1.0) + liquid (= 4.0.3) + mercenary (~> 0.3) + minima (= 2.5.1) + nokogiri (>= 1.13.6, < 2.0) + rouge (= 3.26.0) + terminal-table (~> 1.4) + github-pages-health-check (1.17.9) + addressable (~> 2.3) + dnsruby (~> 1.60) + octokit (~> 4.0) + public_suffix (>= 3.0, < 5.0) + typhoeus (~> 1.3) + html-pipeline (2.14.3) + activesupport (>= 2) + nokogiri (>= 1.4) + http_parser.rb (0.8.0) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + jekyll (3.9.2) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 0.7) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 2.0) + kramdown (>= 1.17, < 3) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 4) + safe_yaml (~> 1.0) + jekyll-avatar (0.7.0) + jekyll (>= 3.0, < 5.0) + jekyll-coffeescript (1.1.1) + coffee-script (~> 2.2) + coffee-script-source (~> 1.11.1) + jekyll-commonmark (1.4.0) + commonmarker (~> 0.22) + jekyll-commonmark-ghpages (0.2.0) + commonmarker (~> 0.23.4) + jekyll (~> 3.9.0) + jekyll-commonmark (~> 1.4.0) + rouge (>= 2.0, < 4.0) + jekyll-default-layout (0.1.4) + jekyll (~> 3.0) + jekyll-feed (0.15.1) + jekyll (>= 3.7, < 5.0) + jekyll-gist (1.5.0) + octokit (~> 4.2) + jekyll-github-metadata (2.13.0) + jekyll (>= 3.4, < 5.0) + octokit (~> 4.0, != 4.4.0) + jekyll-include-cache (0.2.1) + jekyll (>= 3.7, < 5.0) + jekyll-mentions (1.6.0) + html-pipeline (~> 2.3) + jekyll (>= 3.7, < 5.0) + jekyll-optional-front-matter (0.3.2) + jekyll (>= 3.0, < 5.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.3.0) + jekyll (>= 3.0, < 5.0) + jekyll-redirect-from (0.16.0) + jekyll (>= 3.3, < 5.0) + jekyll-relative-links (0.6.1) + jekyll (>= 3.3, < 5.0) + jekyll-remote-theme (0.4.3) + addressable (~> 2.0) + jekyll (>= 3.5, < 5.0) + jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) + rubyzip (>= 1.3.0, < 3.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.8.0) + jekyll (>= 3.8, < 5.0) + jekyll-sitemap (1.4.0) + jekyll (>= 3.7, < 5.0) + jekyll-swiss (1.0.0) + jekyll-theme-architect (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.6.0) + jekyll (> 3.5, < 5.0) + jekyll-github-metadata (~> 2.9) + jekyll-seo-tag (~> 2.0) + jekyll-theme-slate (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.5.3) + jekyll (>= 3.3, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + jemoji (0.12.0) + gemoji (~> 3.0) + html-pipeline (~> 2.2) + jekyll (>= 3.0, < 5.0) + kramdown (2.3.2) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.3) + listen (3.8.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + mercenary (0.3.6) + mini_portile2 (2.8.1) + minima (2.5.1) + jekyll (>= 3.5, < 5.0) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + minitest (5.17.0) + nokogiri (1.14.3) + mini_portile2 (~> 2.8.0) + racc (~> 1.4) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (4.0.7) + racc (1.6.2) + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) + rexml (3.2.5) + rouge (3.26.0) + ruby2_keywords (0.0.5) + rubyzip (2.3.2) + safe_yaml (1.0.5) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.9.2) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) + simpleidn (0.2.1) + unf (~> 0.1.4) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + typhoeus (1.4.0) + ethon (>= 0.9.0) + tzinfo (1.2.11) + thread_safe (~> 0.1) + unf (0.1.4) + unf_ext + unf_ext (0.0.8.2) + unicode-display_width (1.8.0) + webrick (1.8.1) + zeitwerk (2.6.6) + +PLATFORMS + ruby + +DEPENDENCIES + github-pages (>= 227) + jekyll (~> 3.9.2) + webrick (~> 1.8) + +BUNDLED WITH + 2.2.3 diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/_config.yml b/libs/events/node_modules/json-schema-static-docs/gh-pages/_config.yml new file mode 100644 index 000000000..016cce29f --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/_config.yml @@ -0,0 +1,11 @@ +# _config.yml + +title: "JSON Schema Static Docs" +description: Quickly generate human friendly documentation from your JSON schema + +remote_theme: pages-themes/cayman@v0.2.0 +baseurl: /json-schema-static-docs +plugins: + - jekyll-remote-theme + +google_analytics_ga4: G-1J9F0RFJN0 diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/_includes/examples-table.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/_includes/examples-table.md new file mode 100644 index 000000000..9e7f5d503 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/_includes/examples-table.md @@ -0,0 +1,11 @@ +| HTML documentation | JSON Schema | +| --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| [Index of documents](/json-schema-static-docs/examples/examples-index.html) | n/a | +| [Person](/json-schema-static-docs/examples/person.html) | [person.yml](/json-schema-static-docs/yml/person.yml) | +| [Name](/json-schema-static-docs/examples/name.html) | [name.yml](/json-schema-static-docs/yml/name.yml) | +| [Enum Value Documentation](/json-schema-static-docs/examples/enums.html) | [enums.yml](/json-schema-static-docs/yml/enums.yml) | +| [One-of](/json-schema-static-docs/examples/oneof.html) | [oneof.yml](/json-schema-static-docs/yml/oneof.yml) | +| [Draft 2019-09 - Array](/json-schema-static-docs/examples/draft-2019-09/array.html) | [draft-2019-09/array.yml](/json-schema-static-docs/yml/draft-2019-09/array.yml) | +| [Draft 2019-09 - Deprecated](/json-schema-static-docs/examples/draft-2019-09/deprecated.html) | [draft-2019-09/deprecated.yml](/json-schema-static-docs/yml/draft-2019-09/deprecated.yml) | +| [Draft 07 - User](/json-schema-static-docs/examples/draft-07/user.html) | [draft-07/user.yml](/json-schema-static-docs/yml/draft-07/user.yml) | +| [Draft 06 - Animal](/json-schema-static-docs/examples/draft-06/animal.html) | [draft-06/animal.yml](/json-schema-static-docs/yml/draft-06/animal.yml) | diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/_includes/google-analytics.html b/libs/events/node_modules/json-schema-static-docs/gh-pages/_includes/google-analytics.html new file mode 100644 index 000000000..2cf32f4e3 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/_includes/google-analytics.html @@ -0,0 +1,14 @@ + + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/_layouts/default.html b/libs/events/node_modules/json-schema-static-docs/gh-pages/_layouts/default.html new file mode 100644 index 000000000..f6f4b59e3 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/_layouts/default.html @@ -0,0 +1,53 @@ + + + + + +{% seo %} + + + + + + + {% include head-custom.html %} + {% if site.google_analytics_ga4 and jekyll.environment == 'production' %} + {% include google-analytics.html %} + {% endif %} + + + Skip to the content. + + + +
+ {{ content }} + + +
+ + \ No newline at end of file diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/assets/css/style.scss b/libs/events/node_modules/json-schema-static-docs/gh-pages/assets/css/style.scss new file mode 100644 index 000000000..e27f8dee7 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/assets/css/style.scss @@ -0,0 +1,48 @@ +--- +--- + +@import "{{ site.theme }}"; + +th { + background-color: #f8f8f8; + text-align: left; +} + +nav { + position: absolute; + left: 0px; + height: 180px; + width: 100%; +} +nav ol { + list-style-type: none; + margin: 0; + padding: 0; + display: inline-block; + height: 180px; +} +nav li { + background-color: rgba(255, 255, 255, 0.2); + float: left; + padding: 0.2em 0.5em; + margin-right: 0.2em; +} +nav li:hover { + background-color: rgba(255, 255, 255, 0.5); +} +nav a { + color: #fff; +} + +h1 { + clear: both; + margin-top: 50px !important; +} + + +div.jssd-deprecated { + background: #d94c4c; + color: white; + width: 100%; + padding: 10px; +} diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples.md new file mode 100644 index 000000000..96350253f --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples.md @@ -0,0 +1,15 @@ +--- +title: Examples +description: Examples of JSON schema and associated human friendly documentation +permalink: /examples/ +--- + +# Examples + +These examples are generated by [json-scehma-static-docs](/) as markdown and served through [Jekyl](https://jekyllrb.com/). You can serve documents through anything that supports the markdown format. + +{% include examples-table.md %} + +Examples are based on [these yml documents](https://github.com/tomcollins/json-schema-static-docs/tree/master/gh-pages/yml). + +The generated markdown documents can be seen [here](https://github.com/tomcollins/json-schema-static-docs/tree/master/gh-pages/examples). diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-06/animal.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-06/animal.md new file mode 100644 index 000000000..027d51a0d --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-06/animal.md @@ -0,0 +1,130 @@ +--- +title: Draft 06 - User Example +description: A schema demonstrating some draft 06 features + +--- + + +# Draft 06 - User Example + +

A schema demonstrating some draft 06 features

+ + + + + + +
$iddraft-06-animal.yml
$schemahttp://json-schema.org/draft-06/schema#
+ +## Properties + +
NameType
animalTypeString
canFlyBoolean
+ + +## Example +``` +{ + "animalType": "Bear", + "canFly": false +} +``` +## Example +``` +{ + "animalType": "Bat", + "canFly": true +} +``` + +
+ + + +## animalType + + + + + + + + + + + + + + + +
TitleAnimal Type
TypeString
RequiredYes
+ + + + + + +## canFly + + + + + + + + + + + + + + + +
TitleCan Fly
TypeBoolean
RequiredYes
+ + + + + + + + + + +
+ +## Schema +``` +{ + "$id": "draft-06-animal.yml", + "$schema": "http://json-schema.org/draft-06/schema#", + "title": "Draft 06 - User Example", + "description": "A schema demonstrating some draft 06 features", + "examples": [ + { + "animalType": "Bear", + "canFly": false + }, + { + "animalType": "Bat", + "canFly": true + } + ], + "required": [ + "animalType", + "canFly" + ], + "type": "object", + "properties": { + "animalType": { + "type": "string", + "title": "Animal Type" + }, + "canFly": { + "type": "boolean", + "title": "Can Fly" + } + } +} +``` + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-07/user.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-07/user.md new file mode 100644 index 000000000..937e7ee30 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-07/user.md @@ -0,0 +1,143 @@ +--- +title: Draft 07 - User Example +description: A schema demonstrating some draft 07 features + +--- + + +# Draft 07 - User Example + +

A schema demonstrating some draft 07 features

+ + + + + + +
$iddraft-07-user.yml
$schemahttp://json-schema.org/draft-07/schema#
+ +## Properties + +
NameType
usernameString=seymour_butz
passwordString
+ + +## Example +``` +{ + "username": "seymour_butz", + "password": "M0zT4v3rn" +} +``` + +
+ + + +## username + + + + + + + + + + + + + + + + + + + + + + + + + + +
TitleUsername
DescriptionThis is a description
TypeString
RequiredYes
Read Onlytrue
Constseymour_butz
+ + + + + + +## password + + + + + + + + + + + + + + + + + + + + + + + +
TitlePassword
DescriptionA write only password property
TypeString
RequiredNo
Write Onlytrue
+ + + + + + + + + + +
+ +## Schema +``` +{ + "$id": "draft-07-user.yml", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Draft 07 - User Example", + "description": "A schema demonstrating some draft 07 features", + "examples": [ + { + "username": "seymour_butz", + "password": "M0zT4v3rn" + } + ], + "required": [ + "username" + ], + "type": "object", + "properties": { + "username": { + "type": "string", + "title": "Username", + "const": "seymour_butz", + "readOnly": true, + "description": "This is a description", + "$comment": "This is a comment" + }, + "password": { + "type": "string", + "title": "Password", + "writeOnly": true, + "description": "A write only password property" + } + } +} +``` + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-2019-09/array.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-2019-09/array.md new file mode 100644 index 000000000..502a194db --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-2019-09/array.md @@ -0,0 +1,219 @@ +--- +title: Draft 2019-09 - Array Example +description: A schema describing fruits and vegetables + +--- + + +# Draft 2019-09 - Array Example + +

A schema describing fruits and vegetables

+ + + + + + +
$idhttps://example.com/arrays.schema.json
$schemahttps://json-schema.org/draft/2019-09/schema
+ +## Properties + +
NameType
fruitsArray
vegetablesArray
+ + +## Example +``` +{ + "fruits": [ + "Apple" + ], + "vegetables": [ + { + "name": "Tomato", + "hasARoundShape": true + }, + { + "name": "Carrot", + "hasARoundShape": false + } + ] +} +``` + +
+ + + +## fruits + + + + + + + + + + + + + + + + + + + + + + +
TitleFruits
DescriptionAn array of fruit names
TypeArray
RequiredNo
ContainsType: string
+ + + + + + +## vegetables + + + + + + + + + + + + + + + + + + + +
TitleVegetables
DescriptionAn array vegetable objects
TypeArray
RequiredNo
+ + + +### vegetables.name + + + + + + + + + + + + + + + +
TitleName
DescriptionThe name of the vegetable.
TypeString
+ + + + +### vegetables.hasARoundShape + + + + + + + + + + + + + + + +
TitleIs round
DescriptionDoes this vegetable have a round shape?
TypeBoolean
+ + + + + + + + + + + +
+ +## Schema +``` +{ + "$id": "https://example.com/arrays.schema.json", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "Draft 2019-09 - Array Example", + "description": "A schema describing fruits and vegetables", + "examples": [ + { + "fruits": [ + "Apple" + ], + "vegetables": [ + { + "name": "Tomato", + "hasARoundShape": true + }, + { + "name": "Carrot", + "hasARoundShape": false + } + ] + } + ], + "type": "object", + "properties": { + "fruits": { + "title": "Fruits", + "description": "An array of fruit names", + "type": "array", + "contains": { + "type": "string" + } + }, + "vegetables": { + "title": "Vegetables", + "description": "An array vegetable objects", + "type": "array", + "items": { + "$ref": "#/$defs/vegetable" + } + } + }, + "$defs": { + "vegetable": { + "type": "object", + "required": [ + "name", + "hasARoundShape" + ], + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "The name of the vegetable." + }, + "hasARoundShape": { + "type": "boolean", + "title": "Is round", + "description": "Does this vegetable have a round shape?" + } + } + } + } +} +``` + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-2019-09/deprecated.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-2019-09/deprecated.md new file mode 100644 index 000000000..54068ac7b --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/draft-2019-09/deprecated.md @@ -0,0 +1,132 @@ +--- +title: Draft 2019-09 - Deprecated Example +description: A schema demonstrating use of deprecated + +--- +
⚠️ This schema has been marked as deprecated.
+ +# Draft 2019-09 - Deprecated Example + +

A schema demonstrating use of deprecated

+ + + + + + +
$idhttps://example.com/deprecated.schema.json
$schemahttps://json-schema.org/draft/2019-09/schema
+ +## Properties + +
NameType
firstNameString
lastNameString
+ + +## Example +``` +{ + "firstName": "Neil", + "lastName": "Williams" +} +``` + +
+ + + +## firstName + + + + + + + + + + + + + + + + + + + +
TitleFirst Name
DescriptionA persons first name
TypeString
RequiredNo
+ + + + + + +## lastName + + + + + + + + + + + + + + + + + + + + + + + +
Deprecatedtrue
TitleLast Name
DescriptionA persons last name
TypeString
RequiredNo
+ + + + + + + + + + +
+ +## Schema +``` +{ + "$id": "https://example.com/deprecated.schema.json", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "Draft 2019-09 - Deprecated Example", + "description": "A schema demonstrating use of deprecated", + "examples": [ + { + "firstName": "Neil", + "lastName": "Williams" + } + ], + "deprecated": true, + "type": "object", + "properties": { + "firstName": { + "deprecated": false, + "type": "string", + "title": "First Name", + "description": "A persons first name" + }, + "lastName": { + "deprecated": true, + "type": "string", + "title": "Last Name", + "description": "A persons last name" + } + } +} +``` + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/enums.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/enums.md new file mode 100644 index 000000000..7e7ae31c0 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/enums.md @@ -0,0 +1,108 @@ +--- +title: Enum Documentation +description: JSON schema example demonstrating documentation of enum values using the custom meta:enum keyword. This must be enabled using the enableMetaEnum config option. + +--- + + +# Enum Documentation + +

JSON schema example demonstrating documentation of enum values using the custom meta:enum keyword. This must be enabled using the enableMetaEnum config option.

+ + + + + + +
$idenum-documentation.yml
$schemahttp://json-schema.org/draft-07/schema#
+ +## Properties + +
NameType
statusString
+ + +## Example +``` +{ + "status": "Active" +} +``` + +
+ + + +## status + + + + + + + + + + + + + + + + + + + + + + +
TitleStatus
DescriptionThe status of something
TypeString
RequiredYes
Enum
Active
The thing is currently active and in use
Suspended
The thing is currently suspended and may later become Active or Terminated
Deleted
The thing has been permanently terminated
+ + + + + + + + + + +
+ +## Schema +``` +{ + "$id": "enum-documentation.yml", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Enum Documentation", + "description": "JSON schema example demonstrating documentation of enum values using the custom meta:enum keyword. This must be enabled using the enableMetaEnum config option.", + "type": "object", + "examples": [ + { + "status": "Active" + } + ], + "properties": { + "status": { + "title": "Status", + "description": "The status of something", + "type": "string", + "enum": [ + "Active", + "Suspended", + "Terminated" + ], + "meta:enum": { + "Active": "The thing is currently active and in use", + "Suspended": "The thing is currently suspended and may later become Active or Terminated", + "Deleted": "The thing has been permanently terminated" + } + } + }, + "additionalProperties": false, + "required": [ + "status" + ] +} +``` + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/examples-index.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/examples-index.md new file mode 100644 index 000000000..bad554f42 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/examples-index.md @@ -0,0 +1,16 @@ +# List of Examples +- [enums](enums.md) +- [name](name.md) +- [oneof-and-anyof](oneof-and-anyof.md) +- [oneof](oneof.md) +- [person](person.md) + +## Draft-06 +- [draft-06/animal](draft-06/animal.md) + +## Draft-07 +- [draft-07/user](draft-07/user.md) + +## Draft-2019-09 +- [draft-2019-09/array](draft-2019-09/array.md) +- [draft-2019-09/deprecated](draft-2019-09/deprecated.md) diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/name.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/name.md new file mode 100644 index 000000000..c39cab3c4 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/name.md @@ -0,0 +1,209 @@ +--- +title: Name +description: JSON schema example for a name entity + +--- + + +# Name + +

JSON schema example for a name entity

+ + + + + + +
$idname.yml
$schemahttp://json-schema.org/draft-07/schema#
+ +## Properties + +
NameType
titleString
firstNameString
lastNameString
+ + +## Example +``` +{ + "title": "Mr", + "firstName": "Seymour", + "lastName": "Butts" +} +``` + +
+ + + +## title + + + + + + + + + + + + + + + + + + + + + + + + + + +
TitleTitle
DescriptionThe title of a name entity
TypeString
RequiredYes
DefaultMr
Enum
  • Mr
  • Mrs
  • Miss
+ + + + + + +## firstName + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TitleFirst Name
DescriptionThe first name of a name entity
TypeString
RequiredYes
Min Length3
Max Length100
Examples
  • Tom
  • Dick
  • Harry
  • + + + + + + +## lastName + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleLast Name
    DescriptionThe last name of a name entity
    TypeString
    RequiredYes
    Min Length3
    Max Length100
    Examples
  • Smith
  • Jones
  • + + + + + + + + + + +
    + +## Schema +``` +{ + "$id": "name.yml", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Name", + "description": "JSON schema example for a name entity", + "type": "object", + "examples": [ + { + "title": "Mr", + "firstName": "Seymour", + "lastName": "Butts" + } + ], + "properties": { + "title": { + "title": "Title", + "description": "The title of a name entity", + "type": "string", + "default": "Mr", + "enum": [ + "Mr", + "Mrs", + "Miss" + ] + }, + "firstName": { + "title": "First Name", + "description": "The first name of a name entity", + "type": "string", + "minLength": 3, + "maxLength": 100, + "examples": [ + "Tom", + "Dick", + "Harry" + ] + }, + "lastName": { + "title": "Last Name", + "description": "The last name of a name entity", + "type": "string", + "minLength": 3, + "maxLength": 100, + "examples": [ + "Smith", + "Jones" + ] + } + }, + "additionalProperties": false, + "required": [ + "title", + "firstName", + "lastName" + ] +} +``` + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/oneof-and-anyof.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/oneof-and-anyof.md new file mode 100644 index 000000000..a4add835e --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/oneof-and-anyof.md @@ -0,0 +1,226 @@ +--- +title: One-of and Any-of +description: Example schema to demonstrate one of and any of + +--- +# One-of and Any-of + +

    Example schema to demonstrate one of and any of

    + + + + + + +
    $idoneof-and-anyof.yml
    $schemahttp://json-schema.org/draft-07/schema#
    + +## Properties + +
    NameType
    justOneOne of:Object
    Object
    + + +## Example +``` +{ + "justOne": { + "propertyA": "With a string value" + } +} +``` +## Example +``` +{ + "justOne": { + "propertyB": 123, + "propertyC": 456 + } +} +``` + +
    + + + +## justOne + + + + + + + + + + + + + + + + + + + +
    TitleJust One
    DescriptionProperty that demonstrates oneOf
    RequiredYes
    TypeOne of:Object
    Object
    + + + +### justOne.0 + + + + + + + + + + + +
    TitlejustOne option 0 with a single property
    + + + +### justOne.0.propertyA + + + + + + + + + + + +
    TitleProperty A
    TypeString
    + + + + + +### justOne.1 + + + + + + + + + + + +
    TitlejustOne option 1 with two properties
    + + + +### justOne.1.propertyB + + + + + + + + + + + +
    TitleProperty B
    TypeInteger
    + + + + +### justOne.1.propertyC + + + + + + + + + + + +
    TitleProperty C
    TypeInteger
    + + + + + + + + + + + +## Schema +``` +{ + "$id": "oneof-and-anyof.yml", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "One-of and Any-of", + "description": "Example schema to demonstrate one of and any of", + "type": "object", + "examples": [ + { + "justOne": { + "propertyA": "With a string value" + } + }, + { + "justOne": { + "propertyB": 123, + "propertyC": 456 + } + } + ], + "properties": { + "justOne": { + "title": "Just One", + "description": "Property that demonstrates oneOf", + "type": "object", + "oneOf": [ + { + "title": "justOne option 0 with a single property", + "properties": { + "propertyA": { + "type": "string", + "title": "Property A" + } + }, + "required": [ + "propertyA" + ] + }, + { + "title": "justOne option 1 with two properties", + "properties": { + "propertyB": { + "type": "integer", + "title": "Property B" + }, + "propertyC": { + "type": "integer", + "title": "Property C" + } + }, + "required": [ + "propertyB", + "propertyC" + ] + } + ], + "isRequired": true + } + }, + "additionalProperties": false, + "required": [ + "justOne" + ] +} +``` + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/oneof.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/oneof.md new file mode 100644 index 000000000..042e86aec --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/oneof.md @@ -0,0 +1,230 @@ +--- +title: One-of +description: Example schema to demonstrate the use of the oneOf keyword + +--- + + +# One-of + +

    Example schema to demonstrate the use of the oneOf keyword

    + + + + + + +
    $idoneof.yml
    $schemahttp://json-schema.org/draft-07/schema#
    + +## Properties + +
    NameType
    justOneOne of:Object
    Object
    + + +## Example +``` +{ + "justOne": { + "propertyA": "With a string value" + } +} +``` +## Example +``` +{ + "justOne": { + "propertyB": 123, + "propertyC": 456 + } +} +``` + +
    + + + +## justOne + + + + + + + + + + + + + + + + + + + +
    TitleJust One
    DescriptionProperty that demonstrates oneOf
    TypeOne of:Object
    Object
    RequiredYes
    + + + +### justOne.0 + + + + + + + + + + + +
    TitlejustOne option 0 with a single property
    + + + +### justOne.0.propertyA + + + + + + + + + + + +
    TitleProperty A
    TypeString
    + + + + + +### justOne.1 + + + + + + + + + + + +
    TitlejustOne option 1 with two properties
    + + + +### justOne.1.propertyB + + + + + + + + + + + +
    TitleProperty B
    TypeInteger
    + + + + +### justOne.1.propertyC + + + + + + + + + + + +
    TitleProperty C
    TypeInteger
    + + + + + + + + + + + + +
    + +## Schema +``` +{ + "$id": "oneof.yml", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "One-of", + "description": "Example schema to demonstrate the use of the oneOf keyword", + "type": "object", + "examples": [ + { + "justOne": { + "propertyA": "With a string value" + } + }, + { + "justOne": { + "propertyB": 123, + "propertyC": 456 + } + } + ], + "properties": { + "justOne": { + "title": "Just One", + "description": "Property that demonstrates oneOf", + "type": "object", + "oneOf": [ + { + "title": "justOne option 0 with a single property", + "properties": { + "propertyA": { + "type": "string", + "title": "Property A" + } + }, + "required": [ + "propertyA" + ] + }, + { + "title": "justOne option 1 with two properties", + "properties": { + "propertyB": { + "type": "integer", + "title": "Property B" + }, + "propertyC": { + "type": "integer", + "title": "Property C" + } + }, + "required": [ + "propertyB", + "propertyC" + ] + } + ] + } + }, + "additionalProperties": false, + "required": [ + "justOne" + ] +} +``` + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/person.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/person.md new file mode 100644 index 000000000..14636515a --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/examples/person.md @@ -0,0 +1,531 @@ +--- +title: Person +description: JSON schema example for a person entity + +--- + + +# Person + +

    JSON schema example for a person entity

    + + + + + + +
    $idperson.yml
    $schemahttp://json-schema.org/draft-07/schema#
    + +## Properties + +
    NameType
    nameObject (of type Name)
    dateOfBirthString
    addressObject
    friendsArray [Name]
    + + +## Example +``` +{ + "name": { + "title": "Mr", + "firstName": "Seymour", + "lastName": "Butts" + }, + "dateOfBirth": "1980-01-01", + "address": { + "houseNumber": 41, + "street": "Some street", + "city": "Swansea", + "timeAtAddress": { + "years": 1, + "months": 3 + } + } +} +``` +## Example +``` +{ + "name": { + "title": "Mr", + "firstName": "Jane", + "lastName": "Smith" + }, + "dateOfBirth": "1980-01-01", + "address": { + "houseNumber": 310, + "street": "Any street", + "city": "London" + }, + "friends": [ + { + "title": "Mr", + "firstName": "Seymour", + "lastName": "Butts" + }, + { + "title": "Mrs", + "firstName": "Marge", + "lastName": "Simpson" + } + ] +} +``` + +
    + + + +## name + +

    Defined in ./name.html

    + + + + + + + + + + + + + + + + + + + + + + +
    $idname.yml
    TitleName
    DescriptionJSON schema example for a name entity
    TypeObject (of type Name)
    RequiredYes
    + +### Properties +
    NameType
    titleString
    firstNameString
    lastNameString
    + + + + + +## dateOfBirth + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDate of birth
    DescriptionThe date at which a person was born.
    TypeString
    RequiredYes
    Formatdate
    Examples
  • 1992-10-23
  • + + + + + + +## address + + + + + + + + + + + + + + + + + + + +
    TitleAddress
    DescriptionThe address at which a person lives.
    TypeObject
    RequiredYes
    + +### Properties +
    NameType
    houseNumberString
    streetString
    cityString
    timeAtAddressObject
    + + +### address.houseNumber + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleHouse Number
    DescriptionThe house number at which an address is located.
    TypeString
    RequiredYes
    Min Length1
    Max Length10
    + + + + +### address.street + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleStreet
    DescriptionThe street in which an address is located.
    TypeString
    RequiredYes
    Min Length1
    Max Length250
    + + + + +### address.city + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleCity
    DescriptionThe city in which an address is located.
    TypeString
    RequiredYes
    Min Length1
    Max Length250
    + + + + +### address.timeAtAddress + + + + + + + + + + + + + + + + + + + +
    TitleTime at address
    DescriptionHow long the person has lived at this address.
    TypeObject
    RequiredNo
    + + + +### address.timeAtAddress.years + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleYears
    DescriptionThe number of years lived at this address.
    TypeNumber
    RequiredNo
    Minimum1
    Minimum1
    Maximum100
    + + + + +### address.timeAtAddress.months + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleMonths
    DescriptionThe number of months lived at this address.
    TypeInteger
    RequiredNo
    Minimum1
    Minimum1
    Maximum12
    + + + + + + + + +## friends + +

    Defined in ./name.html

    + + + + + + + + + + + + + + + + + + +
    TitleFriends
    DescriptionAn array containing the names of a person's friends.
    TypeArray [Name]
    RequiredNo
    + + + + + + + + + + +
    + +## Schema +``` +{ + "$id": "person.yml", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Person", + "description": "JSON schema example for a person entity", + "type": "object", + "examples": [ + { + "name": { + "title": "Mr", + "firstName": "Seymour", + "lastName": "Butts" + }, + "dateOfBirth": "1980-01-01", + "address": { + "houseNumber": 41, + "street": "Some street", + "city": "Swansea", + "timeAtAddress": { + "years": 1, + "months": 3 + } + } + }, + { + "name": { + "title": "Mr", + "firstName": "Jane", + "lastName": "Smith" + }, + "dateOfBirth": "1980-01-01", + "address": { + "houseNumber": 310, + "street": "Any street", + "city": "London" + }, + "friends": [ + { + "title": "Mr", + "firstName": "Seymour", + "lastName": "Butts" + }, + { + "title": "Mrs", + "firstName": "Marge", + "lastName": "Simpson" + } + ] + } + ], + "properties": { + "name": { + "$ref": "./name.yml" + }, + "dateOfBirth": { + "title": "Date of birth", + "description": "The date at which a person was born.", + "type": "string", + "format": "date", + "examples": [ + "1992-10-23" + ] + }, + "address": { + "title": "Address", + "description": "The address at which a person lives.", + "type": "object", + "properties": { + "houseNumber": { + "title": "House Number", + "description": "The house number at which an address is located.", + "type": "string", + "minLength": 1, + "maxLength": 10 + }, + "street": { + "title": "Street", + "description": "The street in which an address is located.", + "type": "string", + "minLength": 1, + "maxLength": 250 + }, + "city": { + "title": "City", + "description": "The city in which an address is located.", + "type": "string", + "minLength": 1, + "maxLength": 250 + }, + "timeAtAddress": { + "title": "Time at address", + "description": "How long the person has lived at this address.", + "type": "object", + "properties": { + "years": { + "title": "Years", + "description": "The number of years lived at this address.", + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "months": { + "title": "Months", + "description": "The number of months lived at this address.", + "type": "integer", + "minimum": 1, + "maximum": 12 + } + } + } + }, + "required": [ + "houseNumber", + "street", + "city" + ], + "additionalProperties": false + }, + "friends": { + "title": "Friends", + "description": "An array containing the names of a person's friends.", + "type": "array", + "items": { + "$ref": "./name.yml" + } + } + }, + "additionalProperties": false, + "required": [ + "name", + "dateOfBirth", + "address" + ] +} +``` + + diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/index.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/index.md new file mode 100644 index 000000000..7fce2a1cc --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/index.md @@ -0,0 +1,174 @@ +--- +title: JSON Schema Static Docs +--- + +# Json Schema Static Docs + +[![npm version](https://badge.fury.io/js/json-schema-static-docs.svg)](https://badge.fury.io/js/json-schema-static-docs) [![CircleCI](https://circleci.com/gh/tomcollins/json-schema-static-docs/tree/master.svg?style=svg)](https://circleci.com/gh/tomcollins/json-schema-static-docs/tree/master) + +This library generates human friendly static markdown documents based on a set of JSON schema documents. + +## Features + +- quickly generate static documentation with optional frontmatter +- generates an index of documents +- able to display nested properties and objects +- describes array item schema +- displays examples for schema and properties +- generates links between documents when schema include relative $ref values +- support for descriptions when using string enum values via a custom keyword + +See [this post](https://careers.dft.gov.uk/dvla-software-developers-behind-the-screens/) describing how this library is used by the [DVLA](https://github.com/dvla/). + +## Examples + +{% include examples-table.md %} + +See the [examples page](/json-schema-static-docs/examples/) for more info. + +## Support for JSON schema specification versions + +Currently supports schema specified using the following [specification versions](https://json-schema.org/specification-links.html): +draft-06, draft-07 and draft-2019-09. + +Examples for each specification version can be found below. + +You can view a [detailed description of supported keywords](/json-schema-static-docs/support/). + +## Installation + +```bash +npm install json-schema-static-docs +``` + +## Usage + +```javascript +const JsonSchemaStaticDocs = require("json-schema-static-docs"); + +(async () => { + let jsonSchemaStaticDocs = new JsonSchemaStaticDocs({ + inputPath: "schema", + outputPath: "docs", + ajvOptions: { + allowUnionTypes: true, + }, + }); + await jsonSchemaStaticDocs.generate(); + console.log("Documents generated."); +})(); +``` + +## Options + +| Parameter | Description | Default | +| -------------- | --------------------------------------------- | ------------------ | +| inputPath | Directory containing your schema | "schema" | +| inputFileGlob | Glob used to look for schema files | "\*_/_.{yml,json}" | +| outputPath | Where to write documentation files | "docs" | +| createIndex | Create an index of documents | true | +| indexPath | Index file path (relative to outputPath) | "index.md" | +| indexTitle | Title of the generated index page | "Index" | +| templatePath | Where to find templates | "templates" | +| ajvOptions | Options to pass to [AJV](https://ajv.js.org/) | {} | +| enableMetaEnum | Allow documentation of enum values | false | +| addFrontMatter | Add front matter to generated documentation | false | +| displaySchema | Display schema JSON in output | true | + +## Index Creation + +By default a root level index will be created in the specified `outputPath`. + +You can see an example of the [here](examples/examples-index.html); + +### Customising the index + +You can specify a path and title for the index. + +```javascript +let jsonSchemaStaticDocs = new JsonSchemaStaticDocs({ + inputPath: "schema", + outputPath: "docs", + indexPath: "schema-index.md", + indexTitle: "List of schema with custom title", +}); +``` + +## Markdown Front Matter + +If you want to include markdown front matter (for Jekyll, Hugo etc) use the `addFrontMatter` options. + +```javascript +let jsonSchemaStaticDocs = new JsonSchemaStaticDocs({ + inputPath: "schema", + outputPath: "docs", + addFrontMatter: true, +}); +await jsonSchemaStaticDocs.generate(); +``` + +This will prepend generated markdown documents with the schema title or it. + +```yml +--- +title: The schema title or $id +--- +# documentation starts here +``` + +## Describing Enums + +Json-schema allows a set of enumeration values to be defined for a string property but does not allow descriptions to be defined for each value. Descriptions within documentation can be very useful. + +This library supports the `meta:enum` convention (inspired by [adobe/jsonschema2md](https://github.com/adobe/jsonschema2md) to allow descriptions to be defined for enums. + +You will need to enable this feature using the `enableMetaEnum` option: + +```javascript +let jsonSchemaStaticDocs = new JsonSchemaStaticDocs({ + inputPath: "schema", + outputPath: "docs", + enableMetaEnum: true, +}); +await jsonSchemaStaticDocs.generate(); +``` + +_This allows the `meta:enum` keyword to be used when applying strict validation._ + +And then define the `meta:enum` descriptions adjacent to your `enum` e.g. + +```yml +property1: + title: "Property 1" + type: "string" + enum: ["foo", 42] + meta:enum: + foo: Description for foo + 42: Description for 42 +``` + +## Custom Templates + +Templates are authored in [handlebars.js](https://handlebarsjs.com). + +The default template is [templates/markdown/schema.hbs](https://github.com/tomcollins/json-schema-static-docs/blob/master/templates/markdown/schema.hbs). + +You can provide your own custom templates using the `templatePath` option. + +In the example below you will be expected to provide `./your-templates/schema.hbs'. + +```javascript +const JsonSchemaStaticDocs = require("json-schema-static-docs"); + +(async () => { + let jsonSchemaStaticDocs = new JsonSchemaStaticDocs({ + inputPath: "schema", + outputPath: "docs", + templatePath: "your-templates/", + }); + await jsonSchemaStaticDocs.generate(); + console.log("Documents generated."); +})(); +``` + +_There are currently limitations when using custom templates. Some elements are rendered through handlebars helpers outside the templates._ diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/scripts/build-examples.js b/libs/events/node_modules/json-schema-static-docs/gh-pages/scripts/build-examples.js new file mode 100644 index 000000000..250fd5916 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/scripts/build-examples.js @@ -0,0 +1,22 @@ +const JsonSchemaStaticDocs = require("../../lib/json-schema-static-docs"); +const path = require("path"); +const fastGlob = require("fast-glob"); + +const ymlPath = path.resolve(__dirname, "../yml/"); +const examplesPath = path.resolve(__dirname, "../examples/"); + +(async () => { + let jsonSchemaStaticDocs = new JsonSchemaStaticDocs({ + inputPath: ymlPath, + outputPath: examplesPath, + indexPath: "examples-index.md", + indexTitle: "List of Examples", + ajvOptions: { + allowUnionTypes: true, + }, + enableMetaEnum: true, + addFrontMatter: true, + }); + await jsonSchemaStaticDocs.generate(); + console.log("Documents generated."); +})(); diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/support.md b/libs/events/node_modules/json-schema-static-docs/gh-pages/support.md new file mode 100644 index 000000000..089155751 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/support.md @@ -0,0 +1,157 @@ +--- +title: Support +description: Detailed description of support for JSON schema keywords +permalink: /support/ +--- + +# JSON Schema Support + +This library currently supports schema specified using the following [specification versions](https://json-schema.org/specification-links.html): +draft-06, draft-07 and draft-2019-09. + +Supported keywords are described below: + +## Core Vocabulary + +Coverage for [The JSON Schema Core Vocabulary](https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.8.1). + +| Keyword | Supported | +| :----------------- | :-------- | +| `$anchor` | No | +| `$comment` | Yes | +| `$defs` | Yes | +| `$id` | Yes | +| `$recursiveAnchor` | No | +| `$recursiveRef` | No | +| `$ref` | Yes | +| `$schema` | Yes | +| `$vocabulary` | No | + +## A Vocabulary for Applying Subschemas + +Coverage for [A Vocabulary for Applying Subschemas](https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9). + +| Keyword | Supported | +| :---------------------- | :-------- | +| `additionalItems` | No | +| `additionalProperties` | Yes | +| `oneOf` | Yes | +| `allOf` | No | +| `anyOf` | No | +| `contains` | Yes | +| `dependentSchemas` | No | +| `else` | No | +| `if` | No | +| `items` | Yes | +| `not` | No | +| `patternProperties` | No | +| `properties` | Yes | +| `propertyNames` | No | +| `then` | No | +| `unevaluatedItems` | No | +| `unevaluatedProperties` | No | + +## Validation Keywords for Any Instance Type + +Coverage for [Validation Keywords for Any Instance Type](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.1). + +| Keyword | Supported | +| :------ | :-------- | +| `const` | Yes | +| `enum` | Yes | +| `type` | Yes | + +## Validation Keywords for Numeric Instances + +Coverage for [Validation Keywords for Numeric Instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.2). + +| Keyword | Supported | +| :----------------- | :-------- | +| `exclusiveMaximum` | Yes | +| `exclusiveMinimum` | Yes | +| `maximum` | Yes | +| `minimum` | Yes | +| `multipleOf` | Yes | + +## Validation Keywords for Strings + +Coverage for [Validation Keywords for Strings](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.3). + +| Keyword | Supported | +| :---------- | :-------- | +| `maxLength` | Yes | +| `minLength` | Yes | +| `pattern` | Yes | + +## Validation Keywords for Arrays + +Coverage for [Validation Keywords for Arrays](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.4). + +| Keyword | Supported | +| :------------ | :-------- | +| `maxContains` | Yes | +| `maxItems` | Yes | +| `minContains` | Yes | +| `minItems` | Yes | +| `uniqueItems` | Yes | + +## Validation Keywords for Objects + +Coverage for [Validation Keywords for Objects](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.5). + +| Keyword | Supported | +| :------------------ | :-------- | +| `dependentRequired` | No | +| `maxProperties` | Yes | +| `minProperties` | Yes | +| `required` | Yes | + +## Defined Formats + +Coverage for [Defined Formats](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.7.3). + +| Keyword | Supported | +| :---------------------- | :-------- | +| `date` | Yes | +| `date-time` | Yes | +| `duration` | Yes | +| `email` | Yes | +| `hostname` | Yes | +| `idn-email` | Yes | +| `idn-hostname` | Yes | +| `ipv4` | Yes | +| `ipv6` | Yes | +| `iri` | Yes | +| `iri-reference` | Yes | +| `json-pointer` | Yes | +| `regex` | Yes | +| `relative-json-pointer` | Yes | +| `time` | Yes | +| `uri` | Yes | +| `uri-reference` | Yes | +| `uri-template` | Yes | +| `uuid` | Yes | + +## A Vocabulary for the Contents of String-Encoded Data + +Coverage for [A Vocabulary for the Contents of String-Encoded Data](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.8) is 100%. + +| Keyword | Supported | +| :----------------- | :-------- | +| `contentEncoding` | No | +| `contentMediaType` | No | +| `contentSchema` | No | + +## A Vocabulary for Basic Meta-Data Annotations + +Coverage for [A Vocabulary for Basic Meta-Data Annotations](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9). + +| Keyword | Supported | +| :------------ | :-------- | +| `default` | Yes | +| `deprecated` | Yes | +| `description` | Yes | +| `examples` | Yes | +| `readOnly` | Yes | +| `title` | Yes | +| `writeOnly` | Yes | diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-06/animal.yml b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-06/animal.yml new file mode 100644 index 000000000..487d84d12 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-06/animal.yml @@ -0,0 +1,20 @@ +$id: draft-06-animal.yml +$schema: http://json-schema.org/draft-06/schema# +title: Draft 06 - User Example +description: A schema demonstrating some draft 06 features +examples: + - animalType: Bear + canFly: false + - animalType: Bat + canFly: true +required: + - animalType + - canFly +type: object +properties: + animalType: + type: string + title: Animal Type + canFly: + type: boolean + title: Can Fly diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-07/user.yml b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-07/user.yml new file mode 100644 index 000000000..71082d8b3 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-07/user.yml @@ -0,0 +1,23 @@ +$id: draft-07-user.yml +$schema: http://json-schema.org/draft-07/schema# +title: Draft 07 - User Example +description: A schema demonstrating some draft 07 features +examples: + - username: seymour_butz + password: M0zT4v3rn +required: + - username +type: object +properties: + username: + type: string + title: Username + const: seymour_butz + readOnly: true + description: This is a description + $comment: This is a comment + password: + type: string + title: Password + writeOnly: true + description: A write only password property diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-2019-09/array.yml b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-2019-09/array.yml new file mode 100644 index 000000000..d82c3ce12 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-2019-09/array.yml @@ -0,0 +1,41 @@ +"$id": https://example.com/arrays.schema.json +"$schema": https://json-schema.org/draft/2019-09/schema +title: Draft 2019-09 - Array Example +description: A schema describing fruits and vegetables +examples: + - fruits: + - Apple + vegetables: + - name: Tomato + hasARoundShape: true + - name: Carrot + hasARoundShape: false +type: object +properties: + fruits: + title: Fruits + description: An array of fruit names + type: array + contains: + type: string + vegetables: + title: Vegetables + description: An array vegetable objects + type: array + items: + "$ref": "#/$defs/vegetable" +"$defs": + vegetable: + type: object + required: + - name + - hasARoundShape + properties: + name: + type: string + title: Name + description: The name of the vegetable. + hasARoundShape: + type: boolean + title: Is round + description: Does this vegetable have a round shape? diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-2019-09/deprecated.yml b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-2019-09/deprecated.yml new file mode 100644 index 000000000..574b26748 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/draft-2019-09/deprecated.yml @@ -0,0 +1,20 @@ +"$id": https://example.com/deprecated.schema.json +"$schema": https://json-schema.org/draft/2019-09/schema +title: Draft 2019-09 - Deprecated Example +description: A schema demonstrating use of deprecated +examples: + - firstName: Neil + lastName: Williams +deprecated: true +type: object +properties: + firstName: + deprecated: false + type: string + title: First Name + description: A persons first name + lastName: + deprecated: true + type: string + title: Last Name + description: A persons last name diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/enums.yml b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/enums.yml new file mode 100644 index 000000000..c4e02f009 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/enums.yml @@ -0,0 +1,23 @@ +$id: enum-documentation.yml +$schema: http://json-schema.org/draft-07/schema# +title: Enum Documentation +description: JSON schema example demonstrating documentation of enum values using the custom meta:enum keyword. This must be enabled using the enableMetaEnum config option. +type: object +examples: + - status: Active +properties: + status: + title: Status + description: The status of something + type: string + enum: + - Active + - Suspended + - Terminated + meta:enum: + Active: The thing is currently active and in use + Suspended: The thing is currently suspended and may later become Active or Terminated + Deleted: The thing has been permanently terminated +additionalProperties: false +required: + - status diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/name.yml b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/name.yml new file mode 100644 index 000000000..edc19dae0 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/name.yml @@ -0,0 +1,43 @@ +$id: name.yml +$schema: http://json-schema.org/draft-07/schema# +title: Name +description: JSON schema example for a name entity +type: object +examples: + - title: Mr + firstName: "Seymour" + lastName: "Butts" +properties: + title: + title: Title + description: The title of a name entity + type: string + default: Mr + enum: + - Mr + - Mrs + - Miss + firstName: + title: First Name + description: The first name of a name entity + type: string + minLength: 3 + maxLength: 100 + examples: + - Tom + - Dick + - Harry + lastName: + title: Last Name + description: The last name of a name entity + type: string + minLength: 3 + maxLength: 100 + examples: + - Smith + - Jones +additionalProperties: false +required: + - title + - firstName + - lastName diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/oneof.yml b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/oneof.yml new file mode 100644 index 000000000..105cfe4e7 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/oneof.yml @@ -0,0 +1,38 @@ +$id: oneof.yml +$schema: http://json-schema.org/draft-07/schema# +title: One-of +description: Example schema to demonstrate the use of the oneOf keyword +type: object +examples: + - justOne: + propertyA: With a string value + - justOne: + propertyB: 123 + propertyC: 456 +properties: + justOne: + title: Just One + description: Property that demonstrates oneOf + type: object + oneOf: + - title: justOne option 0 with a single property + properties: + propertyA: + type: string + title: Property A + required: + - propertyA + - title: justOne option 1 with two properties + properties: + propertyB: + type: integer + title: Property B + propertyC: + type: integer + title: Property C + required: + - propertyB + - propertyC +additionalProperties: false +required: + - justOne diff --git a/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/person.yml b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/person.yml new file mode 100644 index 000000000..c4fa254e3 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/gh-pages/yml/person.yml @@ -0,0 +1,100 @@ +$id: person.yml +$schema: http://json-schema.org/draft-07/schema# +title: Person +description: JSON schema example for a person entity +type: object +examples: + - name: + title: Mr + firstName: "Seymour" + lastName: "Butts" + dateOfBirth: 1980-01-01 + address: + houseNumber: 41 + street: Some street + city: Swansea + timeAtAddress: + years: 1 + months: 3 + - name: + title: Mr + firstName: "Jane" + lastName: "Smith" + dateOfBirth: 1980-01-01 + address: + houseNumber: 310 + street: Any street + city: London + friends: + - title: Mr + firstName: "Seymour" + lastName: "Butts" + - title: Mrs + firstName: "Marge" + lastName: "Simpson" +properties: + name: + $ref: ./name.yml + dateOfBirth: + title: Date of birth + description: The date at which a person was born. + type: string + format: date + examples: + - 1992-10-23 + address: + title: Address + description: The address at which a person lives. + type: object + properties: + houseNumber: + title: House Number + description: The house number at which an address is located. + type: string + minLength: 1 + maxLength: 10 + street: + title: Street + description: The street in which an address is located. + type: string + minLength: 1 + maxLength: 250 + city: + title: City + description: The city in which an address is located. + type: string + minLength: 1 + maxLength: 250 + timeAtAddress: + title: Time at address + description: How long the person has lived at this address. + type: object + properties: + years: + title: Years + description: The number of years lived at this address. + type: number + minimum: 1 + maximum: 100 + months: + title: Months + description: The number of months lived at this address. + type: integer + minimum: 1 + maximum: 12 + required: + - houseNumber + - street + - city + additionalProperties: false + friends: + title: Friends + description: An array containing the names of a person's friends. + type: array + items: + $ref: ./name.yml +additionalProperties: false +required: + - name + - dateOfBirth + - address diff --git a/libs/events/node_modules/json-schema-static-docs/lib/json-schema-static-docs.js b/libs/events/node_modules/json-schema-static-docs/lib/json-schema-static-docs.js new file mode 100644 index 000000000..1fb2bcf0b --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/json-schema-static-docs.js @@ -0,0 +1,171 @@ +const extend = require("extend"); +const path = require("path"); +const fastGlob = require("fast-glob"); +const Loader = require("./loader"); +const Resolver = require("./resolver"); +const Merger = require("./merger"); +const Renderer = require("./renderer"); +const Writer = require("./writer"); +const Validator = require("./validator"); +const { createIndex } = require("./renderer/index"); +const { determineSchemaRelativePath } = require("./utils"); + +const defaultOptions = { + inputPath: "schema", + inputFileGlob: "**/*.{yml,json}", + outputPath: "docs", + createIndex: true, + indexPath: "index.md", + indexTitle: "Index", + templatePath: path.join(__dirname, "../templates"), + linkBasePath: "./", + resolve: {}, + skipTemplates: false, + ajvOptions: {}, + enableMetaEnum: false, + addFrontMatter: false, + displaySchema: true, +}; + +var JsonSchemaStaticDocs = function (options) { + this._options = extend(true, defaultOptions, options); + + this._options.inputPath = this._options.inputPath.replace(/\/$/, ""); + this._options.outputPath = this._options.outputPath.replace(/\/$/, ""); +}; + +JsonSchemaStaticDocs.prototype.generate = async function () { + const inputPathPattern = fastGlob.convertPathToPattern( + this._options.inputPath + ); + const inputPathGlob = path.join( + inputPathPattern, + this._options.inputFileGlob + ); + + // clean up path (strip leading ./ etc) + const cleanInputPath = path.join(this._options.inputPath); + + const unresolvedSchemas = await Loader.loadFiles(inputPathGlob); + console.log( + "Loaded", + unresolvedSchemas.length, + "schema files from", + inputPathGlob + ); + + const schemas = []; + unresolvedSchemas.forEach((schema) => { + schemas.push(schema.data); + }); + const validator = new Validator(schemas, this._options.ajvOptions); + + if (this._options.enableMetaEnum) { + validator.addMetaEnum(); + } + + unresolvedSchemas.forEach((schema) => { + try { + validator.validateSchema(schema.data); + } catch (e) { + console.error("Error validating schema", schema.filename); + console.error(e); + throw e; + } + + schema.relativeFilename = determineSchemaRelativePath( + schema.filename, + cleanInputPath + ); + }); + + const resolvedSchemas = await Resolver.resolveSchemas( + inputPathGlob, + this._options.resolve + ); + + resolvedSchemas.forEach((schema) => { + schema.relativeFilename = determineSchemaRelativePath( + schema.filename, + cleanInputPath + ); + }); + + if (this._options.skipTemplates === true) { + await Promise.all( + resolvedSchemas.map(async (resolvedSchema) => { + let outputFilename = path.join( + this._options.outputPath, + resolvedSchema.relativeFilename + ); + await Writer.writeFile( + outputFilename, + JSON.stringify(resolvedSchema.data) + ); + }) + ); + console.log( + "Written", + resolvedSchemas.length, + "documents to", + this._options.outputPath + ); + return resolvedSchemas; + } + + const mergedSchemas = Merger.mergeSchemas(unresolvedSchemas, resolvedSchemas); + + mergedSchemas.forEach((mergedSchema) => { + if (mergedSchema.example) { + try { + validator.validateSchemaAndData( + mergedSchema.cleanSchema, + mergedSchema.example.data + ); + } catch (e) { + console.error( + "Error validating", + mergedSchema.example.filename, + "against schema", + mergedSchema.filename + ); + console.error(e); + } + } + }); + + let renderer = new Renderer(this._options.templatePath, this._options); + await renderer.setup(); + + await Promise.all( + mergedSchemas.map(async (mergedSchema) => { + let renderedSchema = renderer.renderSchema(mergedSchema); + let outputFilename = mergedSchema.relativeFilename.replace( + /\.(json|yml)$/, + ".md" + ); + outputFilename = path.join(this._options.outputPath, outputFilename); + await Writer.writeFile(outputFilename, renderedSchema); + }) + ); + console.log( + "Written", + mergedSchemas.length, + "documents to", + this._options.outputPath + ); + + if (this._options.createIndex) { + await createIndex( + `${this._options.outputPath}/${this._options.indexPath}`, + this._options.outputPath, + { + title: this._options.indexTitle, + } + ); + } + + return mergedSchemas; +}; + +module.exports = JsonSchemaStaticDocs; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/loader.js b/libs/events/node_modules/json-schema-static-docs/lib/loader.js new file mode 100644 index 000000000..ab4750b37 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/loader.js @@ -0,0 +1,47 @@ +const fastGlob = require("fast-glob"); +const fs = require("fs"); +const { promisify } = require("util"); +const YAML = require("yaml"); +const readFileAsync = promisify(fs.readFile); + +const loadFiles = async (files) => { + return await Promise.all( + files.map(async (file) => { + let dataObject; + + let fileContent = await readFileAsync(file).catch((e) => { + console.error("Error reading file: ", file); + console.error(e); + }); + + fileContent = fileContent.toString(); + const extension = file.split(".").pop(); + + try { + if (extension === "yml" || extension == "yaml") { + dataObject = YAML.parse(fileContent); + } else { + dataObject = JSON.parse(fileContent); + } + } catch (e) { + console.error("Error parsing file: ", file); + console.error(e); + } + + return { + filename: file, + data: dataObject, + }; + }) + ); +}; + +var Loader = function () {}; + +Loader.loadFiles = async function (glob) { + const files = fastGlob.sync(glob); + const results = await loadFiles(files); + return results.filter((result) => result.data !== undefined); +}; + +module.exports = Loader; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/merger.js b/libs/events/node_modules/json-schema-static-docs/lib/merger.js new file mode 100644 index 000000000..6ca67f1a8 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/merger.js @@ -0,0 +1,148 @@ +const _ = require("lodash"); +const pointer = require("jsonpointer"); + +const getFilename = (path) => { + let parts = path.split("/"); + return parts[parts.length - 1]; +}; + +const resolveRef = ( + unresolvedSchema, + mergedSchema, + unresolvedProperty, + mergedProperty +) => { + let ref; + if (unresolvedProperty.type === "array") { + ref = unresolvedProperty.items?.$ref; + } else { + ref = unresolvedProperty.$ref; + } + + if (!ref) { + return; + } else if (ref.substr(0, 1) !== "#") { + mergedProperty.$ref = ref; + return; + } + + let refPointer = ref.substr(1); + let resolvedRef; + + try { + resolvedRef = pointer.get(unresolvedSchema, refPointer); + } catch (e) { + console.error( + "Error resolving JSON pointer", + refPointer, + "in property", + property.title, + "of schema", + unresolvedSchema.$id + ); + console.error(e); + } + + // @todo technically this could also require resolution + + if (resolvedRef) { + if (resolvedRef.type === "array") { + mergedProperty.items.$ref = resolvedRef.items.$ref || ref; + } else { + mergedProperty.$ref = resolvedRef.$ref || ref; + } + + // @todo handle allOf, anyOf + if (resolvedRef.oneOf) { + resolvedRef.oneOf.forEach((oneItem, index) => { + if (oneItem.$ref) { + let mergedResolvedRef = pointer.get(mergedSchema, refPointer); + if (mergedResolvedRef.oneOf && mergedResolvedRef.oneOf[index]) { + mergedResolvedRef.oneOf[index].$ref = oneItem.$ref; + } + } + }); + } + } + + return; +}; + +const mergeProperty = (unresolvedSchema, mergedSchema, key) => { + let unresolvedProperty; + let mergedProperty; + + if (mergedSchema.properties) { + mergedProperty = mergedSchema.properties[key]; + } else { + return; + } + if (unresolvedSchema && unresolvedSchema.properties) { + unresolvedProperty = unresolvedSchema.properties[key]; + } + + if (mergedProperty === undefined) { + return; + } + + mergedProperty.isRequired = + Array.isArray(mergedSchema.required) && mergedSchema.required.includes(key); + + if (unresolvedProperty) { + resolveRef( + unresolvedSchema, + mergedSchema, + unresolvedProperty, + mergedProperty + ); + } + + if (mergedProperty.properties) { + for (const key in mergedProperty.properties) { + mergeProperty(unresolvedProperty, mergedProperty, key); + } + } +}; + +var Merger = function () {}; + +// resolvedSchemas do not have any $ref data +// add the $ref from the related unresolvedSchemas into each resolvedSchema +Merger.mergeSchemas = function (unresolvedSchemas, resolvedSchemas) { + return unresolvedSchemas.map((unresolvedSchema) => { + let resolvedSchema = resolvedSchemas.find( + (resolvedSchema) => resolvedSchema.filename === unresolvedSchema.filename + ); + + if (!resolvedSchema) { + throw "Unable to resolve schema " + unresolvedSchema.filename; + } + + let mergedSchema = _.cloneDeep(resolvedSchema); + mergedSchema.cleanSchema = _.cloneDeep(resolvedSchema.data); + + if (mergedSchema.data.properties) { + for (const key in mergedSchema.data.properties) { + mergeProperty(unresolvedSchema.data, mergedSchema.data, key); + } + } + + // @todo handle top-level oneOf, allOf, anyOf + if (mergedSchema.data.oneOf) { + mergedSchema.data.oneOf.forEach((one, index) => { + // @todo this is going to throw exceptions + mergedSchema.data.oneOf[index].$ref = + unresolvedSchema.data.oneOf[index].$ref; + }); + } + + mergedSchema.schema = mergedSchema.data; + delete mergedSchema.data; + + mergedSchema.unresolvedSchema = unresolvedSchema.data; + + return mergedSchema; + }); +}; + +module.exports = Merger; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/renderer-markdown.js b/libs/events/node_modules/json-schema-static-docs/lib/renderer-markdown.js new file mode 100644 index 000000000..16d7321bc --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/renderer-markdown.js @@ -0,0 +1,216 @@ +const Handlebars = require("handlebars"); +const fs = require("fs"); +const path = require("path"); +const util = require("util"); +const _ = require("lodash"); +const { + getHtmlAnchorForRef, + getLabelForProperty, + upperCaseFirstCharacter, +} = require("./renderer/helpers"); + +const readFile = util.promisify(fs.readFile); + +/* ------ */ + +Handlebars.registerHelper("isExternalRef", function (value) { + return ( + typeof value === "string" && + (value.match(/^(.+)#/) || value.match(/^(.+)\.(json|yaml|yml)$/)) + ); +}); +Handlebars.registerHelper("getHtmlAnchorForRef", function (ref, label) { + return getHtmlAnchorForRef(ref, label); +}); + +/* ------ */ + +Handlebars.registerHelper("json", function (context) { + return JSON.stringify(context, undefined, 4); +}); + +Handlebars.registerHelper("enumValues", function (enums) { + let html = "
      "; + if (Array.isArray(enums)) { + enums.forEach((e) => { + html += `
    • ${String(e)}
    • `; + }); + } + html += "
    "; + return new Handlebars.SafeString(html); +}); + +Handlebars.registerHelper("isDefined", function (value) { + return value !== undefined; +}); + +Handlebars.registerHelper("isArrayOfStringLikeValues", function (value) { + return Array.isArray(value) && !value.find((v) => typeof v === "object"); +}); + +const propertyRow = (name, property, parentKey) => { + let href = ""; + if (typeof parentKey === "string") { + href = parentKey.toLowerCase(); + } + href += name.toLowerCase(); + + let typeLabel; + if (property.const) { + typeLabel = `${upperCaseFirstCharacter(property.type)}=${property.const}`; + } else { + typeLabel = getLabelForProperty(property); + } + let html = + `${name}` + + `${typeLabel}`; + + return html; +}; + +const oneOfRow = (name, property) => { + const length = Object.keys(property.oneOf).length; + let html = + `${name}` + + `One of:`; + let isFirstRow = true; + + for (const key in property.oneOf) { + let oneOfItem = property.oneOf[key]; + + if (!isFirstRow) { + html += ""; + } + + // oneOf allows common properties to sit above the oneOf items so need to support + // both approaches + html += `${getLabelForProperty( + oneOfItem.type ? oneOfItem : property + )}`; + + isFirstRow = false; + } + + return html; +}; + +const oneOfArrayRow = (oneOf) => { + const length = oneOf.length; + let html = ""; + let isFirstRow = true; + + oneOf.forEach((one) => { + if (isFirstRow) { + html += `One of:`; + } else { + html += ""; + } + + html += `${getLabelForProperty(one)}`; + + isFirstRow = false; + }); + + return html; +}; + +const propertiesTable = (schema, parentKey) => { + let properties = schema.properties; + + let html = + "" + + '' + + ""; + + for (const key in properties) { + let property = properties[key]; + + if ( + property && + property.oneOf != undefined && + (!property.$ref || property.$ref.match(/^#/)) + ) { + html += oneOfRow(key, property); + } else { + html += propertyRow(key, property, parentKey); + } + } + + let oneOf = schema.oneOf; + if (Array.isArray(oneOf) && oneOf.length > 0) { + html += oneOfArrayRow(oneOf); + } + + html += "
    NameType
    "; + + return html; +}; + +Handlebars.registerHelper("concat", function () { + const subArguments = [...arguments].slice(0, -1); + return subArguments.join(""); +}); + +Handlebars.registerHelper("match", function (string, regex) { + let result; + if (typeof string === "string") { + result = string?.match(regex); + } + return result; +}); + +Handlebars.registerHelper("propertiesTable", function (schema, parentKey) { + return new Handlebars.SafeString(propertiesTable(schema, parentKey)); +}); + +Handlebars.registerHelper("propertyTypeRow", function (property) { + let html; + if (property.oneOf != undefined) { + html = `${oneOfRow("Type", property)}`; + } else { + const typeLabel = getLabelForProperty(property); + if (typeLabel) { + html = `Type${typeLabel}`; + } + } + return html ? new Handlebars.SafeString(html) : ""; +}); + +var RendererMarkdown = function (templatePath, options) { + options = options || {}; + this.templatePath = templatePath; + this.addFrontMatter = + options.addFrontMatter !== undefined ? options.addFrontMatter : false; + this.displaySchema = + options.displaySchema !== undefined ? options.displaySchema : false; +}; + +RendererMarkdown.prototype.setup = async function () { + const schemaTemplatePath = path.join(this.templatePath, "schema.hbs"); + let templateSource = await readFile(schemaTemplatePath); + this.templateSchema = Handlebars.compile(templateSource.toString()); +}; + +RendererMarkdown.prototype.renderSchema = function (data) { + data.displaySchema = this.displaySchema; + let result = this.templateSchema(data); + + // this fixes tables that have been broken by unintended double line breaks + // introduced by optional rows. + // could possibly be avoided by use of ~ in templates + result = result.replace(/\|(\n)+\|/g, "|\n|"); + + if (this.addFrontMatter) { + let frontMatter = `title: ${data.schema.title || data.schema.id}\n`; + if (data.schema.description) { + const description = data.schema.description.replace(/\n/g, ""); + frontMatter += `description: ${description}\n`; + } + + result = `---\n${frontMatter}\n---\n${result}`; + } + + return result; +}; + +module.exports = RendererMarkdown; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/renderer.js b/libs/events/node_modules/json-schema-static-docs/lib/renderer.js new file mode 100644 index 000000000..682f79492 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/renderer.js @@ -0,0 +1,16 @@ +let RendererMarkdown = require("./renderer-markdown"); + +function Renderer(templatePath, options) { + options = options || {}; + this.renderer = new RendererMarkdown(templatePath, options); +} + +Renderer.prototype.setup = async function () { + await this.renderer.setup(); +}; + +Renderer.prototype.renderSchema = function (data) { + return this.renderer.renderSchema(data); +}; + +module.exports = Renderer; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/renderer/helpers.js b/libs/events/node_modules/json-schema-static-docs/lib/renderer/helpers.js new file mode 100644 index 000000000..25b6a2f7f --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/renderer/helpers.js @@ -0,0 +1,89 @@ +const upperCaseFirstCharacter = (value) => { + return typeof value === "string" + ? value.substr(0, 1).toUpperCase() + value.substr(1) + : value; +}; + +const convertRelativeUrlToHtmlDocsUrl = (href) => { + return typeof href === "string" + ? href + // document pages use a .html extension + // given $ref=schema.json#/definitions/fooBar + // we want to link to schema.html#fooBar + .replace(/\.json/, ".html") + .replace(/\.yml/, ".html") + // convert any defs into suitable anchors + .replace(/#\/(definitions|\$defs)\//, "#") + // anchor IDs will be lower-case + .replace(/#(.)+$/, (match, offset, string) => { + return match.toLowerCase(); + }) + : href; +}; + +const isHttpRef = (ref) => { + return typeof ref === "string" && ref.match(/^http(s)?:/); +}; +const isRelativeRef = (ref) => { + return typeof ref === "string" && !isHttpRef(ref) && !ref.match(/^#/); +}; + +const formatLabel = (label) => { + if (Array.isArray(label)) { + label = label.join(", "); + label = `[${label}]`; + } else { + label = label || ""; + label = upperCaseFirstCharacter(label); + } + return label; +}; + +const getHtmlAnchorForRef = (ref, label) => { + let refParts = ref.split("/"); + let filename = refParts[refParts.length - 1]; + + let htmlAnchor; + + if (isHttpRef(ref)) { + htmlAnchor = `${filename}`; + } else if (isRelativeRef(ref)) { + // this is a little ugly, + // most of the time the $ref is passed in as the label by the template + // may be a nicer way to handle this as an optional argument in a handlebars helper + label = + !label || label === ref + ? convertRelativeUrlToHtmlDocsUrl(ref) + : formatLabel(label); + htmlAnchor = `${label}`; + } else { + label = formatLabel(label); + htmlAnchor = `${label}`; + } + + return htmlAnchor; +}; + +const getLabelForProperty = (property) => { + let result; + let ref = property.items?.$ref || property.$ref; + let _isRelativeRef = isRelativeRef(ref); + + if (_isRelativeRef && property.type === "array") { + result = `Array [${getHtmlAnchorForRef(ref, property.items.title)}]`; + } else if (_isRelativeRef && property.type === "object") { + result = `Object (of type ${getHtmlAnchorForRef(ref, property.title)})`; + } else { + result = formatLabel(property.type); + } + + return result; +}; + +module.exports = { + getHtmlAnchorForRef, + getLabelForProperty, + upperCaseFirstCharacter, +}; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/renderer/index.js b/libs/events/node_modules/json-schema-static-docs/lib/renderer/index.js new file mode 100644 index 000000000..3b2c78ff5 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/renderer/index.js @@ -0,0 +1,106 @@ +const fs = require("fs"); +const path = require("path"); +const fg = require("fast-glob"); + +const removeSourcePathPrefix = (filename, sourcePath) => { + let result = filename.replace(new RegExp(sourcePath), "").replace(/^\//, ""); + return result; +}; + +const formatTitle = (value) => { + return value.substr(0, 1).toUpperCase() + value.substr(1); +}; + +const formatLink = (filename) => { + const label = filename.replace(/\.md/,''); + const url = filename; + + return `- [${label}](${url})\n`; +}; + +const formatHeading = (value, index) => { + let heading = "#"; + for (var i = 0; i <= index; i++) { + heading += "#"; + } + heading += " "; + return heading + formatTitle(value) + "\n"; +}; + +const updateHeadings = ( + currentHeading, + markdown, + filenameParts, + startingLevel +) => { + filenameParts.forEach((filenamePart, index) => { + if ( + index >= startingLevel && + // do not make the actual filename a heading + index < filenameParts.length - 1 && + // only render heading if there has been a change in value + (!currentHeading[index] || currentHeading[index] !== filenamePart) + ) { + markdown += `\n${formatHeading(filenamePart, index - startingLevel)}`; + } + }); + + currentHeading = filenameParts; + + return { currentHeading, markdown }; +}; + +const renderFilenames = (filenames, startingLevel, sourcePath) => { + let markdown = ""; + let currentHeading = []; + let currentDepth = 0; + + filenames.forEach((filename) => { + if (!filename.match(/index.md$/)) { + const partialFilename = removeSourcePathPrefix(filename, sourcePath); + + const filenameParts = partialFilename.split("/"); + if (!filenameParts) { + filenameParts = [partialFilename]; + } + + if (filenameParts.length < currentDepth) { + markdown += `\n`; + } + currentDepth = filenameParts.length; + + ({ currentHeading, markdown } = updateHeadings( + currentHeading, + markdown, + filenameParts, + startingLevel + )); + markdown += formatLink(partialFilename); + } + }); + return markdown; +}; + +const sortFilenames = (filenames) => { + return filenames.sort((a, b) => { + return a >= b; + }); +}; + +const createIndex = async (indexPath, sourcePath, options) => { + options = options || {}; + + const globPattern = path.join(sourcePath, "/**"); + + let files = await fg([globPattern]); + files = sortFilenames(files); + + let title = options.title || "Index of Schema"; + let markdown = `# ${title}\n`; + markdown += renderFilenames(files, 0, sourcePath); + fs.writeFileSync(indexPath, markdown); +}; + +module.exports = { + createIndex, +}; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/resolver.js b/libs/events/node_modules/json-schema-static-docs/lib/resolver.js new file mode 100644 index 000000000..0697fb208 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/resolver.js @@ -0,0 +1,30 @@ +const fastGlob = require("fast-glob"); +const $RefParser = require("@apidevtools/json-schema-ref-parser"); + +var Resolver = function () {}; + +Resolver.resolveSchemas = async function (fileGlob, resolvers) { + const files = fastGlob.sync(fileGlob); + const results = await Promise.all( + files.map(async (filename) => { + let resolvedSchema = await Resolver.resolveSchema( + filename, + resolvers + ).catch((e) => { + console.error("Error resolving", filename); + console.error(e.message); + }); + return { + filename: filename, + data: resolvedSchema, + }; + }) + ); + return results.filter((results) => results.data != undefined); +}; + +Resolver.resolveSchema = async function (schemaToResolve, resolvers) { + return await $RefParser.dereference(schemaToResolve, { resolve: resolvers }); +}; + +module.exports = Resolver; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/utils.js b/libs/events/node_modules/json-schema-static-docs/lib/utils.js new file mode 100644 index 000000000..3f79f4697 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/utils.js @@ -0,0 +1,11 @@ +const determineSchemaRelativePath = (schemaFilename, schemaInputPath) => { + let outputFilename = schemaFilename.substr(schemaInputPath.length); + if (outputFilename.substr(0, 1) === "/") { + outputFilename = outputFilename.substr(1); + } + return outputFilename; +}; + +module.exports = { + determineSchemaRelativePath: determineSchemaRelativePath, +}; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/validator.js b/libs/events/node_modules/json-schema-static-docs/lib/validator.js new file mode 100644 index 000000000..4361cf928 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/validator.js @@ -0,0 +1,42 @@ +// const Ajv = require("ajv"); +const Ajv = require("ajv/dist/2019"); +const draft7MetaSchema = require("ajv/dist/refs/json-schema-draft-07.json"); +const draft6MetaSchema = require("ajv/dist/refs/json-schema-draft-06.json"); +const addFormats = require("ajv-formats"); + +let Validator = function (schemas, ajvOptions) { + let options = {}; + Object.assign(options, ajvOptions); + // options.schemas = schemas; + this._ajv = new Ajv(options); + this._ajv.addMetaSchema(draft7MetaSchema); + this._ajv.addMetaSchema(draft6MetaSchema); + schemas.forEach((schema) => { + this._ajv.addSchema(schema); + }); + addFormats(this._ajv); +}; + +Validator.prototype.addMetaEnum = function () { + // @todo this should really perform validation to ensure that the input is safe + this._ajv.addKeyword({ + keyword: "meta:enum", + valid: true, + errors: false, + }); +}; + +Validator.prototype.validateSchema = function (schema) { + let validate = this._ajv.compile(schema); + return true; +}; + +Validator.prototype.validateSchemaAndData = function (schema, data) { + var valid = this._ajv.validate(schema, data); + if (!valid) { + throw this._ajv.errors; + } + return valid; +}; + +module.exports = Validator; diff --git a/libs/events/node_modules/json-schema-static-docs/lib/writer.js b/libs/events/node_modules/json-schema-static-docs/lib/writer.js new file mode 100644 index 000000000..20d22df8e --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/lib/writer.js @@ -0,0 +1,15 @@ +const fs = require('fs'); +const makeDir = require('make-dir'); + +var Writer = function(){} + +Writer.writeFile = async function(filename, data) { + let parts = filename.split('/'); + let dirName = parts.splice(0, parts.length-1).join('/'); + if (!fs.existsSync(dirName)) { + await makeDir(dirName); + } + fs.writeFileSync(filename, data); +}; + +module.exports = Writer; \ No newline at end of file diff --git a/libs/events/node_modules/json-schema-static-docs/package.json b/libs/events/node_modules/json-schema-static-docs/package.json new file mode 100644 index 000000000..65dc61553 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/package.json @@ -0,0 +1,43 @@ +{ + "name": "json-schema-static-docs", + "version": "0.24.1", + "description": "Generates static documentation for humans based on the contents of JSON schema files (yml or json).", + "main": "lib/json-schema-static-docs.js", + "bin": { + "json-schema-static-docs": "./cli.js" + }, + "scripts": { + "test": "jest" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/tomcollins/json-schema-static-docs.git" + }, + "bugs": { + "url": "https://github.com/tomcollins/json-schema-static-docs/issues" + }, + "homepage": "https://tomcollins.github.io/json-schema-static-docs/", + "author": "Tom Collins", + "license": "GPL-3.0-only", + "engines": { + "node": ">=14" + }, + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^10.1.0", + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "extend": "^3.0.2", + "fast-glob": "^3.3.1", + "handlebars": "^4.7.7", + "jsonpointer": "^5.0.1", + "lodash": ">=4.17.21", + "make-dir": "^3.1.0", + "mkdirp": "^2.1.6", + "optimist": "^0.5.2", + "rimraf": "^4.4.1", + "yaml": "^2.2.2" + }, + "devDependencies": { + "jest": "^29.5.0" + } +} diff --git a/libs/events/node_modules/json-schema-static-docs/templates/schema.hbs b/libs/events/node_modules/json-schema-static-docs/templates/schema.hbs new file mode 100644 index 000000000..2599ea8d6 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/templates/schema.hbs @@ -0,0 +1,232 @@ +{{#if schema.deprecated}}
    ⚠️ This schema has been marked as deprecated.
    {{/if}} + +{{#if schema.title}}# {{ schema.title }}{{else if schema.description}}# {{ schema.description }}{{else}}# {{/if}} + +{{#if schema.title}}{{#if schema.description}}

    {{ schema.description }}

    {{/if}}{{/if}} + + + +{{#if schema.$id}}{{/if}} +{{#if schema.$schema}}{{/if}} + +
    $id{{ schema.$id }}
    $schema{{ schema.$schema }}
    + +## Properties + +{{propertiesTable schema }} + +{{#if example}} +## Example +``` +{{{json example.data}}} +``` +{{/if}} + +{{#if schema.examples}} +{{#each schema.examples}} +## Example +``` +{{{json this}}} +``` +{{/each}} +{{/if}} + +
    + +{{#each schema.properties}} + +{{> property propertyKey=@key }} + +{{/each}} + + + + +{{#*inline "property"}} + +{{#if (isDefined parentKey)}} +### {{ parentKey }}.{{ propertyKey }} +{{else}} +## {{ propertyKey }} +{{/if}} + +{{#if (isExternalRef this.$ref)}} +

    Defined in {{{ getHtmlAnchorForRef this.$ref this.$ref }}}

    +{{/if}} + +{{> propertyTable}} + +{{#unless (isDefined parentKey)}} + {{#if this.properties}} +### Properties + {{propertiesTable this propertyKey }} + {{/if}} +{{/unless}} + +{{#unless (isExternalRef this.$ref)}} +{{#if this.properties}} +{{#each this.properties}} +{{#if (isDefined ../parentKey)}} +{{> property parentKey=(concat ../parentKey '.' ../propertyKey) propertyKey=@key }} +{{else}} +{{> property parentKey=../propertyKey propertyKey=@key }} +{{/if}} +{{/each}} +{{/if}} +{{#if this.items }} +{{#unless (isDefined this.items.$ref)}} +{{#each this.items.properties}} +{{#if (isDefined ../parentKey)}} +{{> property parentKey=(concat ../parentKey '.' ../propertyKey) propertyKey=@key }} +{{else}} +{{> property parentKey=../propertyKey propertyKey=@key }} +{{/if}} +{{/each}} +{{/unless}} +{{/if}} +{{#if this.oneOf }} +{{#each this.oneOf}} +{{#if (isDefined ../parentKey)}} +{{> property parentKey=(concat ../parentKey '.' ../propertyKey) propertyKey=@key }} +{{else}} +{{> property parentKey=../propertyKey propertyKey=@key }} +{{/if}} +{{/each}} +{{/if}} +{{/unless}} + +{{/inline}} + +{{#if displaySchema}} + +
    + +## Schema +``` +{{{json unresolvedSchema}}} +``` +{{/if}} + + +{{#*inline "propertyTable"}} + + {{!-- + + + + + --}} + + {{#if this.$id}} + + + + + {{/if}} + {{#if this.deprecated}} + + + + + {{/if}} + {{#if this.title}} + + + + + {{/if}} + {{#if this.description}} + + + + + {{/if}} + {{propertyTypeRow this }} + {{#if (isDefined this.isRequired)}} + + + + + {{/if}} + {{#if this.default}} + + + + + {{/if}} + {{#if this.readOnly}} + + + + + {{/if}} + {{#if this.writeOnly}} + + + + + {{/if}} + {{#if this.const}} + + + {{/if}}{{#if this.enum}} + + + {{/if}}{{#if this.minLength}} + + + {{/if}}{{#if this.maxLength}} + + + {{/if}}{{#if this.contains}}{{#if this.contains.type}} + + + {{/if}}{{/if}}{{#if this.minContains}} + + + {{/if}}{{#if this.maxContains}} + + + {{/if}}{{#if this.uniqueItems}} + + + {{/if}}{{#if this.minItems}} + + + {{/if}}{{#if this.maxItems}} + + + {{/if}}{{#if this.minimum}} + + + {{/if}}{{#if this.exclusiveMinimum}} + + + {{/if}}{{#if this.maximum}} + + + {{/if}}{{#if this.exclusiveMaximum}} + + + {{/if}}{{#if this.maxProperties}} + + + {{/if}}{{#if this.minProperties}} + + + {{/if}}{{#if this.multipleOf}} + + + {{/if}}{{#if this.format}} + + + {{/if}}{{#if this.pattern}} + + + {{/if}}{{#if (match this.type '^(string|integer|number|boolean)$')}}{{#if this.examples}} + + + {{/if}}{{/if}} + +
    AttributeValue
    $id{{ this.$id }}
    Deprecated{{this.deprecated}}
    Title{{ this.title }}
    Description{{ this.description }}
    Required{{#if this.isRequired}}Yes{{else}}No{{/if}}
    Default{{this.default}}
    Read Only{{this.readOnly}}
    Write Only{{this.writeOnly}}
    Const{{this.const}}
    Enum{{#if this.meta:enum}}
    {{#each this.meta:enum}}
    {{@key}}
    {{this}}
    {{/each}}
    {{else}}{{enumValues this.enum}}{{/if}}
    Min Length{{this.minLength}}
    Max Length{{this.maxLength}}
    ContainsType: {{this.contains.type}}
    Min Contains{{this.minContains}}
    Max Contains{{this.maxContains}}
    Unique Items{{this.uniqueItems}}
    Min Items{{this.minItems}}
    Max Items{{this.maxItems}}
    Minimum{{this.minimum}}
    Exclusive Minimum{{this.exclusiveMinimum}}
    Maximum{{this.maximum}}
    Exclusive Maximum{{this.exclusiveMaximum}}
    Max Properties{{this.maxProperties}}
    Min Properties{{this.minProperties}}
    Multiple Of{{this.multipleOf}}
    Format{{this.format}}
    Pattern{{this.pattern}}
    Examples{{#each this.examples}}
  • {{this}}
  • {{/each}}
    +{{/inline}} diff --git a/libs/events/node_modules/json-schema-static-docs/tests/examples/bar/name.json b/libs/events/node_modules/json-schema-static-docs/tests/examples/bar/name.json new file mode 100644 index 000000000..1c12e343c --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/examples/bar/name.json @@ -0,0 +1,3 @@ +{ + "lastName": "LastName" +} \ No newline at end of file diff --git a/libs/events/node_modules/json-schema-static-docs/tests/examples/foo/name.json b/libs/events/node_modules/json-schema-static-docs/tests/examples/foo/name.json new file mode 100644 index 000000000..3167556f3 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/examples/foo/name.json @@ -0,0 +1,4 @@ +{ + "firstNames": "First Names", + "lastName": "LastName" +} \ No newline at end of file diff --git a/libs/events/node_modules/json-schema-static-docs/tests/examples/schema-with-errors/malformed.json b/libs/events/node_modules/json-schema-static-docs/tests/examples/schema-with-errors/malformed.json new file mode 100644 index 000000000..5765c131f --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/examples/schema-with-errors/malformed.json @@ -0,0 +1,2 @@ +{ + foo diff --git a/libs/events/node_modules/json-schema-static-docs/tests/examples/schema/name.json b/libs/events/node_modules/json-schema-static-docs/tests/examples/schema/name.json new file mode 100644 index 000000000..fbbd521bc --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/examples/schema/name.json @@ -0,0 +1,39 @@ +{ + "$id": "http://example.com/schemas/name.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Name", + "description": "A name.", + "type": "object", + "properties": { + "firstNames": { + "$ref": "#/definitions/firstNames" + }, + "lastName": { + "$ref": "#/definitions/lastName" + } + }, + "additionalProperties": false, + "required": ["lastName"], + "definitions": { + "firstNames": { + "description": "One or more first names separated by a space character.", + "type": "string", + "minLength": 1, + "maxLength": 100, + "pattern": "[A-Za-z ]{1,100}" + }, + "lastName": { + "description": "A single last name.", + "type": "string", + "minLength": 1, + "maxLength": 100, + "pattern": "[A-Za-z]{1,100}" + } + }, + "examples": [ + { + "firstNames": "Andrew Barry", + "lastName": "Cunningham" + } + ] +} diff --git a/libs/events/node_modules/json-schema-static-docs/tests/examples/schema/person.json b/libs/events/node_modules/json-schema-static-docs/tests/examples/schema/person.json new file mode 100644 index 000000000..ef9153382 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/examples/schema/person.json @@ -0,0 +1,41 @@ +{ + "$id": "http://example.com/schemas/person.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Person", + "description": "A person.", + "type": "object", + "properties": { + "name": { + "$ref": "name.json" + }, + "dateOfBirth": { + "$ref": "#/definitions/dateOfBirth" + }, + "friendsNames": { + "type": "array", + "title": "Friends names", + "description": "Set of friends names.", + "items": { + "$ref": "name.json" + } + } + }, + "additionalProperties": false, + "required": ["name"], + "definitions": { + "dateOfBirth": { + "description": "The date on which a person was born. Does not include time.", + "type": "string", + "format": "date" + } + }, + "examples": [ + { + "name": { + "firstNames": "Jesus", + "lastName": "Christ" + }, + "dateOfBirth": "1900-12-25" + } + ] +} diff --git a/libs/events/node_modules/json-schema-static-docs/tests/examples/schema/sub/different-person.json b/libs/events/node_modules/json-schema-static-docs/tests/examples/schema/sub/different-person.json new file mode 100644 index 000000000..8fbd30fa1 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/examples/schema/sub/different-person.json @@ -0,0 +1,41 @@ +{ + "$id": "http://example.com/schemas/sub/different-person.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Person", + "description": "A person.", + "type": "object", + "properties": { + "name": { + "$ref": "../name.json" + }, + "dateOfBirth": { + "$ref": "#/definitions/dateOfBirth" + }, + "friendsNames": { + "type": "array", + "title": "Friends names", + "description": "Set of friends names.", + "items": { + "$ref": "../name.json" + } + } + }, + "additionalProperties": false, + "required": ["name"], + "definitions": { + "dateOfBirth": { + "description": "The date on which a person was born. Does not include time.", + "type": "string", + "format": "date" + } + }, + "examples": [ + { + "name": { + "firstNames": "Seymour", + "lastName": "Butts" + }, + "dateOfBirth": "1982-04-30" + } + ] +} diff --git a/libs/events/node_modules/json-schema-static-docs/tests/examples/templates/schema.hbs b/libs/events/node_modules/json-schema-static-docs/tests/examples/templates/schema.hbs new file mode 100644 index 000000000..191028156 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/examples/templates/schema.hbs @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/libs/events/node_modules/json-schema-static-docs/tests/handlebars.test.js b/libs/events/node_modules/json-schema-static-docs/tests/handlebars.test.js new file mode 100644 index 000000000..da8944dbb --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/handlebars.test.js @@ -0,0 +1,6 @@ +const RendererMarkdown = require("../lib/renderer-markdown.js"); +const Handlebars = require("handlebars"); + +test("defines expected helpers", () => { + expect(Handlebars.helpers["getHtmlAnchorForRef"]).toBeDefined(); +}); diff --git a/libs/events/node_modules/json-schema-static-docs/tests/json-schema-static-docs.test.js b/libs/events/node_modules/json-schema-static-docs/tests/json-schema-static-docs.test.js new file mode 100644 index 000000000..2d3209510 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/json-schema-static-docs.test.js @@ -0,0 +1,58 @@ +const fs = require("fs"); +const path = require("path"); +const rimraf = require("rimraf"); +const _ = require("lodash"); + +const JsonSchamaStaticDocs = require("../lib/json-schema-static-docs.js"); + +let defaultTestOptions = { + inputPath: "./tests/examples/schema/", + outputPath: "./tests/docs/", +}; +let testOptions = {}; + +beforeEach(() => { + testOptions = _.cloneDeep(defaultTestOptions); + if (fs.existsSync(testOptions.outputPath)) { + rimraf.sync(testOptions.outputPath); + } + fs.mkdirSync(testOptions.outputPath); +}); + +afterEach(() => {}); + +test("resolves single schema", async () => { + const jsonSchameStaticDocs = new JsonSchamaStaticDocs(testOptions); + const result = await jsonSchameStaticDocs.generate(); + expect(result.length).toBe(3); +}); + +test("handles absolute paths", async () => { + testOptions.inputPath = path.resolve(__dirname, "./examples/schema/"); + testOptions.outputPath = path.resolve(__dirname, "./docs/"); + const jsonSchameStaticDocs = new JsonSchamaStaticDocs(testOptions); + let mergedSchemas = await jsonSchameStaticDocs.generate(); + expect(mergedSchemas[2].relativeFilename).toBe("sub/different-person.json"); + const exists = fs.existsSync("./tests/docs/sub/different-person.md"); + expect(exists).toBe(true); +}); + +test("supports custom templates", async () => { + testOptions.templatePath = path.join(__dirname, "examples/templates/"); + const jsonSchameStaticDocs = new JsonSchamaStaticDocs(testOptions); + await jsonSchameStaticDocs.generate(); + let result = fs.readFileSync(path.join(testOptions.outputPath, "name.md")); + expect(result.toString()).toBe("foo"); +}); + +test("allows templates to be skipped", async () => { + testOptions.skipTemplates = true; + const jsonSchameStaticDocs = new JsonSchamaStaticDocs(testOptions); + await jsonSchameStaticDocs.generate(); + let result = fs.readFileSync( + path.join(testOptions.outputPath, "person.json") + ); + let schema = JSON.parse(result.toString()); + expect(schema.title).toBe("Person"); + expect(schema.properties.name.properties.firstNames.type).toBe("string"); +}); diff --git a/libs/events/node_modules/json-schema-static-docs/tests/loader.test.js b/libs/events/node_modules/json-schema-static-docs/tests/loader.test.js new file mode 100644 index 000000000..4d5fad568 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/loader.test.js @@ -0,0 +1,18 @@ +const Loader = require("../lib/loader.js"); + +test("loads single schema", async () => { + const results = await Loader.loadFiles("./tests/examples/schema/person.json"); + expect(results).toHaveLength(1); +}); + +test("loads multiple schema", async () => { + const results = await Loader.loadFiles("./tests/examples/schema/**.json"); + expect(results).toHaveLength(2); +}); + +test("gracefully handles malformed schema", async () => { + const results = await Loader.loadFiles( + "./tests/examples/schema-with-errors/malformed.json" + ); + expect(results).toHaveLength(0); +}); diff --git a/libs/events/node_modules/json-schema-static-docs/tests/merger.test.js b/libs/events/node_modules/json-schema-static-docs/tests/merger.test.js new file mode 100644 index 000000000..dc864129a --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/merger.test.js @@ -0,0 +1,217 @@ +const _ = require("lodash"); +const Merger = require("../lib/merger.js"); + +let unresolvedSchemas = [ + { + filename: "schema/file1.json", + data: { + $id: 1, + title: "1 unresolved", + properties: { property1: { $ref: "#/definitions/property1" } }, + definitions: { + property1: { + title: "Property 1", + type: "object", + properties: { property1_1: { type: "string" } }, + required: ["property1_1"], + }, + }, + }, + }, + { + filename: "schema/file2.json", + data: { + $id: 2, + title: "2 unresolved", + properties: { property2: { $ref: "#/definitions/property2" } }, + definitions: { property2: { $ref: "property2.json" } }, + }, + }, +]; +let resolvedSchemas = [ + { + filename: "schema/file2.json", + data: { + $id: 2, + title: "2 resolved", + properties: { property2: { title: "Property 2" } }, + required: [], + }, + }, + { + filename: "schema/file1.json", + data: { + $id: 1, + title: "1 resolved", + properties: { + property1: { + title: "Property 1", + type: "object", + properties: { property1_1: { type: "string" } }, + required: ["property1_1"], + }, + }, + required: ["property1"], + }, + }, +]; + +let unresolvedSchemas2 = [ + { + filename: "schema/file3.json", + data: { + $id: 3, + title: "3 unresolved", + properties: { property1: { $ref: "#/definitions/property1" } }, + definitions: { + property1: { + oneOf: [{ $ref: "property1.json" }, { $ref: "property2.json" }], + }, + }, + }, + }, +]; +let resolvedSchemas2 = [ + { + filename: "schema/file3.json", + data: { + $id: 3, + title: "3 resolved", + properties: { + property1: { + oneOf: [ + { + title: "oneOfProperty1", + }, + { + title: "oneOfProperty2", + }, + ], + }, + }, + required: [], + definitions: { + property1: { + oneOf: [ + { + title: "oneOfProperty1", + }, + { + title: "oneOfProperty2", + }, + ], + }, + }, + }, + }, +]; + +let unresolvedSchemas3 = [ + { + filename: "schema/file4.json", + data: { + $id: 4, + title: "4 unresolved", + properties: { property1: { $ref: "#/definitions/property1" } }, + definitions: { + property1: { + $ref: "property5.json", + }, + }, + }, + }, +]; + +let resolvedSchemas3 = [ + { + filename: "schema/file4.json", + data: { + $id: 4, + title: "4 unresolved", + properties: { + property1: { + type: "array", + items: { + properties: { + property2: { + type: "string", + }, + }, + }, + }, + }, + definitions: { + property1: { + $ref: "property5.json", + }, + }, + }, + }, +]; + +test("merges schemas", () => { + const results = Merger.mergeSchemas(unresolvedSchemas, resolvedSchemas); + expect(results).toHaveLength(2); + expect(results[0].filename).toBe("schema/file1.json"); + expect(results[0].schema.$id).toBe(1); + expect(results[1].filename).toBe("schema/file2.json"); + expect(results[1].schema.$id).toBe(2); + expect(results[0].schema.properties.property1.title).toBe("Property 1"); + expect(results[0].schema.properties.property1.$ref).toBe( + "#/definitions/property1" + ); + expect(results[1].schema.properties.property2.title).toBe("Property 2"); + expect(results[1].schema.properties.property2.$ref).toBe("property2.json"); +}); + +test("sets $ref in definitions containing OneOf", () => { + const results = Merger.mergeSchemas(unresolvedSchemas2, resolvedSchemas2); + expect(results).toHaveLength(1); + expect(results[0].filename).toBe("schema/file3.json"); + expect(results[0].schema.$id).toBe(3); + let property = results[0].schema.properties.property1; + expect(property.oneOf.length).toBe(2); + expect(property.oneOf[0].title).toBe("oneOfProperty1"); + expect(property.oneOf[1].title).toBe("oneOfProperty2"); +}); + +test("XXX sets isRequired on each schama property", () => { + const results = Merger.mergeSchemas(unresolvedSchemas, resolvedSchemas); + expect(results).toHaveLength(2); + expect(results[0].schema.properties.property1.isRequired).toBe(true); + expect( + results[0].schema.properties.property1.properties.property1_1.isRequired + ).toBe(true); + expect(results[1].schema.properties.property2.isRequired).toBe(false); +}); + +test("handles schema with no properties", () => { + let unresolvedSchemasWithNoProperties = _.cloneDeep(unresolvedSchemas); + let resolvedSchemasWithNoProperties = _.cloneDeep(resolvedSchemas); + + delete unresolvedSchemasWithNoProperties[0].data.properties; + delete unresolvedSchemasWithNoProperties[1].data.properties; + delete resolvedSchemasWithNoProperties[0].data.properties; + delete resolvedSchemasWithNoProperties[1].data.properties; + + const results = Merger.mergeSchemas( + unresolvedSchemasWithNoProperties, + resolvedSchemasWithNoProperties + ); + expect(results).toHaveLength(2); + expect(results[0].filename).toBe("schema/file1.json"); + expect(results[0].schema.$id).toBe(1); + expect(results[1].filename).toBe("schema/file2.json"); + expect(results[1].schema.$id).toBe(2); +}); + +test("sets $ref correctly when following two hops", () => { + let unresolvedSchemas = _.cloneDeep(unresolvedSchemas3); + let resolvedSchemas = _.cloneDeep(resolvedSchemas3); + + const results = Merger.mergeSchemas(unresolvedSchemas, resolvedSchemas); + expect(results).toHaveLength(1); + expect(results[0].filename).toBe("schema/file4.json"); + expect(results[0].schema.$id).toBe(4); + expect(results[0].schema.properties.property1.$ref).toBe("property5.json"); +}); diff --git a/libs/events/node_modules/json-schema-static-docs/tests/renderer-markdown.test.js b/libs/events/node_modules/json-schema-static-docs/tests/renderer-markdown.test.js new file mode 100644 index 000000000..e45ad32f6 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/renderer-markdown.test.js @@ -0,0 +1,233 @@ +const fs = require("fs"); +const path = require("path"); +const rimraf = require("rimraf"); +const _ = require("lodash"); + +const RendererMarkdown = require("../lib/renderer-markdown.js"); + +let defaultTemplatePath = path.join(__dirname, "../templates"); +let rendererMarkdown; + +let defaultMergedSchema = { + schema: { + title: "My Schema", + properties: { + property1: { + title: "Property 1", + type: "string", + isRequired: true, + enum: ["foo", "bar", 42, null], + }, + property2: { + title: "Property 2", + type: ["string", "integer"], + isRequired: false, + }, + property3: { + type: "array", + title: "Property 3", + $ref: "property3.json", + items: { + type: "String", + }, + }, + property4: { + title: "Property 4", + type: "string", + isRequired: true, + enum: ["foo", 42], + "meta:enum": { + foo: "Description for foo", + 42: "Description for 42", + }, + }, + property5: { + title: "Property 5", + type: "object", + isRequired: true, + properties: { + "property5.1": { + type: "object", + properties: { + "property5.1.1": { + type: "string", + }, + }, + }, + }, + }, + }, + }, +}; +const defaultMergedSchemaWithConst = { + schema: { + title: "My Schema", + properties: { + property1: { + title: "Property 1", + type: "string", + const: "foo", + }, + }, + }, +}; +let mergedSchema = {}; + +const removeFormatting = (value) => { + return value.replace(/\n/g, "").replace(/ + { + mergedSchema = _.cloneDeep(defaultMergedSchema); +}); + +test("renders title", async () => { + expect.assertions(1); + rendererMarkdown = new RendererMarkdown(defaultTemplatePath); + await rendererMarkdown.setup(); + let result = rendererMarkdown.renderSchema(mergedSchema); + expect(result).toEqual( + expect.stringContaining("# " + mergedSchema.schema.title) + ); +}); + +test("renders attributes", async () => { + expect.assertions(1); + rendererMarkdown = new RendererMarkdown(defaultTemplatePath); + await rendererMarkdown.setup(); + let result = rendererMarkdown.renderSchema(mergedSchema); + + result = result.match(/## Properties(.*\n)*/)[0]; + result = removeFormatting(result); + + let expectedText = + "## Properties" + + '' + + '' + + '' + + '' + + '' + + '' + + "
    NameType
    property1String
    property2[string, integer]
    property3Array [property3.html]
    property4String
    property5Object
    "; + + expect(result).toContain(expectedText); +}); + +test("renders attributes with const", async () => { + expect.assertions(1); + rendererMarkdown = new RendererMarkdown(defaultTemplatePath); + await rendererMarkdown.setup(); + let result = rendererMarkdown.renderSchema(defaultMergedSchemaWithConst); + + result = result.match(/## Properties(.*\n)*/)[0]; + result = removeFormatting(result); + + let expectedText = + "## Properties" + + '' + + '' + + "
    NameType
    property1String=foo
    "; + + expect(result).toContain(expectedText); +}); + +// tests recursive rendering of nested properties +test("renders nested property title correctly", async () => { + expect.assertions(1); + rendererMarkdown = new RendererMarkdown(defaultTemplatePath); + await rendererMarkdown.setup(); + let result = rendererMarkdown.renderSchema(mergedSchema); + + result = result.match(/## property5(.*\n)*/)[0]; + result = removeFormatting(result); + + let expectedText = + 'TitleProperty 5' + + 'TypeObject' + + 'RequiredYes' + + "" + + "### Properties" + + '' + + '' + + "
    NameType
    property5.1Object
    " + + "### property5.property5.1" + + "" + + '
    TypeObject
    ' + + "### property5.property5.1.property5.1.1" + + "" + + '
    TypeString
    '; + + expect(result).toContain(expectedText); +}); + +test("renders string property enums", async () => { + expect.assertions(1); + rendererMarkdown = new RendererMarkdown(defaultTemplatePath); + await rendererMarkdown.setup(); + let result = rendererMarkdown.renderSchema(mergedSchema); + + result = result.match(/## property1(.*\n)*/)[0]; + result = removeFormatting(result); + + let expectedText = + 'TitleProperty 1' + + 'TypeString' + + 'RequiredYes' + + 'Enum
    • foo
    • bar
    • 42
    • null
    '; + + expect(result).toContain(expectedText); +}); + +test("renders string property enums with meta description", async () => { + expect.assertions(1); + rendererMarkdown = new RendererMarkdown(defaultTemplatePath); + await rendererMarkdown.setup(); + let result = rendererMarkdown.renderSchema(mergedSchema); + + result = result.match(/## property4(.*\n)*/)[0]; + result = removeFormatting(result); + + let expectedText = + 'TitleProperty 4' + + 'TypeString' + + 'RequiredYes' + + 'Enum
    42
    Description for 42
    foo
    Description for foo
    '; + + expect(result).toContain(expectedText); +}); + +test("renders string property with const", async () => { + expect.assertions(1); + mergedSchema = _.cloneDeep(defaultMergedSchemaWithConst); + rendererMarkdown = new RendererMarkdown(defaultTemplatePath); + await rendererMarkdown.setup(); + let result = rendererMarkdown.renderSchema(mergedSchema); + + result = result.match(/## property1(.*\n)*/)[0]; + result = removeFormatting(result); + + let expectedText = + 'TitleProperty 1' + + 'TypeString' + + 'Constfoo'; + + expect(result).toContain(expectedText); +}); + +test("renders array property types", async () => { + expect.assertions(2); + rendererMarkdown = new RendererMarkdown(defaultTemplatePath); + await rendererMarkdown.setup(); + let result = rendererMarkdown.renderSchema(mergedSchema); + + result = result.match(/## property3(.*\n)*/)[0]; + result = removeFormatting(result); + + let expectedTitle = 'TitleProperty 3'; + expect(result).toEqual(expect.stringContaining(expectedTitle)); + + let expectedType = + 'TypeArray [property3.html]'; + + expect(result).toContain(expectedType); +}); diff --git a/libs/events/node_modules/json-schema-static-docs/tests/renderer/helpers.test.js b/libs/events/node_modules/json-schema-static-docs/tests/renderer/helpers.test.js new file mode 100644 index 000000000..cf7a19914 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/renderer/helpers.test.js @@ -0,0 +1,164 @@ +const { + getHtmlAnchorForRef, + getLabelForProperty, +} = require("../../lib/renderer/helpers.js"); + +describe("renderer helpers", () => { + describe("getHtmlAnchorForRef", () => { + describe("handles $ref only to relative file", () => { + const result = getHtmlAnchorForRef("../foo.json"); + expect(result).toBe('../foo.html'); + }); + describe("handles $ref only to relative file with an anchor", () => { + const result = getHtmlAnchorForRef("../foo.json#/definitions/bar"); + expect(result).toBe('../foo.html#bar'); + }); + describe("handles $ref only to relative file with an anchor converting to lower case", () => { + const result = getHtmlAnchorForRef("../foo.json#/definitions/barHumbug"); + expect(result).toBe( + '../foo.html#barhumbug' + ); + }); + describe("handles $ref only to relative file at the same level", () => { + const result = getHtmlAnchorForRef("../foo.json"); + expect(result).toBe('../foo.html'); + }); + describe("handles $ref only to relative file at the same level with an anchor", () => { + const result = getHtmlAnchorForRef("../foo.json#/definitions/bar"); + expect(result).toBe('../foo.html#bar'); + }); + }); + describe("propertyToTypeLabel", () => { + describe("simple property", () => { + test("returns expected result for a string property", async () => { + const property = { + type: "string", + }; + const result = getLabelForProperty(property); + expect(result).toBe("String"); + }); + test("returns expected result for a number property", async () => { + const property = { + type: "number", + }; + const result = getLabelForProperty(property); + expect(result).toBe("Number"); + }); + }); + describe("simple property with $ref", () => { + test("returns expected result for a string with a local $ref", async () => { + const property = { + type: "string", + $ref: "#/definitions/foo", + }; + const result = getLabelForProperty(property); + expect(result).toBe("String"); + }); + + test("returns expected result for a string with a relative $ref", async () => { + const property = { + type: "string", + $ref: "../foo.json#/definitions/bar", + }; + const result = getLabelForProperty(property); + expect(result).toBe("String"); + }); + + test("returns expected result for a string with a http $ref", async () => { + const property = { + type: "string", + $ref: "http://example.com/foo.json#/definitions/bar", + }; + const result = getLabelForProperty(property); + expect(result).toBe("String"); + }); + }); + + describe("object property", () => { + test("returns expected result for an object property", async () => { + const property = { + type: "object", + }; + const result = getLabelForProperty(property); + expect(result).toBe("Object"); + }); + + test("returns expected result for a object with a local $ref", async () => { + const property = { + type: "object", + $ref: "#/definitions/foo", + }; + const result = getLabelForProperty(property); + expect(result).toBe("Object"); + }); + + test("returns expected result for a object with a local $ref and a title", async () => { + const property = { + type: "object", + $ref: "#/definitions/foo", + title: "Foo", + }; + const result = getLabelForProperty(property); + expect(result).toBe("Object"); + }); + + test("returns expected result for a object with a relative $ref", async () => { + const property = { + type: "object", + $ref: "../foo.json#/definitions/bar", + }; + const result = getLabelForProperty(property); + expect(result).toBe( + 'Object (of type ../foo.html#bar)' + ); + }); + test("returns expected result for a object with a relative $ref at the same directory level", async () => { + const property = { + type: "object", + $ref: "foo.json", + }; + const result = getLabelForProperty(property); + expect(result).toBe('Object (of type foo.html)'); + }); + test("returns expected result for a object with a relative $ref at the same directory level with an anchor", async () => { + const property = { + type: "object", + $ref: "foo.json#/definitions/bar", + }; + const result = getLabelForProperty(property); + expect(result).toBe( + 'Object (of type foo.html#bar)' + ); + }); + test("returns expected result for a object with a relative $ref and a title", async () => { + const property = { + type: "object", + $ref: "../foo.json#/definitions/bar", + title: "Foo", + }; + const result = getLabelForProperty(property); + expect(result).toBe( + 'Object (of type Foo)' + ); + }); + + test("returns expected result for a object with a http $ref", async () => { + const property = { + type: "object", + $ref: "http://example.com/foo.json#/definitions/bar", + }; + const result = getLabelForProperty(property); + expect(result).toBe("Object"); + }); + test("returns expected result for a object with a http $ref and a title", async () => { + const property = { + type: "object", + $ref: "http://example.com/foo.json#/definitions/bar", + title: "Foo", + }; + const result = getLabelForProperty(property); + expect(result).toBe("Object"); + }); + }); + }); +}); diff --git a/libs/events/node_modules/json-schema-static-docs/tests/resolver.test.js b/libs/events/node_modules/json-schema-static-docs/tests/resolver.test.js new file mode 100644 index 000000000..59649bb20 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/resolver.test.js @@ -0,0 +1,24 @@ +const Resolver = require("../lib/resolver.js"); + +test("resolves single schema", async () => { + const result = await Resolver.resolveSchema( + "./tests/examples/schema/person.json" + ); + expect(result.properties.name.$ref).toBeUndefined(); + expect(result.properties.name.$id).toBe( + "http://example.com/schemas/name.json" + ); +}); + +test("resolves multiple schemas", async () => { + const results = await Resolver.resolveSchemas( + "./tests/examples/schema/**.json" + ); + expect(results).toHaveLength(2); + expect(results[0].data.$id).toBe("http://example.com/schemas/name.json"); + expect(results[1].data.$id).toBe("http://example.com/schemas/person.json"); + expect(results[1].data.properties.name.$id).toBe( + "http://example.com/schemas/name.json" + ); + expect(results[1].data.properties.name.$ref).toBeUndefined(); +}); diff --git a/libs/events/node_modules/json-schema-static-docs/tests/utils.test.js b/libs/events/node_modules/json-schema-static-docs/tests/utils.test.js new file mode 100644 index 000000000..25f1b33a7 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/utils.test.js @@ -0,0 +1,41 @@ +const { determineSchemaRelativePath } = require("../lib/utils.js"); + +const path = require("path"); +const temp = path.join("./test/", "*/**.json"); +console.log("temp", temp); + +describe("Utils", () => { + describe("determineSchemaRelativePath", () => { + test("handles absolute schemaInputPath", () => { + const outputFilename = determineSchemaRelativePath( + "/Users/test/schema/foo/bar.json", + "/Users/test/schema" + ); + expect(outputFilename).toBe("foo/bar.json"); + }); + + test("handles absolute schemaInputPath with trailing slash", () => { + const outputFilename = determineSchemaRelativePath( + "/Users/test/schema/foo/bar.json", + "/Users/test/schema/" + ); + expect(outputFilename).toBe("foo/bar.json"); + }); + + test("handles relative schemaInputPath", () => { + const outputFilename = determineSchemaRelativePath( + "tests/examples/schema/foo/bar.json", + "tests/examples/schema" + ); + expect(outputFilename).toBe("foo/bar.json"); + }); + + test("handles relative schemaInputPath with trailing slash", () => { + const outputFilename = determineSchemaRelativePath( + "tests/examples/schema/foo/bar.json", + "tests/examples/schema/" + ); + expect(outputFilename).toBe("foo/bar.json"); + }); + }); +}); diff --git a/libs/events/node_modules/json-schema-static-docs/tests/validator.test.js b/libs/events/node_modules/json-schema-static-docs/tests/validator.test.js new file mode 100644 index 000000000..f54c45424 --- /dev/null +++ b/libs/events/node_modules/json-schema-static-docs/tests/validator.test.js @@ -0,0 +1,60 @@ +const _ = require("lodash"); +const Validator = require("../lib/validator.js"); + +let schema = { + $id: "1", + title: "1 unresolved", + type: "object", + properties: { + property1: { + type: ["string", "number"], + }, + additionalProperties: false, + }, + additionalProperties: false, +}; + +let dataValid = { + property1: "bar", +}; + +let dataInvalidAdditional = { + foo: "bar", +}; + +let dataInvalidType = { + property1: null, +}; + +const defaultOptions = { allowUnionTypes: true }; + +test("validates schemas and data", () => { + const validator = new Validator([schema], defaultOptions); + const result = validator.validateSchemaAndData(schema, dataValid); + expect(result).toBe(true); +}); + +test("fails with additional properties", () => { + expect.assertions(2); + const validator = new Validator([schema], defaultOptions); + let result; + try { + result = validator.validateSchemaAndData(schema, dataInvalidAdditional); + } catch (e) { + expect(e.length).toBe(1); + expect(e[0].keyword).toBe("additionalProperties"); + } +}); + +test("fails with invalid type", () => { + expect.assertions(3); + const validator = new Validator([schema], defaultOptions); + let result; + try { + result = validator.validateSchemaAndData(schema, dataInvalidType); + } catch (e) { + expect(e.length).toBe(1); + expect(e[0].keyword).toBe("type"); + expect(e[0].schemaPath).toBe("#/properties/property1/type"); + } +}); diff --git a/libs/events/node_modules/json-schema-traverse/.eslintrc.yml b/libs/events/node_modules/json-schema-traverse/.eslintrc.yml new file mode 100644 index 000000000..618559ab6 --- /dev/null +++ b/libs/events/node_modules/json-schema-traverse/.eslintrc.yml @@ -0,0 +1,27 @@ +extends: eslint:recommended +env: + node: true + browser: true +rules: + block-scoped-var: 2 + complexity: [2, 15] + curly: [2, multi-or-nest, consistent] + dot-location: [2, property] + dot-notation: 2 + indent: [2, 2, SwitchCase: 1] + linebreak-style: [2, unix] + new-cap: 2 + no-console: [2, allow: [warn, error]] + no-else-return: 2 + no-eq-null: 2 + no-fallthrough: 2 + no-invalid-this: 2 + no-return-assign: 2 + no-shadow: 1 + no-trailing-spaces: 2 + no-use-before-define: [2, nofunc] + quotes: [2, single, avoid-escape] + semi: [2, always] + strict: [2, global] + valid-jsdoc: [2, requireReturn: false] + no-control-regex: 0 diff --git a/libs/events/node_modules/json-schema-traverse/.github/FUNDING.yml b/libs/events/node_modules/json-schema-traverse/.github/FUNDING.yml new file mode 100644 index 000000000..44f80f417 --- /dev/null +++ b/libs/events/node_modules/json-schema-traverse/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: epoberezkin +tidelift: "npm/json-schema-traverse" diff --git a/libs/events/node_modules/json-schema-traverse/.github/workflows/build.yml b/libs/events/node_modules/json-schema-traverse/.github/workflows/build.yml new file mode 100644 index 000000000..f8ef5ba80 --- /dev/null +++ b/libs/events/node_modules/json-schema-traverse/.github/workflows/build.yml @@ -0,0 +1,28 @@ +name: build + +on: + push: + branches: [master] + pull_request: + branches: ["*"] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [10.x, 12.x, 14.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/libs/events/node_modules/json-schema-traverse/.github/workflows/publish.yml b/libs/events/node_modules/json-schema-traverse/.github/workflows/publish.yml new file mode 100644 index 000000000..924825b12 --- /dev/null +++ b/libs/events/node_modules/json-schema-traverse/.github/workflows/publish.yml @@ -0,0 +1,27 @@ +name: publish + +on: + release: + types: [published] + +jobs: + publish-npm: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + registry-url: https://registry.npmjs.org/ + - run: npm install + - run: npm test + - name: Publish beta version to npm + if: "github.event.release.prerelease" + run: npm publish --tag beta + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish to npm + if: "!github.event.release.prerelease" + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/libs/events/node_modules/json-schema-traverse/LICENSE b/libs/events/node_modules/json-schema-traverse/LICENSE new file mode 100644 index 000000000..7f1543566 --- /dev/null +++ b/libs/events/node_modules/json-schema-traverse/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Evgeny Poberezkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/events/node_modules/json-schema-traverse/README.md b/libs/events/node_modules/json-schema-traverse/README.md new file mode 100644 index 000000000..f3e60073a --- /dev/null +++ b/libs/events/node_modules/json-schema-traverse/README.md @@ -0,0 +1,95 @@ +# json-schema-traverse +Traverse JSON Schema passing each schema object to callback + +[![build](https://github.com/epoberezkin/json-schema-traverse/workflows/build/badge.svg)](https://github.com/epoberezkin/json-schema-traverse/actions?query=workflow%3Abuild) +[![npm](https://img.shields.io/npm/v/json-schema-traverse)](https://www.npmjs.com/package/json-schema-traverse) +[![coverage](https://coveralls.io/repos/github/epoberezkin/json-schema-traverse/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/json-schema-traverse?branch=master) + + +## Install + +``` +npm install json-schema-traverse +``` + + +## Usage + +```javascript +const traverse = require('json-schema-traverse'); +const schema = { + properties: { + foo: {type: 'string'}, + bar: {type: 'integer'} + } +}; + +traverse(schema, {cb}); +// cb is called 3 times with: +// 1. root schema +// 2. {type: 'string'} +// 3. {type: 'integer'} + +// Or: + +traverse(schema, {cb: {pre, post}}); +// pre is called 3 times with: +// 1. root schema +// 2. {type: 'string'} +// 3. {type: 'integer'} +// +// post is called 3 times with: +// 1. {type: 'string'} +// 2. {type: 'integer'} +// 3. root schema + +``` + +Callback function `cb` is called for each schema object (not including draft-06 boolean schemas), including the root schema, in pre-order traversal. Schema references ($ref) are not resolved, they are passed as is. Alternatively, you can pass a `{pre, post}` object as `cb`, and then `pre` will be called before traversing child elements, and `post` will be called after all child elements have been traversed. + +Callback is passed these parameters: + +- _schema_: the current schema object +- _JSON pointer_: from the root schema to the current schema object +- _root schema_: the schema passed to `traverse` object +- _parent JSON pointer_: from the root schema to the parent schema object (see below) +- _parent keyword_: the keyword inside which this schema appears (e.g. `properties`, `anyOf`, etc.) +- _parent schema_: not necessarily parent object/array; in the example above the parent schema for `{type: 'string'}` is the root schema +- _index/property_: index or property name in the array/object containing multiple schemas; in the example above for `{type: 'string'}` the property name is `'foo'` + + +## Traverse objects in all unknown keywords + +```javascript +const traverse = require('json-schema-traverse'); +const schema = { + mySchema: { + minimum: 1, + maximum: 2 + } +}; + +traverse(schema, {allKeys: true, cb}); +// cb is called 2 times with: +// 1. root schema +// 2. mySchema +``` + +Without option `allKeys: true` callback will be called only with root schema. + + +## Enterprise support + +json-schema-traverse package is a part of [Tidelift enterprise subscription](https://tidelift.com/subscription/pkg/npm-json-schema-traverse?utm_source=npm-json-schema-traverse&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - it provides a centralised commercial support to open-source software users, in addition to the support provided by software maintainers. + + +## Security contact + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. Please do NOT report security vulnerability via GitHub issues. + + +## License + +[MIT](https://github.com/epoberezkin/json-schema-traverse/blob/master/LICENSE) diff --git a/libs/events/node_modules/json-schema-traverse/index.d.ts b/libs/events/node_modules/json-schema-traverse/index.d.ts new file mode 100644 index 000000000..0772daedb --- /dev/null +++ b/libs/events/node_modules/json-schema-traverse/index.d.ts @@ -0,0 +1,40 @@ +declare function traverse( + schema: traverse.SchemaObject, + opts: traverse.Options, + cb?: traverse.Callback +): void; + +declare function traverse( + schema: traverse.SchemaObject, + cb: traverse.Callback +): void; + +declare namespace traverse { + interface SchemaObject { + $id?: string; + $schema?: string; + [x: string]: any; + } + + type Callback = ( + schema: SchemaObject, + jsonPtr: string, + rootSchema: SchemaObject, + parentJsonPtr?: string, + parentKeyword?: string, + parentSchema?: SchemaObject, + keyIndex?: string | number + ) => void; + + interface Options { + allKeys?: boolean; + cb?: + | Callback + | { + pre?: Callback; + post?: Callback; + }; + } +} + +export = traverse; diff --git a/libs/events/node_modules/json-schema-traverse/index.js b/libs/events/node_modules/json-schema-traverse/index.js new file mode 100644 index 000000000..e521bfa85 --- /dev/null +++ b/libs/events/node_modules/json-schema-traverse/index.js @@ -0,0 +1,93 @@ +'use strict'; + +var traverse = module.exports = function (schema, opts, cb) { + // Legacy support for v0.3.1 and earlier. + if (typeof opts == 'function') { + cb = opts; + opts = {}; + } + + cb = opts.cb || cb; + var pre = (typeof cb == 'function') ? cb : cb.pre || function() {}; + var post = cb.post || function() {}; + + _traverse(opts, pre, post, schema, '', schema); +}; + + +traverse.keywords = { + additionalItems: true, + items: true, + contains: true, + additionalProperties: true, + propertyNames: true, + not: true, + if: true, + then: true, + else: true +}; + +traverse.arrayKeywords = { + items: true, + allOf: true, + anyOf: true, + oneOf: true +}; + +traverse.propsKeywords = { + $defs: true, + definitions: true, + properties: true, + patternProperties: true, + dependencies: true +}; + +traverse.skipKeywords = { + default: true, + enum: true, + const: true, + required: true, + maximum: true, + minimum: true, + exclusiveMaximum: true, + exclusiveMinimum: true, + multipleOf: true, + maxLength: true, + minLength: true, + pattern: true, + format: true, + maxItems: true, + minItems: true, + uniqueItems: true, + maxProperties: true, + minProperties: true +}; + + +function _traverse(opts, pre, post, schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) { + if (schema && typeof schema == 'object' && !Array.isArray(schema)) { + pre(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex); + for (var key in schema) { + var sch = schema[key]; + if (Array.isArray(sch)) { + if (key in traverse.arrayKeywords) { + for (var i=0; i & Marc Bachmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/jsonpointer/README.md b/libs/events/node_modules/jsonpointer/README.md new file mode 100644 index 000000000..81c1c3960 --- /dev/null +++ b/libs/events/node_modules/jsonpointer/README.md @@ -0,0 +1,45 @@ +# JSON Pointer for Node.js + +This is an implementation of [JSON Pointer](https://tools.ietf.org/html/rfc6901). + +## CLI + +Looking to filter JSON from the command line? Check out [jsonpointer-cli](https://github.com/joeyespo/jsonpointer-cli). + +## Usage +```javascript +var jsonpointer = require('jsonpointer'); +var obj = { foo: 1, bar: { baz: 2}, qux: [3, 4, 5]}; + +jsonpointer.get(obj, '/foo'); // returns 1 +jsonpointer.get(obj, '/bar/baz'); // returns 2 +jsonpointer.get(obj, '/qux/0'); // returns 3 +jsonpointer.get(obj, '/qux/1'); // returns 4 +jsonpointer.get(obj, '/qux/2'); // returns 5 +jsonpointer.get(obj, '/quo'); // returns undefined + +jsonpointer.set(obj, '/foo', 6); // sets obj.foo = 6; +jsonpointer.set(obj, '/qux/-', 6) // sets obj.qux = [3, 4, 5, 6] + +var pointer = jsonpointer.compile('/foo') +pointer.get(obj) // returns 1 +pointer.set(obj, 1) // sets obj.foo = 1 +``` + +## Testing + + $ npm test + All tests pass. + $ + +[![Node.js CI](https://github.com/janl/node-jsonpointer/actions/workflows/node.js.yml/badge.svg)](https://github.com/janl/node-jsonpointer/actions/workflows/node.js.yml) + +## Author + +(c) 2011-2021 Jan Lehnardt & Marc Bachmann + +Thanks to all contributors. + +## License + +MIT License. diff --git a/libs/events/node_modules/jsonpointer/jsonpointer.d.ts b/libs/events/node_modules/jsonpointer/jsonpointer.d.ts new file mode 100644 index 000000000..705bebca0 --- /dev/null +++ b/libs/events/node_modules/jsonpointer/jsonpointer.d.ts @@ -0,0 +1,35 @@ +interface JSONPointer { + /** + * Looks up a JSON pointer in an object + */ + get(object: Object): any; + + + /** + * Set a value for a JSON pointer on object + */ + set(object: Object, value: any): void; +} + + +declare namespace JSONPointer { + /** + * Looks up a JSON pointer in an object + */ + function get(object: Object, pointer: string): any; + + + /** + * Set a value for a JSON pointer on object + */ + function set(object: Object, pointer: string, value: any): void; + + + /** + * Builds a JSONPointer instance from a pointer value. + */ + function compile(pointer: string): JSONPointer; +} + + +export = JSONPointer; diff --git a/libs/events/node_modules/jsonpointer/jsonpointer.js b/libs/events/node_modules/jsonpointer/jsonpointer.js new file mode 100644 index 000000000..dad907d76 --- /dev/null +++ b/libs/events/node_modules/jsonpointer/jsonpointer.js @@ -0,0 +1,100 @@ +var hasExcape = /~/ +var escapeMatcher = /~[01]/g +function escapeReplacer (m) { + switch (m) { + case '~1': return '/' + case '~0': return '~' + } + throw new Error('Invalid tilde escape: ' + m) +} + +function untilde (str) { + if (!hasExcape.test(str)) return str + return str.replace(escapeMatcher, escapeReplacer) +} + +function setter (obj, pointer, value) { + var part + var hasNextPart + + for (var p = 1, len = pointer.length; p < len;) { + if (pointer[p] === 'constructor' || pointer[p] === 'prototype' || pointer[p] === '__proto__') return obj + + part = untilde(pointer[p++]) + hasNextPart = len > p + + if (typeof obj[part] === 'undefined') { + // support setting of /- + if (Array.isArray(obj) && part === '-') { + part = obj.length + } + + // support nested objects/array when setting values + if (hasNextPart) { + if ((pointer[p] !== '' && pointer[p] < Infinity) || pointer[p] === '-') obj[part] = [] + else obj[part] = {} + } + } + + if (!hasNextPart) break + obj = obj[part] + } + + var oldValue = obj[part] + if (value === undefined) delete obj[part] + else obj[part] = value + return oldValue +} + +function compilePointer (pointer) { + if (typeof pointer === 'string') { + pointer = pointer.split('/') + if (pointer[0] === '') return pointer + throw new Error('Invalid JSON pointer.') + } else if (Array.isArray(pointer)) { + for (const part of pointer) { + if (typeof part !== 'string' && typeof part !== 'number') { + throw new Error('Invalid JSON pointer. Must be of type string or number.') + } + } + return pointer + } + + throw new Error('Invalid JSON pointer.') +} + +function get (obj, pointer) { + if (typeof obj !== 'object') throw new Error('Invalid input object.') + pointer = compilePointer(pointer) + var len = pointer.length + if (len === 1) return obj + + for (var p = 1; p < len;) { + obj = obj[untilde(pointer[p++])] + if (len === p) return obj + if (typeof obj !== 'object' || obj === null) return undefined + } +} + +function set (obj, pointer, value) { + if (typeof obj !== 'object') throw new Error('Invalid input object.') + pointer = compilePointer(pointer) + if (pointer.length === 0) throw new Error('Invalid JSON pointer for set.') + return setter(obj, pointer, value) +} + +function compile (pointer) { + var compiled = compilePointer(pointer) + return { + get: function (object) { + return get(object, compiled) + }, + set: function (object, value) { + return set(object, compiled, value) + } + } +} + +exports.get = get +exports.set = set +exports.compile = compile diff --git a/libs/events/node_modules/jsonpointer/package.json b/libs/events/node_modules/jsonpointer/package.json new file mode 100644 index 000000000..a832ba9fc --- /dev/null +++ b/libs/events/node_modules/jsonpointer/package.json @@ -0,0 +1,48 @@ +{ + "name": "jsonpointer", + "description": "Simple JSON Addressing.", + "tags": [ + "util", + "simple", + "util", + "utility" + ], + "version": "5.0.1", + "author": "Jan Lehnardt ", + "contributors": [ + "Joe Hildebrand ", + "Marc Bachmann " + ], + "repository": { + "type": "git", + "url": "https://github.com/janl/node-jsonpointer.git" + }, + "bugs": { + "url": "http://github.com/janl/node-jsonpointer/issues" + }, + "engines": { + "node": ">=0.10.0" + }, + "main": "./jsonpointer", + "typings": "jsonpointer.d.ts", + "files": [ + "jsonpointer.js", + "jsonpointer.d.ts" + ], + "scripts": { + "test": "npm run test:standard && npm run test:all", + "test:standard": "standard", + "test:all": "node test.js", + "semantic-release": "semantic-release pre && npm publish && semantic-release post" + }, + "license": "MIT", + "devDependencies": { + "semantic-release": "^18.0.0", + "standard": "^16.0.4" + }, + "standard": { + "ignore": [ + "test.js" + ] + } +} diff --git a/libs/events/node_modules/lodash.clonedeep/LICENSE b/libs/events/node_modules/lodash.clonedeep/LICENSE new file mode 100644 index 000000000..e0c69d560 --- /dev/null +++ b/libs/events/node_modules/lodash.clonedeep/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/libs/events/node_modules/lodash.clonedeep/README.md b/libs/events/node_modules/lodash.clonedeep/README.md new file mode 100644 index 000000000..fee48e470 --- /dev/null +++ b/libs/events/node_modules/lodash.clonedeep/README.md @@ -0,0 +1,18 @@ +# lodash.clonedeep v4.5.0 + +The [lodash](https://lodash.com/) method `_.cloneDeep` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.clonedeep +``` + +In Node.js: +```js +var cloneDeep = require('lodash.clonedeep'); +``` + +See the [documentation](https://lodash.com/docs#cloneDeep) or [package source](https://github.com/lodash/lodash/blob/4.5.0-npm-packages/lodash.clonedeep) for more details. diff --git a/libs/events/node_modules/lodash.clonedeep/index.js b/libs/events/node_modules/lodash.clonedeep/index.js new file mode 100644 index 000000000..1b0e50298 --- /dev/null +++ b/libs/events/node_modules/lodash.clonedeep/index.js @@ -0,0 +1,1748 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = +cloneableTags[boolTag] = cloneableTags[dateTag] = +cloneableTags[float32Tag] = cloneableTags[float64Tag] = +cloneableTags[int8Tag] = cloneableTags[int16Tag] = +cloneableTags[int32Tag] = cloneableTags[mapTag] = +cloneableTags[numberTag] = cloneableTags[objectTag] = +cloneableTags[regexpTag] = cloneableTags[setTag] = +cloneableTags[stringTag] = cloneableTags[symbolTag] = +cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = +cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ +function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; +} + +/** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ +function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; +} + +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/** Used for built-in method references. */ +var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + +/* Built-in method references that are verified to be native. */ +var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; +} + +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; +} + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); +} + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; +} + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; +} + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); +} + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Stack(entries) { + this.__data__ = new ListCache(entries); +} + +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = new ListCache; +} + +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + return this.__data__['delete'](key); +} + +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} + +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} + +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ +function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; +} + +// Add methods to `Stack`. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; +} + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } +} + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); +} + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; +} + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; +} + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); +} + +/** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + return objectToString.call(value); +} + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; +} + +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ +function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); +} + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ +function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); +} + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} + +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; +} + +/** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); +} + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); +} + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +/** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +var getTag = baseGetTag; + +// Fallback for data views, maps, sets, and weak maps in IE 11, +// for data views in Edge < 14, and promises in Node.js. +if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; +} + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; +} + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return baseClone(value, true, true); +} + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ +function stubFalse() { + return false; +} + +module.exports = cloneDeep; diff --git a/libs/events/node_modules/lodash.clonedeep/package.json b/libs/events/node_modules/lodash.clonedeep/package.json new file mode 100644 index 000000000..fb1d626d5 --- /dev/null +++ b/libs/events/node_modules/lodash.clonedeep/package.json @@ -0,0 +1,17 @@ +{ + "name": "lodash.clonedeep", + "version": "4.5.0", + "description": "The lodash method `_.cloneDeep` exported as a module.", + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "keywords": "lodash-modularized, clonedeep", + "author": "John-David Dalton (http://allyoucanleet.com/)", + "contributors": [ + "John-David Dalton (http://allyoucanleet.com/)", + "Blaine Bublitz (https://github.com/phated)", + "Mathias Bynens (https://mathiasbynens.be/)" + ], + "repository": "lodash/lodash", + "scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" } +} diff --git a/libs/events/node_modules/lodash/LICENSE b/libs/events/node_modules/lodash/LICENSE new file mode 100644 index 000000000..77c42f140 --- /dev/null +++ b/libs/events/node_modules/lodash/LICENSE @@ -0,0 +1,47 @@ +Copyright OpenJS Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/libs/events/node_modules/lodash/README.md b/libs/events/node_modules/lodash/README.md new file mode 100644 index 000000000..3ab1a05ce --- /dev/null +++ b/libs/events/node_modules/lodash/README.md @@ -0,0 +1,39 @@ +# lodash v4.17.21 + +The [Lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules. + +## Installation + +Using npm: +```shell +$ npm i -g npm +$ npm i --save lodash +``` + +In Node.js: +```js +// Load the full build. +var _ = require('lodash'); +// Load the core build. +var _ = require('lodash/core'); +// Load the FP build for immutable auto-curried iteratee-first data-last methods. +var fp = require('lodash/fp'); + +// Load method categories. +var array = require('lodash/array'); +var object = require('lodash/fp/object'); + +// Cherry-pick methods for smaller browserify/rollup/webpack bundles. +var at = require('lodash/at'); +var curryN = require('lodash/fp/curryN'); +``` + +See the [package source](https://github.com/lodash/lodash/tree/4.17.21-npm) for more details. + +**Note:**
    +Install [n_](https://www.npmjs.com/package/n_) for Lodash use in the Node.js < 6 REPL. + +## Support + +Tested in Chrome 74-75, Firefox 66-67, IE 11, Edge 18, Safari 11-12, & Node.js 8-12.
    +Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. diff --git a/libs/events/node_modules/lodash/_DataView.js b/libs/events/node_modules/lodash/_DataView.js new file mode 100644 index 000000000..ac2d57ca6 --- /dev/null +++ b/libs/events/node_modules/lodash/_DataView.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var DataView = getNative(root, 'DataView'); + +module.exports = DataView; diff --git a/libs/events/node_modules/lodash/_Hash.js b/libs/events/node_modules/lodash/_Hash.js new file mode 100644 index 000000000..b504fe340 --- /dev/null +++ b/libs/events/node_modules/lodash/_Hash.js @@ -0,0 +1,32 @@ +var hashClear = require('./_hashClear'), + hashDelete = require('./_hashDelete'), + hashGet = require('./_hashGet'), + hashHas = require('./_hashHas'), + hashSet = require('./_hashSet'); + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +module.exports = Hash; diff --git a/libs/events/node_modules/lodash/_LazyWrapper.js b/libs/events/node_modules/lodash/_LazyWrapper.js new file mode 100644 index 000000000..81786c7f1 --- /dev/null +++ b/libs/events/node_modules/lodash/_LazyWrapper.js @@ -0,0 +1,28 @@ +var baseCreate = require('./_baseCreate'), + baseLodash = require('./_baseLodash'); + +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295; + +/** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ +function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; +} + +// Ensure `LazyWrapper` is an instance of `baseLodash`. +LazyWrapper.prototype = baseCreate(baseLodash.prototype); +LazyWrapper.prototype.constructor = LazyWrapper; + +module.exports = LazyWrapper; diff --git a/libs/events/node_modules/lodash/_ListCache.js b/libs/events/node_modules/lodash/_ListCache.js new file mode 100644 index 000000000..26895c3a8 --- /dev/null +++ b/libs/events/node_modules/lodash/_ListCache.js @@ -0,0 +1,32 @@ +var listCacheClear = require('./_listCacheClear'), + listCacheDelete = require('./_listCacheDelete'), + listCacheGet = require('./_listCacheGet'), + listCacheHas = require('./_listCacheHas'), + listCacheSet = require('./_listCacheSet'); + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +module.exports = ListCache; diff --git a/libs/events/node_modules/lodash/_LodashWrapper.js b/libs/events/node_modules/lodash/_LodashWrapper.js new file mode 100644 index 000000000..c1e4d9df7 --- /dev/null +++ b/libs/events/node_modules/lodash/_LodashWrapper.js @@ -0,0 +1,22 @@ +var baseCreate = require('./_baseCreate'), + baseLodash = require('./_baseLodash'); + +/** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable explicit method chain sequences. + */ +function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; +} + +LodashWrapper.prototype = baseCreate(baseLodash.prototype); +LodashWrapper.prototype.constructor = LodashWrapper; + +module.exports = LodashWrapper; diff --git a/libs/events/node_modules/lodash/_Map.js b/libs/events/node_modules/lodash/_Map.js new file mode 100644 index 000000000..b73f29a0f --- /dev/null +++ b/libs/events/node_modules/lodash/_Map.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'); + +module.exports = Map; diff --git a/libs/events/node_modules/lodash/_MapCache.js b/libs/events/node_modules/lodash/_MapCache.js new file mode 100644 index 000000000..4a4eea7bf --- /dev/null +++ b/libs/events/node_modules/lodash/_MapCache.js @@ -0,0 +1,32 @@ +var mapCacheClear = require('./_mapCacheClear'), + mapCacheDelete = require('./_mapCacheDelete'), + mapCacheGet = require('./_mapCacheGet'), + mapCacheHas = require('./_mapCacheHas'), + mapCacheSet = require('./_mapCacheSet'); + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +module.exports = MapCache; diff --git a/libs/events/node_modules/lodash/_Promise.js b/libs/events/node_modules/lodash/_Promise.js new file mode 100644 index 000000000..247b9e1ba --- /dev/null +++ b/libs/events/node_modules/lodash/_Promise.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var Promise = getNative(root, 'Promise'); + +module.exports = Promise; diff --git a/libs/events/node_modules/lodash/_Set.js b/libs/events/node_modules/lodash/_Set.js new file mode 100644 index 000000000..b3c8dcbf0 --- /dev/null +++ b/libs/events/node_modules/lodash/_Set.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var Set = getNative(root, 'Set'); + +module.exports = Set; diff --git a/libs/events/node_modules/lodash/_SetCache.js b/libs/events/node_modules/lodash/_SetCache.js new file mode 100644 index 000000000..6468b0647 --- /dev/null +++ b/libs/events/node_modules/lodash/_SetCache.js @@ -0,0 +1,27 @@ +var MapCache = require('./_MapCache'), + setCacheAdd = require('./_setCacheAdd'), + setCacheHas = require('./_setCacheHas'); + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; +SetCache.prototype.has = setCacheHas; + +module.exports = SetCache; diff --git a/libs/events/node_modules/lodash/_Stack.js b/libs/events/node_modules/lodash/_Stack.js new file mode 100644 index 000000000..80b2cf1b0 --- /dev/null +++ b/libs/events/node_modules/lodash/_Stack.js @@ -0,0 +1,27 @@ +var ListCache = require('./_ListCache'), + stackClear = require('./_stackClear'), + stackDelete = require('./_stackDelete'), + stackGet = require('./_stackGet'), + stackHas = require('./_stackHas'), + stackSet = require('./_stackSet'); + +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; +} + +// Add methods to `Stack`. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; + +module.exports = Stack; diff --git a/libs/events/node_modules/lodash/_Symbol.js b/libs/events/node_modules/lodash/_Symbol.js new file mode 100644 index 000000000..a013f7c5b --- /dev/null +++ b/libs/events/node_modules/lodash/_Symbol.js @@ -0,0 +1,6 @@ +var root = require('./_root'); + +/** Built-in value references. */ +var Symbol = root.Symbol; + +module.exports = Symbol; diff --git a/libs/events/node_modules/lodash/_Uint8Array.js b/libs/events/node_modules/lodash/_Uint8Array.js new file mode 100644 index 000000000..2fb30e157 --- /dev/null +++ b/libs/events/node_modules/lodash/_Uint8Array.js @@ -0,0 +1,6 @@ +var root = require('./_root'); + +/** Built-in value references. */ +var Uint8Array = root.Uint8Array; + +module.exports = Uint8Array; diff --git a/libs/events/node_modules/lodash/_WeakMap.js b/libs/events/node_modules/lodash/_WeakMap.js new file mode 100644 index 000000000..567f86c61 --- /dev/null +++ b/libs/events/node_modules/lodash/_WeakMap.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var WeakMap = getNative(root, 'WeakMap'); + +module.exports = WeakMap; diff --git a/libs/events/node_modules/lodash/_apply.js b/libs/events/node_modules/lodash/_apply.js new file mode 100644 index 000000000..36436dda5 --- /dev/null +++ b/libs/events/node_modules/lodash/_apply.js @@ -0,0 +1,21 @@ +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +module.exports = apply; diff --git a/libs/events/node_modules/lodash/_arrayAggregator.js b/libs/events/node_modules/lodash/_arrayAggregator.js new file mode 100644 index 000000000..d96c3ca47 --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayAggregator.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ +function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; +} + +module.exports = arrayAggregator; diff --git a/libs/events/node_modules/lodash/_arrayEach.js b/libs/events/node_modules/lodash/_arrayEach.js new file mode 100644 index 000000000..2c5f57968 --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayEach.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +module.exports = arrayEach; diff --git a/libs/events/node_modules/lodash/_arrayEachRight.js b/libs/events/node_modules/lodash/_arrayEachRight.js new file mode 100644 index 000000000..976ca5c29 --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayEachRight.js @@ -0,0 +1,21 @@ +/** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEachRight(array, iteratee) { + var length = array == null ? 0 : array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; +} + +module.exports = arrayEachRight; diff --git a/libs/events/node_modules/lodash/_arrayEvery.js b/libs/events/node_modules/lodash/_arrayEvery.js new file mode 100644 index 000000000..e26a91845 --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayEvery.js @@ -0,0 +1,23 @@ +/** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ +function arrayEvery(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; +} + +module.exports = arrayEvery; diff --git a/libs/events/node_modules/lodash/_arrayFilter.js b/libs/events/node_modules/lodash/_arrayFilter.js new file mode 100644 index 000000000..75ea25445 --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayFilter.js @@ -0,0 +1,25 @@ +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +module.exports = arrayFilter; diff --git a/libs/events/node_modules/lodash/_arrayIncludes.js b/libs/events/node_modules/lodash/_arrayIncludes.js new file mode 100644 index 000000000..3737a6d9e --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayIncludes.js @@ -0,0 +1,17 @@ +var baseIndexOf = require('./_baseIndexOf'); + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && baseIndexOf(array, value, 0) > -1; +} + +module.exports = arrayIncludes; diff --git a/libs/events/node_modules/lodash/_arrayIncludesWith.js b/libs/events/node_modules/lodash/_arrayIncludesWith.js new file mode 100644 index 000000000..235fd9758 --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayIncludesWith.js @@ -0,0 +1,22 @@ +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +module.exports = arrayIncludesWith; diff --git a/libs/events/node_modules/lodash/_arrayLikeKeys.js b/libs/events/node_modules/lodash/_arrayLikeKeys.js new file mode 100644 index 000000000..b2ec9ce78 --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayLikeKeys.js @@ -0,0 +1,49 @@ +var baseTimes = require('./_baseTimes'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isBuffer = require('./isBuffer'), + isIndex = require('./_isIndex'), + isTypedArray = require('./isTypedArray'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; +} + +module.exports = arrayLikeKeys; diff --git a/libs/events/node_modules/lodash/_arrayMap.js b/libs/events/node_modules/lodash/_arrayMap.js new file mode 100644 index 000000000..22b22464e --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayMap.js @@ -0,0 +1,21 @@ +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +module.exports = arrayMap; diff --git a/libs/events/node_modules/lodash/_arrayPush.js b/libs/events/node_modules/lodash/_arrayPush.js new file mode 100644 index 000000000..7d742b383 --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayPush.js @@ -0,0 +1,20 @@ +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +module.exports = arrayPush; diff --git a/libs/events/node_modules/lodash/_arrayReduce.js b/libs/events/node_modules/lodash/_arrayReduce.js new file mode 100644 index 000000000..de8b79b28 --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayReduce.js @@ -0,0 +1,26 @@ +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +module.exports = arrayReduce; diff --git a/libs/events/node_modules/lodash/_arrayReduceRight.js b/libs/events/node_modules/lodash/_arrayReduceRight.js new file mode 100644 index 000000000..22d8976de --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayReduceRight.js @@ -0,0 +1,24 @@ +/** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array == null ? 0 : array.length; + if (initAccum && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; +} + +module.exports = arrayReduceRight; diff --git a/libs/events/node_modules/lodash/_arraySample.js b/libs/events/node_modules/lodash/_arraySample.js new file mode 100644 index 000000000..fcab0105e --- /dev/null +++ b/libs/events/node_modules/lodash/_arraySample.js @@ -0,0 +1,15 @@ +var baseRandom = require('./_baseRandom'); + +/** + * A specialized version of `_.sample` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @returns {*} Returns the random element. + */ +function arraySample(array) { + var length = array.length; + return length ? array[baseRandom(0, length - 1)] : undefined; +} + +module.exports = arraySample; diff --git a/libs/events/node_modules/lodash/_arraySampleSize.js b/libs/events/node_modules/lodash/_arraySampleSize.js new file mode 100644 index 000000000..8c7e364f5 --- /dev/null +++ b/libs/events/node_modules/lodash/_arraySampleSize.js @@ -0,0 +1,17 @@ +var baseClamp = require('./_baseClamp'), + copyArray = require('./_copyArray'), + shuffleSelf = require('./_shuffleSelf'); + +/** + * A specialized version of `_.sampleSize` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ +function arraySampleSize(array, n) { + return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); +} + +module.exports = arraySampleSize; diff --git a/libs/events/node_modules/lodash/_arrayShuffle.js b/libs/events/node_modules/lodash/_arrayShuffle.js new file mode 100644 index 000000000..46313a39b --- /dev/null +++ b/libs/events/node_modules/lodash/_arrayShuffle.js @@ -0,0 +1,15 @@ +var copyArray = require('./_copyArray'), + shuffleSelf = require('./_shuffleSelf'); + +/** + * A specialized version of `_.shuffle` for arrays. + * + * @private + * @param {Array} array The array to shuffle. + * @returns {Array} Returns the new shuffled array. + */ +function arrayShuffle(array) { + return shuffleSelf(copyArray(array)); +} + +module.exports = arrayShuffle; diff --git a/libs/events/node_modules/lodash/_arraySome.js b/libs/events/node_modules/lodash/_arraySome.js new file mode 100644 index 000000000..6fd02fd4a --- /dev/null +++ b/libs/events/node_modules/lodash/_arraySome.js @@ -0,0 +1,23 @@ +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +module.exports = arraySome; diff --git a/libs/events/node_modules/lodash/_asciiSize.js b/libs/events/node_modules/lodash/_asciiSize.js new file mode 100644 index 000000000..11d29c33a --- /dev/null +++ b/libs/events/node_modules/lodash/_asciiSize.js @@ -0,0 +1,12 @@ +var baseProperty = require('./_baseProperty'); + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = baseProperty('length'); + +module.exports = asciiSize; diff --git a/libs/events/node_modules/lodash/_asciiToArray.js b/libs/events/node_modules/lodash/_asciiToArray.js new file mode 100644 index 000000000..8e3dd5b47 --- /dev/null +++ b/libs/events/node_modules/lodash/_asciiToArray.js @@ -0,0 +1,12 @@ +/** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function asciiToArray(string) { + return string.split(''); +} + +module.exports = asciiToArray; diff --git a/libs/events/node_modules/lodash/_asciiWords.js b/libs/events/node_modules/lodash/_asciiWords.js new file mode 100644 index 000000000..d765f0f76 --- /dev/null +++ b/libs/events/node_modules/lodash/_asciiWords.js @@ -0,0 +1,15 @@ +/** Used to match words composed of alphanumeric characters. */ +var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; + +/** + * Splits an ASCII `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ +function asciiWords(string) { + return string.match(reAsciiWord) || []; +} + +module.exports = asciiWords; diff --git a/libs/events/node_modules/lodash/_assignMergeValue.js b/libs/events/node_modules/lodash/_assignMergeValue.js new file mode 100644 index 000000000..cb1185e99 --- /dev/null +++ b/libs/events/node_modules/lodash/_assignMergeValue.js @@ -0,0 +1,20 @@ +var baseAssignValue = require('./_baseAssignValue'), + eq = require('./eq'); + +/** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } +} + +module.exports = assignMergeValue; diff --git a/libs/events/node_modules/lodash/_assignValue.js b/libs/events/node_modules/lodash/_assignValue.js new file mode 100644 index 000000000..40839575b --- /dev/null +++ b/libs/events/node_modules/lodash/_assignValue.js @@ -0,0 +1,28 @@ +var baseAssignValue = require('./_baseAssignValue'), + eq = require('./eq'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } +} + +module.exports = assignValue; diff --git a/libs/events/node_modules/lodash/_assocIndexOf.js b/libs/events/node_modules/lodash/_assocIndexOf.js new file mode 100644 index 000000000..5b77a2bdd --- /dev/null +++ b/libs/events/node_modules/lodash/_assocIndexOf.js @@ -0,0 +1,21 @@ +var eq = require('./eq'); + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +module.exports = assocIndexOf; diff --git a/libs/events/node_modules/lodash/_baseAggregator.js b/libs/events/node_modules/lodash/_baseAggregator.js new file mode 100644 index 000000000..4bc9e91f4 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseAggregator.js @@ -0,0 +1,21 @@ +var baseEach = require('./_baseEach'); + +/** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ +function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; +} + +module.exports = baseAggregator; diff --git a/libs/events/node_modules/lodash/_baseAssign.js b/libs/events/node_modules/lodash/_baseAssign.js new file mode 100644 index 000000000..e5c4a1a5b --- /dev/null +++ b/libs/events/node_modules/lodash/_baseAssign.js @@ -0,0 +1,17 @@ +var copyObject = require('./_copyObject'), + keys = require('./keys'); + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); +} + +module.exports = baseAssign; diff --git a/libs/events/node_modules/lodash/_baseAssignIn.js b/libs/events/node_modules/lodash/_baseAssignIn.js new file mode 100644 index 000000000..6624f9006 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseAssignIn.js @@ -0,0 +1,17 @@ +var copyObject = require('./_copyObject'), + keysIn = require('./keysIn'); + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && copyObject(source, keysIn(source), object); +} + +module.exports = baseAssignIn; diff --git a/libs/events/node_modules/lodash/_baseAssignValue.js b/libs/events/node_modules/lodash/_baseAssignValue.js new file mode 100644 index 000000000..d6f66ef3a --- /dev/null +++ b/libs/events/node_modules/lodash/_baseAssignValue.js @@ -0,0 +1,25 @@ +var defineProperty = require('./_defineProperty'); + +/** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } +} + +module.exports = baseAssignValue; diff --git a/libs/events/node_modules/lodash/_baseAt.js b/libs/events/node_modules/lodash/_baseAt.js new file mode 100644 index 000000000..90e4237a0 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseAt.js @@ -0,0 +1,23 @@ +var get = require('./get'); + +/** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths to pick. + * @returns {Array} Returns the picked elements. + */ +function baseAt(object, paths) { + var index = -1, + length = paths.length, + result = Array(length), + skip = object == null; + + while (++index < length) { + result[index] = skip ? undefined : get(object, paths[index]); + } + return result; +} + +module.exports = baseAt; diff --git a/libs/events/node_modules/lodash/_baseClamp.js b/libs/events/node_modules/lodash/_baseClamp.js new file mode 100644 index 000000000..a1c569292 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseClamp.js @@ -0,0 +1,22 @@ +/** + * The base implementation of `_.clamp` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ +function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; +} + +module.exports = baseClamp; diff --git a/libs/events/node_modules/lodash/_baseClone.js b/libs/events/node_modules/lodash/_baseClone.js new file mode 100644 index 000000000..69f87054c --- /dev/null +++ b/libs/events/node_modules/lodash/_baseClone.js @@ -0,0 +1,166 @@ +var Stack = require('./_Stack'), + arrayEach = require('./_arrayEach'), + assignValue = require('./_assignValue'), + baseAssign = require('./_baseAssign'), + baseAssignIn = require('./_baseAssignIn'), + cloneBuffer = require('./_cloneBuffer'), + copyArray = require('./_copyArray'), + copySymbols = require('./_copySymbols'), + copySymbolsIn = require('./_copySymbolsIn'), + getAllKeys = require('./_getAllKeys'), + getAllKeysIn = require('./_getAllKeysIn'), + getTag = require('./_getTag'), + initCloneArray = require('./_initCloneArray'), + initCloneByTag = require('./_initCloneByTag'), + initCloneObject = require('./_initCloneObject'), + isArray = require('./isArray'), + isBuffer = require('./isBuffer'), + isMap = require('./isMap'), + isObject = require('./isObject'), + isSet = require('./isSet'), + keys = require('./keys'), + keysIn = require('./keysIn'); + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = +cloneableTags[boolTag] = cloneableTags[dateTag] = +cloneableTags[float32Tag] = cloneableTags[float64Tag] = +cloneableTags[int8Tag] = cloneableTags[int16Tag] = +cloneableTags[int32Tag] = cloneableTags[mapTag] = +cloneableTags[numberTag] = cloneableTags[objectTag] = +cloneableTags[regexpTag] = cloneableTags[setTag] = +cloneableTags[stringTag] = cloneableTags[symbolTag] = +cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = +cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : initCloneObject(value); + if (!isDeep) { + return isFlat + ? copySymbolsIn(value, baseAssignIn(result, value)) + : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? getAllKeysIn : getAllKeys) + : (isFlat ? keysIn : keys); + + var props = isArr ? undefined : keysFunc(value); + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +module.exports = baseClone; diff --git a/libs/events/node_modules/lodash/_baseConforms.js b/libs/events/node_modules/lodash/_baseConforms.js new file mode 100644 index 000000000..947e20d40 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseConforms.js @@ -0,0 +1,18 @@ +var baseConformsTo = require('./_baseConformsTo'), + keys = require('./keys'); + +/** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new spec function. + */ +function baseConforms(source) { + var props = keys(source); + return function(object) { + return baseConformsTo(object, source, props); + }; +} + +module.exports = baseConforms; diff --git a/libs/events/node_modules/lodash/_baseConformsTo.js b/libs/events/node_modules/lodash/_baseConformsTo.js new file mode 100644 index 000000000..e449cb84b --- /dev/null +++ b/libs/events/node_modules/lodash/_baseConformsTo.js @@ -0,0 +1,27 @@ +/** + * The base implementation of `_.conformsTo` which accepts `props` to check. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + */ +function baseConformsTo(object, source, props) { + var length = props.length; + if (object == null) { + return !length; + } + object = Object(object); + while (length--) { + var key = props[length], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in object)) || !predicate(value)) { + return false; + } + } + return true; +} + +module.exports = baseConformsTo; diff --git a/libs/events/node_modules/lodash/_baseCreate.js b/libs/events/node_modules/lodash/_baseCreate.js new file mode 100644 index 000000000..ffa6a52ac --- /dev/null +++ b/libs/events/node_modules/lodash/_baseCreate.js @@ -0,0 +1,30 @@ +var isObject = require('./isObject'); + +/** Built-in value references. */ +var objectCreate = Object.create; + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ +var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; +}()); + +module.exports = baseCreate; diff --git a/libs/events/node_modules/lodash/_baseDelay.js b/libs/events/node_modules/lodash/_baseDelay.js new file mode 100644 index 000000000..1486d697e --- /dev/null +++ b/libs/events/node_modules/lodash/_baseDelay.js @@ -0,0 +1,21 @@ +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * The base implementation of `_.delay` and `_.defer` which accepts `args` + * to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Array} args The arguments to provide to `func`. + * @returns {number|Object} Returns the timer id or timeout object. + */ +function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); +} + +module.exports = baseDelay; diff --git a/libs/events/node_modules/lodash/_baseDifference.js b/libs/events/node_modules/lodash/_baseDifference.js new file mode 100644 index 000000000..343ac19f0 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseDifference.js @@ -0,0 +1,67 @@ +var SetCache = require('./_SetCache'), + arrayIncludes = require('./_arrayIncludes'), + arrayIncludesWith = require('./_arrayIncludesWith'), + arrayMap = require('./_arrayMap'), + baseUnary = require('./_baseUnary'), + cacheHas = require('./_cacheHas'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of methods like `_.difference` without support + * for excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ +function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; + + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee == null ? value : iteratee(value); + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); + } + else if (!includes(values, computed, comparator)) { + result.push(value); + } + } + return result; +} + +module.exports = baseDifference; diff --git a/libs/events/node_modules/lodash/_baseEach.js b/libs/events/node_modules/lodash/_baseEach.js new file mode 100644 index 000000000..512c06768 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseEach.js @@ -0,0 +1,14 @@ +var baseForOwn = require('./_baseForOwn'), + createBaseEach = require('./_createBaseEach'); + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = createBaseEach(baseForOwn); + +module.exports = baseEach; diff --git a/libs/events/node_modules/lodash/_baseEachRight.js b/libs/events/node_modules/lodash/_baseEachRight.js new file mode 100644 index 000000000..0a8feeca4 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseEachRight.js @@ -0,0 +1,14 @@ +var baseForOwnRight = require('./_baseForOwnRight'), + createBaseEach = require('./_createBaseEach'); + +/** + * The base implementation of `_.forEachRight` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEachRight = createBaseEach(baseForOwnRight, true); + +module.exports = baseEachRight; diff --git a/libs/events/node_modules/lodash/_baseEvery.js b/libs/events/node_modules/lodash/_baseEvery.js new file mode 100644 index 000000000..fa52f7bc7 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseEvery.js @@ -0,0 +1,21 @@ +var baseEach = require('./_baseEach'); + +/** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ +function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; +} + +module.exports = baseEvery; diff --git a/libs/events/node_modules/lodash/_baseExtremum.js b/libs/events/node_modules/lodash/_baseExtremum.js new file mode 100644 index 000000000..9d6aa77ed --- /dev/null +++ b/libs/events/node_modules/lodash/_baseExtremum.js @@ -0,0 +1,32 @@ +var isSymbol = require('./isSymbol'); + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !isSymbol(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +module.exports = baseExtremum; diff --git a/libs/events/node_modules/lodash/_baseFill.js b/libs/events/node_modules/lodash/_baseFill.js new file mode 100644 index 000000000..46ef9c761 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseFill.js @@ -0,0 +1,32 @@ +var toInteger = require('./toInteger'), + toLength = require('./toLength'); + +/** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ +function baseFill(array, value, start, end) { + var length = array.length; + + start = toInteger(start); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : toInteger(end); + if (end < 0) { + end += length; + } + end = start > end ? 0 : toLength(end); + while (start < end) { + array[start++] = value; + } + return array; +} + +module.exports = baseFill; diff --git a/libs/events/node_modules/lodash/_baseFilter.js b/libs/events/node_modules/lodash/_baseFilter.js new file mode 100644 index 000000000..467847736 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseFilter.js @@ -0,0 +1,21 @@ +var baseEach = require('./_baseEach'); + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +module.exports = baseFilter; diff --git a/libs/events/node_modules/lodash/_baseFindIndex.js b/libs/events/node_modules/lodash/_baseFindIndex.js new file mode 100644 index 000000000..e3f5d8aa2 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseFindIndex.js @@ -0,0 +1,24 @@ +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +module.exports = baseFindIndex; diff --git a/libs/events/node_modules/lodash/_baseFindKey.js b/libs/events/node_modules/lodash/_baseFindKey.js new file mode 100644 index 000000000..2e430f3a2 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseFindKey.js @@ -0,0 +1,23 @@ +/** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ +function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; +} + +module.exports = baseFindKey; diff --git a/libs/events/node_modules/lodash/_baseFlatten.js b/libs/events/node_modules/lodash/_baseFlatten.js new file mode 100644 index 000000000..4b1e009b1 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseFlatten.js @@ -0,0 +1,38 @@ +var arrayPush = require('./_arrayPush'), + isFlattenable = require('./_isFlattenable'); + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +module.exports = baseFlatten; diff --git a/libs/events/node_modules/lodash/_baseFor.js b/libs/events/node_modules/lodash/_baseFor.js new file mode 100644 index 000000000..d946590f8 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseFor.js @@ -0,0 +1,16 @@ +var createBaseFor = require('./_createBaseFor'); + +/** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseFor = createBaseFor(); + +module.exports = baseFor; diff --git a/libs/events/node_modules/lodash/_baseForOwn.js b/libs/events/node_modules/lodash/_baseForOwn.js new file mode 100644 index 000000000..503d52344 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseForOwn.js @@ -0,0 +1,16 @@ +var baseFor = require('./_baseFor'), + keys = require('./keys'); + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); +} + +module.exports = baseForOwn; diff --git a/libs/events/node_modules/lodash/_baseForOwnRight.js b/libs/events/node_modules/lodash/_baseForOwnRight.js new file mode 100644 index 000000000..a4b10e6c5 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseForOwnRight.js @@ -0,0 +1,16 @@ +var baseForRight = require('./_baseForRight'), + keys = require('./keys'); + +/** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); +} + +module.exports = baseForOwnRight; diff --git a/libs/events/node_modules/lodash/_baseForRight.js b/libs/events/node_modules/lodash/_baseForRight.js new file mode 100644 index 000000000..32842cd81 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseForRight.js @@ -0,0 +1,15 @@ +var createBaseFor = require('./_createBaseFor'); + +/** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseForRight = createBaseFor(true); + +module.exports = baseForRight; diff --git a/libs/events/node_modules/lodash/_baseFunctions.js b/libs/events/node_modules/lodash/_baseFunctions.js new file mode 100644 index 000000000..d23bc9b47 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseFunctions.js @@ -0,0 +1,19 @@ +var arrayFilter = require('./_arrayFilter'), + isFunction = require('./isFunction'); + +/** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the function names. + */ +function baseFunctions(object, props) { + return arrayFilter(props, function(key) { + return isFunction(object[key]); + }); +} + +module.exports = baseFunctions; diff --git a/libs/events/node_modules/lodash/_baseGet.js b/libs/events/node_modules/lodash/_baseGet.js new file mode 100644 index 000000000..a194913d2 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseGet.js @@ -0,0 +1,24 @@ +var castPath = require('./_castPath'), + toKey = require('./_toKey'); + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +module.exports = baseGet; diff --git a/libs/events/node_modules/lodash/_baseGetAllKeys.js b/libs/events/node_modules/lodash/_baseGetAllKeys.js new file mode 100644 index 000000000..8ad204ea4 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseGetAllKeys.js @@ -0,0 +1,20 @@ +var arrayPush = require('./_arrayPush'), + isArray = require('./isArray'); + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); +} + +module.exports = baseGetAllKeys; diff --git a/libs/events/node_modules/lodash/_baseGetTag.js b/libs/events/node_modules/lodash/_baseGetTag.js new file mode 100644 index 000000000..b927ccc17 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseGetTag.js @@ -0,0 +1,28 @@ +var Symbol = require('./_Symbol'), + getRawTag = require('./_getRawTag'), + objectToString = require('./_objectToString'); + +/** `Object#toString` result references. */ +var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); +} + +module.exports = baseGetTag; diff --git a/libs/events/node_modules/lodash/_baseGt.js b/libs/events/node_modules/lodash/_baseGt.js new file mode 100644 index 000000000..502d273ca --- /dev/null +++ b/libs/events/node_modules/lodash/_baseGt.js @@ -0,0 +1,14 @@ +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +module.exports = baseGt; diff --git a/libs/events/node_modules/lodash/_baseHas.js b/libs/events/node_modules/lodash/_baseHas.js new file mode 100644 index 000000000..1b730321c --- /dev/null +++ b/libs/events/node_modules/lodash/_baseHas.js @@ -0,0 +1,19 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && hasOwnProperty.call(object, key); +} + +module.exports = baseHas; diff --git a/libs/events/node_modules/lodash/_baseHasIn.js b/libs/events/node_modules/lodash/_baseHasIn.js new file mode 100644 index 000000000..2e0d04269 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseHasIn.js @@ -0,0 +1,13 @@ +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +module.exports = baseHasIn; diff --git a/libs/events/node_modules/lodash/_baseInRange.js b/libs/events/node_modules/lodash/_baseInRange.js new file mode 100644 index 000000000..ec9566618 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseInRange.js @@ -0,0 +1,18 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * The base implementation of `_.inRange` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ +function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); +} + +module.exports = baseInRange; diff --git a/libs/events/node_modules/lodash/_baseIndexOf.js b/libs/events/node_modules/lodash/_baseIndexOf.js new file mode 100644 index 000000000..167e706e7 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIndexOf.js @@ -0,0 +1,20 @@ +var baseFindIndex = require('./_baseFindIndex'), + baseIsNaN = require('./_baseIsNaN'), + strictIndexOf = require('./_strictIndexOf'); + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); +} + +module.exports = baseIndexOf; diff --git a/libs/events/node_modules/lodash/_baseIndexOfWith.js b/libs/events/node_modules/lodash/_baseIndexOfWith.js new file mode 100644 index 000000000..f815fe0dd --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIndexOfWith.js @@ -0,0 +1,23 @@ +/** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } + } + return -1; +} + +module.exports = baseIndexOfWith; diff --git a/libs/events/node_modules/lodash/_baseIntersection.js b/libs/events/node_modules/lodash/_baseIntersection.js new file mode 100644 index 000000000..c1d250c2a --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIntersection.js @@ -0,0 +1,74 @@ +var SetCache = require('./_SetCache'), + arrayIncludes = require('./_arrayIncludes'), + arrayIncludesWith = require('./_arrayIncludesWith'), + arrayMap = require('./_arrayMap'), + baseUnary = require('./_baseUnary'), + cacheHas = require('./_cacheHas'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ +function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + seen = caches[0]; + + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +module.exports = baseIntersection; diff --git a/libs/events/node_modules/lodash/_baseInverter.js b/libs/events/node_modules/lodash/_baseInverter.js new file mode 100644 index 000000000..fbc337f01 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseInverter.js @@ -0,0 +1,21 @@ +var baseForOwn = require('./_baseForOwn'); + +/** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ +function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function(value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; +} + +module.exports = baseInverter; diff --git a/libs/events/node_modules/lodash/_baseInvoke.js b/libs/events/node_modules/lodash/_baseInvoke.js new file mode 100644 index 000000000..49bcf3c35 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseInvoke.js @@ -0,0 +1,24 @@ +var apply = require('./_apply'), + castPath = require('./_castPath'), + last = require('./last'), + parent = require('./_parent'), + toKey = require('./_toKey'); + +/** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ +function baseInvoke(object, path, args) { + path = castPath(path, object); + object = parent(object, path); + var func = object == null ? object : object[toKey(last(path))]; + return func == null ? undefined : apply(func, object, args); +} + +module.exports = baseInvoke; diff --git a/libs/events/node_modules/lodash/_baseIsArguments.js b/libs/events/node_modules/lodash/_baseIsArguments.js new file mode 100644 index 000000000..b3562cca2 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsArguments.js @@ -0,0 +1,18 @@ +var baseGetTag = require('./_baseGetTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]'; + +/** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ +function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; +} + +module.exports = baseIsArguments; diff --git a/libs/events/node_modules/lodash/_baseIsArrayBuffer.js b/libs/events/node_modules/lodash/_baseIsArrayBuffer.js new file mode 100644 index 000000000..a2c4f30a8 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsArrayBuffer.js @@ -0,0 +1,17 @@ +var baseGetTag = require('./_baseGetTag'), + isObjectLike = require('./isObjectLike'); + +var arrayBufferTag = '[object ArrayBuffer]'; + +/** + * The base implementation of `_.isArrayBuffer` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + */ +function baseIsArrayBuffer(value) { + return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; +} + +module.exports = baseIsArrayBuffer; diff --git a/libs/events/node_modules/lodash/_baseIsDate.js b/libs/events/node_modules/lodash/_baseIsDate.js new file mode 100644 index 000000000..ba67c7857 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsDate.js @@ -0,0 +1,18 @@ +var baseGetTag = require('./_baseGetTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var dateTag = '[object Date]'; + +/** + * The base implementation of `_.isDate` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + */ +function baseIsDate(value) { + return isObjectLike(value) && baseGetTag(value) == dateTag; +} + +module.exports = baseIsDate; diff --git a/libs/events/node_modules/lodash/_baseIsEqual.js b/libs/events/node_modules/lodash/_baseIsEqual.js new file mode 100644 index 000000000..00a68a4f5 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsEqual.js @@ -0,0 +1,28 @@ +var baseIsEqualDeep = require('./_baseIsEqualDeep'), + isObjectLike = require('./isObjectLike'); + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +module.exports = baseIsEqual; diff --git a/libs/events/node_modules/lodash/_baseIsEqualDeep.js b/libs/events/node_modules/lodash/_baseIsEqualDeep.js new file mode 100644 index 000000000..e3cfd6a8d --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsEqualDeep.js @@ -0,0 +1,83 @@ +var Stack = require('./_Stack'), + equalArrays = require('./_equalArrays'), + equalByTag = require('./_equalByTag'), + equalObjects = require('./_equalObjects'), + getTag = require('./_getTag'), + isArray = require('./isArray'), + isBuffer = require('./isBuffer'), + isTypedArray = require('./isTypedArray'); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : getTag(object), + othTag = othIsArr ? arrayTag : getTag(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +module.exports = baseIsEqualDeep; diff --git a/libs/events/node_modules/lodash/_baseIsMap.js b/libs/events/node_modules/lodash/_baseIsMap.js new file mode 100644 index 000000000..02a4021ca --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsMap.js @@ -0,0 +1,18 @@ +var getTag = require('./_getTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; +} + +module.exports = baseIsMap; diff --git a/libs/events/node_modules/lodash/_baseIsMatch.js b/libs/events/node_modules/lodash/_baseIsMatch.js new file mode 100644 index 000000000..72494bed4 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsMatch.js @@ -0,0 +1,62 @@ +var Stack = require('./_Stack'), + baseIsEqual = require('./_baseIsEqual'); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +module.exports = baseIsMatch; diff --git a/libs/events/node_modules/lodash/_baseIsNaN.js b/libs/events/node_modules/lodash/_baseIsNaN.js new file mode 100644 index 000000000..316f1eb1e --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsNaN.js @@ -0,0 +1,12 @@ +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +module.exports = baseIsNaN; diff --git a/libs/events/node_modules/lodash/_baseIsNative.js b/libs/events/node_modules/lodash/_baseIsNative.js new file mode 100644 index 000000000..870233049 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsNative.js @@ -0,0 +1,47 @@ +var isFunction = require('./isFunction'), + isMasked = require('./_isMasked'), + isObject = require('./isObject'), + toSource = require('./_toSource'); + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +module.exports = baseIsNative; diff --git a/libs/events/node_modules/lodash/_baseIsRegExp.js b/libs/events/node_modules/lodash/_baseIsRegExp.js new file mode 100644 index 000000000..6cd7c1aee --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsRegExp.js @@ -0,0 +1,18 @@ +var baseGetTag = require('./_baseGetTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var regexpTag = '[object RegExp]'; + +/** + * The base implementation of `_.isRegExp` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + */ +function baseIsRegExp(value) { + return isObjectLike(value) && baseGetTag(value) == regexpTag; +} + +module.exports = baseIsRegExp; diff --git a/libs/events/node_modules/lodash/_baseIsSet.js b/libs/events/node_modules/lodash/_baseIsSet.js new file mode 100644 index 000000000..6dee36716 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsSet.js @@ -0,0 +1,18 @@ +var getTag = require('./_getTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return isObjectLike(value) && getTag(value) == setTag; +} + +module.exports = baseIsSet; diff --git a/libs/events/node_modules/lodash/_baseIsTypedArray.js b/libs/events/node_modules/lodash/_baseIsTypedArray.js new file mode 100644 index 000000000..1edb32ff3 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIsTypedArray.js @@ -0,0 +1,60 @@ +var baseGetTag = require('./_baseGetTag'), + isLength = require('./isLength'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = +typedArrayTags[errorTag] = typedArrayTags[funcTag] = +typedArrayTags[mapTag] = typedArrayTags[numberTag] = +typedArrayTags[objectTag] = typedArrayTags[regexpTag] = +typedArrayTags[setTag] = typedArrayTags[stringTag] = +typedArrayTags[weakMapTag] = false; + +/** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ +function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; +} + +module.exports = baseIsTypedArray; diff --git a/libs/events/node_modules/lodash/_baseIteratee.js b/libs/events/node_modules/lodash/_baseIteratee.js new file mode 100644 index 000000000..995c25756 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseIteratee.js @@ -0,0 +1,31 @@ +var baseMatches = require('./_baseMatches'), + baseMatchesProperty = require('./_baseMatchesProperty'), + identity = require('./identity'), + isArray = require('./isArray'), + property = require('./property'); + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); +} + +module.exports = baseIteratee; diff --git a/libs/events/node_modules/lodash/_baseKeys.js b/libs/events/node_modules/lodash/_baseKeys.js new file mode 100644 index 000000000..45e9e6f39 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseKeys.js @@ -0,0 +1,30 @@ +var isPrototype = require('./_isPrototype'), + nativeKeys = require('./_nativeKeys'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +module.exports = baseKeys; diff --git a/libs/events/node_modules/lodash/_baseKeysIn.js b/libs/events/node_modules/lodash/_baseKeysIn.js new file mode 100644 index 000000000..ea8a0a174 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseKeysIn.js @@ -0,0 +1,33 @@ +var isObject = require('./isObject'), + isPrototype = require('./_isPrototype'), + nativeKeysIn = require('./_nativeKeysIn'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +module.exports = baseKeysIn; diff --git a/libs/events/node_modules/lodash/_baseLodash.js b/libs/events/node_modules/lodash/_baseLodash.js new file mode 100644 index 000000000..f76c790e2 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseLodash.js @@ -0,0 +1,10 @@ +/** + * The function whose prototype chain sequence wrappers inherit from. + * + * @private + */ +function baseLodash() { + // No operation performed. +} + +module.exports = baseLodash; diff --git a/libs/events/node_modules/lodash/_baseLt.js b/libs/events/node_modules/lodash/_baseLt.js new file mode 100644 index 000000000..8674d2946 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseLt.js @@ -0,0 +1,14 @@ +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +module.exports = baseLt; diff --git a/libs/events/node_modules/lodash/_baseMap.js b/libs/events/node_modules/lodash/_baseMap.js new file mode 100644 index 000000000..0bf5cead5 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseMap.js @@ -0,0 +1,22 @@ +var baseEach = require('./_baseEach'), + isArrayLike = require('./isArrayLike'); + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +module.exports = baseMap; diff --git a/libs/events/node_modules/lodash/_baseMatches.js b/libs/events/node_modules/lodash/_baseMatches.js new file mode 100644 index 000000000..e56582ad8 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseMatches.js @@ -0,0 +1,22 @@ +var baseIsMatch = require('./_baseIsMatch'), + getMatchData = require('./_getMatchData'), + matchesStrictComparable = require('./_matchesStrictComparable'); + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; +} + +module.exports = baseMatches; diff --git a/libs/events/node_modules/lodash/_baseMatchesProperty.js b/libs/events/node_modules/lodash/_baseMatchesProperty.js new file mode 100644 index 000000000..24afd893d --- /dev/null +++ b/libs/events/node_modules/lodash/_baseMatchesProperty.js @@ -0,0 +1,33 @@ +var baseIsEqual = require('./_baseIsEqual'), + get = require('./get'), + hasIn = require('./hasIn'), + isKey = require('./_isKey'), + isStrictComparable = require('./_isStrictComparable'), + matchesStrictComparable = require('./_matchesStrictComparable'), + toKey = require('./_toKey'); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); + }; +} + +module.exports = baseMatchesProperty; diff --git a/libs/events/node_modules/lodash/_baseMean.js b/libs/events/node_modules/lodash/_baseMean.js new file mode 100644 index 000000000..fa9e00a0a --- /dev/null +++ b/libs/events/node_modules/lodash/_baseMean.js @@ -0,0 +1,20 @@ +var baseSum = require('./_baseSum'); + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** + * The base implementation of `_.mean` and `_.meanBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the mean. + */ +function baseMean(array, iteratee) { + var length = array == null ? 0 : array.length; + return length ? (baseSum(array, iteratee) / length) : NAN; +} + +module.exports = baseMean; diff --git a/libs/events/node_modules/lodash/_baseMerge.js b/libs/events/node_modules/lodash/_baseMerge.js new file mode 100644 index 000000000..c98b5eb0b --- /dev/null +++ b/libs/events/node_modules/lodash/_baseMerge.js @@ -0,0 +1,42 @@ +var Stack = require('./_Stack'), + assignMergeValue = require('./_assignMergeValue'), + baseFor = require('./_baseFor'), + baseMergeDeep = require('./_baseMergeDeep'), + isObject = require('./isObject'), + keysIn = require('./keysIn'), + safeGet = require('./_safeGet'); + +/** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ +function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); +} + +module.exports = baseMerge; diff --git a/libs/events/node_modules/lodash/_baseMergeDeep.js b/libs/events/node_modules/lodash/_baseMergeDeep.js new file mode 100644 index 000000000..4679e8dce --- /dev/null +++ b/libs/events/node_modules/lodash/_baseMergeDeep.js @@ -0,0 +1,94 @@ +var assignMergeValue = require('./_assignMergeValue'), + cloneBuffer = require('./_cloneBuffer'), + cloneTypedArray = require('./_cloneTypedArray'), + copyArray = require('./_copyArray'), + initCloneObject = require('./_initCloneObject'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLikeObject = require('./isArrayLikeObject'), + isBuffer = require('./isBuffer'), + isFunction = require('./isFunction'), + isObject = require('./isObject'), + isPlainObject = require('./isPlainObject'), + isTypedArray = require('./isTypedArray'), + safeGet = require('./_safeGet'), + toPlainObject = require('./toPlainObject'); + +/** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ +function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); +} + +module.exports = baseMergeDeep; diff --git a/libs/events/node_modules/lodash/_baseNth.js b/libs/events/node_modules/lodash/_baseNth.js new file mode 100644 index 000000000..0403c2a36 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseNth.js @@ -0,0 +1,20 @@ +var isIndex = require('./_isIndex'); + +/** + * The base implementation of `_.nth` which doesn't coerce arguments. + * + * @private + * @param {Array} array The array to query. + * @param {number} n The index of the element to return. + * @returns {*} Returns the nth element of `array`. + */ +function baseNth(array, n) { + var length = array.length; + if (!length) { + return; + } + n += n < 0 ? length : 0; + return isIndex(n, length) ? array[n] : undefined; +} + +module.exports = baseNth; diff --git a/libs/events/node_modules/lodash/_baseOrderBy.js b/libs/events/node_modules/lodash/_baseOrderBy.js new file mode 100644 index 000000000..775a01741 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseOrderBy.js @@ -0,0 +1,49 @@ +var arrayMap = require('./_arrayMap'), + baseGet = require('./_baseGet'), + baseIteratee = require('./_baseIteratee'), + baseMap = require('./_baseMap'), + baseSortBy = require('./_baseSortBy'), + baseUnary = require('./_baseUnary'), + compareMultiple = require('./_compareMultiple'), + identity = require('./identity'), + isArray = require('./isArray'); + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = arrayMap(iteratees, function(iteratee) { + if (isArray(iteratee)) { + return function(value) { + return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity]; + } + + var index = -1; + iteratees = arrayMap(iteratees, baseUnary(baseIteratee)); + + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); +} + +module.exports = baseOrderBy; diff --git a/libs/events/node_modules/lodash/_basePick.js b/libs/events/node_modules/lodash/_basePick.js new file mode 100644 index 000000000..09b458a60 --- /dev/null +++ b/libs/events/node_modules/lodash/_basePick.js @@ -0,0 +1,19 @@ +var basePickBy = require('./_basePickBy'), + hasIn = require('./hasIn'); + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return basePickBy(object, paths, function(value, path) { + return hasIn(object, path); + }); +} + +module.exports = basePick; diff --git a/libs/events/node_modules/lodash/_basePickBy.js b/libs/events/node_modules/lodash/_basePickBy.js new file mode 100644 index 000000000..85be68c84 --- /dev/null +++ b/libs/events/node_modules/lodash/_basePickBy.js @@ -0,0 +1,30 @@ +var baseGet = require('./_baseGet'), + baseSet = require('./_baseSet'), + castPath = require('./_castPath'); + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; +} + +module.exports = basePickBy; diff --git a/libs/events/node_modules/lodash/_baseProperty.js b/libs/events/node_modules/lodash/_baseProperty.js new file mode 100644 index 000000000..496281ec4 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseProperty.js @@ -0,0 +1,14 @@ +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +module.exports = baseProperty; diff --git a/libs/events/node_modules/lodash/_basePropertyDeep.js b/libs/events/node_modules/lodash/_basePropertyDeep.js new file mode 100644 index 000000000..1e5aae50c --- /dev/null +++ b/libs/events/node_modules/lodash/_basePropertyDeep.js @@ -0,0 +1,16 @@ +var baseGet = require('./_baseGet'); + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; +} + +module.exports = basePropertyDeep; diff --git a/libs/events/node_modules/lodash/_basePropertyOf.js b/libs/events/node_modules/lodash/_basePropertyOf.js new file mode 100644 index 000000000..461739990 --- /dev/null +++ b/libs/events/node_modules/lodash/_basePropertyOf.js @@ -0,0 +1,14 @@ +/** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyOf(object) { + return function(key) { + return object == null ? undefined : object[key]; + }; +} + +module.exports = basePropertyOf; diff --git a/libs/events/node_modules/lodash/_basePullAll.js b/libs/events/node_modules/lodash/_basePullAll.js new file mode 100644 index 000000000..305720ede --- /dev/null +++ b/libs/events/node_modules/lodash/_basePullAll.js @@ -0,0 +1,51 @@ +var arrayMap = require('./_arrayMap'), + baseIndexOf = require('./_baseIndexOf'), + baseIndexOfWith = require('./_baseIndexOfWith'), + baseUnary = require('./_baseUnary'), + copyArray = require('./_copyArray'); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + */ +function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; + + if (array === values) { + values = copyArray(values); + } + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; +} + +module.exports = basePullAll; diff --git a/libs/events/node_modules/lodash/_basePullAt.js b/libs/events/node_modules/lodash/_basePullAt.js new file mode 100644 index 000000000..c3e9e7102 --- /dev/null +++ b/libs/events/node_modules/lodash/_basePullAt.js @@ -0,0 +1,37 @@ +var baseUnset = require('./_baseUnset'), + isIndex = require('./_isIndex'); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * The base implementation of `_.pullAt` without support for individual + * indexes or capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ +function basePullAt(array, indexes) { + var length = array ? indexes.length : 0, + lastIndex = length - 1; + + while (length--) { + var index = indexes[length]; + if (length == lastIndex || index !== previous) { + var previous = index; + if (isIndex(index)) { + splice.call(array, index, 1); + } else { + baseUnset(array, index); + } + } + } + return array; +} + +module.exports = basePullAt; diff --git a/libs/events/node_modules/lodash/_baseRandom.js b/libs/events/node_modules/lodash/_baseRandom.js new file mode 100644 index 000000000..94f76a766 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseRandom.js @@ -0,0 +1,18 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeFloor = Math.floor, + nativeRandom = Math.random; + +/** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ +function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); +} + +module.exports = baseRandom; diff --git a/libs/events/node_modules/lodash/_baseRange.js b/libs/events/node_modules/lodash/_baseRange.js new file mode 100644 index 000000000..0fb8e419f --- /dev/null +++ b/libs/events/node_modules/lodash/_baseRange.js @@ -0,0 +1,28 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +module.exports = baseRange; diff --git a/libs/events/node_modules/lodash/_baseReduce.js b/libs/events/node_modules/lodash/_baseReduce.js new file mode 100644 index 000000000..5a1f8b57f --- /dev/null +++ b/libs/events/node_modules/lodash/_baseReduce.js @@ -0,0 +1,23 @@ +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +module.exports = baseReduce; diff --git a/libs/events/node_modules/lodash/_baseRepeat.js b/libs/events/node_modules/lodash/_baseRepeat.js new file mode 100644 index 000000000..ee44c31ab --- /dev/null +++ b/libs/events/node_modules/lodash/_baseRepeat.js @@ -0,0 +1,35 @@ +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeFloor = Math.floor; + +/** + * The base implementation of `_.repeat` which doesn't coerce arguments. + * + * @private + * @param {string} string The string to repeat. + * @param {number} n The number of times to repeat the string. + * @returns {string} Returns the repeated string. + */ +function baseRepeat(string, n) { + var result = ''; + if (!string || n < 1 || n > MAX_SAFE_INTEGER) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + if (n) { + string += string; + } + } while (n); + + return result; +} + +module.exports = baseRepeat; diff --git a/libs/events/node_modules/lodash/_baseRest.js b/libs/events/node_modules/lodash/_baseRest.js new file mode 100644 index 000000000..d0dc4bdd1 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseRest.js @@ -0,0 +1,17 @@ +var identity = require('./identity'), + overRest = require('./_overRest'), + setToString = require('./_setToString'); + +/** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ +function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); +} + +module.exports = baseRest; diff --git a/libs/events/node_modules/lodash/_baseSample.js b/libs/events/node_modules/lodash/_baseSample.js new file mode 100644 index 000000000..58582b911 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSample.js @@ -0,0 +1,15 @@ +var arraySample = require('./_arraySample'), + values = require('./values'); + +/** + * The base implementation of `_.sample`. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + */ +function baseSample(collection) { + return arraySample(values(collection)); +} + +module.exports = baseSample; diff --git a/libs/events/node_modules/lodash/_baseSampleSize.js b/libs/events/node_modules/lodash/_baseSampleSize.js new file mode 100644 index 000000000..5c90ec518 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSampleSize.js @@ -0,0 +1,18 @@ +var baseClamp = require('./_baseClamp'), + shuffleSelf = require('./_shuffleSelf'), + values = require('./values'); + +/** + * The base implementation of `_.sampleSize` without param guards. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ +function baseSampleSize(collection, n) { + var array = values(collection); + return shuffleSelf(array, baseClamp(n, 0, array.length)); +} + +module.exports = baseSampleSize; diff --git a/libs/events/node_modules/lodash/_baseSet.js b/libs/events/node_modules/lodash/_baseSet.js new file mode 100644 index 000000000..99f4fbf9c --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSet.js @@ -0,0 +1,51 @@ +var assignValue = require('./_assignValue'), + castPath = require('./_castPath'), + isIndex = require('./_isIndex'), + isObject = require('./isObject'), + toKey = require('./_toKey'); + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +module.exports = baseSet; diff --git a/libs/events/node_modules/lodash/_baseSetData.js b/libs/events/node_modules/lodash/_baseSetData.js new file mode 100644 index 000000000..c409947dd --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSetData.js @@ -0,0 +1,17 @@ +var identity = require('./identity'), + metaMap = require('./_metaMap'); + +/** + * The base implementation of `setData` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ +var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; +}; + +module.exports = baseSetData; diff --git a/libs/events/node_modules/lodash/_baseSetToString.js b/libs/events/node_modules/lodash/_baseSetToString.js new file mode 100644 index 000000000..89eaca38d --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSetToString.js @@ -0,0 +1,22 @@ +var constant = require('./constant'), + defineProperty = require('./_defineProperty'), + identity = require('./identity'); + +/** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ +var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); +}; + +module.exports = baseSetToString; diff --git a/libs/events/node_modules/lodash/_baseShuffle.js b/libs/events/node_modules/lodash/_baseShuffle.js new file mode 100644 index 000000000..023077ac4 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseShuffle.js @@ -0,0 +1,15 @@ +var shuffleSelf = require('./_shuffleSelf'), + values = require('./values'); + +/** + * The base implementation of `_.shuffle`. + * + * @private + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + */ +function baseShuffle(collection) { + return shuffleSelf(values(collection)); +} + +module.exports = baseShuffle; diff --git a/libs/events/node_modules/lodash/_baseSlice.js b/libs/events/node_modules/lodash/_baseSlice.js new file mode 100644 index 000000000..786f6c99e --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSlice.js @@ -0,0 +1,31 @@ +/** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; +} + +module.exports = baseSlice; diff --git a/libs/events/node_modules/lodash/_baseSome.js b/libs/events/node_modules/lodash/_baseSome.js new file mode 100644 index 000000000..58f3f447a --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSome.js @@ -0,0 +1,22 @@ +var baseEach = require('./_baseEach'); + +/** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; +} + +module.exports = baseSome; diff --git a/libs/events/node_modules/lodash/_baseSortBy.js b/libs/events/node_modules/lodash/_baseSortBy.js new file mode 100644 index 000000000..a25c92eda --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSortBy.js @@ -0,0 +1,21 @@ +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +module.exports = baseSortBy; diff --git a/libs/events/node_modules/lodash/_baseSortedIndex.js b/libs/events/node_modules/lodash/_baseSortedIndex.js new file mode 100644 index 000000000..638c366c7 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSortedIndex.js @@ -0,0 +1,42 @@ +var baseSortedIndexBy = require('./_baseSortedIndexBy'), + identity = require('./identity'), + isSymbol = require('./isSymbol'); + +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + +/** + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ +function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array == null ? low : array.length; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if (computed !== null && !isSymbol(computed) && + (retHighest ? (computed <= value) : (computed < value))) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return baseSortedIndexBy(array, value, identity, retHighest); +} + +module.exports = baseSortedIndex; diff --git a/libs/events/node_modules/lodash/_baseSortedIndexBy.js b/libs/events/node_modules/lodash/_baseSortedIndexBy.js new file mode 100644 index 000000000..c247b377f --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSortedIndexBy.js @@ -0,0 +1,67 @@ +var isSymbol = require('./isSymbol'); + +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeFloor = Math.floor, + nativeMin = Math.min; + +/** + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ +function baseSortedIndexBy(array, value, iteratee, retHighest) { + var low = 0, + high = array == null ? 0 : array.length; + if (high === 0) { + return 0; + } + + value = iteratee(value); + var valIsNaN = value !== value, + valIsNull = value === null, + valIsSymbol = isSymbol(value), + valIsUndefined = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + othIsDefined = computed !== undefined, + othIsNull = computed === null, + othIsReflexive = computed === computed, + othIsSymbol = isSymbol(computed); + + if (valIsNaN) { + var setLow = retHighest || othIsReflexive; + } else if (valIsUndefined) { + setLow = othIsReflexive && (retHighest || othIsDefined); + } else if (valIsNull) { + setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); + } else if (valIsSymbol) { + setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); + } else if (othIsNull || othIsSymbol) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); +} + +module.exports = baseSortedIndexBy; diff --git a/libs/events/node_modules/lodash/_baseSortedUniq.js b/libs/events/node_modules/lodash/_baseSortedUniq.js new file mode 100644 index 000000000..802159a3d --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSortedUniq.js @@ -0,0 +1,30 @@ +var eq = require('./eq'); + +/** + * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseSortedUniq(array, iteratee) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!index || !eq(computed, seen)) { + var seen = computed; + result[resIndex++] = value === 0 ? 0 : value; + } + } + return result; +} + +module.exports = baseSortedUniq; diff --git a/libs/events/node_modules/lodash/_baseSum.js b/libs/events/node_modules/lodash/_baseSum.js new file mode 100644 index 000000000..a9e84c13c --- /dev/null +++ b/libs/events/node_modules/lodash/_baseSum.js @@ -0,0 +1,24 @@ +/** + * The base implementation of `_.sum` and `_.sumBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ +function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + if (current !== undefined) { + result = result === undefined ? current : (result + current); + } + } + return result; +} + +module.exports = baseSum; diff --git a/libs/events/node_modules/lodash/_baseTimes.js b/libs/events/node_modules/lodash/_baseTimes.js new file mode 100644 index 000000000..0603fc37e --- /dev/null +++ b/libs/events/node_modules/lodash/_baseTimes.js @@ -0,0 +1,20 @@ +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +module.exports = baseTimes; diff --git a/libs/events/node_modules/lodash/_baseToNumber.js b/libs/events/node_modules/lodash/_baseToNumber.js new file mode 100644 index 000000000..04859f391 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseToNumber.js @@ -0,0 +1,24 @@ +var isSymbol = require('./isSymbol'); + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** + * The base implementation of `_.toNumber` which doesn't ensure correct + * conversions of binary, hexadecimal, or octal string values. + * + * @private + * @param {*} value The value to process. + * @returns {number} Returns the number. + */ +function baseToNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + return +value; +} + +module.exports = baseToNumber; diff --git a/libs/events/node_modules/lodash/_baseToPairs.js b/libs/events/node_modules/lodash/_baseToPairs.js new file mode 100644 index 000000000..bff199128 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseToPairs.js @@ -0,0 +1,18 @@ +var arrayMap = require('./_arrayMap'); + +/** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the key-value pairs. + */ +function baseToPairs(object, props) { + return arrayMap(props, function(key) { + return [key, object[key]]; + }); +} + +module.exports = baseToPairs; diff --git a/libs/events/node_modules/lodash/_baseToString.js b/libs/events/node_modules/lodash/_baseToString.js new file mode 100644 index 000000000..ada6ad298 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseToString.js @@ -0,0 +1,37 @@ +var Symbol = require('./_Symbol'), + arrayMap = require('./_arrayMap'), + isArray = require('./isArray'), + isSymbol = require('./isSymbol'); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +module.exports = baseToString; diff --git a/libs/events/node_modules/lodash/_baseTrim.js b/libs/events/node_modules/lodash/_baseTrim.js new file mode 100644 index 000000000..3e2797d99 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseTrim.js @@ -0,0 +1,19 @@ +var trimmedEndIndex = require('./_trimmedEndIndex'); + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +module.exports = baseTrim; diff --git a/libs/events/node_modules/lodash/_baseUnary.js b/libs/events/node_modules/lodash/_baseUnary.js new file mode 100644 index 000000000..98639e92f --- /dev/null +++ b/libs/events/node_modules/lodash/_baseUnary.js @@ -0,0 +1,14 @@ +/** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ +function baseUnary(func) { + return function(value) { + return func(value); + }; +} + +module.exports = baseUnary; diff --git a/libs/events/node_modules/lodash/_baseUniq.js b/libs/events/node_modules/lodash/_baseUniq.js new file mode 100644 index 000000000..aea459dc7 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseUniq.js @@ -0,0 +1,72 @@ +var SetCache = require('./_SetCache'), + arrayIncludes = require('./_arrayIncludes'), + arrayIncludesWith = require('./_arrayIncludesWith'), + cacheHas = require('./_cacheHas'), + createSet = require('./_createSet'), + setToArray = require('./_setToArray'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +module.exports = baseUniq; diff --git a/libs/events/node_modules/lodash/_baseUnset.js b/libs/events/node_modules/lodash/_baseUnset.js new file mode 100644 index 000000000..eefc6e37d --- /dev/null +++ b/libs/events/node_modules/lodash/_baseUnset.js @@ -0,0 +1,20 @@ +var castPath = require('./_castPath'), + last = require('./last'), + parent = require('./_parent'), + toKey = require('./_toKey'); + +/** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The property path to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ +function baseUnset(object, path) { + path = castPath(path, object); + object = parent(object, path); + return object == null || delete object[toKey(last(path))]; +} + +module.exports = baseUnset; diff --git a/libs/events/node_modules/lodash/_baseUpdate.js b/libs/events/node_modules/lodash/_baseUpdate.js new file mode 100644 index 000000000..92a623777 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseUpdate.js @@ -0,0 +1,18 @@ +var baseGet = require('./_baseGet'), + baseSet = require('./_baseSet'); + +/** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); +} + +module.exports = baseUpdate; diff --git a/libs/events/node_modules/lodash/_baseValues.js b/libs/events/node_modules/lodash/_baseValues.js new file mode 100644 index 000000000..b95faadcf --- /dev/null +++ b/libs/events/node_modules/lodash/_baseValues.js @@ -0,0 +1,19 @@ +var arrayMap = require('./_arrayMap'); + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); +} + +module.exports = baseValues; diff --git a/libs/events/node_modules/lodash/_baseWhile.js b/libs/events/node_modules/lodash/_baseWhile.js new file mode 100644 index 000000000..07eac61b9 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseWhile.js @@ -0,0 +1,26 @@ +var baseSlice = require('./_baseSlice'); + +/** + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ +function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && + predicate(array[index], index, array)) {} + + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); +} + +module.exports = baseWhile; diff --git a/libs/events/node_modules/lodash/_baseWrapperValue.js b/libs/events/node_modules/lodash/_baseWrapperValue.js new file mode 100644 index 000000000..443e0df5e --- /dev/null +++ b/libs/events/node_modules/lodash/_baseWrapperValue.js @@ -0,0 +1,25 @@ +var LazyWrapper = require('./_LazyWrapper'), + arrayPush = require('./_arrayPush'), + arrayReduce = require('./_arrayReduce'); + +/** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ +function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + return arrayReduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); +} + +module.exports = baseWrapperValue; diff --git a/libs/events/node_modules/lodash/_baseXor.js b/libs/events/node_modules/lodash/_baseXor.js new file mode 100644 index 000000000..8e69338bf --- /dev/null +++ b/libs/events/node_modules/lodash/_baseXor.js @@ -0,0 +1,36 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + baseUniq = require('./_baseUniq'); + +/** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ +function baseXor(arrays, iteratee, comparator) { + var length = arrays.length; + if (length < 2) { + return length ? baseUniq(arrays[0]) : []; + } + var index = -1, + result = Array(length); + + while (++index < length) { + var array = arrays[index], + othIndex = -1; + + while (++othIndex < length) { + if (othIndex != index) { + result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); + } + } + } + return baseUniq(baseFlatten(result, 1), iteratee, comparator); +} + +module.exports = baseXor; diff --git a/libs/events/node_modules/lodash/_baseZipObject.js b/libs/events/node_modules/lodash/_baseZipObject.js new file mode 100644 index 000000000..401f85be2 --- /dev/null +++ b/libs/events/node_modules/lodash/_baseZipObject.js @@ -0,0 +1,23 @@ +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +module.exports = baseZipObject; diff --git a/libs/events/node_modules/lodash/_cacheHas.js b/libs/events/node_modules/lodash/_cacheHas.js new file mode 100644 index 000000000..2dec89268 --- /dev/null +++ b/libs/events/node_modules/lodash/_cacheHas.js @@ -0,0 +1,13 @@ +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +module.exports = cacheHas; diff --git a/libs/events/node_modules/lodash/_castArrayLikeObject.js b/libs/events/node_modules/lodash/_castArrayLikeObject.js new file mode 100644 index 000000000..92c75fa1a --- /dev/null +++ b/libs/events/node_modules/lodash/_castArrayLikeObject.js @@ -0,0 +1,14 @@ +var isArrayLikeObject = require('./isArrayLikeObject'); + +/** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array|Object} Returns the cast array-like object. + */ +function castArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; +} + +module.exports = castArrayLikeObject; diff --git a/libs/events/node_modules/lodash/_castFunction.js b/libs/events/node_modules/lodash/_castFunction.js new file mode 100644 index 000000000..98c91ae63 --- /dev/null +++ b/libs/events/node_modules/lodash/_castFunction.js @@ -0,0 +1,14 @@ +var identity = require('./identity'); + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : identity; +} + +module.exports = castFunction; diff --git a/libs/events/node_modules/lodash/_castPath.js b/libs/events/node_modules/lodash/_castPath.js new file mode 100644 index 000000000..017e4c1b4 --- /dev/null +++ b/libs/events/node_modules/lodash/_castPath.js @@ -0,0 +1,21 @@ +var isArray = require('./isArray'), + isKey = require('./_isKey'), + stringToPath = require('./_stringToPath'), + toString = require('./toString'); + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); +} + +module.exports = castPath; diff --git a/libs/events/node_modules/lodash/_castRest.js b/libs/events/node_modules/lodash/_castRest.js new file mode 100644 index 000000000..213c66f19 --- /dev/null +++ b/libs/events/node_modules/lodash/_castRest.js @@ -0,0 +1,14 @@ +var baseRest = require('./_baseRest'); + +/** + * A `baseRest` alias which can be replaced with `identity` by module + * replacement plugins. + * + * @private + * @type {Function} + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +var castRest = baseRest; + +module.exports = castRest; diff --git a/libs/events/node_modules/lodash/_castSlice.js b/libs/events/node_modules/lodash/_castSlice.js new file mode 100644 index 000000000..071faeba5 --- /dev/null +++ b/libs/events/node_modules/lodash/_castSlice.js @@ -0,0 +1,18 @@ +var baseSlice = require('./_baseSlice'); + +/** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ +function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); +} + +module.exports = castSlice; diff --git a/libs/events/node_modules/lodash/_charsEndIndex.js b/libs/events/node_modules/lodash/_charsEndIndex.js new file mode 100644 index 000000000..07908ff3a --- /dev/null +++ b/libs/events/node_modules/lodash/_charsEndIndex.js @@ -0,0 +1,19 @@ +var baseIndexOf = require('./_baseIndexOf'); + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ +function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; +} + +module.exports = charsEndIndex; diff --git a/libs/events/node_modules/lodash/_charsStartIndex.js b/libs/events/node_modules/lodash/_charsStartIndex.js new file mode 100644 index 000000000..b17afd254 --- /dev/null +++ b/libs/events/node_modules/lodash/_charsStartIndex.js @@ -0,0 +1,20 @@ +var baseIndexOf = require('./_baseIndexOf'); + +/** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ +function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; +} + +module.exports = charsStartIndex; diff --git a/libs/events/node_modules/lodash/_cloneArrayBuffer.js b/libs/events/node_modules/lodash/_cloneArrayBuffer.js new file mode 100644 index 000000000..c3d8f6e39 --- /dev/null +++ b/libs/events/node_modules/lodash/_cloneArrayBuffer.js @@ -0,0 +1,16 @@ +var Uint8Array = require('./_Uint8Array'); + +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} + +module.exports = cloneArrayBuffer; diff --git a/libs/events/node_modules/lodash/_cloneBuffer.js b/libs/events/node_modules/lodash/_cloneBuffer.js new file mode 100644 index 000000000..27c48109b --- /dev/null +++ b/libs/events/node_modules/lodash/_cloneBuffer.js @@ -0,0 +1,35 @@ +var root = require('./_root'); + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; + +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; +} + +module.exports = cloneBuffer; diff --git a/libs/events/node_modules/lodash/_cloneDataView.js b/libs/events/node_modules/lodash/_cloneDataView.js new file mode 100644 index 000000000..9c9b7b054 --- /dev/null +++ b/libs/events/node_modules/lodash/_cloneDataView.js @@ -0,0 +1,16 @@ +var cloneArrayBuffer = require('./_cloneArrayBuffer'); + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +module.exports = cloneDataView; diff --git a/libs/events/node_modules/lodash/_cloneRegExp.js b/libs/events/node_modules/lodash/_cloneRegExp.js new file mode 100644 index 000000000..64a30dfb4 --- /dev/null +++ b/libs/events/node_modules/lodash/_cloneRegExp.js @@ -0,0 +1,17 @@ +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +module.exports = cloneRegExp; diff --git a/libs/events/node_modules/lodash/_cloneSymbol.js b/libs/events/node_modules/lodash/_cloneSymbol.js new file mode 100644 index 000000000..bede39f50 --- /dev/null +++ b/libs/events/node_modules/lodash/_cloneSymbol.js @@ -0,0 +1,18 @@ +var Symbol = require('./_Symbol'); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +module.exports = cloneSymbol; diff --git a/libs/events/node_modules/lodash/_cloneTypedArray.js b/libs/events/node_modules/lodash/_cloneTypedArray.js new file mode 100644 index 000000000..7aad84d4f --- /dev/null +++ b/libs/events/node_modules/lodash/_cloneTypedArray.js @@ -0,0 +1,16 @@ +var cloneArrayBuffer = require('./_cloneArrayBuffer'); + +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} + +module.exports = cloneTypedArray; diff --git a/libs/events/node_modules/lodash/_compareAscending.js b/libs/events/node_modules/lodash/_compareAscending.js new file mode 100644 index 000000000..8dc279108 --- /dev/null +++ b/libs/events/node_modules/lodash/_compareAscending.js @@ -0,0 +1,41 @@ +var isSymbol = require('./isSymbol'); + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = isSymbol(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = isSymbol(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +module.exports = compareAscending; diff --git a/libs/events/node_modules/lodash/_compareMultiple.js b/libs/events/node_modules/lodash/_compareMultiple.js new file mode 100644 index 000000000..ad61f0fbc --- /dev/null +++ b/libs/events/node_modules/lodash/_compareMultiple.js @@ -0,0 +1,44 @@ +var compareAscending = require('./_compareAscending'); + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +module.exports = compareMultiple; diff --git a/libs/events/node_modules/lodash/_composeArgs.js b/libs/events/node_modules/lodash/_composeArgs.js new file mode 100644 index 000000000..1ce40f4f9 --- /dev/null +++ b/libs/events/node_modules/lodash/_composeArgs.js @@ -0,0 +1,39 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ +function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; +} + +module.exports = composeArgs; diff --git a/libs/events/node_modules/lodash/_composeArgsRight.js b/libs/events/node_modules/lodash/_composeArgsRight.js new file mode 100644 index 000000000..8dc588d0a --- /dev/null +++ b/libs/events/node_modules/lodash/_composeArgsRight.js @@ -0,0 +1,41 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ +function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; + + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + } + return result; +} + +module.exports = composeArgsRight; diff --git a/libs/events/node_modules/lodash/_copyArray.js b/libs/events/node_modules/lodash/_copyArray.js new file mode 100644 index 000000000..cd94d5d09 --- /dev/null +++ b/libs/events/node_modules/lodash/_copyArray.js @@ -0,0 +1,20 @@ +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} + +module.exports = copyArray; diff --git a/libs/events/node_modules/lodash/_copyObject.js b/libs/events/node_modules/lodash/_copyObject.js new file mode 100644 index 000000000..2f2a5c23b --- /dev/null +++ b/libs/events/node_modules/lodash/_copyObject.js @@ -0,0 +1,40 @@ +var assignValue = require('./_assignValue'), + baseAssignValue = require('./_baseAssignValue'); + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; +} + +module.exports = copyObject; diff --git a/libs/events/node_modules/lodash/_copySymbols.js b/libs/events/node_modules/lodash/_copySymbols.js new file mode 100644 index 000000000..c35944ab5 --- /dev/null +++ b/libs/events/node_modules/lodash/_copySymbols.js @@ -0,0 +1,16 @@ +var copyObject = require('./_copyObject'), + getSymbols = require('./_getSymbols'); + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); +} + +module.exports = copySymbols; diff --git a/libs/events/node_modules/lodash/_copySymbolsIn.js b/libs/events/node_modules/lodash/_copySymbolsIn.js new file mode 100644 index 000000000..fdf20a73c --- /dev/null +++ b/libs/events/node_modules/lodash/_copySymbolsIn.js @@ -0,0 +1,16 @@ +var copyObject = require('./_copyObject'), + getSymbolsIn = require('./_getSymbolsIn'); + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return copyObject(source, getSymbolsIn(source), object); +} + +module.exports = copySymbolsIn; diff --git a/libs/events/node_modules/lodash/_coreJsData.js b/libs/events/node_modules/lodash/_coreJsData.js new file mode 100644 index 000000000..f8e5b4e34 --- /dev/null +++ b/libs/events/node_modules/lodash/_coreJsData.js @@ -0,0 +1,6 @@ +var root = require('./_root'); + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +module.exports = coreJsData; diff --git a/libs/events/node_modules/lodash/_countHolders.js b/libs/events/node_modules/lodash/_countHolders.js new file mode 100644 index 000000000..718fcdaa8 --- /dev/null +++ b/libs/events/node_modules/lodash/_countHolders.js @@ -0,0 +1,21 @@ +/** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ +function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + ++result; + } + } + return result; +} + +module.exports = countHolders; diff --git a/libs/events/node_modules/lodash/_createAggregator.js b/libs/events/node_modules/lodash/_createAggregator.js new file mode 100644 index 000000000..0be42c41c --- /dev/null +++ b/libs/events/node_modules/lodash/_createAggregator.js @@ -0,0 +1,23 @@ +var arrayAggregator = require('./_arrayAggregator'), + baseAggregator = require('./_baseAggregator'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ +function createAggregator(setter, initializer) { + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, baseIteratee(iteratee, 2), accumulator); + }; +} + +module.exports = createAggregator; diff --git a/libs/events/node_modules/lodash/_createAssigner.js b/libs/events/node_modules/lodash/_createAssigner.js new file mode 100644 index 000000000..1f904c51b --- /dev/null +++ b/libs/events/node_modules/lodash/_createAssigner.js @@ -0,0 +1,37 @@ +var baseRest = require('./_baseRest'), + isIterateeCall = require('./_isIterateeCall'); + +/** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); +} + +module.exports = createAssigner; diff --git a/libs/events/node_modules/lodash/_createBaseEach.js b/libs/events/node_modules/lodash/_createBaseEach.js new file mode 100644 index 000000000..d24fdd1bb --- /dev/null +++ b/libs/events/node_modules/lodash/_createBaseEach.js @@ -0,0 +1,32 @@ +var isArrayLike = require('./isArrayLike'); + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +module.exports = createBaseEach; diff --git a/libs/events/node_modules/lodash/_createBaseFor.js b/libs/events/node_modules/lodash/_createBaseFor.js new file mode 100644 index 000000000..94cbf297a --- /dev/null +++ b/libs/events/node_modules/lodash/_createBaseFor.js @@ -0,0 +1,25 @@ +/** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; +} + +module.exports = createBaseFor; diff --git a/libs/events/node_modules/lodash/_createBind.js b/libs/events/node_modules/lodash/_createBind.js new file mode 100644 index 000000000..07cb99f4d --- /dev/null +++ b/libs/events/node_modules/lodash/_createBind.js @@ -0,0 +1,28 @@ +var createCtor = require('./_createCtor'), + root = require('./_root'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_BIND_FLAG = 1; + +/** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createBind(func, bitmask, thisArg) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } + return wrapper; +} + +module.exports = createBind; diff --git a/libs/events/node_modules/lodash/_createCaseFirst.js b/libs/events/node_modules/lodash/_createCaseFirst.js new file mode 100644 index 000000000..fe8ea4830 --- /dev/null +++ b/libs/events/node_modules/lodash/_createCaseFirst.js @@ -0,0 +1,33 @@ +var castSlice = require('./_castSlice'), + hasUnicode = require('./_hasUnicode'), + stringToArray = require('./_stringToArray'), + toString = require('./toString'); + +/** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new case function. + */ +function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = hasUnicode(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols + ? strSymbols[0] + : string.charAt(0); + + var trailing = strSymbols + ? castSlice(strSymbols, 1).join('') + : string.slice(1); + + return chr[methodName]() + trailing; + }; +} + +module.exports = createCaseFirst; diff --git a/libs/events/node_modules/lodash/_createCompounder.js b/libs/events/node_modules/lodash/_createCompounder.js new file mode 100644 index 000000000..8d4cee2cd --- /dev/null +++ b/libs/events/node_modules/lodash/_createCompounder.js @@ -0,0 +1,24 @@ +var arrayReduce = require('./_arrayReduce'), + deburr = require('./deburr'), + words = require('./words'); + +/** Used to compose unicode capture groups. */ +var rsApos = "['\u2019]"; + +/** Used to match apostrophes. */ +var reApos = RegExp(rsApos, 'g'); + +/** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ +function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); + }; +} + +module.exports = createCompounder; diff --git a/libs/events/node_modules/lodash/_createCtor.js b/libs/events/node_modules/lodash/_createCtor.js new file mode 100644 index 000000000..9047aa5fa --- /dev/null +++ b/libs/events/node_modules/lodash/_createCtor.js @@ -0,0 +1,37 @@ +var baseCreate = require('./_baseCreate'), + isObject = require('./isObject'); + +/** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ +function createCtor(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. See + // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; +} + +module.exports = createCtor; diff --git a/libs/events/node_modules/lodash/_createCurry.js b/libs/events/node_modules/lodash/_createCurry.js new file mode 100644 index 000000000..f06c2cdd8 --- /dev/null +++ b/libs/events/node_modules/lodash/_createCurry.js @@ -0,0 +1,46 @@ +var apply = require('./_apply'), + createCtor = require('./_createCtor'), + createHybrid = require('./_createHybrid'), + createRecurry = require('./_createRecurry'), + getHolder = require('./_getHolder'), + replaceHolders = require('./_replaceHolders'), + root = require('./_root'); + +/** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createCurry(func, bitmask, arity) { + var Ctor = createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getHolder(wrapper); + + while (index--) { + args[index] = arguments[index]; + } + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + return wrapper; +} + +module.exports = createCurry; diff --git a/libs/events/node_modules/lodash/_createFind.js b/libs/events/node_modules/lodash/_createFind.js new file mode 100644 index 000000000..8859ff89f --- /dev/null +++ b/libs/events/node_modules/lodash/_createFind.js @@ -0,0 +1,25 @@ +var baseIteratee = require('./_baseIteratee'), + isArrayLike = require('./isArrayLike'), + keys = require('./keys'); + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!isArrayLike(collection)) { + var iteratee = baseIteratee(predicate, 3); + collection = keys(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +module.exports = createFind; diff --git a/libs/events/node_modules/lodash/_createFlow.js b/libs/events/node_modules/lodash/_createFlow.js new file mode 100644 index 000000000..baaddbf5e --- /dev/null +++ b/libs/events/node_modules/lodash/_createFlow.js @@ -0,0 +1,78 @@ +var LodashWrapper = require('./_LodashWrapper'), + flatRest = require('./_flatRest'), + getData = require('./_getData'), + getFuncName = require('./_getFuncName'), + isArray = require('./isArray'), + isLaziable = require('./_isLaziable'); + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used to compose bitmasks for function metadata. */ +var WRAP_CURRY_FLAG = 8, + WRAP_PARTIAL_FLAG = 32, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256; + +/** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ +function createFlow(fromRight) { + return flatRest(function(funcs) { + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; + + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? index : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && + data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) + ? wrapper[funcName]() + : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value)) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }); +} + +module.exports = createFlow; diff --git a/libs/events/node_modules/lodash/_createHybrid.js b/libs/events/node_modules/lodash/_createHybrid.js new file mode 100644 index 000000000..b671bd11f --- /dev/null +++ b/libs/events/node_modules/lodash/_createHybrid.js @@ -0,0 +1,92 @@ +var composeArgs = require('./_composeArgs'), + composeArgsRight = require('./_composeArgsRight'), + countHolders = require('./_countHolders'), + createCtor = require('./_createCtor'), + createRecurry = require('./_createRecurry'), + getHolder = require('./_getHolder'), + reorder = require('./_reorder'), + replaceHolders = require('./_replaceHolders'), + root = require('./_root'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_FLAG = 8, + WRAP_CURRY_RIGHT_FLAG = 16, + WRAP_ARY_FLAG = 128, + WRAP_FLIP_FLAG = 512; + +/** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided + * to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & WRAP_ARY_FLAG, + isBind = bitmask & WRAP_BIND_FLAG, + isBindKey = bitmask & WRAP_BIND_KEY_FLAG, + isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), + isFlip = bitmask & WRAP_FLIP_FLAG, + Ctor = isBindKey ? undefined : createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length; + + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getHolder(wrapper), + holdersCount = countHolders(args, placeholder); + } + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + length = args.length; + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } + if (isAry && ary < length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtor(fn); + } + return fn.apply(thisBinding, args); + } + return wrapper; +} + +module.exports = createHybrid; diff --git a/libs/events/node_modules/lodash/_createInverter.js b/libs/events/node_modules/lodash/_createInverter.js new file mode 100644 index 000000000..6c0c56299 --- /dev/null +++ b/libs/events/node_modules/lodash/_createInverter.js @@ -0,0 +1,17 @@ +var baseInverter = require('./_baseInverter'); + +/** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ +function createInverter(setter, toIteratee) { + return function(object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; +} + +module.exports = createInverter; diff --git a/libs/events/node_modules/lodash/_createMathOperation.js b/libs/events/node_modules/lodash/_createMathOperation.js new file mode 100644 index 000000000..f1e238ac0 --- /dev/null +++ b/libs/events/node_modules/lodash/_createMathOperation.js @@ -0,0 +1,38 @@ +var baseToNumber = require('./_baseToNumber'), + baseToString = require('./_baseToString'); + +/** + * Creates a function that performs a mathematical operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @param {number} [defaultValue] The value used for `undefined` arguments. + * @returns {Function} Returns the new mathematical operation function. + */ +function createMathOperation(operator, defaultValue) { + return function(value, other) { + var result; + if (value === undefined && other === undefined) { + return defaultValue; + } + if (value !== undefined) { + result = value; + } + if (other !== undefined) { + if (result === undefined) { + return other; + } + if (typeof value == 'string' || typeof other == 'string') { + value = baseToString(value); + other = baseToString(other); + } else { + value = baseToNumber(value); + other = baseToNumber(other); + } + result = operator(value, other); + } + return result; + }; +} + +module.exports = createMathOperation; diff --git a/libs/events/node_modules/lodash/_createOver.js b/libs/events/node_modules/lodash/_createOver.js new file mode 100644 index 000000000..3b9455161 --- /dev/null +++ b/libs/events/node_modules/lodash/_createOver.js @@ -0,0 +1,27 @@ +var apply = require('./_apply'), + arrayMap = require('./_arrayMap'), + baseIteratee = require('./_baseIteratee'), + baseRest = require('./_baseRest'), + baseUnary = require('./_baseUnary'), + flatRest = require('./_flatRest'); + +/** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new over function. + */ +function createOver(arrayFunc) { + return flatRest(function(iteratees) { + iteratees = arrayMap(iteratees, baseUnary(baseIteratee)); + return baseRest(function(args) { + var thisArg = this; + return arrayFunc(iteratees, function(iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); +} + +module.exports = createOver; diff --git a/libs/events/node_modules/lodash/_createPadding.js b/libs/events/node_modules/lodash/_createPadding.js new file mode 100644 index 000000000..2124612b8 --- /dev/null +++ b/libs/events/node_modules/lodash/_createPadding.js @@ -0,0 +1,33 @@ +var baseRepeat = require('./_baseRepeat'), + baseToString = require('./_baseToString'), + castSlice = require('./_castSlice'), + hasUnicode = require('./_hasUnicode'), + stringSize = require('./_stringSize'), + stringToArray = require('./_stringToArray'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil; + +/** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. + * + * @private + * @param {number} length The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padding for `string`. + */ +function createPadding(length, chars) { + chars = chars === undefined ? ' ' : baseToString(chars); + + var charsLength = chars.length; + if (charsLength < 2) { + return charsLength ? baseRepeat(chars, length) : chars; + } + var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); + return hasUnicode(chars) + ? castSlice(stringToArray(result), 0, length).join('') + : result.slice(0, length); +} + +module.exports = createPadding; diff --git a/libs/events/node_modules/lodash/_createPartial.js b/libs/events/node_modules/lodash/_createPartial.js new file mode 100644 index 000000000..e16c248b5 --- /dev/null +++ b/libs/events/node_modules/lodash/_createPartial.js @@ -0,0 +1,43 @@ +var apply = require('./_apply'), + createCtor = require('./_createCtor'), + root = require('./_root'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_BIND_FLAG = 1; + +/** + * Creates a function that wraps `func` to invoke it with the `this` binding + * of `thisArg` and `partials` prepended to the arguments it receives. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to + * the new function. + * @returns {Function} Returns the new wrapped function. + */ +function createPartial(func, bitmask, thisArg, partials) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return apply(fn, isBind ? thisArg : this, args); + } + return wrapper; +} + +module.exports = createPartial; diff --git a/libs/events/node_modules/lodash/_createRange.js b/libs/events/node_modules/lodash/_createRange.js new file mode 100644 index 000000000..9f52c7793 --- /dev/null +++ b/libs/events/node_modules/lodash/_createRange.js @@ -0,0 +1,30 @@ +var baseRange = require('./_baseRange'), + isIterateeCall = require('./_isIterateeCall'), + toFinite = require('./toFinite'); + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toFinite(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); + return baseRange(start, end, step, fromRight); + }; +} + +module.exports = createRange; diff --git a/libs/events/node_modules/lodash/_createRecurry.js b/libs/events/node_modules/lodash/_createRecurry.js new file mode 100644 index 000000000..eb29fb24c --- /dev/null +++ b/libs/events/node_modules/lodash/_createRecurry.js @@ -0,0 +1,56 @@ +var isLaziable = require('./_isLaziable'), + setData = require('./_setData'), + setWrapToString = require('./_setWrapToString'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_BOUND_FLAG = 4, + WRAP_CURRY_FLAG = 8, + WRAP_PARTIAL_FLAG = 32, + WRAP_PARTIAL_RIGHT_FLAG = 64; + +/** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & WRAP_CURRY_FLAG, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); + + if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { + bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, argPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return setWrapToString(result, func, bitmask); +} + +module.exports = createRecurry; diff --git a/libs/events/node_modules/lodash/_createRelationalOperation.js b/libs/events/node_modules/lodash/_createRelationalOperation.js new file mode 100644 index 000000000..a17c6b5e7 --- /dev/null +++ b/libs/events/node_modules/lodash/_createRelationalOperation.js @@ -0,0 +1,20 @@ +var toNumber = require('./toNumber'); + +/** + * Creates a function that performs a relational operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @returns {Function} Returns the new relational operation function. + */ +function createRelationalOperation(operator) { + return function(value, other) { + if (!(typeof value == 'string' && typeof other == 'string')) { + value = toNumber(value); + other = toNumber(other); + } + return operator(value, other); + }; +} + +module.exports = createRelationalOperation; diff --git a/libs/events/node_modules/lodash/_createRound.js b/libs/events/node_modules/lodash/_createRound.js new file mode 100644 index 000000000..88be5df39 --- /dev/null +++ b/libs/events/node_modules/lodash/_createRound.js @@ -0,0 +1,35 @@ +var root = require('./_root'), + toInteger = require('./toInteger'), + toNumber = require('./toNumber'), + toString = require('./toString'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsFinite = root.isFinite, + nativeMin = Math.min; + +/** + * Creates a function like `_.round`. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ +function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + number = toNumber(number); + precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); + if (precision && nativeIsFinite(number)) { + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); + } + return func(number); + }; +} + +module.exports = createRound; diff --git a/libs/events/node_modules/lodash/_createSet.js b/libs/events/node_modules/lodash/_createSet.js new file mode 100644 index 000000000..0f644eeae --- /dev/null +++ b/libs/events/node_modules/lodash/_createSet.js @@ -0,0 +1,19 @@ +var Set = require('./_Set'), + noop = require('./noop'), + setToArray = require('./_setToArray'); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { + return new Set(values); +}; + +module.exports = createSet; diff --git a/libs/events/node_modules/lodash/_createToPairs.js b/libs/events/node_modules/lodash/_createToPairs.js new file mode 100644 index 000000000..568417afd --- /dev/null +++ b/libs/events/node_modules/lodash/_createToPairs.js @@ -0,0 +1,30 @@ +var baseToPairs = require('./_baseToPairs'), + getTag = require('./_getTag'), + mapToArray = require('./_mapToArray'), + setToPairs = require('./_setToPairs'); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Creates a `_.toPairs` or `_.toPairsIn` function. + * + * @private + * @param {Function} keysFunc The function to get the keys of a given object. + * @returns {Function} Returns the new pairs function. + */ +function createToPairs(keysFunc) { + return function(object) { + var tag = getTag(object); + if (tag == mapTag) { + return mapToArray(object); + } + if (tag == setTag) { + return setToPairs(object); + } + return baseToPairs(object, keysFunc(object)); + }; +} + +module.exports = createToPairs; diff --git a/libs/events/node_modules/lodash/_createWrap.js b/libs/events/node_modules/lodash/_createWrap.js new file mode 100644 index 000000000..33f0633e4 --- /dev/null +++ b/libs/events/node_modules/lodash/_createWrap.js @@ -0,0 +1,106 @@ +var baseSetData = require('./_baseSetData'), + createBind = require('./_createBind'), + createCurry = require('./_createCurry'), + createHybrid = require('./_createHybrid'), + createPartial = require('./_createPartial'), + getData = require('./_getData'), + mergeData = require('./_mergeData'), + setData = require('./_setData'), + setWrapToString = require('./_setWrapToString'), + toInteger = require('./toInteger'); + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used to compose bitmasks for function metadata. */ +var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_FLAG = 8, + WRAP_CURRY_RIGHT_FLAG = 16, + WRAP_PARTIAL_FLAG = 32, + WRAP_PARTIAL_RIGHT_FLAG = 64; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * 512 - `_.flip` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + + if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; + + if (data) { + mergeData(newData, data); + } + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] === undefined + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { + bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == WRAP_BIND_FLAG) { + var result = createBind(func, bitmask, thisArg); + } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { + result = createCurry(func, bitmask, arity); + } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { + result = createPartial(func, bitmask, thisArg, partials); + } else { + result = createHybrid.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setWrapToString(setter(result, newData), func, bitmask); +} + +module.exports = createWrap; diff --git a/libs/events/node_modules/lodash/_customDefaultsAssignIn.js b/libs/events/node_modules/lodash/_customDefaultsAssignIn.js new file mode 100644 index 000000000..1f49e6fc4 --- /dev/null +++ b/libs/events/node_modules/lodash/_customDefaultsAssignIn.js @@ -0,0 +1,29 @@ +var eq = require('./eq'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used by `_.defaults` to customize its `_.assignIn` use to assign properties + * of source objects to the destination object for all destination properties + * that resolve to `undefined`. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ +function customDefaultsAssignIn(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; +} + +module.exports = customDefaultsAssignIn; diff --git a/libs/events/node_modules/lodash/_customDefaultsMerge.js b/libs/events/node_modules/lodash/_customDefaultsMerge.js new file mode 100644 index 000000000..4cab31751 --- /dev/null +++ b/libs/events/node_modules/lodash/_customDefaultsMerge.js @@ -0,0 +1,28 @@ +var baseMerge = require('./_baseMerge'), + isObject = require('./isObject'); + +/** + * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source + * objects into destination objects that are passed thru. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + * @returns {*} Returns the value to assign. + */ +function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, objValue); + baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); + stack['delete'](srcValue); + } + return objValue; +} + +module.exports = customDefaultsMerge; diff --git a/libs/events/node_modules/lodash/_customOmitClone.js b/libs/events/node_modules/lodash/_customOmitClone.js new file mode 100644 index 000000000..968db2ef3 --- /dev/null +++ b/libs/events/node_modules/lodash/_customOmitClone.js @@ -0,0 +1,16 @@ +var isPlainObject = require('./isPlainObject'); + +/** + * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain + * objects. + * + * @private + * @param {*} value The value to inspect. + * @param {string} key The key of the property to inspect. + * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. + */ +function customOmitClone(value) { + return isPlainObject(value) ? undefined : value; +} + +module.exports = customOmitClone; diff --git a/libs/events/node_modules/lodash/_deburrLetter.js b/libs/events/node_modules/lodash/_deburrLetter.js new file mode 100644 index 000000000..3e531edcf --- /dev/null +++ b/libs/events/node_modules/lodash/_deburrLetter.js @@ -0,0 +1,71 @@ +var basePropertyOf = require('./_basePropertyOf'); + +/** Used to map Latin Unicode letters to basic Latin letters. */ +var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 's' +}; + +/** + * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A + * letters to basic Latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ +var deburrLetter = basePropertyOf(deburredLetters); + +module.exports = deburrLetter; diff --git a/libs/events/node_modules/lodash/_defineProperty.js b/libs/events/node_modules/lodash/_defineProperty.js new file mode 100644 index 000000000..b6116d92a --- /dev/null +++ b/libs/events/node_modules/lodash/_defineProperty.js @@ -0,0 +1,11 @@ +var getNative = require('./_getNative'); + +var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} +}()); + +module.exports = defineProperty; diff --git a/libs/events/node_modules/lodash/_equalArrays.js b/libs/events/node_modules/lodash/_equalArrays.js new file mode 100644 index 000000000..824228c78 --- /dev/null +++ b/libs/events/node_modules/lodash/_equalArrays.js @@ -0,0 +1,84 @@ +var SetCache = require('./_SetCache'), + arraySome = require('./_arraySome'), + cacheHas = require('./_cacheHas'); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +module.exports = equalArrays; diff --git a/libs/events/node_modules/lodash/_equalByTag.js b/libs/events/node_modules/lodash/_equalByTag.js new file mode 100644 index 000000000..71919e867 --- /dev/null +++ b/libs/events/node_modules/lodash/_equalByTag.js @@ -0,0 +1,112 @@ +var Symbol = require('./_Symbol'), + Uint8Array = require('./_Uint8Array'), + eq = require('./eq'), + equalArrays = require('./_equalArrays'), + mapToArray = require('./_mapToArray'), + setToArray = require('./_setToArray'); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +module.exports = equalByTag; diff --git a/libs/events/node_modules/lodash/_equalObjects.js b/libs/events/node_modules/lodash/_equalObjects.js new file mode 100644 index 000000000..cdaacd2df --- /dev/null +++ b/libs/events/node_modules/lodash/_equalObjects.js @@ -0,0 +1,90 @@ +var getAllKeys = require('./_getAllKeys'); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +module.exports = equalObjects; diff --git a/libs/events/node_modules/lodash/_escapeHtmlChar.js b/libs/events/node_modules/lodash/_escapeHtmlChar.js new file mode 100644 index 000000000..7ca68ee62 --- /dev/null +++ b/libs/events/node_modules/lodash/_escapeHtmlChar.js @@ -0,0 +1,21 @@ +var basePropertyOf = require('./_basePropertyOf'); + +/** Used to map characters to HTML entities. */ +var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' +}; + +/** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ +var escapeHtmlChar = basePropertyOf(htmlEscapes); + +module.exports = escapeHtmlChar; diff --git a/libs/events/node_modules/lodash/_escapeStringChar.js b/libs/events/node_modules/lodash/_escapeStringChar.js new file mode 100644 index 000000000..44eca96ca --- /dev/null +++ b/libs/events/node_modules/lodash/_escapeStringChar.js @@ -0,0 +1,22 @@ +/** Used to escape characters for inclusion in compiled string literals. */ +var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' +}; + +/** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ +function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; +} + +module.exports = escapeStringChar; diff --git a/libs/events/node_modules/lodash/_flatRest.js b/libs/events/node_modules/lodash/_flatRest.js new file mode 100644 index 000000000..94ab6cca7 --- /dev/null +++ b/libs/events/node_modules/lodash/_flatRest.js @@ -0,0 +1,16 @@ +var flatten = require('./flatten'), + overRest = require('./_overRest'), + setToString = require('./_setToString'); + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return setToString(overRest(func, undefined, flatten), func + ''); +} + +module.exports = flatRest; diff --git a/libs/events/node_modules/lodash/_freeGlobal.js b/libs/events/node_modules/lodash/_freeGlobal.js new file mode 100644 index 000000000..bbec998fc --- /dev/null +++ b/libs/events/node_modules/lodash/_freeGlobal.js @@ -0,0 +1,4 @@ +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +module.exports = freeGlobal; diff --git a/libs/events/node_modules/lodash/_getAllKeys.js b/libs/events/node_modules/lodash/_getAllKeys.js new file mode 100644 index 000000000..a9ce6995a --- /dev/null +++ b/libs/events/node_modules/lodash/_getAllKeys.js @@ -0,0 +1,16 @@ +var baseGetAllKeys = require('./_baseGetAllKeys'), + getSymbols = require('./_getSymbols'), + keys = require('./keys'); + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); +} + +module.exports = getAllKeys; diff --git a/libs/events/node_modules/lodash/_getAllKeysIn.js b/libs/events/node_modules/lodash/_getAllKeysIn.js new file mode 100644 index 000000000..1b4667841 --- /dev/null +++ b/libs/events/node_modules/lodash/_getAllKeysIn.js @@ -0,0 +1,17 @@ +var baseGetAllKeys = require('./_baseGetAllKeys'), + getSymbolsIn = require('./_getSymbolsIn'), + keysIn = require('./keysIn'); + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); +} + +module.exports = getAllKeysIn; diff --git a/libs/events/node_modules/lodash/_getData.js b/libs/events/node_modules/lodash/_getData.js new file mode 100644 index 000000000..a1fe7b779 --- /dev/null +++ b/libs/events/node_modules/lodash/_getData.js @@ -0,0 +1,15 @@ +var metaMap = require('./_metaMap'), + noop = require('./noop'); + +/** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ +var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); +}; + +module.exports = getData; diff --git a/libs/events/node_modules/lodash/_getFuncName.js b/libs/events/node_modules/lodash/_getFuncName.js new file mode 100644 index 000000000..21e15b337 --- /dev/null +++ b/libs/events/node_modules/lodash/_getFuncName.js @@ -0,0 +1,31 @@ +var realNames = require('./_realNames'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ +function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; +} + +module.exports = getFuncName; diff --git a/libs/events/node_modules/lodash/_getHolder.js b/libs/events/node_modules/lodash/_getHolder.js new file mode 100644 index 000000000..65e94b5c2 --- /dev/null +++ b/libs/events/node_modules/lodash/_getHolder.js @@ -0,0 +1,13 @@ +/** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ +function getHolder(func) { + var object = func; + return object.placeholder; +} + +module.exports = getHolder; diff --git a/libs/events/node_modules/lodash/_getMapData.js b/libs/events/node_modules/lodash/_getMapData.js new file mode 100644 index 000000000..17f63032e --- /dev/null +++ b/libs/events/node_modules/lodash/_getMapData.js @@ -0,0 +1,18 @@ +var isKeyable = require('./_isKeyable'); + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +module.exports = getMapData; diff --git a/libs/events/node_modules/lodash/_getMatchData.js b/libs/events/node_modules/lodash/_getMatchData.js new file mode 100644 index 000000000..2cc70f917 --- /dev/null +++ b/libs/events/node_modules/lodash/_getMatchData.js @@ -0,0 +1,24 @@ +var isStrictComparable = require('./_isStrictComparable'), + keys = require('./keys'); + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; +} + +module.exports = getMatchData; diff --git a/libs/events/node_modules/lodash/_getNative.js b/libs/events/node_modules/lodash/_getNative.js new file mode 100644 index 000000000..97a622b83 --- /dev/null +++ b/libs/events/node_modules/lodash/_getNative.js @@ -0,0 +1,17 @@ +var baseIsNative = require('./_baseIsNative'), + getValue = require('./_getValue'); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +module.exports = getNative; diff --git a/libs/events/node_modules/lodash/_getPrototype.js b/libs/events/node_modules/lodash/_getPrototype.js new file mode 100644 index 000000000..e80861212 --- /dev/null +++ b/libs/events/node_modules/lodash/_getPrototype.js @@ -0,0 +1,6 @@ +var overArg = require('./_overArg'); + +/** Built-in value references. */ +var getPrototype = overArg(Object.getPrototypeOf, Object); + +module.exports = getPrototype; diff --git a/libs/events/node_modules/lodash/_getRawTag.js b/libs/events/node_modules/lodash/_getRawTag.js new file mode 100644 index 000000000..49a95c9c6 --- /dev/null +++ b/libs/events/node_modules/lodash/_getRawTag.js @@ -0,0 +1,46 @@ +var Symbol = require('./_Symbol'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ +function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; +} + +module.exports = getRawTag; diff --git a/libs/events/node_modules/lodash/_getSymbols.js b/libs/events/node_modules/lodash/_getSymbols.js new file mode 100644 index 000000000..7d6eafebb --- /dev/null +++ b/libs/events/node_modules/lodash/_getSymbols.js @@ -0,0 +1,30 @@ +var arrayFilter = require('./_arrayFilter'), + stubArray = require('./stubArray'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +module.exports = getSymbols; diff --git a/libs/events/node_modules/lodash/_getSymbolsIn.js b/libs/events/node_modules/lodash/_getSymbolsIn.js new file mode 100644 index 000000000..cec0855a4 --- /dev/null +++ b/libs/events/node_modules/lodash/_getSymbolsIn.js @@ -0,0 +1,25 @@ +var arrayPush = require('./_arrayPush'), + getPrototype = require('./_getPrototype'), + getSymbols = require('./_getSymbols'), + stubArray = require('./stubArray'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; +}; + +module.exports = getSymbolsIn; diff --git a/libs/events/node_modules/lodash/_getTag.js b/libs/events/node_modules/lodash/_getTag.js new file mode 100644 index 000000000..deaf89d58 --- /dev/null +++ b/libs/events/node_modules/lodash/_getTag.js @@ -0,0 +1,58 @@ +var DataView = require('./_DataView'), + Map = require('./_Map'), + Promise = require('./_Promise'), + Set = require('./_Set'), + WeakMap = require('./_WeakMap'), + baseGetTag = require('./_baseGetTag'), + toSource = require('./_toSource'); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + setTag = '[object Set]', + weakMapTag = '[object WeakMap]'; + +var dataViewTag = '[object DataView]'; + +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +var getTag = baseGetTag; + +// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. +if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; +} + +module.exports = getTag; diff --git a/libs/events/node_modules/lodash/_getValue.js b/libs/events/node_modules/lodash/_getValue.js new file mode 100644 index 000000000..5f7d77367 --- /dev/null +++ b/libs/events/node_modules/lodash/_getValue.js @@ -0,0 +1,13 @@ +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +module.exports = getValue; diff --git a/libs/events/node_modules/lodash/_getView.js b/libs/events/node_modules/lodash/_getView.js new file mode 100644 index 000000000..df1e5d44b --- /dev/null +++ b/libs/events/node_modules/lodash/_getView.js @@ -0,0 +1,33 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ +function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; +} + +module.exports = getView; diff --git a/libs/events/node_modules/lodash/_getWrapDetails.js b/libs/events/node_modules/lodash/_getWrapDetails.js new file mode 100644 index 000000000..3bcc6e48a --- /dev/null +++ b/libs/events/node_modules/lodash/_getWrapDetails.js @@ -0,0 +1,17 @@ +/** Used to match wrap detail comments. */ +var reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, + reSplitDetails = /,? & /; + +/** + * Extracts wrapper details from the `source` body comment. + * + * @private + * @param {string} source The source to inspect. + * @returns {Array} Returns the wrapper details. + */ +function getWrapDetails(source) { + var match = source.match(reWrapDetails); + return match ? match[1].split(reSplitDetails) : []; +} + +module.exports = getWrapDetails; diff --git a/libs/events/node_modules/lodash/_hasPath.js b/libs/events/node_modules/lodash/_hasPath.js new file mode 100644 index 000000000..93dbde152 --- /dev/null +++ b/libs/events/node_modules/lodash/_hasPath.js @@ -0,0 +1,39 @@ +var castPath = require('./_castPath'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isIndex = require('./_isIndex'), + isLength = require('./isLength'), + toKey = require('./_toKey'); + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); +} + +module.exports = hasPath; diff --git a/libs/events/node_modules/lodash/_hasUnicode.js b/libs/events/node_modules/lodash/_hasUnicode.js new file mode 100644 index 000000000..cb6ca15f6 --- /dev/null +++ b/libs/events/node_modules/lodash/_hasUnicode.js @@ -0,0 +1,26 @@ +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +module.exports = hasUnicode; diff --git a/libs/events/node_modules/lodash/_hasUnicodeWord.js b/libs/events/node_modules/lodash/_hasUnicodeWord.js new file mode 100644 index 000000000..95d52c444 --- /dev/null +++ b/libs/events/node_modules/lodash/_hasUnicodeWord.js @@ -0,0 +1,15 @@ +/** Used to detect strings that need a more robust regexp to match words. */ +var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + +/** + * Checks if `string` contains a word composed of Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a word is found, else `false`. + */ +function hasUnicodeWord(string) { + return reHasUnicodeWord.test(string); +} + +module.exports = hasUnicodeWord; diff --git a/libs/events/node_modules/lodash/_hashClear.js b/libs/events/node_modules/lodash/_hashClear.js new file mode 100644 index 000000000..5d4b70cc4 --- /dev/null +++ b/libs/events/node_modules/lodash/_hashClear.js @@ -0,0 +1,15 @@ +var nativeCreate = require('./_nativeCreate'); + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; +} + +module.exports = hashClear; diff --git a/libs/events/node_modules/lodash/_hashDelete.js b/libs/events/node_modules/lodash/_hashDelete.js new file mode 100644 index 000000000..ea9dabf13 --- /dev/null +++ b/libs/events/node_modules/lodash/_hashDelete.js @@ -0,0 +1,17 @@ +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; +} + +module.exports = hashDelete; diff --git a/libs/events/node_modules/lodash/_hashGet.js b/libs/events/node_modules/lodash/_hashGet.js new file mode 100644 index 000000000..1fc2f34b1 --- /dev/null +++ b/libs/events/node_modules/lodash/_hashGet.js @@ -0,0 +1,30 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +module.exports = hashGet; diff --git a/libs/events/node_modules/lodash/_hashHas.js b/libs/events/node_modules/lodash/_hashHas.js new file mode 100644 index 000000000..281a5517c --- /dev/null +++ b/libs/events/node_modules/lodash/_hashHas.js @@ -0,0 +1,23 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); +} + +module.exports = hashHas; diff --git a/libs/events/node_modules/lodash/_hashSet.js b/libs/events/node_modules/lodash/_hashSet.js new file mode 100644 index 000000000..e1055283e --- /dev/null +++ b/libs/events/node_modules/lodash/_hashSet.js @@ -0,0 +1,23 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +module.exports = hashSet; diff --git a/libs/events/node_modules/lodash/_initCloneArray.js b/libs/events/node_modules/lodash/_initCloneArray.js new file mode 100644 index 000000000..078c15af9 --- /dev/null +++ b/libs/events/node_modules/lodash/_initCloneArray.js @@ -0,0 +1,26 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +module.exports = initCloneArray; diff --git a/libs/events/node_modules/lodash/_initCloneByTag.js b/libs/events/node_modules/lodash/_initCloneByTag.js new file mode 100644 index 000000000..f69a008ca --- /dev/null +++ b/libs/events/node_modules/lodash/_initCloneByTag.js @@ -0,0 +1,77 @@ +var cloneArrayBuffer = require('./_cloneArrayBuffer'), + cloneDataView = require('./_cloneDataView'), + cloneRegExp = require('./_cloneRegExp'), + cloneSymbol = require('./_cloneSymbol'), + cloneTypedArray = require('./_cloneTypedArray'); + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return cloneSymbol(object); + } +} + +module.exports = initCloneByTag; diff --git a/libs/events/node_modules/lodash/_initCloneObject.js b/libs/events/node_modules/lodash/_initCloneObject.js new file mode 100644 index 000000000..5a13e64a5 --- /dev/null +++ b/libs/events/node_modules/lodash/_initCloneObject.js @@ -0,0 +1,18 @@ +var baseCreate = require('./_baseCreate'), + getPrototype = require('./_getPrototype'), + isPrototype = require('./_isPrototype'); + +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; +} + +module.exports = initCloneObject; diff --git a/libs/events/node_modules/lodash/_insertWrapDetails.js b/libs/events/node_modules/lodash/_insertWrapDetails.js new file mode 100644 index 000000000..e79080864 --- /dev/null +++ b/libs/events/node_modules/lodash/_insertWrapDetails.js @@ -0,0 +1,23 @@ +/** Used to match wrap detail comments. */ +var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/; + +/** + * Inserts wrapper `details` in a comment at the top of the `source` body. + * + * @private + * @param {string} source The source to modify. + * @returns {Array} details The details to insert. + * @returns {string} Returns the modified source. + */ +function insertWrapDetails(source, details) { + var length = details.length; + if (!length) { + return source; + } + var lastIndex = length - 1; + details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; + details = details.join(length > 2 ? ', ' : ' '); + return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); +} + +module.exports = insertWrapDetails; diff --git a/libs/events/node_modules/lodash/_isFlattenable.js b/libs/events/node_modules/lodash/_isFlattenable.js new file mode 100644 index 000000000..4cc2c249c --- /dev/null +++ b/libs/events/node_modules/lodash/_isFlattenable.js @@ -0,0 +1,20 @@ +var Symbol = require('./_Symbol'), + isArguments = require('./isArguments'), + isArray = require('./isArray'); + +/** Built-in value references. */ +var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return isArray(value) || isArguments(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +module.exports = isFlattenable; diff --git a/libs/events/node_modules/lodash/_isIndex.js b/libs/events/node_modules/lodash/_isIndex.js new file mode 100644 index 000000000..061cd390c --- /dev/null +++ b/libs/events/node_modules/lodash/_isIndex.js @@ -0,0 +1,25 @@ +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); +} + +module.exports = isIndex; diff --git a/libs/events/node_modules/lodash/_isIterateeCall.js b/libs/events/node_modules/lodash/_isIterateeCall.js new file mode 100644 index 000000000..a0bb5a9cf --- /dev/null +++ b/libs/events/node_modules/lodash/_isIterateeCall.js @@ -0,0 +1,30 @@ +var eq = require('./eq'), + isArrayLike = require('./isArrayLike'), + isIndex = require('./_isIndex'), + isObject = require('./isObject'); + +/** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; +} + +module.exports = isIterateeCall; diff --git a/libs/events/node_modules/lodash/_isKey.js b/libs/events/node_modules/lodash/_isKey.js new file mode 100644 index 000000000..ff08b0680 --- /dev/null +++ b/libs/events/node_modules/lodash/_isKey.js @@ -0,0 +1,29 @@ +var isArray = require('./isArray'), + isSymbol = require('./isSymbol'); + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +module.exports = isKey; diff --git a/libs/events/node_modules/lodash/_isKeyable.js b/libs/events/node_modules/lodash/_isKeyable.js new file mode 100644 index 000000000..39f1828d4 --- /dev/null +++ b/libs/events/node_modules/lodash/_isKeyable.js @@ -0,0 +1,15 @@ +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +module.exports = isKeyable; diff --git a/libs/events/node_modules/lodash/_isLaziable.js b/libs/events/node_modules/lodash/_isLaziable.js new file mode 100644 index 000000000..a57c4f2dc --- /dev/null +++ b/libs/events/node_modules/lodash/_isLaziable.js @@ -0,0 +1,28 @@ +var LazyWrapper = require('./_LazyWrapper'), + getData = require('./_getData'), + getFuncName = require('./_getFuncName'), + lodash = require('./wrapperLodash'); + +/** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, + * else `false`. + */ +function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; +} + +module.exports = isLaziable; diff --git a/libs/events/node_modules/lodash/_isMaskable.js b/libs/events/node_modules/lodash/_isMaskable.js new file mode 100644 index 000000000..eb98d09f3 --- /dev/null +++ b/libs/events/node_modules/lodash/_isMaskable.js @@ -0,0 +1,14 @@ +var coreJsData = require('./_coreJsData'), + isFunction = require('./isFunction'), + stubFalse = require('./stubFalse'); + +/** + * Checks if `func` is capable of being masked. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `func` is maskable, else `false`. + */ +var isMaskable = coreJsData ? isFunction : stubFalse; + +module.exports = isMaskable; diff --git a/libs/events/node_modules/lodash/_isMasked.js b/libs/events/node_modules/lodash/_isMasked.js new file mode 100644 index 000000000..4b0f21ba8 --- /dev/null +++ b/libs/events/node_modules/lodash/_isMasked.js @@ -0,0 +1,20 @@ +var coreJsData = require('./_coreJsData'); + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +module.exports = isMasked; diff --git a/libs/events/node_modules/lodash/_isPrototype.js b/libs/events/node_modules/lodash/_isPrototype.js new file mode 100644 index 000000000..0f29498d4 --- /dev/null +++ b/libs/events/node_modules/lodash/_isPrototype.js @@ -0,0 +1,18 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +module.exports = isPrototype; diff --git a/libs/events/node_modules/lodash/_isStrictComparable.js b/libs/events/node_modules/lodash/_isStrictComparable.js new file mode 100644 index 000000000..b59f40b85 --- /dev/null +++ b/libs/events/node_modules/lodash/_isStrictComparable.js @@ -0,0 +1,15 @@ +var isObject = require('./isObject'); + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !isObject(value); +} + +module.exports = isStrictComparable; diff --git a/libs/events/node_modules/lodash/_iteratorToArray.js b/libs/events/node_modules/lodash/_iteratorToArray.js new file mode 100644 index 000000000..476856647 --- /dev/null +++ b/libs/events/node_modules/lodash/_iteratorToArray.js @@ -0,0 +1,18 @@ +/** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ +function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; +} + +module.exports = iteratorToArray; diff --git a/libs/events/node_modules/lodash/_lazyClone.js b/libs/events/node_modules/lodash/_lazyClone.js new file mode 100644 index 000000000..d8a51f870 --- /dev/null +++ b/libs/events/node_modules/lodash/_lazyClone.js @@ -0,0 +1,23 @@ +var LazyWrapper = require('./_LazyWrapper'), + copyArray = require('./_copyArray'); + +/** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ +function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; +} + +module.exports = lazyClone; diff --git a/libs/events/node_modules/lodash/_lazyReverse.js b/libs/events/node_modules/lodash/_lazyReverse.js new file mode 100644 index 000000000..c5b52190f --- /dev/null +++ b/libs/events/node_modules/lodash/_lazyReverse.js @@ -0,0 +1,23 @@ +var LazyWrapper = require('./_LazyWrapper'); + +/** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ +function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; +} + +module.exports = lazyReverse; diff --git a/libs/events/node_modules/lodash/_lazyValue.js b/libs/events/node_modules/lodash/_lazyValue.js new file mode 100644 index 000000000..371ca8d22 --- /dev/null +++ b/libs/events/node_modules/lodash/_lazyValue.js @@ -0,0 +1,69 @@ +var baseWrapperValue = require('./_baseWrapperValue'), + getView = require('./_getView'), + isArray = require('./isArray'); + +/** Used to indicate the type of lazy iteratees. */ +var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ +function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || (!isRight && arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; +} + +module.exports = lazyValue; diff --git a/libs/events/node_modules/lodash/_listCacheClear.js b/libs/events/node_modules/lodash/_listCacheClear.js new file mode 100644 index 000000000..acbe39a59 --- /dev/null +++ b/libs/events/node_modules/lodash/_listCacheClear.js @@ -0,0 +1,13 @@ +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; + this.size = 0; +} + +module.exports = listCacheClear; diff --git a/libs/events/node_modules/lodash/_listCacheDelete.js b/libs/events/node_modules/lodash/_listCacheDelete.js new file mode 100644 index 000000000..b1384ade9 --- /dev/null +++ b/libs/events/node_modules/lodash/_listCacheDelete.js @@ -0,0 +1,35 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; +} + +module.exports = listCacheDelete; diff --git a/libs/events/node_modules/lodash/_listCacheGet.js b/libs/events/node_modules/lodash/_listCacheGet.js new file mode 100644 index 000000000..f8192fc38 --- /dev/null +++ b/libs/events/node_modules/lodash/_listCacheGet.js @@ -0,0 +1,19 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +module.exports = listCacheGet; diff --git a/libs/events/node_modules/lodash/_listCacheHas.js b/libs/events/node_modules/lodash/_listCacheHas.js new file mode 100644 index 000000000..2adf67146 --- /dev/null +++ b/libs/events/node_modules/lodash/_listCacheHas.js @@ -0,0 +1,16 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +module.exports = listCacheHas; diff --git a/libs/events/node_modules/lodash/_listCacheSet.js b/libs/events/node_modules/lodash/_listCacheSet.js new file mode 100644 index 000000000..5855c95e4 --- /dev/null +++ b/libs/events/node_modules/lodash/_listCacheSet.js @@ -0,0 +1,26 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +module.exports = listCacheSet; diff --git a/libs/events/node_modules/lodash/_mapCacheClear.js b/libs/events/node_modules/lodash/_mapCacheClear.js new file mode 100644 index 000000000..bc9ca204a --- /dev/null +++ b/libs/events/node_modules/lodash/_mapCacheClear.js @@ -0,0 +1,21 @@ +var Hash = require('./_Hash'), + ListCache = require('./_ListCache'), + Map = require('./_Map'); + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +module.exports = mapCacheClear; diff --git a/libs/events/node_modules/lodash/_mapCacheDelete.js b/libs/events/node_modules/lodash/_mapCacheDelete.js new file mode 100644 index 000000000..946ca3c93 --- /dev/null +++ b/libs/events/node_modules/lodash/_mapCacheDelete.js @@ -0,0 +1,18 @@ +var getMapData = require('./_getMapData'); + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; +} + +module.exports = mapCacheDelete; diff --git a/libs/events/node_modules/lodash/_mapCacheGet.js b/libs/events/node_modules/lodash/_mapCacheGet.js new file mode 100644 index 000000000..f29f55cfd --- /dev/null +++ b/libs/events/node_modules/lodash/_mapCacheGet.js @@ -0,0 +1,16 @@ +var getMapData = require('./_getMapData'); + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +module.exports = mapCacheGet; diff --git a/libs/events/node_modules/lodash/_mapCacheHas.js b/libs/events/node_modules/lodash/_mapCacheHas.js new file mode 100644 index 000000000..a1214c028 --- /dev/null +++ b/libs/events/node_modules/lodash/_mapCacheHas.js @@ -0,0 +1,16 @@ +var getMapData = require('./_getMapData'); + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +module.exports = mapCacheHas; diff --git a/libs/events/node_modules/lodash/_mapCacheSet.js b/libs/events/node_modules/lodash/_mapCacheSet.js new file mode 100644 index 000000000..734684927 --- /dev/null +++ b/libs/events/node_modules/lodash/_mapCacheSet.js @@ -0,0 +1,22 @@ +var getMapData = require('./_getMapData'); + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; +} + +module.exports = mapCacheSet; diff --git a/libs/events/node_modules/lodash/_mapToArray.js b/libs/events/node_modules/lodash/_mapToArray.js new file mode 100644 index 000000000..fe3dd531a --- /dev/null +++ b/libs/events/node_modules/lodash/_mapToArray.js @@ -0,0 +1,18 @@ +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +module.exports = mapToArray; diff --git a/libs/events/node_modules/lodash/_matchesStrictComparable.js b/libs/events/node_modules/lodash/_matchesStrictComparable.js new file mode 100644 index 000000000..f608af9ec --- /dev/null +++ b/libs/events/node_modules/lodash/_matchesStrictComparable.js @@ -0,0 +1,20 @@ +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +module.exports = matchesStrictComparable; diff --git a/libs/events/node_modules/lodash/_memoizeCapped.js b/libs/events/node_modules/lodash/_memoizeCapped.js new file mode 100644 index 000000000..7f71c8fba --- /dev/null +++ b/libs/events/node_modules/lodash/_memoizeCapped.js @@ -0,0 +1,26 @@ +var memoize = require('./memoize'); + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +module.exports = memoizeCapped; diff --git a/libs/events/node_modules/lodash/_mergeData.js b/libs/events/node_modules/lodash/_mergeData.js new file mode 100644 index 000000000..cb570f976 --- /dev/null +++ b/libs/events/node_modules/lodash/_mergeData.js @@ -0,0 +1,90 @@ +var composeArgs = require('./_composeArgs'), + composeArgsRight = require('./_composeArgsRight'), + replaceHolders = require('./_replaceHolders'); + +/** Used as the internal argument placeholder. */ +var PLACEHOLDER = '__lodash_placeholder__'; + +/** Used to compose bitmasks for function metadata. */ +var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_BOUND_FLAG = 4, + WRAP_CURRY_FLAG = 8, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and + * `_.rearg` modify function arguments, making the order in which they are + * executed important, preventing the merging of metadata. However, we make + * an exception for a safe combined case where curried functions have `_.ary` + * and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ +function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); + + var isCombo = + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & WRAP_BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : value; + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = value; + } + // Use source `ary` if it's smaller. + if (srcBitmask & WRAP_ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; +} + +module.exports = mergeData; diff --git a/libs/events/node_modules/lodash/_metaMap.js b/libs/events/node_modules/lodash/_metaMap.js new file mode 100644 index 000000000..0157a0b09 --- /dev/null +++ b/libs/events/node_modules/lodash/_metaMap.js @@ -0,0 +1,6 @@ +var WeakMap = require('./_WeakMap'); + +/** Used to store function metadata. */ +var metaMap = WeakMap && new WeakMap; + +module.exports = metaMap; diff --git a/libs/events/node_modules/lodash/_nativeCreate.js b/libs/events/node_modules/lodash/_nativeCreate.js new file mode 100644 index 000000000..c7aede85b --- /dev/null +++ b/libs/events/node_modules/lodash/_nativeCreate.js @@ -0,0 +1,6 @@ +var getNative = require('./_getNative'); + +/* Built-in method references that are verified to be native. */ +var nativeCreate = getNative(Object, 'create'); + +module.exports = nativeCreate; diff --git a/libs/events/node_modules/lodash/_nativeKeys.js b/libs/events/node_modules/lodash/_nativeKeys.js new file mode 100644 index 000000000..479a104a1 --- /dev/null +++ b/libs/events/node_modules/lodash/_nativeKeys.js @@ -0,0 +1,6 @@ +var overArg = require('./_overArg'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = overArg(Object.keys, Object); + +module.exports = nativeKeys; diff --git a/libs/events/node_modules/lodash/_nativeKeysIn.js b/libs/events/node_modules/lodash/_nativeKeysIn.js new file mode 100644 index 000000000..00ee50594 --- /dev/null +++ b/libs/events/node_modules/lodash/_nativeKeysIn.js @@ -0,0 +1,20 @@ +/** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; +} + +module.exports = nativeKeysIn; diff --git a/libs/events/node_modules/lodash/_nodeUtil.js b/libs/events/node_modules/lodash/_nodeUtil.js new file mode 100644 index 000000000..983d78f75 --- /dev/null +++ b/libs/events/node_modules/lodash/_nodeUtil.js @@ -0,0 +1,30 @@ +var freeGlobal = require('./_freeGlobal'); + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Detect free variable `process` from Node.js. */ +var freeProcess = moduleExports && freeGlobal.process; + +/** Used to access faster Node.js helpers. */ +var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} +}()); + +module.exports = nodeUtil; diff --git a/libs/events/node_modules/lodash/_objectToString.js b/libs/events/node_modules/lodash/_objectToString.js new file mode 100644 index 000000000..c614ec09b --- /dev/null +++ b/libs/events/node_modules/lodash/_objectToString.js @@ -0,0 +1,22 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ +function objectToString(value) { + return nativeObjectToString.call(value); +} + +module.exports = objectToString; diff --git a/libs/events/node_modules/lodash/_overArg.js b/libs/events/node_modules/lodash/_overArg.js new file mode 100644 index 000000000..651c5c55f --- /dev/null +++ b/libs/events/node_modules/lodash/_overArg.js @@ -0,0 +1,15 @@ +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +module.exports = overArg; diff --git a/libs/events/node_modules/lodash/_overRest.js b/libs/events/node_modules/lodash/_overRest.js new file mode 100644 index 000000000..c7cdef339 --- /dev/null +++ b/libs/events/node_modules/lodash/_overRest.js @@ -0,0 +1,36 @@ +var apply = require('./_apply'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ +function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; +} + +module.exports = overRest; diff --git a/libs/events/node_modules/lodash/_parent.js b/libs/events/node_modules/lodash/_parent.js new file mode 100644 index 000000000..f174328fc --- /dev/null +++ b/libs/events/node_modules/lodash/_parent.js @@ -0,0 +1,16 @@ +var baseGet = require('./_baseGet'), + baseSlice = require('./_baseSlice'); + +/** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ +function parent(object, path) { + return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); +} + +module.exports = parent; diff --git a/libs/events/node_modules/lodash/_reEscape.js b/libs/events/node_modules/lodash/_reEscape.js new file mode 100644 index 000000000..7f47eda68 --- /dev/null +++ b/libs/events/node_modules/lodash/_reEscape.js @@ -0,0 +1,4 @@ +/** Used to match template delimiters. */ +var reEscape = /<%-([\s\S]+?)%>/g; + +module.exports = reEscape; diff --git a/libs/events/node_modules/lodash/_reEvaluate.js b/libs/events/node_modules/lodash/_reEvaluate.js new file mode 100644 index 000000000..6adfc312c --- /dev/null +++ b/libs/events/node_modules/lodash/_reEvaluate.js @@ -0,0 +1,4 @@ +/** Used to match template delimiters. */ +var reEvaluate = /<%([\s\S]+?)%>/g; + +module.exports = reEvaluate; diff --git a/libs/events/node_modules/lodash/_reInterpolate.js b/libs/events/node_modules/lodash/_reInterpolate.js new file mode 100644 index 000000000..d02ff0b29 --- /dev/null +++ b/libs/events/node_modules/lodash/_reInterpolate.js @@ -0,0 +1,4 @@ +/** Used to match template delimiters. */ +var reInterpolate = /<%=([\s\S]+?)%>/g; + +module.exports = reInterpolate; diff --git a/libs/events/node_modules/lodash/_realNames.js b/libs/events/node_modules/lodash/_realNames.js new file mode 100644 index 000000000..aa0d52926 --- /dev/null +++ b/libs/events/node_modules/lodash/_realNames.js @@ -0,0 +1,4 @@ +/** Used to lookup unminified function names. */ +var realNames = {}; + +module.exports = realNames; diff --git a/libs/events/node_modules/lodash/_reorder.js b/libs/events/node_modules/lodash/_reorder.js new file mode 100644 index 000000000..a3502b051 --- /dev/null +++ b/libs/events/node_modules/lodash/_reorder.js @@ -0,0 +1,29 @@ +var copyArray = require('./_copyArray'), + isIndex = require('./_isIndex'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ +function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; +} + +module.exports = reorder; diff --git a/libs/events/node_modules/lodash/_replaceHolders.js b/libs/events/node_modules/lodash/_replaceHolders.js new file mode 100644 index 000000000..74360ec4d --- /dev/null +++ b/libs/events/node_modules/lodash/_replaceHolders.js @@ -0,0 +1,29 @@ +/** Used as the internal argument placeholder. */ +var PLACEHOLDER = '__lodash_placeholder__'; + +/** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ +function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } + return result; +} + +module.exports = replaceHolders; diff --git a/libs/events/node_modules/lodash/_root.js b/libs/events/node_modules/lodash/_root.js new file mode 100644 index 000000000..d2852bed4 --- /dev/null +++ b/libs/events/node_modules/lodash/_root.js @@ -0,0 +1,9 @@ +var freeGlobal = require('./_freeGlobal'); + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +module.exports = root; diff --git a/libs/events/node_modules/lodash/_safeGet.js b/libs/events/node_modules/lodash/_safeGet.js new file mode 100644 index 000000000..b070897db --- /dev/null +++ b/libs/events/node_modules/lodash/_safeGet.js @@ -0,0 +1,21 @@ +/** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + + if (key == '__proto__') { + return; + } + + return object[key]; +} + +module.exports = safeGet; diff --git a/libs/events/node_modules/lodash/_setCacheAdd.js b/libs/events/node_modules/lodash/_setCacheAdd.js new file mode 100644 index 000000000..1081a7442 --- /dev/null +++ b/libs/events/node_modules/lodash/_setCacheAdd.js @@ -0,0 +1,19 @@ +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +module.exports = setCacheAdd; diff --git a/libs/events/node_modules/lodash/_setCacheHas.js b/libs/events/node_modules/lodash/_setCacheHas.js new file mode 100644 index 000000000..9a492556e --- /dev/null +++ b/libs/events/node_modules/lodash/_setCacheHas.js @@ -0,0 +1,14 @@ +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +module.exports = setCacheHas; diff --git a/libs/events/node_modules/lodash/_setData.js b/libs/events/node_modules/lodash/_setData.js new file mode 100644 index 000000000..e5cf3eb96 --- /dev/null +++ b/libs/events/node_modules/lodash/_setData.js @@ -0,0 +1,20 @@ +var baseSetData = require('./_baseSetData'), + shortOut = require('./_shortOut'); + +/** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity + * function to avoid garbage collection pauses in V8. See + * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ +var setData = shortOut(baseSetData); + +module.exports = setData; diff --git a/libs/events/node_modules/lodash/_setToArray.js b/libs/events/node_modules/lodash/_setToArray.js new file mode 100644 index 000000000..b87f07418 --- /dev/null +++ b/libs/events/node_modules/lodash/_setToArray.js @@ -0,0 +1,18 @@ +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +module.exports = setToArray; diff --git a/libs/events/node_modules/lodash/_setToPairs.js b/libs/events/node_modules/lodash/_setToPairs.js new file mode 100644 index 000000000..36ad37a05 --- /dev/null +++ b/libs/events/node_modules/lodash/_setToPairs.js @@ -0,0 +1,18 @@ +/** + * Converts `set` to its value-value pairs. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the value-value pairs. + */ +function setToPairs(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = [value, value]; + }); + return result; +} + +module.exports = setToPairs; diff --git a/libs/events/node_modules/lodash/_setToString.js b/libs/events/node_modules/lodash/_setToString.js new file mode 100644 index 000000000..6ca841967 --- /dev/null +++ b/libs/events/node_modules/lodash/_setToString.js @@ -0,0 +1,14 @@ +var baseSetToString = require('./_baseSetToString'), + shortOut = require('./_shortOut'); + +/** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ +var setToString = shortOut(baseSetToString); + +module.exports = setToString; diff --git a/libs/events/node_modules/lodash/_setWrapToString.js b/libs/events/node_modules/lodash/_setWrapToString.js new file mode 100644 index 000000000..decdc4499 --- /dev/null +++ b/libs/events/node_modules/lodash/_setWrapToString.js @@ -0,0 +1,21 @@ +var getWrapDetails = require('./_getWrapDetails'), + insertWrapDetails = require('./_insertWrapDetails'), + setToString = require('./_setToString'), + updateWrapDetails = require('./_updateWrapDetails'); + +/** + * Sets the `toString` method of `wrapper` to mimic the source of `reference` + * with wrapper details in a comment at the top of the source body. + * + * @private + * @param {Function} wrapper The function to modify. + * @param {Function} reference The reference function. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Function} Returns `wrapper`. + */ +function setWrapToString(wrapper, reference, bitmask) { + var source = (reference + ''); + return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); +} + +module.exports = setWrapToString; diff --git a/libs/events/node_modules/lodash/_shortOut.js b/libs/events/node_modules/lodash/_shortOut.js new file mode 100644 index 000000000..3300a0796 --- /dev/null +++ b/libs/events/node_modules/lodash/_shortOut.js @@ -0,0 +1,37 @@ +/** Used to detect hot functions by number of calls within a span of milliseconds. */ +var HOT_COUNT = 800, + HOT_SPAN = 16; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeNow = Date.now; + +/** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ +function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; +} + +module.exports = shortOut; diff --git a/libs/events/node_modules/lodash/_shuffleSelf.js b/libs/events/node_modules/lodash/_shuffleSelf.js new file mode 100644 index 000000000..8bcc4f5c3 --- /dev/null +++ b/libs/events/node_modules/lodash/_shuffleSelf.js @@ -0,0 +1,28 @@ +var baseRandom = require('./_baseRandom'); + +/** + * A specialized version of `_.shuffle` which mutates and sets the size of `array`. + * + * @private + * @param {Array} array The array to shuffle. + * @param {number} [size=array.length] The size of `array`. + * @returns {Array} Returns `array`. + */ +function shuffleSelf(array, size) { + var index = -1, + length = array.length, + lastIndex = length - 1; + + size = size === undefined ? length : size; + while (++index < size) { + var rand = baseRandom(index, lastIndex), + value = array[rand]; + + array[rand] = array[index]; + array[index] = value; + } + array.length = size; + return array; +} + +module.exports = shuffleSelf; diff --git a/libs/events/node_modules/lodash/_stackClear.js b/libs/events/node_modules/lodash/_stackClear.js new file mode 100644 index 000000000..ce8e5a92f --- /dev/null +++ b/libs/events/node_modules/lodash/_stackClear.js @@ -0,0 +1,15 @@ +var ListCache = require('./_ListCache'); + +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = new ListCache; + this.size = 0; +} + +module.exports = stackClear; diff --git a/libs/events/node_modules/lodash/_stackDelete.js b/libs/events/node_modules/lodash/_stackDelete.js new file mode 100644 index 000000000..ff9887ab6 --- /dev/null +++ b/libs/events/node_modules/lodash/_stackDelete.js @@ -0,0 +1,18 @@ +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; +} + +module.exports = stackDelete; diff --git a/libs/events/node_modules/lodash/_stackGet.js b/libs/events/node_modules/lodash/_stackGet.js new file mode 100644 index 000000000..1cdf00409 --- /dev/null +++ b/libs/events/node_modules/lodash/_stackGet.js @@ -0,0 +1,14 @@ +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} + +module.exports = stackGet; diff --git a/libs/events/node_modules/lodash/_stackHas.js b/libs/events/node_modules/lodash/_stackHas.js new file mode 100644 index 000000000..16a3ad11b --- /dev/null +++ b/libs/events/node_modules/lodash/_stackHas.js @@ -0,0 +1,14 @@ +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} + +module.exports = stackHas; diff --git a/libs/events/node_modules/lodash/_stackSet.js b/libs/events/node_modules/lodash/_stackSet.js new file mode 100644 index 000000000..b790ac5f4 --- /dev/null +++ b/libs/events/node_modules/lodash/_stackSet.js @@ -0,0 +1,34 @@ +var ListCache = require('./_ListCache'), + Map = require('./_Map'), + MapCache = require('./_MapCache'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ +function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; +} + +module.exports = stackSet; diff --git a/libs/events/node_modules/lodash/_strictIndexOf.js b/libs/events/node_modules/lodash/_strictIndexOf.js new file mode 100644 index 000000000..0486a4956 --- /dev/null +++ b/libs/events/node_modules/lodash/_strictIndexOf.js @@ -0,0 +1,23 @@ +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +module.exports = strictIndexOf; diff --git a/libs/events/node_modules/lodash/_strictLastIndexOf.js b/libs/events/node_modules/lodash/_strictLastIndexOf.js new file mode 100644 index 000000000..d7310dcc2 --- /dev/null +++ b/libs/events/node_modules/lodash/_strictLastIndexOf.js @@ -0,0 +1,21 @@ +/** + * A specialized version of `_.lastIndexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictLastIndexOf(array, value, fromIndex) { + var index = fromIndex + 1; + while (index--) { + if (array[index] === value) { + return index; + } + } + return index; +} + +module.exports = strictLastIndexOf; diff --git a/libs/events/node_modules/lodash/_stringSize.js b/libs/events/node_modules/lodash/_stringSize.js new file mode 100644 index 000000000..17ef462a6 --- /dev/null +++ b/libs/events/node_modules/lodash/_stringSize.js @@ -0,0 +1,18 @@ +var asciiSize = require('./_asciiSize'), + hasUnicode = require('./_hasUnicode'), + unicodeSize = require('./_unicodeSize'); + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return hasUnicode(string) + ? unicodeSize(string) + : asciiSize(string); +} + +module.exports = stringSize; diff --git a/libs/events/node_modules/lodash/_stringToArray.js b/libs/events/node_modules/lodash/_stringToArray.js new file mode 100644 index 000000000..d161158c6 --- /dev/null +++ b/libs/events/node_modules/lodash/_stringToArray.js @@ -0,0 +1,18 @@ +var asciiToArray = require('./_asciiToArray'), + hasUnicode = require('./_hasUnicode'), + unicodeToArray = require('./_unicodeToArray'); + +/** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); +} + +module.exports = stringToArray; diff --git a/libs/events/node_modules/lodash/_stringToPath.js b/libs/events/node_modules/lodash/_stringToPath.js new file mode 100644 index 000000000..8f39f8a29 --- /dev/null +++ b/libs/events/node_modules/lodash/_stringToPath.js @@ -0,0 +1,27 @@ +var memoizeCapped = require('./_memoizeCapped'); + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +module.exports = stringToPath; diff --git a/libs/events/node_modules/lodash/_toKey.js b/libs/events/node_modules/lodash/_toKey.js new file mode 100644 index 000000000..c6d645c4d --- /dev/null +++ b/libs/events/node_modules/lodash/_toKey.js @@ -0,0 +1,21 @@ +var isSymbol = require('./isSymbol'); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +module.exports = toKey; diff --git a/libs/events/node_modules/lodash/_toSource.js b/libs/events/node_modules/lodash/_toSource.js new file mode 100644 index 000000000..a020b386c --- /dev/null +++ b/libs/events/node_modules/lodash/_toSource.js @@ -0,0 +1,26 @@ +/** Used for built-in method references. */ +var funcProto = Function.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +module.exports = toSource; diff --git a/libs/events/node_modules/lodash/_trimmedEndIndex.js b/libs/events/node_modules/lodash/_trimmedEndIndex.js new file mode 100644 index 000000000..139439ad4 --- /dev/null +++ b/libs/events/node_modules/lodash/_trimmedEndIndex.js @@ -0,0 +1,19 @@ +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +module.exports = trimmedEndIndex; diff --git a/libs/events/node_modules/lodash/_unescapeHtmlChar.js b/libs/events/node_modules/lodash/_unescapeHtmlChar.js new file mode 100644 index 000000000..a71fecb3f --- /dev/null +++ b/libs/events/node_modules/lodash/_unescapeHtmlChar.js @@ -0,0 +1,21 @@ +var basePropertyOf = require('./_basePropertyOf'); + +/** Used to map HTML entities to characters. */ +var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" +}; + +/** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ +var unescapeHtmlChar = basePropertyOf(htmlUnescapes); + +module.exports = unescapeHtmlChar; diff --git a/libs/events/node_modules/lodash/_unicodeSize.js b/libs/events/node_modules/lodash/_unicodeSize.js new file mode 100644 index 000000000..68137ec2c --- /dev/null +++ b/libs/events/node_modules/lodash/_unicodeSize.js @@ -0,0 +1,44 @@ +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + rsAstralRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +module.exports = unicodeSize; diff --git a/libs/events/node_modules/lodash/_unicodeToArray.js b/libs/events/node_modules/lodash/_unicodeToArray.js new file mode 100644 index 000000000..2a725c062 --- /dev/null +++ b/libs/events/node_modules/lodash/_unicodeToArray.js @@ -0,0 +1,40 @@ +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + rsAstralRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function unicodeToArray(string) { + return string.match(reUnicode) || []; +} + +module.exports = unicodeToArray; diff --git a/libs/events/node_modules/lodash/_unicodeWords.js b/libs/events/node_modules/lodash/_unicodeWords.js new file mode 100644 index 000000000..e72e6e0f9 --- /dev/null +++ b/libs/events/node_modules/lodash/_unicodeWords.js @@ -0,0 +1,69 @@ +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsDingbatRange = '\\u2700-\\u27bf', + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsPunctuationRange = '\\u2000-\\u206f', + rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = '\\ufe0e\\ufe0f', + rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; + +/** Used to compose unicode capture groups. */ +var rsApos = "['\u2019]", + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', + rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', + rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', + rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', + rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq; + +/** Used to match complex or compound words. */ +var reUnicodeWord = RegExp([ + rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', + rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, + rsUpper + '+' + rsOptContrUpper, + rsOrdUpper, + rsOrdLower, + rsDigits, + rsEmoji +].join('|'), 'g'); + +/** + * Splits a Unicode `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ +function unicodeWords(string) { + return string.match(reUnicodeWord) || []; +} + +module.exports = unicodeWords; diff --git a/libs/events/node_modules/lodash/_updateWrapDetails.js b/libs/events/node_modules/lodash/_updateWrapDetails.js new file mode 100644 index 000000000..8759fbdf7 --- /dev/null +++ b/libs/events/node_modules/lodash/_updateWrapDetails.js @@ -0,0 +1,46 @@ +var arrayEach = require('./_arrayEach'), + arrayIncludes = require('./_arrayIncludes'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_FLAG = 8, + WRAP_CURRY_RIGHT_FLAG = 16, + WRAP_PARTIAL_FLAG = 32, + WRAP_PARTIAL_RIGHT_FLAG = 64, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256, + WRAP_FLIP_FLAG = 512; + +/** Used to associate wrap methods with their bit flags. */ +var wrapFlags = [ + ['ary', WRAP_ARY_FLAG], + ['bind', WRAP_BIND_FLAG], + ['bindKey', WRAP_BIND_KEY_FLAG], + ['curry', WRAP_CURRY_FLAG], + ['curryRight', WRAP_CURRY_RIGHT_FLAG], + ['flip', WRAP_FLIP_FLAG], + ['partial', WRAP_PARTIAL_FLAG], + ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], + ['rearg', WRAP_REARG_FLAG] +]; + +/** + * Updates wrapper `details` based on `bitmask` flags. + * + * @private + * @returns {Array} details The details to modify. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Array} Returns `details`. + */ +function updateWrapDetails(details, bitmask) { + arrayEach(wrapFlags, function(pair) { + var value = '_.' + pair[0]; + if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { + details.push(value); + } + }); + return details.sort(); +} + +module.exports = updateWrapDetails; diff --git a/libs/events/node_modules/lodash/_wrapperClone.js b/libs/events/node_modules/lodash/_wrapperClone.js new file mode 100644 index 000000000..7bb58a2e8 --- /dev/null +++ b/libs/events/node_modules/lodash/_wrapperClone.js @@ -0,0 +1,23 @@ +var LazyWrapper = require('./_LazyWrapper'), + LodashWrapper = require('./_LodashWrapper'), + copyArray = require('./_copyArray'); + +/** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ +function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; +} + +module.exports = wrapperClone; diff --git a/libs/events/node_modules/lodash/add.js b/libs/events/node_modules/lodash/add.js new file mode 100644 index 000000000..f06951564 --- /dev/null +++ b/libs/events/node_modules/lodash/add.js @@ -0,0 +1,22 @@ +var createMathOperation = require('./_createMathOperation'); + +/** + * Adds two numbers. + * + * @static + * @memberOf _ + * @since 3.4.0 + * @category Math + * @param {number} augend The first number in an addition. + * @param {number} addend The second number in an addition. + * @returns {number} Returns the total. + * @example + * + * _.add(6, 4); + * // => 10 + */ +var add = createMathOperation(function(augend, addend) { + return augend + addend; +}, 0); + +module.exports = add; diff --git a/libs/events/node_modules/lodash/after.js b/libs/events/node_modules/lodash/after.js new file mode 100644 index 000000000..3900c979a --- /dev/null +++ b/libs/events/node_modules/lodash/after.js @@ -0,0 +1,42 @@ +var toInteger = require('./toInteger'); + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => Logs 'done saving!' after the two async saves have completed. + */ +function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; +} + +module.exports = after; diff --git a/libs/events/node_modules/lodash/array.js b/libs/events/node_modules/lodash/array.js new file mode 100644 index 000000000..af688d3ee --- /dev/null +++ b/libs/events/node_modules/lodash/array.js @@ -0,0 +1,67 @@ +module.exports = { + 'chunk': require('./chunk'), + 'compact': require('./compact'), + 'concat': require('./concat'), + 'difference': require('./difference'), + 'differenceBy': require('./differenceBy'), + 'differenceWith': require('./differenceWith'), + 'drop': require('./drop'), + 'dropRight': require('./dropRight'), + 'dropRightWhile': require('./dropRightWhile'), + 'dropWhile': require('./dropWhile'), + 'fill': require('./fill'), + 'findIndex': require('./findIndex'), + 'findLastIndex': require('./findLastIndex'), + 'first': require('./first'), + 'flatten': require('./flatten'), + 'flattenDeep': require('./flattenDeep'), + 'flattenDepth': require('./flattenDepth'), + 'fromPairs': require('./fromPairs'), + 'head': require('./head'), + 'indexOf': require('./indexOf'), + 'initial': require('./initial'), + 'intersection': require('./intersection'), + 'intersectionBy': require('./intersectionBy'), + 'intersectionWith': require('./intersectionWith'), + 'join': require('./join'), + 'last': require('./last'), + 'lastIndexOf': require('./lastIndexOf'), + 'nth': require('./nth'), + 'pull': require('./pull'), + 'pullAll': require('./pullAll'), + 'pullAllBy': require('./pullAllBy'), + 'pullAllWith': require('./pullAllWith'), + 'pullAt': require('./pullAt'), + 'remove': require('./remove'), + 'reverse': require('./reverse'), + 'slice': require('./slice'), + 'sortedIndex': require('./sortedIndex'), + 'sortedIndexBy': require('./sortedIndexBy'), + 'sortedIndexOf': require('./sortedIndexOf'), + 'sortedLastIndex': require('./sortedLastIndex'), + 'sortedLastIndexBy': require('./sortedLastIndexBy'), + 'sortedLastIndexOf': require('./sortedLastIndexOf'), + 'sortedUniq': require('./sortedUniq'), + 'sortedUniqBy': require('./sortedUniqBy'), + 'tail': require('./tail'), + 'take': require('./take'), + 'takeRight': require('./takeRight'), + 'takeRightWhile': require('./takeRightWhile'), + 'takeWhile': require('./takeWhile'), + 'union': require('./union'), + 'unionBy': require('./unionBy'), + 'unionWith': require('./unionWith'), + 'uniq': require('./uniq'), + 'uniqBy': require('./uniqBy'), + 'uniqWith': require('./uniqWith'), + 'unzip': require('./unzip'), + 'unzipWith': require('./unzipWith'), + 'without': require('./without'), + 'xor': require('./xor'), + 'xorBy': require('./xorBy'), + 'xorWith': require('./xorWith'), + 'zip': require('./zip'), + 'zipObject': require('./zipObject'), + 'zipObjectDeep': require('./zipObjectDeep'), + 'zipWith': require('./zipWith') +}; diff --git a/libs/events/node_modules/lodash/ary.js b/libs/events/node_modules/lodash/ary.js new file mode 100644 index 000000000..70c87d094 --- /dev/null +++ b/libs/events/node_modules/lodash/ary.js @@ -0,0 +1,29 @@ +var createWrap = require('./_createWrap'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_ARY_FLAG = 128; + +/** + * Creates a function that invokes `func`, with up to `n` arguments, + * ignoring any additional arguments. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new capped function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ +function ary(func, n, guard) { + n = guard ? undefined : n; + n = (func && n == null) ? func.length : n; + return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n); +} + +module.exports = ary; diff --git a/libs/events/node_modules/lodash/assign.js b/libs/events/node_modules/lodash/assign.js new file mode 100644 index 000000000..909db26a3 --- /dev/null +++ b/libs/events/node_modules/lodash/assign.js @@ -0,0 +1,58 @@ +var assignValue = require('./_assignValue'), + copyObject = require('./_copyObject'), + createAssigner = require('./_createAssigner'), + isArrayLike = require('./isArrayLike'), + isPrototype = require('./_isPrototype'), + keys = require('./keys'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ +var assign = createAssigner(function(object, source) { + if (isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } +}); + +module.exports = assign; diff --git a/libs/events/node_modules/lodash/assignIn.js b/libs/events/node_modules/lodash/assignIn.js new file mode 100644 index 000000000..e663473a0 --- /dev/null +++ b/libs/events/node_modules/lodash/assignIn.js @@ -0,0 +1,40 @@ +var copyObject = require('./_copyObject'), + createAssigner = require('./_createAssigner'), + keysIn = require('./keysIn'); + +/** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assign + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assignIn({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } + */ +var assignIn = createAssigner(function(object, source) { + copyObject(source, keysIn(source), object); +}); + +module.exports = assignIn; diff --git a/libs/events/node_modules/lodash/assignInWith.js b/libs/events/node_modules/lodash/assignInWith.js new file mode 100644 index 000000000..68fcc0b03 --- /dev/null +++ b/libs/events/node_modules/lodash/assignInWith.js @@ -0,0 +1,38 @@ +var copyObject = require('./_copyObject'), + createAssigner = require('./_createAssigner'), + keysIn = require('./keysIn'); + +/** + * This method is like `_.assignIn` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keysIn(source), object, customizer); +}); + +module.exports = assignInWith; diff --git a/libs/events/node_modules/lodash/assignWith.js b/libs/events/node_modules/lodash/assignWith.js new file mode 100644 index 000000000..7dc6c761b --- /dev/null +++ b/libs/events/node_modules/lodash/assignWith.js @@ -0,0 +1,37 @@ +var copyObject = require('./_copyObject'), + createAssigner = require('./_createAssigner'), + keys = require('./keys'); + +/** + * This method is like `_.assign` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignInWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keys(source), object, customizer); +}); + +module.exports = assignWith; diff --git a/libs/events/node_modules/lodash/at.js b/libs/events/node_modules/lodash/at.js new file mode 100644 index 000000000..781ee9e5f --- /dev/null +++ b/libs/events/node_modules/lodash/at.js @@ -0,0 +1,23 @@ +var baseAt = require('./_baseAt'), + flatRest = require('./_flatRest'); + +/** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Array} Returns the picked values. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + */ +var at = flatRest(baseAt); + +module.exports = at; diff --git a/libs/events/node_modules/lodash/attempt.js b/libs/events/node_modules/lodash/attempt.js new file mode 100644 index 000000000..624d01524 --- /dev/null +++ b/libs/events/node_modules/lodash/attempt.js @@ -0,0 +1,35 @@ +var apply = require('./_apply'), + baseRest = require('./_baseRest'), + isError = require('./isError'); + +/** + * Attempts to invoke `func`, returning either the result or the caught error + * object. Any additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Util + * @param {Function} func The function to attempt. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {*} Returns the `func` result or error object. + * @example + * + * // Avoid throwing errors for invalid selectors. + * var elements = _.attempt(function(selector) { + * return document.querySelectorAll(selector); + * }, '>_>'); + * + * if (_.isError(elements)) { + * elements = []; + * } + */ +var attempt = baseRest(function(func, args) { + try { + return apply(func, undefined, args); + } catch (e) { + return isError(e) ? e : new Error(e); + } +}); + +module.exports = attempt; diff --git a/libs/events/node_modules/lodash/before.js b/libs/events/node_modules/lodash/before.js new file mode 100644 index 000000000..a3e0a16c7 --- /dev/null +++ b/libs/events/node_modules/lodash/before.js @@ -0,0 +1,40 @@ +var toInteger = require('./toInteger'); + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => Allows adding up to 4 contacts to the list. + */ +function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; +} + +module.exports = before; diff --git a/libs/events/node_modules/lodash/bind.js b/libs/events/node_modules/lodash/bind.js new file mode 100644 index 000000000..b1076e93e --- /dev/null +++ b/libs/events/node_modules/lodash/bind.js @@ -0,0 +1,57 @@ +var baseRest = require('./_baseRest'), + createWrap = require('./_createWrap'), + getHolder = require('./_getHolder'), + replaceHolders = require('./_replaceHolders'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_BIND_FLAG = 1, + WRAP_PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and `partials` prepended to the arguments it receives. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * function greet(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ +var bind = baseRest(function(func, thisArg, partials) { + var bitmask = WRAP_BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bind)); + bitmask |= WRAP_PARTIAL_FLAG; + } + return createWrap(func, bitmask, thisArg, partials, holders); +}); + +// Assign default placeholders. +bind.placeholder = {}; + +module.exports = bind; diff --git a/libs/events/node_modules/lodash/bindAll.js b/libs/events/node_modules/lodash/bindAll.js new file mode 100644 index 000000000..a35706dee --- /dev/null +++ b/libs/events/node_modules/lodash/bindAll.js @@ -0,0 +1,41 @@ +var arrayEach = require('./_arrayEach'), + baseAssignValue = require('./_baseAssignValue'), + bind = require('./bind'), + flatRest = require('./_flatRest'), + toKey = require('./_toKey'); + +/** + * Binds methods of an object to the object itself, overwriting the existing + * method. + * + * **Note:** This method doesn't set the "length" property of bound functions. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} methodNames The object method names to bind. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'click': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view, ['click']); + * jQuery(element).on('click', view.click); + * // => Logs 'clicked docs' when clicked. + */ +var bindAll = flatRest(function(object, methodNames) { + arrayEach(methodNames, function(key) { + key = toKey(key); + baseAssignValue(object, key, bind(object[key], object)); + }); + return object; +}); + +module.exports = bindAll; diff --git a/libs/events/node_modules/lodash/bindKey.js b/libs/events/node_modules/lodash/bindKey.js new file mode 100644 index 000000000..f7fd64cd4 --- /dev/null +++ b/libs/events/node_modules/lodash/bindKey.js @@ -0,0 +1,68 @@ +var baseRest = require('./_baseRest'), + createWrap = require('./_createWrap'), + getHolder = require('./_getHolder'), + replaceHolders = require('./_replaceHolders'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes the method at `object[key]` with `partials` + * prepended to the arguments it receives. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. See + * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Function + * @param {Object} object The object to invoke the method on. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // Bound with placeholders. + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ +var bindKey = baseRest(function(object, key, partials) { + var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bindKey)); + bitmask |= WRAP_PARTIAL_FLAG; + } + return createWrap(key, bitmask, object, partials, holders); +}); + +// Assign default placeholders. +bindKey.placeholder = {}; + +module.exports = bindKey; diff --git a/libs/events/node_modules/lodash/camelCase.js b/libs/events/node_modules/lodash/camelCase.js new file mode 100644 index 000000000..d7390def5 --- /dev/null +++ b/libs/events/node_modules/lodash/camelCase.js @@ -0,0 +1,29 @@ +var capitalize = require('./capitalize'), + createCompounder = require('./_createCompounder'); + +/** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ +var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); +}); + +module.exports = camelCase; diff --git a/libs/events/node_modules/lodash/capitalize.js b/libs/events/node_modules/lodash/capitalize.js new file mode 100644 index 000000000..3e1600e7d --- /dev/null +++ b/libs/events/node_modules/lodash/capitalize.js @@ -0,0 +1,23 @@ +var toString = require('./toString'), + upperFirst = require('./upperFirst'); + +/** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ +function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); +} + +module.exports = capitalize; diff --git a/libs/events/node_modules/lodash/castArray.js b/libs/events/node_modules/lodash/castArray.js new file mode 100644 index 000000000..e470bdb9b --- /dev/null +++ b/libs/events/node_modules/lodash/castArray.js @@ -0,0 +1,44 @@ +var isArray = require('./isArray'); + +/** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ +function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; +} + +module.exports = castArray; diff --git a/libs/events/node_modules/lodash/ceil.js b/libs/events/node_modules/lodash/ceil.js new file mode 100644 index 000000000..56c8722cf --- /dev/null +++ b/libs/events/node_modules/lodash/ceil.js @@ -0,0 +1,26 @@ +var createRound = require('./_createRound'); + +/** + * Computes `number` rounded up to `precision`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Math + * @param {number} number The number to round up. + * @param {number} [precision=0] The precision to round up to. + * @returns {number} Returns the rounded up number. + * @example + * + * _.ceil(4.006); + * // => 5 + * + * _.ceil(6.004, 2); + * // => 6.01 + * + * _.ceil(6040, -2); + * // => 6100 + */ +var ceil = createRound('ceil'); + +module.exports = ceil; diff --git a/libs/events/node_modules/lodash/chain.js b/libs/events/node_modules/lodash/chain.js new file mode 100644 index 000000000..f6cd6475f --- /dev/null +++ b/libs/events/node_modules/lodash/chain.js @@ -0,0 +1,38 @@ +var lodash = require('./wrapperLodash'); + +/** + * Creates a `lodash` wrapper instance that wraps `value` with explicit method + * chain sequences enabled. The result of such sequences must be unwrapped + * with `_#value`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ +function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; +} + +module.exports = chain; diff --git a/libs/events/node_modules/lodash/chunk.js b/libs/events/node_modules/lodash/chunk.js new file mode 100644 index 000000000..5b562fef3 --- /dev/null +++ b/libs/events/node_modules/lodash/chunk.js @@ -0,0 +1,50 @@ +var baseSlice = require('./_baseSlice'), + isIterateeCall = require('./_isIterateeCall'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the new array of chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ +function chunk(array, size, guard) { + if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { + size = 1; + } else { + size = nativeMax(toInteger(size), 0); + } + var length = array == null ? 0 : array.length; + if (!length || size < 1) { + return []; + } + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[resIndex++] = baseSlice(array, index, (index += size)); + } + return result; +} + +module.exports = chunk; diff --git a/libs/events/node_modules/lodash/clamp.js b/libs/events/node_modules/lodash/clamp.js new file mode 100644 index 000000000..91a72c978 --- /dev/null +++ b/libs/events/node_modules/lodash/clamp.js @@ -0,0 +1,39 @@ +var baseClamp = require('./_baseClamp'), + toNumber = require('./toNumber'); + +/** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ +function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); +} + +module.exports = clamp; diff --git a/libs/events/node_modules/lodash/clone.js b/libs/events/node_modules/lodash/clone.js new file mode 100644 index 000000000..dd439d639 --- /dev/null +++ b/libs/events/node_modules/lodash/clone.js @@ -0,0 +1,36 @@ +var baseClone = require('./_baseClone'); + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return baseClone(value, CLONE_SYMBOLS_FLAG); +} + +module.exports = clone; diff --git a/libs/events/node_modules/lodash/cloneDeep.js b/libs/events/node_modules/lodash/cloneDeep.js new file mode 100644 index 000000000..4425fbe8b --- /dev/null +++ b/libs/events/node_modules/lodash/cloneDeep.js @@ -0,0 +1,29 @@ +var baseClone = require('./_baseClone'); + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +module.exports = cloneDeep; diff --git a/libs/events/node_modules/lodash/cloneDeepWith.js b/libs/events/node_modules/lodash/cloneDeepWith.js new file mode 100644 index 000000000..fd9c6c050 --- /dev/null +++ b/libs/events/node_modules/lodash/cloneDeepWith.js @@ -0,0 +1,40 @@ +var baseClone = require('./_baseClone'); + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @see _.cloneWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ +function cloneDeepWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); +} + +module.exports = cloneDeepWith; diff --git a/libs/events/node_modules/lodash/cloneWith.js b/libs/events/node_modules/lodash/cloneWith.js new file mode 100644 index 000000000..d2f4e756d --- /dev/null +++ b/libs/events/node_modules/lodash/cloneWith.js @@ -0,0 +1,42 @@ +var baseClone = require('./_baseClone'); + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined`, + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @see _.cloneDeepWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ +function cloneWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); +} + +module.exports = cloneWith; diff --git a/libs/events/node_modules/lodash/collection.js b/libs/events/node_modules/lodash/collection.js new file mode 100644 index 000000000..77fe837f3 --- /dev/null +++ b/libs/events/node_modules/lodash/collection.js @@ -0,0 +1,30 @@ +module.exports = { + 'countBy': require('./countBy'), + 'each': require('./each'), + 'eachRight': require('./eachRight'), + 'every': require('./every'), + 'filter': require('./filter'), + 'find': require('./find'), + 'findLast': require('./findLast'), + 'flatMap': require('./flatMap'), + 'flatMapDeep': require('./flatMapDeep'), + 'flatMapDepth': require('./flatMapDepth'), + 'forEach': require('./forEach'), + 'forEachRight': require('./forEachRight'), + 'groupBy': require('./groupBy'), + 'includes': require('./includes'), + 'invokeMap': require('./invokeMap'), + 'keyBy': require('./keyBy'), + 'map': require('./map'), + 'orderBy': require('./orderBy'), + 'partition': require('./partition'), + 'reduce': require('./reduce'), + 'reduceRight': require('./reduceRight'), + 'reject': require('./reject'), + 'sample': require('./sample'), + 'sampleSize': require('./sampleSize'), + 'shuffle': require('./shuffle'), + 'size': require('./size'), + 'some': require('./some'), + 'sortBy': require('./sortBy') +}; diff --git a/libs/events/node_modules/lodash/commit.js b/libs/events/node_modules/lodash/commit.js new file mode 100644 index 000000000..fe4db7178 --- /dev/null +++ b/libs/events/node_modules/lodash/commit.js @@ -0,0 +1,33 @@ +var LodashWrapper = require('./_LodashWrapper'); + +/** + * Executes the chain sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ +function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); +} + +module.exports = wrapperCommit; diff --git a/libs/events/node_modules/lodash/compact.js b/libs/events/node_modules/lodash/compact.js new file mode 100644 index 000000000..031fab4e6 --- /dev/null +++ b/libs/events/node_modules/lodash/compact.js @@ -0,0 +1,31 @@ +/** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ +function compact(array) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[resIndex++] = value; + } + } + return result; +} + +module.exports = compact; diff --git a/libs/events/node_modules/lodash/concat.js b/libs/events/node_modules/lodash/concat.js new file mode 100644 index 000000000..1da48a4fc --- /dev/null +++ b/libs/events/node_modules/lodash/concat.js @@ -0,0 +1,43 @@ +var arrayPush = require('./_arrayPush'), + baseFlatten = require('./_baseFlatten'), + copyArray = require('./_copyArray'), + isArray = require('./isArray'); + +/** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ +function concat() { + var length = arguments.length; + if (!length) { + return []; + } + var args = Array(length - 1), + array = arguments[0], + index = length; + + while (index--) { + args[index - 1] = arguments[index]; + } + return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); +} + +module.exports = concat; diff --git a/libs/events/node_modules/lodash/cond.js b/libs/events/node_modules/lodash/cond.js new file mode 100644 index 000000000..64555986a --- /dev/null +++ b/libs/events/node_modules/lodash/cond.js @@ -0,0 +1,60 @@ +var apply = require('./_apply'), + arrayMap = require('./_arrayMap'), + baseIteratee = require('./_baseIteratee'), + baseRest = require('./_baseRest'); + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that iterates over `pairs` and invokes the corresponding + * function of the first predicate to return truthy. The predicate-function + * pairs are invoked with the `this` binding and arguments of the created + * function. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Util + * @param {Array} pairs The predicate-function pairs. + * @returns {Function} Returns the new composite function. + * @example + * + * var func = _.cond([ + * [_.matches({ 'a': 1 }), _.constant('matches A')], + * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')], + * [_.stubTrue, _.constant('no match')] + * ]); + * + * func({ 'a': 1, 'b': 2 }); + * // => 'matches A' + * + * func({ 'a': 0, 'b': 1 }); + * // => 'matches B' + * + * func({ 'a': '1', 'b': '2' }); + * // => 'no match' + */ +function cond(pairs) { + var length = pairs == null ? 0 : pairs.length, + toIteratee = baseIteratee; + + pairs = !length ? [] : arrayMap(pairs, function(pair) { + if (typeof pair[1] != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return [toIteratee(pair[0]), pair[1]]; + }); + + return baseRest(function(args) { + var index = -1; + while (++index < length) { + var pair = pairs[index]; + if (apply(pair[0], this, args)) { + return apply(pair[1], this, args); + } + } + }); +} + +module.exports = cond; diff --git a/libs/events/node_modules/lodash/conforms.js b/libs/events/node_modules/lodash/conforms.js new file mode 100644 index 000000000..5501a949a --- /dev/null +++ b/libs/events/node_modules/lodash/conforms.js @@ -0,0 +1,35 @@ +var baseClone = require('./_baseClone'), + baseConforms = require('./_baseConforms'); + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1; + +/** + * Creates a function that invokes the predicate properties of `source` with + * the corresponding property values of a given object, returning `true` if + * all predicates return truthy, else `false`. + * + * **Note:** The created function is equivalent to `_.conformsTo` with + * `source` partially applied. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Util + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new spec function. + * @example + * + * var objects = [ + * { 'a': 2, 'b': 1 }, + * { 'a': 1, 'b': 2 } + * ]; + * + * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } })); + * // => [{ 'a': 1, 'b': 2 }] + */ +function conforms(source) { + return baseConforms(baseClone(source, CLONE_DEEP_FLAG)); +} + +module.exports = conforms; diff --git a/libs/events/node_modules/lodash/conformsTo.js b/libs/events/node_modules/lodash/conformsTo.js new file mode 100644 index 000000000..b8a93ebf4 --- /dev/null +++ b/libs/events/node_modules/lodash/conformsTo.js @@ -0,0 +1,32 @@ +var baseConformsTo = require('./_baseConformsTo'), + keys = require('./keys'); + +/** + * Checks if `object` conforms to `source` by invoking the predicate + * properties of `source` with the corresponding property values of `object`. + * + * **Note:** This method is equivalent to `_.conforms` when `source` is + * partially applied. + * + * @static + * @memberOf _ + * @since 4.14.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); + * // => true + * + * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); + * // => false + */ +function conformsTo(object, source) { + return source == null || baseConformsTo(object, source, keys(source)); +} + +module.exports = conformsTo; diff --git a/libs/events/node_modules/lodash/constant.js b/libs/events/node_modules/lodash/constant.js new file mode 100644 index 000000000..655ece3fb --- /dev/null +++ b/libs/events/node_modules/lodash/constant.js @@ -0,0 +1,26 @@ +/** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new constant function. + * @example + * + * var objects = _.times(2, _.constant({ 'a': 1 })); + * + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); + * // => true + */ +function constant(value) { + return function() { + return value; + }; +} + +module.exports = constant; diff --git a/libs/events/node_modules/lodash/core.js b/libs/events/node_modules/lodash/core.js new file mode 100644 index 000000000..be1d567d6 --- /dev/null +++ b/libs/events/node_modules/lodash/core.js @@ -0,0 +1,3877 @@ +/** + * @license + * Lodash (Custom Build) + * Build: `lodash core -o ./dist/lodash.core.js` + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '4.17.21'; + + /** Error message constants. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** Used to compose bitmasks for function metadata. */ + var WRAP_BIND_FLAG = 1, + WRAP_PARTIAL_FLAG = 32; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + asyncTag = '[object AsyncFunction]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + numberTag = '[object Number]', + objectTag = '[object Object]', + proxyTag = '[object Proxy]', + regexpTag = '[object RegExp]', + stringTag = '[object String]'; + + /** Used to match HTML entities and HTML characters. */ + var reUnescapedHtml = /[&<>"']/g, + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + + /*--------------------------------------------------------------------------*/ + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + array.push.apply(array, values); + return array; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyOf(object) { + return function(key) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return baseMap(props, function(key) { + return object[key]; + }); + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + var escapeHtmlChar = basePropertyOf(htmlEscapes); + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /*--------------------------------------------------------------------------*/ + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Built-in value references. */ + var objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsFinite = root.isFinite, + nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chain sequences. Methods that operate on and return arrays, collections, + * and functions can be chained together. Methods that retrieve a single value + * or may return a primitive value will automatically end the chain sequence + * and return the unwrapped value. Otherwise, the value must be unwrapped + * with `_#value`. + * + * Explicit chain sequences, which must be unwrapped with `_#value`, may be + * enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. + * Shortcut fusion is an optimization to merge iteratee calls; this avoids + * the creation of intermediate arrays and can greatly reduce the number of + * iteratee executions. Sections of a chain sequence qualify for shortcut + * fusion if the section is applied to an array and iteratees accept only + * one argument. The heuristic for whether a section qualifies for shortcut + * fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, + * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, + * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, + * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, + * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, + * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, + * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, + * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, + * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, + * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, + * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, + * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, + * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, + * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, + * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, + * `zipObject`, `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, + * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, + * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, + * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, + * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, + * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, + * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, + * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, + * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, + * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, + * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, + * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, + * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, + * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, + * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, + * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, + * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, + * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, + * `upperFirst`, `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + return value instanceof LodashWrapper + ? value + : new LodashWrapper(value); + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable explicit method chain sequences. + */ + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + } + + LodashWrapper.prototype = baseCreate(lodash.prototype); + LodashWrapper.prototype.constructor = LodashWrapper; + + /*------------------------------------------------------------------------*/ + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + object[key] = value; + } + + /** + * The base implementation of `_.delay` and `_.defer` which accepts `args` + * to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Array} args The arguments to provide to `func`. + * @returns {number|Object} Returns the timer id or timeout object. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !false) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the function names. + */ + function baseFunctions(object, props) { + return baseFilter(props, function(key) { + return isFunction(object[key]); + }); + } + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString(value); + } + + /** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ + function baseGt(value, other) { + return value > other; + } + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + var baseIsArguments = noop; + + /** + * The base implementation of `_.isDate` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + */ + function baseIsDate(value) { + return isObjectLike(value) && baseGetTag(value) == dateTag; + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : baseGetTag(object), + othTag = othIsArr ? arrayTag : baseGetTag(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + stack || (stack = []); + var objStack = find(stack, function(entry) { + return entry[0] == object; + }); + var othStack = find(stack, function(entry) { + return entry[0] == other; + }); + if (objStack && othStack) { + return objStack[1] == other; + } + stack.push([object, other]); + stack.push([other, object]); + if (isSameTag && !objIsObj) { + var result = (objIsArr) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + stack.pop(); + return result; + } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + var result = equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + stack.pop(); + return result; + } + } + if (!isSameTag) { + return false; + } + var result = equalObjects(object, other, bitmask, customizer, equalFunc, stack); + stack.pop(); + return result; + } + + /** + * The base implementation of `_.isRegExp` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + */ + function baseIsRegExp(value) { + return isObjectLike(value) && baseGetTag(value) == regexpTag; + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(func) { + if (typeof func == 'function') { + return func; + } + if (func == null) { + return identity; + } + return (typeof func == 'object' ? baseMatches : baseProperty)(func); + } + + /** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ + function baseLt(value, other) { + return value < other; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatches(source) { + var props = nativeKeys(source); + return function(object) { + var length = props.length; + if (object == null) { + return !length; + } + object = Object(object); + while (length--) { + var key = props[length]; + if (!(key in object && + baseIsEqual(source[key], object[key], COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG) + )) { + return false; + } + } + return true; + }; + } + + /** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, props) { + object = Object(object); + return reduce(props, function(result, key) { + if (key in object) { + result[key] = object[key]; + } + return result; + }, {}); + } + + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source) { + return baseSlice(source, 0, source.length); + } + + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + return reduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = false; + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = false; + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtor(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. See + // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ + function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!isArrayLike(collection)) { + var iteratee = baseIteratee(predicate, 3); + collection = keys(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the `this` binding + * of `thisArg` and `partials` prepended to the arguments it receives. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to + * the new function. + * @returns {Function} Returns the new wrapped function. + */ + function createPartial(func, bitmask, thisArg, partials) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return fn.apply(isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? [] : undefined; + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + var compared; + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!baseSome(other, function(othValue, othIndex) { + if (!indexOf(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + return result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + var compared; + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + return result; + } + + /** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + function flatRest(func) { + return setToString(overRest(func, undefined, flatten), func + ''); + } + + /** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ + function isFlattenable(value) { + return isArray(value) || isArguments(value); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString.call(value); + } + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return func.apply(this, otherArgs); + }; + } + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = identity; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + return baseFilter(array, Boolean); + } + + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + function concat() { + var length = arguments.length; + if (!length) { + return []; + } + var args = Array(length - 1), + array = arguments[0], + index = length; + + while (index--) { + args[index - 1] = arguments[index]; + } + return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ + function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseFindIndex(array, baseIteratee(predicate, 3), index); + } + + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ + function flattenDeep(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return (array && array.length) ? array[0] : undefined; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the + * offset from the end of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + function indexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else { + fromIndex = 0; + } + var index = (fromIndex || 0) - 1, + isReflexive = value === value; + + while (++index < length) { + var other = array[index]; + if ((isReflexive ? other === value : other !== other)) { + return index; + } + } + return -1; + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of + * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are + * returned. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array == null ? 0 : array.length; + start = start == null ? 0 : +start; + end = end === undefined ? length : +end; + return length ? baseSlice(array, start, end) : []; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` wrapper instance that wraps `value` with explicit method + * chain sequences enabled. The result of such sequences must be unwrapped + * with `_#value`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain sequence in order to modify intermediate results. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain sequence. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor) { + return interceptor(value); + } + + /** + * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. + * + * @name chain + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chain sequence to resolve the unwrapped value. + * + * @name value + * @memberOf _ + * @since 0.1.0 + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * **Note:** This method returns `true` for + * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because + * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of + * elements of empty collections. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, guard) { + predicate = guard ? undefined : predicate; + return baseEvery(collection, baseIteratee(predicate)); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ + function filter(collection, predicate) { + return baseFilter(collection, baseIteratee(predicate)); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ + var find = createFind(findIndex); + + /** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forEach(collection, iteratee) { + return baseEach(collection, baseIteratee(iteratee)); + } + + /** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee) { + return baseMap(collection, baseIteratee(iteratee)); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator) { + return baseReduce(collection, baseIteratee(iteratee), accumulator, arguments.length < 3, baseEach); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + if (collection == null) { + return 0; + } + collection = isArrayLike(collection) ? collection : nativeKeys(collection); + return collection.length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, guard) { + predicate = guard ? undefined : predicate; + return baseSome(collection, baseIteratee(predicate)); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ + function sortBy(collection, iteratee) { + var index = 0; + iteratee = baseIteratee(iteratee); + + return baseMap(baseMap(collection, function(value, key, collection) { + return { 'value': value, 'index': index++, 'criteria': iteratee(value, key, collection) }; + }).sort(function(object, other) { + return compareAscending(object.criteria, other.criteria) || (object.index - other.index); + }), baseProperty('value')); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => Allows adding up to 4 contacts to the list. + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and `partials` prepended to the arguments it receives. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * function greet(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = baseRest(function(func, thisArg, partials) { + return createPartial(func, WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG, thisArg, partials); + }); + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => Logs 'deferred' after one millisecond. + */ + var defer = baseRest(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => Logs 'later' after one second. + */ + var delay = baseRest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + var args = arguments; + return !predicate.apply(this, args); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // => `createApplication` is invoked once + */ + function once(func) { + return before(2, func); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + if (!isObject(value)) { + return value; + } + return isArray(value) ? copyArray(value) : copyObject(value, nativeKeys(value)); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); + } + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + var isDate = baseIsDate; + + /** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (isArrayLike(value) && + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { + return !value.length; + } + return !nativeKeys(value).length; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on + * [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MIN_VALUE); + * // => true + * + * _.isFinite(Infinity); + * // => false + * + * _.isFinite('3'); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + var isRegExp = baseIsRegExp; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Converts `value` to an array. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!isArrayLike(value)) { + return values(value); + } + return value.length ? copyArray(value) : []; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ + var toInteger = Number; + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + var toNumber = Number; + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + if (typeof value == 'string') { + return value; + } + return value == null ? '' : (value + ''); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ + var assign = createAssigner(function(object, source) { + copyObject(source, nativeKeys(source), object); + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assign + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assignIn({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } + */ + var assignIn = createAssigner(function(object, source) { + copyObject(source, nativeKeysIn(source), object); + }); + + /** + * Creates an object that inherits from the `prototype` object. If a + * `properties` object is given, its own enumerable string keyed properties + * are assigned to the created object. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties == null ? result : assign(result, properties); + } + + /** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var defaults = baseRest(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; + }); + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return object != null && hasOwnProperty.call(object, path); + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + var keys = nativeKeys; + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + var keysIn = nativeKeysIn; + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = flatRest(function(object, paths) { + return object == null ? {} : basePick(object, paths); + }); + + /** + * This method is like `_.get` except that if the resolved value is a + * function it's invoked with the `this` binding of its parent object and + * its result is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + var value = object == null ? undefined : object[path]; + if (value === undefined) { + value = defaultValue; + } + return isFunction(value) ? value.call(object) : value; + } + + /** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object == null ? [] : baseValues(object, keys(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /*------------------------------------------------------------------------*/ + + /** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ + function identity(value) { + return value; + } + + /** + * Creates a function that invokes `func` with the arguments of the created + * function. If `func` is a property name, the created function returns the + * property value for a given element. If `func` is an array or object, the + * created function returns `true` for elements that contain the equivalent + * source properties, otherwise it returns `false`. + * + * @static + * @since 4.0.0 + * @memberOf _ + * @category Util + * @param {*} [func=_.identity] The value to convert to a callback. + * @returns {Function} Returns the callback. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true })); + * // => [{ 'user': 'barney', 'age': 36, 'active': true }] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, _.iteratee(['user', 'fred'])); + * // => [{ 'user': 'fred', 'age': 40 }] + * + * // The `_.property` iteratee shorthand. + * _.map(users, _.iteratee('user')); + * // => ['barney', 'fred'] + * + * // Create custom iteratee shorthands. + * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) { + * return !_.isRegExp(func) ? iteratee(func) : function(string) { + * return func.test(string); + * }; + * }); + * + * _.filter(['abc', 'def'], /ef/); + * // => ['def'] + */ + var iteratee = baseIteratee; + + /** + * Creates a function that performs a partial deep comparison between a given + * object and `source`, returning `true` if the given object has equivalent + * property values, else `false`. + * + * **Note:** The created function is equivalent to `_.isMatch` with `source` + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * **Note:** Multiple values can be checked by combining several matchers + * using `_.overSome` + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Util + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + * @example + * + * var objects = [ + * { 'a': 1, 'b': 2, 'c': 3 }, + * { 'a': 4, 'b': 5, 'c': 6 } + * ]; + * + * _.filter(objects, _.matches({ 'a': 4, 'c': 6 })); + * // => [{ 'a': 4, 'b': 5, 'c': 6 }] + * + * // Checking for several possible values + * _.filter(objects, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })])); + * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }] + */ + function matches(source) { + return baseMatches(assign({}, source)); + } + + /** + * Adds all own enumerable string keyed function properties of a source + * object to the destination object. If `object` is a function, then methods + * are added to its prototype as well. + * + * **Note:** Use `_.runInContext` to create a pristine `lodash` function to + * avoid conflicts caused by modifying the original. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {Function|Object} [object=lodash] The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.chain=true] Specify whether mixins are chainable. + * @returns {Function|Object} Returns `object`. + * @example + * + * function vowels(string) { + * return _.filter(string, function(v) { + * return /[aeiou]/i.test(v); + * }); + * } + * + * _.mixin({ 'vowels': vowels }); + * _.vowels('fred'); + * // => ['e'] + * + * _('fred').vowels().value(); + * // => ['e'] + * + * _.mixin({ 'vowels': vowels }, { 'chain': false }); + * _('fred').vowels(); + * // => ['e'] + */ + function mixin(object, source, options) { + var props = keys(source), + methodNames = baseFunctions(source, props); + + if (options == null && + !(isObject(source) && (methodNames.length || !props.length))) { + options = source; + source = object; + object = this; + methodNames = baseFunctions(source, keys(source)); + } + var chain = !(isObject(options) && 'chain' in options) || !!options.chain, + isFunc = isFunction(object); + + baseEach(methodNames, function(methodName) { + var func = source[methodName]; + object[methodName] = func; + if (isFunc) { + object.prototype[methodName] = function() { + var chainAll = this.__chain__; + if (chain || chainAll) { + var result = object(this.__wrapped__), + actions = result.__actions__ = copyArray(this.__actions__); + + actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); + result.__chain__ = chainAll; + return result; + } + return func.apply(object, arrayPush([this.value()], arguments)); + }; + } + }); + + return object; + } + + /** + * Reverts the `_` variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + if (root._ === this) { + root._ = oldDash; + } + return this; + } + + /** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ + function noop() { + // No operation performed. + } + + /** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ + function uniqueId(prefix) { + var id = ++idCounter; + return toString(prefix) + id; + } + + /*------------------------------------------------------------------------*/ + + /** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ + function max(array) { + return (array && array.length) + ? baseExtremum(array, identity, baseGt) + : undefined; + } + + /** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ + function min(array) { + return (array && array.length) + ? baseExtremum(array, identity, baseLt) + : undefined; + } + + /*------------------------------------------------------------------------*/ + + // Add methods that return wrapped values in chain sequences. + lodash.assignIn = assignIn; + lodash.before = before; + lodash.bind = bind; + lodash.chain = chain; + lodash.compact = compact; + lodash.concat = concat; + lodash.create = create; + lodash.defaults = defaults; + lodash.defer = defer; + lodash.delay = delay; + lodash.filter = filter; + lodash.flatten = flatten; + lodash.flattenDeep = flattenDeep; + lodash.iteratee = iteratee; + lodash.keys = keys; + lodash.map = map; + lodash.matches = matches; + lodash.mixin = mixin; + lodash.negate = negate; + lodash.once = once; + lodash.pick = pick; + lodash.slice = slice; + lodash.sortBy = sortBy; + lodash.tap = tap; + lodash.thru = thru; + lodash.toArray = toArray; + lodash.values = values; + + // Add aliases. + lodash.extend = assignIn; + + // Add methods to `lodash.prototype`. + mixin(lodash, lodash); + + /*------------------------------------------------------------------------*/ + + // Add methods that return unwrapped values in chain sequences. + lodash.clone = clone; + lodash.escape = escape; + lodash.every = every; + lodash.find = find; + lodash.forEach = forEach; + lodash.has = has; + lodash.head = head; + lodash.identity = identity; + lodash.indexOf = indexOf; + lodash.isArguments = isArguments; + lodash.isArray = isArray; + lodash.isBoolean = isBoolean; + lodash.isDate = isDate; + lodash.isEmpty = isEmpty; + lodash.isEqual = isEqual; + lodash.isFinite = isFinite; + lodash.isFunction = isFunction; + lodash.isNaN = isNaN; + lodash.isNull = isNull; + lodash.isNumber = isNumber; + lodash.isObject = isObject; + lodash.isRegExp = isRegExp; + lodash.isString = isString; + lodash.isUndefined = isUndefined; + lodash.last = last; + lodash.max = max; + lodash.min = min; + lodash.noConflict = noConflict; + lodash.noop = noop; + lodash.reduce = reduce; + lodash.result = result; + lodash.size = size; + lodash.some = some; + lodash.uniqueId = uniqueId; + + // Add aliases. + lodash.each = forEach; + lodash.first = head; + + mixin(lodash, (function() { + var source = {}; + baseForOwn(lodash, function(func, methodName) { + if (!hasOwnProperty.call(lodash.prototype, methodName)) { + source[methodName] = func; + } + }); + return source; + }()), { 'chain': false }); + + /*------------------------------------------------------------------------*/ + + /** + * The semantic version number. + * + * @static + * @memberOf _ + * @type {string} + */ + lodash.VERSION = VERSION; + + // Add `Array` methods to `lodash.prototype`. + baseEach(['pop', 'join', 'replace', 'reverse', 'split', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { + var func = (/^(?:replace|split)$/.test(methodName) ? String.prototype : arrayProto)[methodName], + chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', + retUnwrapped = /^(?:pop|join|replace|shift)$/.test(methodName); + + lodash.prototype[methodName] = function() { + var args = arguments; + if (retUnwrapped && !this.__chain__) { + var value = this.value(); + return func.apply(isArray(value) ? value : [], args); + } + return this[chainName](function(value) { + return func.apply(isArray(value) ? value : [], args); + }); + }; + }); + + // Add chain sequence methods to the `lodash` wrapper. + lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; + + /*--------------------------------------------------------------------------*/ + + // Some AMD build optimizers, like r.js, check for condition patterns like: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose Lodash on the global object to prevent errors when Lodash is + // loaded by a script tag in the presence of an AMD loader. + // See http://requirejs.org/docs/errors.html#mismatch for more details. + // Use `_.noConflict` to remove Lodash from the global object. + root._ = lodash; + + // Define as an anonymous module so, through path mapping, it can be + // referenced as the "underscore" module. + define(function() { + return lodash; + }); + } + // Check for `exports` after `define` in case a build optimizer adds it. + else if (freeModule) { + // Export for Node.js. + (freeModule.exports = lodash)._ = lodash; + // Export for CommonJS support. + freeExports._ = lodash; + } + else { + // Export to the global object. + root._ = lodash; + } +}.call(this)); diff --git a/libs/events/node_modules/lodash/core.min.js b/libs/events/node_modules/lodash/core.min.js new file mode 100644 index 000000000..e425e4d4f --- /dev/null +++ b/libs/events/node_modules/lodash/core.min.js @@ -0,0 +1,29 @@ +/** + * @license + * Lodash (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + * Build: `lodash core -o ./dist/lodash.core.js` + */ +;(function(){function n(n){return H(n)&&pn.call(n,"callee")&&!yn.call(n,"callee")}function t(n,t){return n.push.apply(n,t),n}function r(n){return function(t){return null==t?Z:t[n]}}function e(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)}),r}function u(n,t){return j(t,function(t){return n[t]})}function o(n){return n instanceof i?n:new i(n)}function i(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t}function c(n,t,r){if(typeof n!="function")throw new TypeError("Expected a function"); +return setTimeout(function(){n.apply(Z,r)},t)}function f(n,t){var r=true;return mn(n,function(n,e,u){return r=!!t(n,e,u)}),r}function a(n,t,r){for(var e=-1,u=n.length;++et}function b(n,t,r,e,u){return n===t||(null==n||null==t||!H(n)&&!H(t)?n!==n&&t!==t:y(n,t,r,e,b,u))}function y(n,t,r,e,u,o){var i=Nn(n),c=Nn(t),f=i?"[object Array]":hn.call(n),a=c?"[object Array]":hn.call(t),f="[object Arguments]"==f?"[object Object]":f,a="[object Arguments]"==a?"[object Object]":a,l="[object Object]"==f,c="[object Object]"==a,a=f==a;o||(o=[]);var p=An(o,function(t){return t[0]==n}),s=An(o,function(n){ +return n[0]==t});if(p&&s)return p[1]==t;if(o.push([n,t]),o.push([t,n]),a&&!l){if(i)r=T(n,t,r,e,u,o);else n:{switch(f){case"[object Boolean]":case"[object Date]":case"[object Number]":r=J(+n,+t);break n;case"[object Error]":r=n.name==t.name&&n.message==t.message;break n;case"[object RegExp]":case"[object String]":r=n==t+"";break n}r=false}return o.pop(),r}return 1&r||(i=l&&pn.call(n,"__wrapped__"),f=c&&pn.call(t,"__wrapped__"),!i&&!f)?!!a&&(r=B(n,t,r,e,u,o),o.pop(),r):(i=i?n.value():n,f=f?t.value():t, +r=u(i,f,r,e,o),o.pop(),r)}function g(n){return typeof n=="function"?n:null==n?X:(typeof n=="object"?d:r)(n)}function _(n,t){return nt&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++ei))return false;var c=o.get(n),f=o.get(t);if(c&&f)return c==t&&f==n;for(var c=-1,f=true,a=2&r?[]:Z;++cr?jn(e+r,0):r:0,r=(r||0)-1;for(var u=t===t;++rarguments.length,mn); +}function G(n,t){var r;if(typeof t!="function")throw new TypeError("Expected a function");return n=Fn(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=Z),r}}function J(n,t){return n===t||n!==n&&t!==t}function M(n){var t;return(t=null!=n)&&(t=n.length,t=typeof t=="number"&&-1=t),t&&!U(n)}function U(n){return!!V(n)&&(n=hn.call(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function V(n){var t=typeof n; +return null!=n&&("object"==t||"function"==t)}function H(n){return null!=n&&typeof n=="object"}function K(n){return typeof n=="number"||H(n)&&"[object Number]"==hn.call(n)}function L(n){return typeof n=="string"||!Nn(n)&&H(n)&&"[object String]"==hn.call(n)}function Q(n){return typeof n=="string"?n:null==n?"":n+""}function W(n){return null==n?[]:u(n,Dn(n))}function X(n){return n}function Y(n,r,e){var u=Dn(r),o=h(r,u);null!=e||V(r)&&(o.length||!u.length)||(e=r,r=n,n=this,o=h(r,Dn(r)));var i=!(V(e)&&"chain"in e&&!e.chain),c=U(n); +return mn(o,function(e){var u=r[e];n[e]=u,c&&(n.prototype[e]=function(){var r=this.__chain__;if(i||r){var e=n(this.__wrapped__);return(e.__actions__=A(this.__actions__)).push({func:u,args:arguments,thisArg:n}),e.__chain__=r,e}return u.apply(n,t([this.value()],arguments))})}),n}var Z,nn=1/0,tn=/[&<>"']/g,rn=RegExp(tn.source),en=/^(?:0|[1-9]\d*)$/,un=typeof self=="object"&&self&&self.Object===Object&&self,on=typeof global=="object"&&global&&global.Object===Object&&global||un||Function("return this")(),cn=(un=typeof exports=="object"&&exports&&!exports.nodeType&&exports)&&typeof module=="object"&&module&&!module.nodeType&&module,fn=function(n){ +return function(t){return null==n?Z:n[t]}}({"&":"&","<":"<",">":">",'"':""","'":"'"}),an=Array.prototype,ln=Object.prototype,pn=ln.hasOwnProperty,sn=0,hn=ln.toString,vn=on._,bn=Object.create,yn=ln.propertyIsEnumerable,gn=on.isFinite,_n=function(n,t){return function(r){return n(t(r))}}(Object.keys,Object),jn=Math.max,dn=function(){function n(){}return function(t){return V(t)?bn?bn(t):(n.prototype=t,t=new n,n.prototype=Z,t):{}}}();i.prototype=dn(o.prototype),i.prototype.constructor=i; +var mn=function(n,t){return function(r,e){if(null==r)return r;if(!M(r))return n(r,e);for(var u=r.length,o=t?u:-1,i=Object(r);(t?o--:++or&&(r=jn(e+r,0));n:{for(t=g(t),e=n.length,r+=-1;++re||o&&c&&a||!u&&a||!i){r=1;break n}if(!o&&r { '4': 1, '6': 2 } + * + * // The `_.property` iteratee shorthand. + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ +var countBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + ++result[key]; + } else { + baseAssignValue(result, key, 1); + } +}); + +module.exports = countBy; diff --git a/libs/events/node_modules/lodash/create.js b/libs/events/node_modules/lodash/create.js new file mode 100644 index 000000000..919edb850 --- /dev/null +++ b/libs/events/node_modules/lodash/create.js @@ -0,0 +1,43 @@ +var baseAssign = require('./_baseAssign'), + baseCreate = require('./_baseCreate'); + +/** + * Creates an object that inherits from the `prototype` object. If a + * `properties` object is given, its own enumerable string keyed properties + * are assigned to the created object. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ +function create(prototype, properties) { + var result = baseCreate(prototype); + return properties == null ? result : baseAssign(result, properties); +} + +module.exports = create; diff --git a/libs/events/node_modules/lodash/curry.js b/libs/events/node_modules/lodash/curry.js new file mode 100644 index 000000000..918db1a4a --- /dev/null +++ b/libs/events/node_modules/lodash/curry.js @@ -0,0 +1,57 @@ +var createWrap = require('./_createWrap'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_CURRY_FLAG = 8; + +/** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ +function curry(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curry.placeholder; + return result; +} + +// Assign default placeholders. +curry.placeholder = {}; + +module.exports = curry; diff --git a/libs/events/node_modules/lodash/curryRight.js b/libs/events/node_modules/lodash/curryRight.js new file mode 100644 index 000000000..c85b6f339 --- /dev/null +++ b/libs/events/node_modules/lodash/curryRight.js @@ -0,0 +1,54 @@ +var createWrap = require('./_createWrap'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_CURRY_RIGHT_FLAG = 16; + +/** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ +function curryRight(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryRight.placeholder; + return result; +} + +// Assign default placeholders. +curryRight.placeholder = {}; + +module.exports = curryRight; diff --git a/libs/events/node_modules/lodash/date.js b/libs/events/node_modules/lodash/date.js new file mode 100644 index 000000000..cbf5b4109 --- /dev/null +++ b/libs/events/node_modules/lodash/date.js @@ -0,0 +1,3 @@ +module.exports = { + 'now': require('./now') +}; diff --git a/libs/events/node_modules/lodash/debounce.js b/libs/events/node_modules/lodash/debounce.js new file mode 100644 index 000000000..8f751d53d --- /dev/null +++ b/libs/events/node_modules/lodash/debounce.js @@ -0,0 +1,191 @@ +var isObject = require('./isObject'), + now = require('./now'), + toNumber = require('./toNumber'); + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ +function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + timeWaiting = wait - timeSinceLastCall; + + return maxing + ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + clearTimeout(timerId); + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; +} + +module.exports = debounce; diff --git a/libs/events/node_modules/lodash/deburr.js b/libs/events/node_modules/lodash/deburr.js new file mode 100644 index 000000000..f85e314a0 --- /dev/null +++ b/libs/events/node_modules/lodash/deburr.js @@ -0,0 +1,45 @@ +var deburrLetter = require('./_deburrLetter'), + toString = require('./toString'); + +/** Used to match Latin Unicode letters (excluding mathematical operators). */ +var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + +/** Used to compose unicode character classes. */ +var rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange; + +/** Used to compose unicode capture groups. */ +var rsCombo = '[' + rsComboRange + ']'; + +/** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ +var reComboMark = RegExp(rsCombo, 'g'); + +/** + * Deburrs `string` by converting + * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters to basic Latin letters and removing + * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ +function deburr(string) { + string = toString(string); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); +} + +module.exports = deburr; diff --git a/libs/events/node_modules/lodash/defaultTo.js b/libs/events/node_modules/lodash/defaultTo.js new file mode 100644 index 000000000..5b333592e --- /dev/null +++ b/libs/events/node_modules/lodash/defaultTo.js @@ -0,0 +1,25 @@ +/** + * Checks `value` to determine whether a default value should be returned in + * its place. The `defaultValue` is returned if `value` is `NaN`, `null`, + * or `undefined`. + * + * @static + * @memberOf _ + * @since 4.14.0 + * @category Util + * @param {*} value The value to check. + * @param {*} defaultValue The default value. + * @returns {*} Returns the resolved value. + * @example + * + * _.defaultTo(1, 10); + * // => 1 + * + * _.defaultTo(undefined, 10); + * // => 10 + */ +function defaultTo(value, defaultValue) { + return (value == null || value !== value) ? defaultValue : value; +} + +module.exports = defaultTo; diff --git a/libs/events/node_modules/lodash/defaults.js b/libs/events/node_modules/lodash/defaults.js new file mode 100644 index 000000000..c74df044c --- /dev/null +++ b/libs/events/node_modules/lodash/defaults.js @@ -0,0 +1,64 @@ +var baseRest = require('./_baseRest'), + eq = require('./eq'), + isIterateeCall = require('./_isIterateeCall'), + keysIn = require('./keysIn'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = baseRest(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +module.exports = defaults; diff --git a/libs/events/node_modules/lodash/defaultsDeep.js b/libs/events/node_modules/lodash/defaultsDeep.js new file mode 100644 index 000000000..9b5fa3ee2 --- /dev/null +++ b/libs/events/node_modules/lodash/defaultsDeep.js @@ -0,0 +1,30 @@ +var apply = require('./_apply'), + baseRest = require('./_baseRest'), + customDefaultsMerge = require('./_customDefaultsMerge'), + mergeWith = require('./mergeWith'); + +/** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaults + * @example + * + * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); + * // => { 'a': { 'b': 2, 'c': 3 } } + */ +var defaultsDeep = baseRest(function(args) { + args.push(undefined, customDefaultsMerge); + return apply(mergeWith, undefined, args); +}); + +module.exports = defaultsDeep; diff --git a/libs/events/node_modules/lodash/defer.js b/libs/events/node_modules/lodash/defer.js new file mode 100644 index 000000000..f6d6c6fa6 --- /dev/null +++ b/libs/events/node_modules/lodash/defer.js @@ -0,0 +1,26 @@ +var baseDelay = require('./_baseDelay'), + baseRest = require('./_baseRest'); + +/** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => Logs 'deferred' after one millisecond. + */ +var defer = baseRest(function(func, args) { + return baseDelay(func, 1, args); +}); + +module.exports = defer; diff --git a/libs/events/node_modules/lodash/delay.js b/libs/events/node_modules/lodash/delay.js new file mode 100644 index 000000000..bd554796f --- /dev/null +++ b/libs/events/node_modules/lodash/delay.js @@ -0,0 +1,28 @@ +var baseDelay = require('./_baseDelay'), + baseRest = require('./_baseRest'), + toNumber = require('./toNumber'); + +/** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => Logs 'later' after one second. + */ +var delay = baseRest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); +}); + +module.exports = delay; diff --git a/libs/events/node_modules/lodash/difference.js b/libs/events/node_modules/lodash/difference.js new file mode 100644 index 000000000..fa28bb301 --- /dev/null +++ b/libs/events/node_modules/lodash/difference.js @@ -0,0 +1,33 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + baseRest = require('./_baseRest'), + isArrayLikeObject = require('./isArrayLikeObject'); + +/** + * Creates an array of `array` values not included in the other given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * **Note:** Unlike `_.pullAll`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.without, _.xor + * @example + * + * _.difference([2, 1], [2, 3]); + * // => [1] + */ +var difference = baseRest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) + : []; +}); + +module.exports = difference; diff --git a/libs/events/node_modules/lodash/differenceBy.js b/libs/events/node_modules/lodash/differenceBy.js new file mode 100644 index 000000000..2cd63e7ec --- /dev/null +++ b/libs/events/node_modules/lodash/differenceBy.js @@ -0,0 +1,44 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + baseIteratee = require('./_baseIteratee'), + baseRest = require('./_baseRest'), + isArrayLikeObject = require('./isArrayLikeObject'), + last = require('./last'); + +/** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * **Note:** Unlike `_.pullAllBy`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ +var differenceBy = baseRest(function(array, values) { + var iteratee = last(values); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), baseIteratee(iteratee, 2)) + : []; +}); + +module.exports = differenceBy; diff --git a/libs/events/node_modules/lodash/differenceWith.js b/libs/events/node_modules/lodash/differenceWith.js new file mode 100644 index 000000000..c0233f4b9 --- /dev/null +++ b/libs/events/node_modules/lodash/differenceWith.js @@ -0,0 +1,40 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + baseRest = require('./_baseRest'), + isArrayLikeObject = require('./isArrayLikeObject'), + last = require('./last'); + +/** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. The order and + * references of result values are determined by the first array. The comparator + * is invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.pullAllWith`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ +var differenceWith = baseRest(function(array, values) { + var comparator = last(values); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) + : []; +}); + +module.exports = differenceWith; diff --git a/libs/events/node_modules/lodash/divide.js b/libs/events/node_modules/lodash/divide.js new file mode 100644 index 000000000..8cae0cd1b --- /dev/null +++ b/libs/events/node_modules/lodash/divide.js @@ -0,0 +1,22 @@ +var createMathOperation = require('./_createMathOperation'); + +/** + * Divide two numbers. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Math + * @param {number} dividend The first number in a division. + * @param {number} divisor The second number in a division. + * @returns {number} Returns the quotient. + * @example + * + * _.divide(6, 4); + * // => 1.5 + */ +var divide = createMathOperation(function(dividend, divisor) { + return dividend / divisor; +}, 1); + +module.exports = divide; diff --git a/libs/events/node_modules/lodash/drop.js b/libs/events/node_modules/lodash/drop.js new file mode 100644 index 000000000..d5c3cbaa4 --- /dev/null +++ b/libs/events/node_modules/lodash/drop.js @@ -0,0 +1,38 @@ +var baseSlice = require('./_baseSlice'), + toInteger = require('./toInteger'); + +/** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function drop(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); +} + +module.exports = drop; diff --git a/libs/events/node_modules/lodash/dropRight.js b/libs/events/node_modules/lodash/dropRight.js new file mode 100644 index 000000000..441fe9968 --- /dev/null +++ b/libs/events/node_modules/lodash/dropRight.js @@ -0,0 +1,39 @@ +var baseSlice = require('./_baseSlice'), + toInteger = require('./toInteger'); + +/** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function dropRight(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, 0, n < 0 ? 0 : n); +} + +module.exports = dropRight; diff --git a/libs/events/node_modules/lodash/dropRightWhile.js b/libs/events/node_modules/lodash/dropRightWhile.js new file mode 100644 index 000000000..9ad36a044 --- /dev/null +++ b/libs/events/node_modules/lodash/dropRightWhile.js @@ -0,0 +1,45 @@ +var baseIteratee = require('./_baseIteratee'), + baseWhile = require('./_baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] + * + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ +function dropRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, baseIteratee(predicate, 3), true, true) + : []; +} + +module.exports = dropRightWhile; diff --git a/libs/events/node_modules/lodash/dropWhile.js b/libs/events/node_modules/lodash/dropWhile.js new file mode 100644 index 000000000..903ef568c --- /dev/null +++ b/libs/events/node_modules/lodash/dropWhile.js @@ -0,0 +1,45 @@ +var baseIteratee = require('./_baseIteratee'), + baseWhile = require('./_baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.dropWhile(users, function(o) { return !o.active; }); + * // => objects for ['pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ +function dropWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, baseIteratee(predicate, 3), true) + : []; +} + +module.exports = dropWhile; diff --git a/libs/events/node_modules/lodash/each.js b/libs/events/node_modules/lodash/each.js new file mode 100644 index 000000000..8800f4204 --- /dev/null +++ b/libs/events/node_modules/lodash/each.js @@ -0,0 +1 @@ +module.exports = require('./forEach'); diff --git a/libs/events/node_modules/lodash/eachRight.js b/libs/events/node_modules/lodash/eachRight.js new file mode 100644 index 000000000..3252b2aba --- /dev/null +++ b/libs/events/node_modules/lodash/eachRight.js @@ -0,0 +1 @@ +module.exports = require('./forEachRight'); diff --git a/libs/events/node_modules/lodash/endsWith.js b/libs/events/node_modules/lodash/endsWith.js new file mode 100644 index 000000000..76fc866e3 --- /dev/null +++ b/libs/events/node_modules/lodash/endsWith.js @@ -0,0 +1,43 @@ +var baseClamp = require('./_baseClamp'), + baseToString = require('./_baseToString'), + toInteger = require('./toInteger'), + toString = require('./toString'); + +/** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search up to. + * @returns {boolean} Returns `true` if `string` ends with `target`, + * else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ +function endsWith(string, target, position) { + string = toString(string); + target = baseToString(target); + + var length = string.length; + position = position === undefined + ? length + : baseClamp(toInteger(position), 0, length); + + var end = position; + position -= target.length; + return position >= 0 && string.slice(position, end) == target; +} + +module.exports = endsWith; diff --git a/libs/events/node_modules/lodash/entries.js b/libs/events/node_modules/lodash/entries.js new file mode 100644 index 000000000..7a88df204 --- /dev/null +++ b/libs/events/node_modules/lodash/entries.js @@ -0,0 +1 @@ +module.exports = require('./toPairs'); diff --git a/libs/events/node_modules/lodash/entriesIn.js b/libs/events/node_modules/lodash/entriesIn.js new file mode 100644 index 000000000..f6c6331c1 --- /dev/null +++ b/libs/events/node_modules/lodash/entriesIn.js @@ -0,0 +1 @@ +module.exports = require('./toPairsIn'); diff --git a/libs/events/node_modules/lodash/eq.js b/libs/events/node_modules/lodash/eq.js new file mode 100644 index 000000000..a94068805 --- /dev/null +++ b/libs/events/node_modules/lodash/eq.js @@ -0,0 +1,37 @@ +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +module.exports = eq; diff --git a/libs/events/node_modules/lodash/escape.js b/libs/events/node_modules/lodash/escape.js new file mode 100644 index 000000000..9247e0029 --- /dev/null +++ b/libs/events/node_modules/lodash/escape.js @@ -0,0 +1,43 @@ +var escapeHtmlChar = require('./_escapeHtmlChar'), + toString = require('./toString'); + +/** Used to match HTML entities and HTML characters. */ +var reUnescapedHtml = /[&<>"']/g, + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + +/** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ +function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; +} + +module.exports = escape; diff --git a/libs/events/node_modules/lodash/escapeRegExp.js b/libs/events/node_modules/lodash/escapeRegExp.js new file mode 100644 index 000000000..0a58c69fc --- /dev/null +++ b/libs/events/node_modules/lodash/escapeRegExp.js @@ -0,0 +1,32 @@ +var toString = require('./toString'); + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); + +/** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ +function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; +} + +module.exports = escapeRegExp; diff --git a/libs/events/node_modules/lodash/every.js b/libs/events/node_modules/lodash/every.js new file mode 100644 index 000000000..25080dac4 --- /dev/null +++ b/libs/events/node_modules/lodash/every.js @@ -0,0 +1,56 @@ +var arrayEvery = require('./_arrayEvery'), + baseEvery = require('./_baseEvery'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'), + isIterateeCall = require('./_isIterateeCall'); + +/** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * **Note:** This method returns `true` for + * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because + * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of + * elements of empty collections. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ +function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, baseIteratee(predicate, 3)); +} + +module.exports = every; diff --git a/libs/events/node_modules/lodash/extend.js b/libs/events/node_modules/lodash/extend.js new file mode 100644 index 000000000..e00166c20 --- /dev/null +++ b/libs/events/node_modules/lodash/extend.js @@ -0,0 +1 @@ +module.exports = require('./assignIn'); diff --git a/libs/events/node_modules/lodash/extendWith.js b/libs/events/node_modules/lodash/extendWith.js new file mode 100644 index 000000000..dbdcb3b4e --- /dev/null +++ b/libs/events/node_modules/lodash/extendWith.js @@ -0,0 +1 @@ +module.exports = require('./assignInWith'); diff --git a/libs/events/node_modules/lodash/fill.js b/libs/events/node_modules/lodash/fill.js new file mode 100644 index 000000000..ae13aa1c9 --- /dev/null +++ b/libs/events/node_modules/lodash/fill.js @@ -0,0 +1,45 @@ +var baseFill = require('./_baseFill'), + isIterateeCall = require('./_isIterateeCall'); + +/** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] + */ +function fill(array, value, start, end) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); +} + +module.exports = fill; diff --git a/libs/events/node_modules/lodash/filter.js b/libs/events/node_modules/lodash/filter.js new file mode 100644 index 000000000..89e0c8c48 --- /dev/null +++ b/libs/events/node_modules/lodash/filter.js @@ -0,0 +1,52 @@ +var arrayFilter = require('./_arrayFilter'), + baseFilter = require('./_baseFilter'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, baseIteratee(predicate, 3)); +} + +module.exports = filter; diff --git a/libs/events/node_modules/lodash/find.js b/libs/events/node_modules/lodash/find.js new file mode 100644 index 000000000..de732ccb4 --- /dev/null +++ b/libs/events/node_modules/lodash/find.js @@ -0,0 +1,42 @@ +var createFind = require('./_createFind'), + findIndex = require('./findIndex'); + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = createFind(findIndex); + +module.exports = find; diff --git a/libs/events/node_modules/lodash/findIndex.js b/libs/events/node_modules/lodash/findIndex.js new file mode 100644 index 000000000..4689069f8 --- /dev/null +++ b/libs/events/node_modules/lodash/findIndex.js @@ -0,0 +1,55 @@ +var baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseFindIndex(array, baseIteratee(predicate, 3), index); +} + +module.exports = findIndex; diff --git a/libs/events/node_modules/lodash/findKey.js b/libs/events/node_modules/lodash/findKey.js new file mode 100644 index 000000000..cac0248a9 --- /dev/null +++ b/libs/events/node_modules/lodash/findKey.js @@ -0,0 +1,44 @@ +var baseFindKey = require('./_baseFindKey'), + baseForOwn = require('./_baseForOwn'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ +function findKey(object, predicate) { + return baseFindKey(object, baseIteratee(predicate, 3), baseForOwn); +} + +module.exports = findKey; diff --git a/libs/events/node_modules/lodash/findLast.js b/libs/events/node_modules/lodash/findLast.js new file mode 100644 index 000000000..70b4271dc --- /dev/null +++ b/libs/events/node_modules/lodash/findLast.js @@ -0,0 +1,25 @@ +var createFind = require('./_createFind'), + findLastIndex = require('./findLastIndex'); + +/** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=collection.length-1] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ +var findLast = createFind(findLastIndex); + +module.exports = findLast; diff --git a/libs/events/node_modules/lodash/findLastIndex.js b/libs/events/node_modules/lodash/findLastIndex.js new file mode 100644 index 000000000..7da3431f6 --- /dev/null +++ b/libs/events/node_modules/lodash/findLastIndex.js @@ -0,0 +1,59 @@ +var baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ +function findLastIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length - 1; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = fromIndex < 0 + ? nativeMax(length + index, 0) + : nativeMin(index, length - 1); + } + return baseFindIndex(array, baseIteratee(predicate, 3), index, true); +} + +module.exports = findLastIndex; diff --git a/libs/events/node_modules/lodash/findLastKey.js b/libs/events/node_modules/lodash/findLastKey.js new file mode 100644 index 000000000..66fb9fbce --- /dev/null +++ b/libs/events/node_modules/lodash/findLastKey.js @@ -0,0 +1,44 @@ +var baseFindKey = require('./_baseFindKey'), + baseForOwnRight = require('./_baseForOwnRight'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ +function findLastKey(object, predicate) { + return baseFindKey(object, baseIteratee(predicate, 3), baseForOwnRight); +} + +module.exports = findLastKey; diff --git a/libs/events/node_modules/lodash/first.js b/libs/events/node_modules/lodash/first.js new file mode 100644 index 000000000..53f4ad13e --- /dev/null +++ b/libs/events/node_modules/lodash/first.js @@ -0,0 +1 @@ +module.exports = require('./head'); diff --git a/libs/events/node_modules/lodash/flake.lock b/libs/events/node_modules/lodash/flake.lock new file mode 100644 index 000000000..dd0325218 --- /dev/null +++ b/libs/events/node_modules/lodash/flake.lock @@ -0,0 +1,40 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1613582597, + "narHash": "sha256-6LvipIvFuhyorHpUqK3HjySC5Y6gshXHFBhU9EJ4DoM=", + "path": "/nix/store/srvplqq673sqd9vyfhyc5w1p88y1gfm4-source", + "rev": "6b1057b452c55bb3b463f0d7055bc4ec3fd1f381", + "type": "path" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "utils": "utils" + } + }, + "utils": { + "locked": { + "lastModified": 1610051610, + "narHash": "sha256-U9rPz/usA1/Aohhk7Cmc2gBrEEKRzcW4nwPWMPwja4Y=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3982c9903e93927c2164caa727cd3f6a0e6d14cc", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/libs/events/node_modules/lodash/flake.nix b/libs/events/node_modules/lodash/flake.nix new file mode 100644 index 000000000..15a451c6f --- /dev/null +++ b/libs/events/node_modules/lodash/flake.nix @@ -0,0 +1,20 @@ +{ + inputs = { + utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, utils }: + utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages."${system}"; + in rec { + devShell = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ + yarn + nodejs-14_x + nodePackages.typescript-language-server + nodePackages.eslint + ]; + }; + }); +} diff --git a/libs/events/node_modules/lodash/flatMap.js b/libs/events/node_modules/lodash/flatMap.js new file mode 100644 index 000000000..e6685068f --- /dev/null +++ b/libs/events/node_modules/lodash/flatMap.js @@ -0,0 +1,29 @@ +var baseFlatten = require('./_baseFlatten'), + map = require('./map'); + +/** + * Creates a flattened array of values by running each element in `collection` + * thru `iteratee` and flattening the mapped results. The iteratee is invoked + * with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ +function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); +} + +module.exports = flatMap; diff --git a/libs/events/node_modules/lodash/flatMapDeep.js b/libs/events/node_modules/lodash/flatMapDeep.js new file mode 100644 index 000000000..4653d6033 --- /dev/null +++ b/libs/events/node_modules/lodash/flatMapDeep.js @@ -0,0 +1,31 @@ +var baseFlatten = require('./_baseFlatten'), + map = require('./map'); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDeep([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ +function flatMapDeep(collection, iteratee) { + return baseFlatten(map(collection, iteratee), INFINITY); +} + +module.exports = flatMapDeep; diff --git a/libs/events/node_modules/lodash/flatMapDepth.js b/libs/events/node_modules/lodash/flatMapDepth.js new file mode 100644 index 000000000..6d72005c9 --- /dev/null +++ b/libs/events/node_modules/lodash/flatMapDepth.js @@ -0,0 +1,31 @@ +var baseFlatten = require('./_baseFlatten'), + map = require('./map'), + toInteger = require('./toInteger'); + +/** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDepth([1, 2], duplicate, 2); + * // => [[1, 1], [2, 2]] + */ +function flatMapDepth(collection, iteratee, depth) { + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(map(collection, iteratee), depth); +} + +module.exports = flatMapDepth; diff --git a/libs/events/node_modules/lodash/flatten.js b/libs/events/node_modules/lodash/flatten.js new file mode 100644 index 000000000..3f09f7f77 --- /dev/null +++ b/libs/events/node_modules/lodash/flatten.js @@ -0,0 +1,22 @@ +var baseFlatten = require('./_baseFlatten'); + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, 1) : []; +} + +module.exports = flatten; diff --git a/libs/events/node_modules/lodash/flattenDeep.js b/libs/events/node_modules/lodash/flattenDeep.js new file mode 100644 index 000000000..8ad585cf4 --- /dev/null +++ b/libs/events/node_modules/lodash/flattenDeep.js @@ -0,0 +1,25 @@ +var baseFlatten = require('./_baseFlatten'); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ +function flattenDeep(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, INFINITY) : []; +} + +module.exports = flattenDeep; diff --git a/libs/events/node_modules/lodash/flattenDepth.js b/libs/events/node_modules/lodash/flattenDepth.js new file mode 100644 index 000000000..441fdcc22 --- /dev/null +++ b/libs/events/node_modules/lodash/flattenDepth.js @@ -0,0 +1,33 @@ +var baseFlatten = require('./_baseFlatten'), + toInteger = require('./toInteger'); + +/** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ +function flattenDepth(array, depth) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); +} + +module.exports = flattenDepth; diff --git a/libs/events/node_modules/lodash/flip.js b/libs/events/node_modules/lodash/flip.js new file mode 100644 index 000000000..c28dd7896 --- /dev/null +++ b/libs/events/node_modules/lodash/flip.js @@ -0,0 +1,28 @@ +var createWrap = require('./_createWrap'); + +/** Used to compose bitmasks for function metadata. */ +var WRAP_FLIP_FLAG = 512; + +/** + * Creates a function that invokes `func` with arguments reversed. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to flip arguments for. + * @returns {Function} Returns the new flipped function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ +function flip(func) { + return createWrap(func, WRAP_FLIP_FLAG); +} + +module.exports = flip; diff --git a/libs/events/node_modules/lodash/floor.js b/libs/events/node_modules/lodash/floor.js new file mode 100644 index 000000000..ab6dfa28a --- /dev/null +++ b/libs/events/node_modules/lodash/floor.js @@ -0,0 +1,26 @@ +var createRound = require('./_createRound'); + +/** + * Computes `number` rounded down to `precision`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Math + * @param {number} number The number to round down. + * @param {number} [precision=0] The precision to round down to. + * @returns {number} Returns the rounded down number. + * @example + * + * _.floor(4.006); + * // => 4 + * + * _.floor(0.046, 2); + * // => 0.04 + * + * _.floor(4060, -2); + * // => 4000 + */ +var floor = createRound('floor'); + +module.exports = floor; diff --git a/libs/events/node_modules/lodash/flow.js b/libs/events/node_modules/lodash/flow.js new file mode 100644 index 000000000..74b6b62d4 --- /dev/null +++ b/libs/events/node_modules/lodash/flow.js @@ -0,0 +1,27 @@ +var createFlow = require('./_createFlow'); + +/** + * Creates a function that returns the result of invoking the given functions + * with the `this` binding of the created function, where each successive + * invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Util + * @param {...(Function|Function[])} [funcs] The functions to invoke. + * @returns {Function} Returns the new composite function. + * @see _.flowRight + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow([_.add, square]); + * addSquare(1, 2); + * // => 9 + */ +var flow = createFlow(); + +module.exports = flow; diff --git a/libs/events/node_modules/lodash/flowRight.js b/libs/events/node_modules/lodash/flowRight.js new file mode 100644 index 000000000..114614105 --- /dev/null +++ b/libs/events/node_modules/lodash/flowRight.js @@ -0,0 +1,26 @@ +var createFlow = require('./_createFlow'); + +/** + * This method is like `_.flow` except that it creates a function that + * invokes the given functions from right to left. + * + * @static + * @since 3.0.0 + * @memberOf _ + * @category Util + * @param {...(Function|Function[])} [funcs] The functions to invoke. + * @returns {Function} Returns the new composite function. + * @see _.flow + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight([square, _.add]); + * addSquare(1, 2); + * // => 9 + */ +var flowRight = createFlow(true); + +module.exports = flowRight; diff --git a/libs/events/node_modules/lodash/forEach.js b/libs/events/node_modules/lodash/forEach.js new file mode 100644 index 000000000..c64eaa73f --- /dev/null +++ b/libs/events/node_modules/lodash/forEach.js @@ -0,0 +1,41 @@ +var arrayEach = require('./_arrayEach'), + baseEach = require('./_baseEach'), + castFunction = require('./_castFunction'), + isArray = require('./isArray'); + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = isArray(collection) ? arrayEach : baseEach; + return func(collection, castFunction(iteratee)); +} + +module.exports = forEach; diff --git a/libs/events/node_modules/lodash/forEachRight.js b/libs/events/node_modules/lodash/forEachRight.js new file mode 100644 index 000000000..7390ebaf8 --- /dev/null +++ b/libs/events/node_modules/lodash/forEachRight.js @@ -0,0 +1,31 @@ +var arrayEachRight = require('./_arrayEachRight'), + baseEachRight = require('./_baseEachRight'), + castFunction = require('./_castFunction'), + isArray = require('./isArray'); + +/** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @alias eachRight + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEach + * @example + * + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `2` then `1`. + */ +function forEachRight(collection, iteratee) { + var func = isArray(collection) ? arrayEachRight : baseEachRight; + return func(collection, castFunction(iteratee)); +} + +module.exports = forEachRight; diff --git a/libs/events/node_modules/lodash/forIn.js b/libs/events/node_modules/lodash/forIn.js new file mode 100644 index 000000000..583a59638 --- /dev/null +++ b/libs/events/node_modules/lodash/forIn.js @@ -0,0 +1,39 @@ +var baseFor = require('./_baseFor'), + castFunction = require('./_castFunction'), + keysIn = require('./keysIn'); + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, castFunction(iteratee), keysIn); +} + +module.exports = forIn; diff --git a/libs/events/node_modules/lodash/forInRight.js b/libs/events/node_modules/lodash/forInRight.js new file mode 100644 index 000000000..4aedf58af --- /dev/null +++ b/libs/events/node_modules/lodash/forInRight.js @@ -0,0 +1,37 @@ +var baseForRight = require('./_baseForRight'), + castFunction = require('./_castFunction'), + keysIn = require('./keysIn'); + +/** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forIn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. + */ +function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, castFunction(iteratee), keysIn); +} + +module.exports = forInRight; diff --git a/libs/events/node_modules/lodash/forOwn.js b/libs/events/node_modules/lodash/forOwn.js new file mode 100644 index 000000000..94eed8402 --- /dev/null +++ b/libs/events/node_modules/lodash/forOwn.js @@ -0,0 +1,36 @@ +var baseForOwn = require('./_baseForOwn'), + castFunction = require('./_castFunction'); + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && baseForOwn(object, castFunction(iteratee)); +} + +module.exports = forOwn; diff --git a/libs/events/node_modules/lodash/forOwnRight.js b/libs/events/node_modules/lodash/forOwnRight.js new file mode 100644 index 000000000..86f338f03 --- /dev/null +++ b/libs/events/node_modules/lodash/forOwnRight.js @@ -0,0 +1,34 @@ +var baseForOwnRight = require('./_baseForOwnRight'), + castFunction = require('./_castFunction'); + +/** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. + */ +function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, castFunction(iteratee)); +} + +module.exports = forOwnRight; diff --git a/libs/events/node_modules/lodash/fp.js b/libs/events/node_modules/lodash/fp.js new file mode 100644 index 000000000..e372dbbdf --- /dev/null +++ b/libs/events/node_modules/lodash/fp.js @@ -0,0 +1,2 @@ +var _ = require('./lodash.min').runInContext(); +module.exports = require('./fp/_baseConvert')(_, _); diff --git a/libs/events/node_modules/lodash/fp/F.js b/libs/events/node_modules/lodash/fp/F.js new file mode 100644 index 000000000..a05a63ad9 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/F.js @@ -0,0 +1 @@ +module.exports = require('./stubFalse'); diff --git a/libs/events/node_modules/lodash/fp/T.js b/libs/events/node_modules/lodash/fp/T.js new file mode 100644 index 000000000..e2ba8ea56 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/T.js @@ -0,0 +1 @@ +module.exports = require('./stubTrue'); diff --git a/libs/events/node_modules/lodash/fp/__.js b/libs/events/node_modules/lodash/fp/__.js new file mode 100644 index 000000000..4af98deb4 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/__.js @@ -0,0 +1 @@ +module.exports = require('./placeholder'); diff --git a/libs/events/node_modules/lodash/fp/_baseConvert.js b/libs/events/node_modules/lodash/fp/_baseConvert.js new file mode 100644 index 000000000..9baf8e190 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/_baseConvert.js @@ -0,0 +1,569 @@ +var mapping = require('./_mapping'), + fallbackHolder = require('./placeholder'); + +/** Built-in value reference. */ +var push = Array.prototype.push; + +/** + * Creates a function, with an arity of `n`, that invokes `func` with the + * arguments it receives. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} n The arity of the new function. + * @returns {Function} Returns the new function. + */ +function baseArity(func, n) { + return n == 2 + ? function(a, b) { return func.apply(undefined, arguments); } + : function(a) { return func.apply(undefined, arguments); }; +} + +/** + * Creates a function that invokes `func`, with up to `n` arguments, ignoring + * any additional arguments. + * + * @private + * @param {Function} func The function to cap arguments for. + * @param {number} n The arity cap. + * @returns {Function} Returns the new function. + */ +function baseAry(func, n) { + return n == 2 + ? function(a, b) { return func(a, b); } + : function(a) { return func(a); }; +} + +/** + * Creates a clone of `array`. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the cloned array. + */ +function cloneArray(array) { + var length = array ? array.length : 0, + result = Array(length); + + while (length--) { + result[length] = array[length]; + } + return result; +} + +/** + * Creates a function that clones a given object using the assignment `func`. + * + * @private + * @param {Function} func The assignment function. + * @returns {Function} Returns the new cloner function. + */ +function createCloner(func) { + return function(object) { + return func({}, object); + }; +} + +/** + * A specialized version of `_.spread` which flattens the spread array into + * the arguments of the invoked `func`. + * + * @private + * @param {Function} func The function to spread arguments over. + * @param {number} start The start position of the spread. + * @returns {Function} Returns the new function. + */ +function flatSpread(func, start) { + return function() { + var length = arguments.length, + lastIndex = length - 1, + args = Array(length); + + while (length--) { + args[length] = arguments[length]; + } + var array = args[start], + otherArgs = args.slice(0, start); + + if (array) { + push.apply(otherArgs, array); + } + if (start != lastIndex) { + push.apply(otherArgs, args.slice(start + 1)); + } + return func.apply(this, otherArgs); + }; +} + +/** + * Creates a function that wraps `func` and uses `cloner` to clone the first + * argument it receives. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} cloner The function to clone arguments. + * @returns {Function} Returns the new immutable function. + */ +function wrapImmutable(func, cloner) { + return function() { + var length = arguments.length; + if (!length) { + return; + } + var args = Array(length); + while (length--) { + args[length] = arguments[length]; + } + var result = args[0] = cloner.apply(undefined, args); + func.apply(undefined, args); + return result; + }; +} + +/** + * The base implementation of `convert` which accepts a `util` object of methods + * required to perform conversions. + * + * @param {Object} util The util object. + * @param {string} name The name of the function to convert. + * @param {Function} func The function to convert. + * @param {Object} [options] The options object. + * @param {boolean} [options.cap=true] Specify capping iteratee arguments. + * @param {boolean} [options.curry=true] Specify currying. + * @param {boolean} [options.fixed=true] Specify fixed arity. + * @param {boolean} [options.immutable=true] Specify immutable operations. + * @param {boolean} [options.rearg=true] Specify rearranging arguments. + * @returns {Function|Object} Returns the converted function or object. + */ +function baseConvert(util, name, func, options) { + var isLib = typeof name == 'function', + isObj = name === Object(name); + + if (isObj) { + options = func; + func = name; + name = undefined; + } + if (func == null) { + throw new TypeError; + } + options || (options = {}); + + var config = { + 'cap': 'cap' in options ? options.cap : true, + 'curry': 'curry' in options ? options.curry : true, + 'fixed': 'fixed' in options ? options.fixed : true, + 'immutable': 'immutable' in options ? options.immutable : true, + 'rearg': 'rearg' in options ? options.rearg : true + }; + + var defaultHolder = isLib ? func : fallbackHolder, + forceCurry = ('curry' in options) && options.curry, + forceFixed = ('fixed' in options) && options.fixed, + forceRearg = ('rearg' in options) && options.rearg, + pristine = isLib ? func.runInContext() : undefined; + + var helpers = isLib ? func : { + 'ary': util.ary, + 'assign': util.assign, + 'clone': util.clone, + 'curry': util.curry, + 'forEach': util.forEach, + 'isArray': util.isArray, + 'isError': util.isError, + 'isFunction': util.isFunction, + 'isWeakMap': util.isWeakMap, + 'iteratee': util.iteratee, + 'keys': util.keys, + 'rearg': util.rearg, + 'toInteger': util.toInteger, + 'toPath': util.toPath + }; + + var ary = helpers.ary, + assign = helpers.assign, + clone = helpers.clone, + curry = helpers.curry, + each = helpers.forEach, + isArray = helpers.isArray, + isError = helpers.isError, + isFunction = helpers.isFunction, + isWeakMap = helpers.isWeakMap, + keys = helpers.keys, + rearg = helpers.rearg, + toInteger = helpers.toInteger, + toPath = helpers.toPath; + + var aryMethodKeys = keys(mapping.aryMethod); + + var wrappers = { + 'castArray': function(castArray) { + return function() { + var value = arguments[0]; + return isArray(value) + ? castArray(cloneArray(value)) + : castArray.apply(undefined, arguments); + }; + }, + 'iteratee': function(iteratee) { + return function() { + var func = arguments[0], + arity = arguments[1], + result = iteratee(func, arity), + length = result.length; + + if (config.cap && typeof arity == 'number') { + arity = arity > 2 ? (arity - 2) : 1; + return (length && length <= arity) ? result : baseAry(result, arity); + } + return result; + }; + }, + 'mixin': function(mixin) { + return function(source) { + var func = this; + if (!isFunction(func)) { + return mixin(func, Object(source)); + } + var pairs = []; + each(keys(source), function(key) { + if (isFunction(source[key])) { + pairs.push([key, func.prototype[key]]); + } + }); + + mixin(func, Object(source)); + + each(pairs, function(pair) { + var value = pair[1]; + if (isFunction(value)) { + func.prototype[pair[0]] = value; + } else { + delete func.prototype[pair[0]]; + } + }); + return func; + }; + }, + 'nthArg': function(nthArg) { + return function(n) { + var arity = n < 0 ? 1 : (toInteger(n) + 1); + return curry(nthArg(n), arity); + }; + }, + 'rearg': function(rearg) { + return function(func, indexes) { + var arity = indexes ? indexes.length : 0; + return curry(rearg(func, indexes), arity); + }; + }, + 'runInContext': function(runInContext) { + return function(context) { + return baseConvert(util, runInContext(context), options); + }; + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * Casts `func` to a function with an arity capped iteratee if needed. + * + * @private + * @param {string} name The name of the function to inspect. + * @param {Function} func The function to inspect. + * @returns {Function} Returns the cast function. + */ + function castCap(name, func) { + if (config.cap) { + var indexes = mapping.iterateeRearg[name]; + if (indexes) { + return iterateeRearg(func, indexes); + } + var n = !isLib && mapping.iterateeAry[name]; + if (n) { + return iterateeAry(func, n); + } + } + return func; + } + + /** + * Casts `func` to a curried function if needed. + * + * @private + * @param {string} name The name of the function to inspect. + * @param {Function} func The function to inspect. + * @param {number} n The arity of `func`. + * @returns {Function} Returns the cast function. + */ + function castCurry(name, func, n) { + return (forceCurry || (config.curry && n > 1)) + ? curry(func, n) + : func; + } + + /** + * Casts `func` to a fixed arity function if needed. + * + * @private + * @param {string} name The name of the function to inspect. + * @param {Function} func The function to inspect. + * @param {number} n The arity cap. + * @returns {Function} Returns the cast function. + */ + function castFixed(name, func, n) { + if (config.fixed && (forceFixed || !mapping.skipFixed[name])) { + var data = mapping.methodSpread[name], + start = data && data.start; + + return start === undefined ? ary(func, n) : flatSpread(func, start); + } + return func; + } + + /** + * Casts `func` to an rearged function if needed. + * + * @private + * @param {string} name The name of the function to inspect. + * @param {Function} func The function to inspect. + * @param {number} n The arity of `func`. + * @returns {Function} Returns the cast function. + */ + function castRearg(name, func, n) { + return (config.rearg && n > 1 && (forceRearg || !mapping.skipRearg[name])) + ? rearg(func, mapping.methodRearg[name] || mapping.aryRearg[n]) + : func; + } + + /** + * Creates a clone of `object` by `path`. + * + * @private + * @param {Object} object The object to clone. + * @param {Array|string} path The path to clone by. + * @returns {Object} Returns the cloned object. + */ + function cloneByPath(object, path) { + path = toPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + result = clone(Object(object)), + nested = result; + + while (nested != null && ++index < length) { + var key = path[index], + value = nested[key]; + + if (value != null && + !(isFunction(value) || isError(value) || isWeakMap(value))) { + nested[key] = clone(index == lastIndex ? value : Object(value)); + } + nested = nested[key]; + } + return result; + } + + /** + * Converts `lodash` to an immutable auto-curried iteratee-first data-last + * version with conversion `options` applied. + * + * @param {Object} [options] The options object. See `baseConvert` for more details. + * @returns {Function} Returns the converted `lodash`. + */ + function convertLib(options) { + return _.runInContext.convert(options)(undefined); + } + + /** + * Create a converter function for `func` of `name`. + * + * @param {string} name The name of the function to convert. + * @param {Function} func The function to convert. + * @returns {Function} Returns the new converter function. + */ + function createConverter(name, func) { + var realName = mapping.aliasToReal[name] || name, + methodName = mapping.remap[realName] || realName, + oldOptions = options; + + return function(options) { + var newUtil = isLib ? pristine : helpers, + newFunc = isLib ? pristine[methodName] : func, + newOptions = assign(assign({}, oldOptions), options); + + return baseConvert(newUtil, realName, newFunc, newOptions); + }; + } + + /** + * Creates a function that wraps `func` to invoke its iteratee, with up to `n` + * arguments, ignoring any additional arguments. + * + * @private + * @param {Function} func The function to cap iteratee arguments for. + * @param {number} n The arity cap. + * @returns {Function} Returns the new function. + */ + function iterateeAry(func, n) { + return overArg(func, function(func) { + return typeof func == 'function' ? baseAry(func, n) : func; + }); + } + + /** + * Creates a function that wraps `func` to invoke its iteratee with arguments + * arranged according to the specified `indexes` where the argument value at + * the first index is provided as the first argument, the argument value at + * the second index is provided as the second argument, and so on. + * + * @private + * @param {Function} func The function to rearrange iteratee arguments for. + * @param {number[]} indexes The arranged argument indexes. + * @returns {Function} Returns the new function. + */ + function iterateeRearg(func, indexes) { + return overArg(func, function(func) { + var n = indexes.length; + return baseArity(rearg(baseAry(func, n), indexes), n); + }); + } + + /** + * Creates a function that invokes `func` with its first argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function() { + var length = arguments.length; + if (!length) { + return func(); + } + var args = Array(length); + while (length--) { + args[length] = arguments[length]; + } + var index = config.rearg ? 0 : (length - 1); + args[index] = transform(args[index]); + return func.apply(undefined, args); + }; + } + + /** + * Creates a function that wraps `func` and applys the conversions + * rules by `name`. + * + * @private + * @param {string} name The name of the function to wrap. + * @param {Function} func The function to wrap. + * @returns {Function} Returns the converted function. + */ + function wrap(name, func, placeholder) { + var result, + realName = mapping.aliasToReal[name] || name, + wrapped = func, + wrapper = wrappers[realName]; + + if (wrapper) { + wrapped = wrapper(func); + } + else if (config.immutable) { + if (mapping.mutate.array[realName]) { + wrapped = wrapImmutable(func, cloneArray); + } + else if (mapping.mutate.object[realName]) { + wrapped = wrapImmutable(func, createCloner(func)); + } + else if (mapping.mutate.set[realName]) { + wrapped = wrapImmutable(func, cloneByPath); + } + } + each(aryMethodKeys, function(aryKey) { + each(mapping.aryMethod[aryKey], function(otherName) { + if (realName == otherName) { + var data = mapping.methodSpread[realName], + afterRearg = data && data.afterRearg; + + result = afterRearg + ? castFixed(realName, castRearg(realName, wrapped, aryKey), aryKey) + : castRearg(realName, castFixed(realName, wrapped, aryKey), aryKey); + + result = castCap(realName, result); + result = castCurry(realName, result, aryKey); + return false; + } + }); + return !result; + }); + + result || (result = wrapped); + if (result == func) { + result = forceCurry ? curry(result, 1) : function() { + return func.apply(this, arguments); + }; + } + result.convert = createConverter(realName, func); + result.placeholder = func.placeholder = placeholder; + + return result; + } + + /*--------------------------------------------------------------------------*/ + + if (!isObj) { + return wrap(name, func, defaultHolder); + } + var _ = func; + + // Convert methods by ary cap. + var pairs = []; + each(aryMethodKeys, function(aryKey) { + each(mapping.aryMethod[aryKey], function(key) { + var func = _[mapping.remap[key] || key]; + if (func) { + pairs.push([key, wrap(key, func, _)]); + } + }); + }); + + // Convert remaining methods. + each(keys(_), function(key) { + var func = _[key]; + if (typeof func == 'function') { + var length = pairs.length; + while (length--) { + if (pairs[length][0] == key) { + return; + } + } + func.convert = createConverter(key, func); + pairs.push([key, func]); + } + }); + + // Assign to `_` leaving `_.prototype` unchanged to allow chaining. + each(pairs, function(pair) { + _[pair[0]] = pair[1]; + }); + + _.convert = convertLib; + _.placeholder = _; + + // Assign aliases. + each(keys(_), function(key) { + each(mapping.realToAlias[key] || [], function(alias) { + _[alias] = _[key]; + }); + }); + + return _; +} + +module.exports = baseConvert; diff --git a/libs/events/node_modules/lodash/fp/_convertBrowser.js b/libs/events/node_modules/lodash/fp/_convertBrowser.js new file mode 100644 index 000000000..bde030dc0 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/_convertBrowser.js @@ -0,0 +1,18 @@ +var baseConvert = require('./_baseConvert'); + +/** + * Converts `lodash` to an immutable auto-curried iteratee-first data-last + * version with conversion `options` applied. + * + * @param {Function} lodash The lodash function to convert. + * @param {Object} [options] The options object. See `baseConvert` for more details. + * @returns {Function} Returns the converted `lodash`. + */ +function browserConvert(lodash, options) { + return baseConvert(lodash, lodash, options); +} + +if (typeof _ == 'function' && typeof _.runInContext == 'function') { + _ = browserConvert(_.runInContext()); +} +module.exports = browserConvert; diff --git a/libs/events/node_modules/lodash/fp/_falseOptions.js b/libs/events/node_modules/lodash/fp/_falseOptions.js new file mode 100644 index 000000000..773235e34 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/_falseOptions.js @@ -0,0 +1,7 @@ +module.exports = { + 'cap': false, + 'curry': false, + 'fixed': false, + 'immutable': false, + 'rearg': false +}; diff --git a/libs/events/node_modules/lodash/fp/_mapping.js b/libs/events/node_modules/lodash/fp/_mapping.js new file mode 100644 index 000000000..a642ec058 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/_mapping.js @@ -0,0 +1,358 @@ +/** Used to map aliases to their real names. */ +exports.aliasToReal = { + + // Lodash aliases. + 'each': 'forEach', + 'eachRight': 'forEachRight', + 'entries': 'toPairs', + 'entriesIn': 'toPairsIn', + 'extend': 'assignIn', + 'extendAll': 'assignInAll', + 'extendAllWith': 'assignInAllWith', + 'extendWith': 'assignInWith', + 'first': 'head', + + // Methods that are curried variants of others. + 'conforms': 'conformsTo', + 'matches': 'isMatch', + 'property': 'get', + + // Ramda aliases. + '__': 'placeholder', + 'F': 'stubFalse', + 'T': 'stubTrue', + 'all': 'every', + 'allPass': 'overEvery', + 'always': 'constant', + 'any': 'some', + 'anyPass': 'overSome', + 'apply': 'spread', + 'assoc': 'set', + 'assocPath': 'set', + 'complement': 'negate', + 'compose': 'flowRight', + 'contains': 'includes', + 'dissoc': 'unset', + 'dissocPath': 'unset', + 'dropLast': 'dropRight', + 'dropLastWhile': 'dropRightWhile', + 'equals': 'isEqual', + 'identical': 'eq', + 'indexBy': 'keyBy', + 'init': 'initial', + 'invertObj': 'invert', + 'juxt': 'over', + 'omitAll': 'omit', + 'nAry': 'ary', + 'path': 'get', + 'pathEq': 'matchesProperty', + 'pathOr': 'getOr', + 'paths': 'at', + 'pickAll': 'pick', + 'pipe': 'flow', + 'pluck': 'map', + 'prop': 'get', + 'propEq': 'matchesProperty', + 'propOr': 'getOr', + 'props': 'at', + 'symmetricDifference': 'xor', + 'symmetricDifferenceBy': 'xorBy', + 'symmetricDifferenceWith': 'xorWith', + 'takeLast': 'takeRight', + 'takeLastWhile': 'takeRightWhile', + 'unapply': 'rest', + 'unnest': 'flatten', + 'useWith': 'overArgs', + 'where': 'conformsTo', + 'whereEq': 'isMatch', + 'zipObj': 'zipObject' +}; + +/** Used to map ary to method names. */ +exports.aryMethod = { + '1': [ + 'assignAll', 'assignInAll', 'attempt', 'castArray', 'ceil', 'create', + 'curry', 'curryRight', 'defaultsAll', 'defaultsDeepAll', 'floor', 'flow', + 'flowRight', 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'mergeAll', + 'methodOf', 'mixin', 'nthArg', 'over', 'overEvery', 'overSome','rest', 'reverse', + 'round', 'runInContext', 'spread', 'template', 'trim', 'trimEnd', 'trimStart', + 'uniqueId', 'words', 'zipAll' + ], + '2': [ + 'add', 'after', 'ary', 'assign', 'assignAllWith', 'assignIn', 'assignInAllWith', + 'at', 'before', 'bind', 'bindAll', 'bindKey', 'chunk', 'cloneDeepWith', + 'cloneWith', 'concat', 'conformsTo', 'countBy', 'curryN', 'curryRightN', + 'debounce', 'defaults', 'defaultsDeep', 'defaultTo', 'delay', 'difference', + 'divide', 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', + 'every', 'filter', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', + 'findLastKey', 'flatMap', 'flatMapDeep', 'flattenDepth', 'forEach', + 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'get', + 'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf', 'intersection', + 'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch', 'join', 'keyBy', + 'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues', 'matchesProperty', + 'maxBy', 'meanBy', 'merge', 'mergeAllWith', 'minBy', 'multiply', 'nth', 'omit', + 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', 'partial', + 'partialRight', 'partition', 'pick', 'pickBy', 'propertyOf', 'pull', 'pullAll', + 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', + 'repeat', 'restFrom', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex', + 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy', + 'split', 'spreadFrom', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', + 'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', + 'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', + 'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', + 'zipObjectDeep' + ], + '3': [ + 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', + 'findFrom', 'findIndexFrom', 'findLastFrom', 'findLastIndexFrom', 'getOr', + 'includesFrom', 'indexOfFrom', 'inRange', 'intersectionBy', 'intersectionWith', + 'invokeArgs', 'invokeArgsMap', 'isEqualWith', 'isMatchWith', 'flatMapDepth', + 'lastIndexOfFrom', 'mergeWith', 'orderBy', 'padChars', 'padCharsEnd', + 'padCharsStart', 'pullAllBy', 'pullAllWith', 'rangeStep', 'rangeStepRight', + 'reduce', 'reduceRight', 'replace', 'set', 'slice', 'sortedIndexBy', + 'sortedLastIndexBy', 'transform', 'unionBy', 'unionWith', 'update', 'xorBy', + 'xorWith', 'zipWith' + ], + '4': [ + 'fill', 'setWith', 'updateWith' + ] +}; + +/** Used to map ary to rearg configs. */ +exports.aryRearg = { + '2': [1, 0], + '3': [2, 0, 1], + '4': [3, 2, 0, 1] +}; + +/** Used to map method names to their iteratee ary. */ +exports.iterateeAry = { + 'dropRightWhile': 1, + 'dropWhile': 1, + 'every': 1, + 'filter': 1, + 'find': 1, + 'findFrom': 1, + 'findIndex': 1, + 'findIndexFrom': 1, + 'findKey': 1, + 'findLast': 1, + 'findLastFrom': 1, + 'findLastIndex': 1, + 'findLastIndexFrom': 1, + 'findLastKey': 1, + 'flatMap': 1, + 'flatMapDeep': 1, + 'flatMapDepth': 1, + 'forEach': 1, + 'forEachRight': 1, + 'forIn': 1, + 'forInRight': 1, + 'forOwn': 1, + 'forOwnRight': 1, + 'map': 1, + 'mapKeys': 1, + 'mapValues': 1, + 'partition': 1, + 'reduce': 2, + 'reduceRight': 2, + 'reject': 1, + 'remove': 1, + 'some': 1, + 'takeRightWhile': 1, + 'takeWhile': 1, + 'times': 1, + 'transform': 2 +}; + +/** Used to map method names to iteratee rearg configs. */ +exports.iterateeRearg = { + 'mapKeys': [1], + 'reduceRight': [1, 0] +}; + +/** Used to map method names to rearg configs. */ +exports.methodRearg = { + 'assignInAllWith': [1, 0], + 'assignInWith': [1, 2, 0], + 'assignAllWith': [1, 0], + 'assignWith': [1, 2, 0], + 'differenceBy': [1, 2, 0], + 'differenceWith': [1, 2, 0], + 'getOr': [2, 1, 0], + 'intersectionBy': [1, 2, 0], + 'intersectionWith': [1, 2, 0], + 'isEqualWith': [1, 2, 0], + 'isMatchWith': [2, 1, 0], + 'mergeAllWith': [1, 0], + 'mergeWith': [1, 2, 0], + 'padChars': [2, 1, 0], + 'padCharsEnd': [2, 1, 0], + 'padCharsStart': [2, 1, 0], + 'pullAllBy': [2, 1, 0], + 'pullAllWith': [2, 1, 0], + 'rangeStep': [1, 2, 0], + 'rangeStepRight': [1, 2, 0], + 'setWith': [3, 1, 2, 0], + 'sortedIndexBy': [2, 1, 0], + 'sortedLastIndexBy': [2, 1, 0], + 'unionBy': [1, 2, 0], + 'unionWith': [1, 2, 0], + 'updateWith': [3, 1, 2, 0], + 'xorBy': [1, 2, 0], + 'xorWith': [1, 2, 0], + 'zipWith': [1, 2, 0] +}; + +/** Used to map method names to spread configs. */ +exports.methodSpread = { + 'assignAll': { 'start': 0 }, + 'assignAllWith': { 'start': 0 }, + 'assignInAll': { 'start': 0 }, + 'assignInAllWith': { 'start': 0 }, + 'defaultsAll': { 'start': 0 }, + 'defaultsDeepAll': { 'start': 0 }, + 'invokeArgs': { 'start': 2 }, + 'invokeArgsMap': { 'start': 2 }, + 'mergeAll': { 'start': 0 }, + 'mergeAllWith': { 'start': 0 }, + 'partial': { 'start': 1 }, + 'partialRight': { 'start': 1 }, + 'without': { 'start': 1 }, + 'zipAll': { 'start': 0 } +}; + +/** Used to identify methods which mutate arrays or objects. */ +exports.mutate = { + 'array': { + 'fill': true, + 'pull': true, + 'pullAll': true, + 'pullAllBy': true, + 'pullAllWith': true, + 'pullAt': true, + 'remove': true, + 'reverse': true + }, + 'object': { + 'assign': true, + 'assignAll': true, + 'assignAllWith': true, + 'assignIn': true, + 'assignInAll': true, + 'assignInAllWith': true, + 'assignInWith': true, + 'assignWith': true, + 'defaults': true, + 'defaultsAll': true, + 'defaultsDeep': true, + 'defaultsDeepAll': true, + 'merge': true, + 'mergeAll': true, + 'mergeAllWith': true, + 'mergeWith': true, + }, + 'set': { + 'set': true, + 'setWith': true, + 'unset': true, + 'update': true, + 'updateWith': true + } +}; + +/** Used to map real names to their aliases. */ +exports.realToAlias = (function() { + var hasOwnProperty = Object.prototype.hasOwnProperty, + object = exports.aliasToReal, + result = {}; + + for (var key in object) { + var value = object[key]; + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + return result; +}()); + +/** Used to map method names to other names. */ +exports.remap = { + 'assignAll': 'assign', + 'assignAllWith': 'assignWith', + 'assignInAll': 'assignIn', + 'assignInAllWith': 'assignInWith', + 'curryN': 'curry', + 'curryRightN': 'curryRight', + 'defaultsAll': 'defaults', + 'defaultsDeepAll': 'defaultsDeep', + 'findFrom': 'find', + 'findIndexFrom': 'findIndex', + 'findLastFrom': 'findLast', + 'findLastIndexFrom': 'findLastIndex', + 'getOr': 'get', + 'includesFrom': 'includes', + 'indexOfFrom': 'indexOf', + 'invokeArgs': 'invoke', + 'invokeArgsMap': 'invokeMap', + 'lastIndexOfFrom': 'lastIndexOf', + 'mergeAll': 'merge', + 'mergeAllWith': 'mergeWith', + 'padChars': 'pad', + 'padCharsEnd': 'padEnd', + 'padCharsStart': 'padStart', + 'propertyOf': 'get', + 'rangeStep': 'range', + 'rangeStepRight': 'rangeRight', + 'restFrom': 'rest', + 'spreadFrom': 'spread', + 'trimChars': 'trim', + 'trimCharsEnd': 'trimEnd', + 'trimCharsStart': 'trimStart', + 'zipAll': 'zip' +}; + +/** Used to track methods that skip fixing their arity. */ +exports.skipFixed = { + 'castArray': true, + 'flow': true, + 'flowRight': true, + 'iteratee': true, + 'mixin': true, + 'rearg': true, + 'runInContext': true +}; + +/** Used to track methods that skip rearranging arguments. */ +exports.skipRearg = { + 'add': true, + 'assign': true, + 'assignIn': true, + 'bind': true, + 'bindKey': true, + 'concat': true, + 'difference': true, + 'divide': true, + 'eq': true, + 'gt': true, + 'gte': true, + 'isEqual': true, + 'lt': true, + 'lte': true, + 'matchesProperty': true, + 'merge': true, + 'multiply': true, + 'overArgs': true, + 'partial': true, + 'partialRight': true, + 'propertyOf': true, + 'random': true, + 'range': true, + 'rangeRight': true, + 'subtract': true, + 'zip': true, + 'zipObject': true, + 'zipObjectDeep': true +}; diff --git a/libs/events/node_modules/lodash/fp/_util.js b/libs/events/node_modules/lodash/fp/_util.js new file mode 100644 index 000000000..1dbf36f5d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/_util.js @@ -0,0 +1,16 @@ +module.exports = { + 'ary': require('../ary'), + 'assign': require('../_baseAssign'), + 'clone': require('../clone'), + 'curry': require('../curry'), + 'forEach': require('../_arrayEach'), + 'isArray': require('../isArray'), + 'isError': require('../isError'), + 'isFunction': require('../isFunction'), + 'isWeakMap': require('../isWeakMap'), + 'iteratee': require('../iteratee'), + 'keys': require('../_baseKeys'), + 'rearg': require('../rearg'), + 'toInteger': require('../toInteger'), + 'toPath': require('../toPath') +}; diff --git a/libs/events/node_modules/lodash/fp/add.js b/libs/events/node_modules/lodash/fp/add.js new file mode 100644 index 000000000..816eeece3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/add.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('add', require('../add')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/after.js b/libs/events/node_modules/lodash/fp/after.js new file mode 100644 index 000000000..21a0167ab --- /dev/null +++ b/libs/events/node_modules/lodash/fp/after.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('after', require('../after')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/all.js b/libs/events/node_modules/lodash/fp/all.js new file mode 100644 index 000000000..d0839f77e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/all.js @@ -0,0 +1 @@ +module.exports = require('./every'); diff --git a/libs/events/node_modules/lodash/fp/allPass.js b/libs/events/node_modules/lodash/fp/allPass.js new file mode 100644 index 000000000..79b73ef84 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/allPass.js @@ -0,0 +1 @@ +module.exports = require('./overEvery'); diff --git a/libs/events/node_modules/lodash/fp/always.js b/libs/events/node_modules/lodash/fp/always.js new file mode 100644 index 000000000..988770307 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/always.js @@ -0,0 +1 @@ +module.exports = require('./constant'); diff --git a/libs/events/node_modules/lodash/fp/any.js b/libs/events/node_modules/lodash/fp/any.js new file mode 100644 index 000000000..900ac25e8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/any.js @@ -0,0 +1 @@ +module.exports = require('./some'); diff --git a/libs/events/node_modules/lodash/fp/anyPass.js b/libs/events/node_modules/lodash/fp/anyPass.js new file mode 100644 index 000000000..2774ab37a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/anyPass.js @@ -0,0 +1 @@ +module.exports = require('./overSome'); diff --git a/libs/events/node_modules/lodash/fp/apply.js b/libs/events/node_modules/lodash/fp/apply.js new file mode 100644 index 000000000..2b7571296 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/apply.js @@ -0,0 +1 @@ +module.exports = require('./spread'); diff --git a/libs/events/node_modules/lodash/fp/array.js b/libs/events/node_modules/lodash/fp/array.js new file mode 100644 index 000000000..fe939c2c2 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/array.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../array')); diff --git a/libs/events/node_modules/lodash/fp/ary.js b/libs/events/node_modules/lodash/fp/ary.js new file mode 100644 index 000000000..8edf18778 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/ary.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('ary', require('../ary')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/assign.js b/libs/events/node_modules/lodash/fp/assign.js new file mode 100644 index 000000000..23f47af17 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assign.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('assign', require('../assign')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/assignAll.js b/libs/events/node_modules/lodash/fp/assignAll.js new file mode 100644 index 000000000..b1d36c7ef --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assignAll.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('assignAll', require('../assign')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/assignAllWith.js b/libs/events/node_modules/lodash/fp/assignAllWith.js new file mode 100644 index 000000000..21e836e6f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assignAllWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('assignAllWith', require('../assignWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/assignIn.js b/libs/events/node_modules/lodash/fp/assignIn.js new file mode 100644 index 000000000..6e7c65fad --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assignIn.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('assignIn', require('../assignIn')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/assignInAll.js b/libs/events/node_modules/lodash/fp/assignInAll.js new file mode 100644 index 000000000..7ba75dba1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assignInAll.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('assignInAll', require('../assignIn')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/assignInAllWith.js b/libs/events/node_modules/lodash/fp/assignInAllWith.js new file mode 100644 index 000000000..e766903d4 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assignInAllWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('assignInAllWith', require('../assignInWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/assignInWith.js b/libs/events/node_modules/lodash/fp/assignInWith.js new file mode 100644 index 000000000..acb592367 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assignInWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('assignInWith', require('../assignInWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/assignWith.js b/libs/events/node_modules/lodash/fp/assignWith.js new file mode 100644 index 000000000..eb925212d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assignWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('assignWith', require('../assignWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/assoc.js b/libs/events/node_modules/lodash/fp/assoc.js new file mode 100644 index 000000000..7648820c9 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assoc.js @@ -0,0 +1 @@ +module.exports = require('./set'); diff --git a/libs/events/node_modules/lodash/fp/assocPath.js b/libs/events/node_modules/lodash/fp/assocPath.js new file mode 100644 index 000000000..7648820c9 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/assocPath.js @@ -0,0 +1 @@ +module.exports = require('./set'); diff --git a/libs/events/node_modules/lodash/fp/at.js b/libs/events/node_modules/lodash/fp/at.js new file mode 100644 index 000000000..cc39d257c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/at.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('at', require('../at')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/attempt.js b/libs/events/node_modules/lodash/fp/attempt.js new file mode 100644 index 000000000..26ca42ea0 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/attempt.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('attempt', require('../attempt')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/before.js b/libs/events/node_modules/lodash/fp/before.js new file mode 100644 index 000000000..7a2de65d2 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/before.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('before', require('../before')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/bind.js b/libs/events/node_modules/lodash/fp/bind.js new file mode 100644 index 000000000..5cbe4f302 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/bind.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('bind', require('../bind')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/bindAll.js b/libs/events/node_modules/lodash/fp/bindAll.js new file mode 100644 index 000000000..6b4a4a0f2 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/bindAll.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('bindAll', require('../bindAll')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/bindKey.js b/libs/events/node_modules/lodash/fp/bindKey.js new file mode 100644 index 000000000..6a46c6b19 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/bindKey.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('bindKey', require('../bindKey')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/camelCase.js b/libs/events/node_modules/lodash/fp/camelCase.js new file mode 100644 index 000000000..87b77b493 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/camelCase.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('camelCase', require('../camelCase'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/capitalize.js b/libs/events/node_modules/lodash/fp/capitalize.js new file mode 100644 index 000000000..cac74e14f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/capitalize.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('capitalize', require('../capitalize'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/castArray.js b/libs/events/node_modules/lodash/fp/castArray.js new file mode 100644 index 000000000..8681c099e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/castArray.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('castArray', require('../castArray')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/ceil.js b/libs/events/node_modules/lodash/fp/ceil.js new file mode 100644 index 000000000..f416b7294 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/ceil.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('ceil', require('../ceil')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/chain.js b/libs/events/node_modules/lodash/fp/chain.js new file mode 100644 index 000000000..604fe398b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/chain.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('chain', require('../chain'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/chunk.js b/libs/events/node_modules/lodash/fp/chunk.js new file mode 100644 index 000000000..871ab0858 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/chunk.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('chunk', require('../chunk')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/clamp.js b/libs/events/node_modules/lodash/fp/clamp.js new file mode 100644 index 000000000..3b06c01ce --- /dev/null +++ b/libs/events/node_modules/lodash/fp/clamp.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('clamp', require('../clamp')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/clone.js b/libs/events/node_modules/lodash/fp/clone.js new file mode 100644 index 000000000..cadb59c91 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/clone.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('clone', require('../clone'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/cloneDeep.js b/libs/events/node_modules/lodash/fp/cloneDeep.js new file mode 100644 index 000000000..a6107aac9 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/cloneDeep.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('cloneDeep', require('../cloneDeep'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/cloneDeepWith.js b/libs/events/node_modules/lodash/fp/cloneDeepWith.js new file mode 100644 index 000000000..6f01e44a3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/cloneDeepWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('cloneDeepWith', require('../cloneDeepWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/cloneWith.js b/libs/events/node_modules/lodash/fp/cloneWith.js new file mode 100644 index 000000000..aa8857810 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/cloneWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('cloneWith', require('../cloneWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/collection.js b/libs/events/node_modules/lodash/fp/collection.js new file mode 100644 index 000000000..fc8b328a0 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/collection.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../collection')); diff --git a/libs/events/node_modules/lodash/fp/commit.js b/libs/events/node_modules/lodash/fp/commit.js new file mode 100644 index 000000000..130a894f8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/commit.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('commit', require('../commit'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/compact.js b/libs/events/node_modules/lodash/fp/compact.js new file mode 100644 index 000000000..ce8f7a1ac --- /dev/null +++ b/libs/events/node_modules/lodash/fp/compact.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('compact', require('../compact'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/complement.js b/libs/events/node_modules/lodash/fp/complement.js new file mode 100644 index 000000000..93eb462b3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/complement.js @@ -0,0 +1 @@ +module.exports = require('./negate'); diff --git a/libs/events/node_modules/lodash/fp/compose.js b/libs/events/node_modules/lodash/fp/compose.js new file mode 100644 index 000000000..1954e9423 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/compose.js @@ -0,0 +1 @@ +module.exports = require('./flowRight'); diff --git a/libs/events/node_modules/lodash/fp/concat.js b/libs/events/node_modules/lodash/fp/concat.js new file mode 100644 index 000000000..e59346ad9 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/concat.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('concat', require('../concat')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/cond.js b/libs/events/node_modules/lodash/fp/cond.js new file mode 100644 index 000000000..6a0120efd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/cond.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('cond', require('../cond'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/conforms.js b/libs/events/node_modules/lodash/fp/conforms.js new file mode 100644 index 000000000..3247f64a8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/conforms.js @@ -0,0 +1 @@ +module.exports = require('./conformsTo'); diff --git a/libs/events/node_modules/lodash/fp/conformsTo.js b/libs/events/node_modules/lodash/fp/conformsTo.js new file mode 100644 index 000000000..aa7f41ec0 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/conformsTo.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('conformsTo', require('../conformsTo')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/constant.js b/libs/events/node_modules/lodash/fp/constant.js new file mode 100644 index 000000000..9e406fc09 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/constant.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('constant', require('../constant'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/contains.js b/libs/events/node_modules/lodash/fp/contains.js new file mode 100644 index 000000000..594722af5 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/contains.js @@ -0,0 +1 @@ +module.exports = require('./includes'); diff --git a/libs/events/node_modules/lodash/fp/convert.js b/libs/events/node_modules/lodash/fp/convert.js new file mode 100644 index 000000000..4795dc424 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/convert.js @@ -0,0 +1,18 @@ +var baseConvert = require('./_baseConvert'), + util = require('./_util'); + +/** + * Converts `func` of `name` to an immutable auto-curried iteratee-first data-last + * version with conversion `options` applied. If `name` is an object its methods + * will be converted. + * + * @param {string} name The name of the function to wrap. + * @param {Function} [func] The function to wrap. + * @param {Object} [options] The options object. See `baseConvert` for more details. + * @returns {Function|Object} Returns the converted function or object. + */ +function convert(name, func, options) { + return baseConvert(util, name, func, options); +} + +module.exports = convert; diff --git a/libs/events/node_modules/lodash/fp/countBy.js b/libs/events/node_modules/lodash/fp/countBy.js new file mode 100644 index 000000000..dfa464326 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/countBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('countBy', require('../countBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/create.js b/libs/events/node_modules/lodash/fp/create.js new file mode 100644 index 000000000..752025fb8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/create.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('create', require('../create')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/curry.js b/libs/events/node_modules/lodash/fp/curry.js new file mode 100644 index 000000000..b0b4168c5 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/curry.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('curry', require('../curry')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/curryN.js b/libs/events/node_modules/lodash/fp/curryN.js new file mode 100644 index 000000000..2ae7d00a6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/curryN.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('curryN', require('../curry')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/curryRight.js b/libs/events/node_modules/lodash/fp/curryRight.js new file mode 100644 index 000000000..cb619eb5d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/curryRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('curryRight', require('../curryRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/curryRightN.js b/libs/events/node_modules/lodash/fp/curryRightN.js new file mode 100644 index 000000000..2495afc89 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/curryRightN.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('curryRightN', require('../curryRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/date.js b/libs/events/node_modules/lodash/fp/date.js new file mode 100644 index 000000000..82cb952bc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/date.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../date')); diff --git a/libs/events/node_modules/lodash/fp/debounce.js b/libs/events/node_modules/lodash/fp/debounce.js new file mode 100644 index 000000000..26122293a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/debounce.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('debounce', require('../debounce')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/deburr.js b/libs/events/node_modules/lodash/fp/deburr.js new file mode 100644 index 000000000..96463ab88 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/deburr.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('deburr', require('../deburr'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/defaultTo.js b/libs/events/node_modules/lodash/fp/defaultTo.js new file mode 100644 index 000000000..d6b52a444 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/defaultTo.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('defaultTo', require('../defaultTo')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/defaults.js b/libs/events/node_modules/lodash/fp/defaults.js new file mode 100644 index 000000000..e1a8e6e7d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/defaults.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('defaults', require('../defaults')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/defaultsAll.js b/libs/events/node_modules/lodash/fp/defaultsAll.js new file mode 100644 index 000000000..238fcc3c2 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/defaultsAll.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('defaultsAll', require('../defaults')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/defaultsDeep.js b/libs/events/node_modules/lodash/fp/defaultsDeep.js new file mode 100644 index 000000000..1f172ff94 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/defaultsDeep.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('defaultsDeep', require('../defaultsDeep')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/defaultsDeepAll.js b/libs/events/node_modules/lodash/fp/defaultsDeepAll.js new file mode 100644 index 000000000..6835f2f07 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/defaultsDeepAll.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('defaultsDeepAll', require('../defaultsDeep')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/defer.js b/libs/events/node_modules/lodash/fp/defer.js new file mode 100644 index 000000000..ec7990fe2 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/defer.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('defer', require('../defer'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/delay.js b/libs/events/node_modules/lodash/fp/delay.js new file mode 100644 index 000000000..556dbd568 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/delay.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('delay', require('../delay')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/difference.js b/libs/events/node_modules/lodash/fp/difference.js new file mode 100644 index 000000000..2d0376542 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/difference.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('difference', require('../difference')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/differenceBy.js b/libs/events/node_modules/lodash/fp/differenceBy.js new file mode 100644 index 000000000..2f914910a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/differenceBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('differenceBy', require('../differenceBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/differenceWith.js b/libs/events/node_modules/lodash/fp/differenceWith.js new file mode 100644 index 000000000..bcf5ad2e1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/differenceWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('differenceWith', require('../differenceWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/dissoc.js b/libs/events/node_modules/lodash/fp/dissoc.js new file mode 100644 index 000000000..7ec7be190 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/dissoc.js @@ -0,0 +1 @@ +module.exports = require('./unset'); diff --git a/libs/events/node_modules/lodash/fp/dissocPath.js b/libs/events/node_modules/lodash/fp/dissocPath.js new file mode 100644 index 000000000..7ec7be190 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/dissocPath.js @@ -0,0 +1 @@ +module.exports = require('./unset'); diff --git a/libs/events/node_modules/lodash/fp/divide.js b/libs/events/node_modules/lodash/fp/divide.js new file mode 100644 index 000000000..82048c5e0 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/divide.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('divide', require('../divide')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/drop.js b/libs/events/node_modules/lodash/fp/drop.js new file mode 100644 index 000000000..2fa9b4faa --- /dev/null +++ b/libs/events/node_modules/lodash/fp/drop.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('drop', require('../drop')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/dropLast.js b/libs/events/node_modules/lodash/fp/dropLast.js new file mode 100644 index 000000000..174e52551 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/dropLast.js @@ -0,0 +1 @@ +module.exports = require('./dropRight'); diff --git a/libs/events/node_modules/lodash/fp/dropLastWhile.js b/libs/events/node_modules/lodash/fp/dropLastWhile.js new file mode 100644 index 000000000..be2a9d24a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/dropLastWhile.js @@ -0,0 +1 @@ +module.exports = require('./dropRightWhile'); diff --git a/libs/events/node_modules/lodash/fp/dropRight.js b/libs/events/node_modules/lodash/fp/dropRight.js new file mode 100644 index 000000000..e98881fcd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/dropRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('dropRight', require('../dropRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/dropRightWhile.js b/libs/events/node_modules/lodash/fp/dropRightWhile.js new file mode 100644 index 000000000..cacaa7019 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/dropRightWhile.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('dropRightWhile', require('../dropRightWhile')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/dropWhile.js b/libs/events/node_modules/lodash/fp/dropWhile.js new file mode 100644 index 000000000..285f864d1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/dropWhile.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('dropWhile', require('../dropWhile')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/each.js b/libs/events/node_modules/lodash/fp/each.js new file mode 100644 index 000000000..8800f4204 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/each.js @@ -0,0 +1 @@ +module.exports = require('./forEach'); diff --git a/libs/events/node_modules/lodash/fp/eachRight.js b/libs/events/node_modules/lodash/fp/eachRight.js new file mode 100644 index 000000000..3252b2aba --- /dev/null +++ b/libs/events/node_modules/lodash/fp/eachRight.js @@ -0,0 +1 @@ +module.exports = require('./forEachRight'); diff --git a/libs/events/node_modules/lodash/fp/endsWith.js b/libs/events/node_modules/lodash/fp/endsWith.js new file mode 100644 index 000000000..17dc2a495 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/endsWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('endsWith', require('../endsWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/entries.js b/libs/events/node_modules/lodash/fp/entries.js new file mode 100644 index 000000000..7a88df204 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/entries.js @@ -0,0 +1 @@ +module.exports = require('./toPairs'); diff --git a/libs/events/node_modules/lodash/fp/entriesIn.js b/libs/events/node_modules/lodash/fp/entriesIn.js new file mode 100644 index 000000000..f6c6331c1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/entriesIn.js @@ -0,0 +1 @@ +module.exports = require('./toPairsIn'); diff --git a/libs/events/node_modules/lodash/fp/eq.js b/libs/events/node_modules/lodash/fp/eq.js new file mode 100644 index 000000000..9a3d21bf1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/eq.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('eq', require('../eq')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/equals.js b/libs/events/node_modules/lodash/fp/equals.js new file mode 100644 index 000000000..e6a5ce0ca --- /dev/null +++ b/libs/events/node_modules/lodash/fp/equals.js @@ -0,0 +1 @@ +module.exports = require('./isEqual'); diff --git a/libs/events/node_modules/lodash/fp/escape.js b/libs/events/node_modules/lodash/fp/escape.js new file mode 100644 index 000000000..52c1fbba6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/escape.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('escape', require('../escape'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/escapeRegExp.js b/libs/events/node_modules/lodash/fp/escapeRegExp.js new file mode 100644 index 000000000..369b2eff6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/escapeRegExp.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('escapeRegExp', require('../escapeRegExp'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/every.js b/libs/events/node_modules/lodash/fp/every.js new file mode 100644 index 000000000..95c2776c3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/every.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('every', require('../every')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/extend.js b/libs/events/node_modules/lodash/fp/extend.js new file mode 100644 index 000000000..e00166c20 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/extend.js @@ -0,0 +1 @@ +module.exports = require('./assignIn'); diff --git a/libs/events/node_modules/lodash/fp/extendAll.js b/libs/events/node_modules/lodash/fp/extendAll.js new file mode 100644 index 000000000..cc55b64fc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/extendAll.js @@ -0,0 +1 @@ +module.exports = require('./assignInAll'); diff --git a/libs/events/node_modules/lodash/fp/extendAllWith.js b/libs/events/node_modules/lodash/fp/extendAllWith.js new file mode 100644 index 000000000..6679d208b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/extendAllWith.js @@ -0,0 +1 @@ +module.exports = require('./assignInAllWith'); diff --git a/libs/events/node_modules/lodash/fp/extendWith.js b/libs/events/node_modules/lodash/fp/extendWith.js new file mode 100644 index 000000000..dbdcb3b4e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/extendWith.js @@ -0,0 +1 @@ +module.exports = require('./assignInWith'); diff --git a/libs/events/node_modules/lodash/fp/fill.js b/libs/events/node_modules/lodash/fp/fill.js new file mode 100644 index 000000000..b2d47e84e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/fill.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('fill', require('../fill')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/filter.js b/libs/events/node_modules/lodash/fp/filter.js new file mode 100644 index 000000000..796d501ce --- /dev/null +++ b/libs/events/node_modules/lodash/fp/filter.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('filter', require('../filter')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/find.js b/libs/events/node_modules/lodash/fp/find.js new file mode 100644 index 000000000..f805d336a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/find.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('find', require('../find')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/findFrom.js b/libs/events/node_modules/lodash/fp/findFrom.js new file mode 100644 index 000000000..da8275e84 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/findFrom.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('findFrom', require('../find')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/findIndex.js b/libs/events/node_modules/lodash/fp/findIndex.js new file mode 100644 index 000000000..8c15fd116 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/findIndex.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('findIndex', require('../findIndex')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/findIndexFrom.js b/libs/events/node_modules/lodash/fp/findIndexFrom.js new file mode 100644 index 000000000..32e98cb95 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/findIndexFrom.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('findIndexFrom', require('../findIndex')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/findKey.js b/libs/events/node_modules/lodash/fp/findKey.js new file mode 100644 index 000000000..475bcfa8a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/findKey.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('findKey', require('../findKey')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/findLast.js b/libs/events/node_modules/lodash/fp/findLast.js new file mode 100644 index 000000000..093fe94e7 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/findLast.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('findLast', require('../findLast')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/findLastFrom.js b/libs/events/node_modules/lodash/fp/findLastFrom.js new file mode 100644 index 000000000..76c38fbad --- /dev/null +++ b/libs/events/node_modules/lodash/fp/findLastFrom.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('findLastFrom', require('../findLast')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/findLastIndex.js b/libs/events/node_modules/lodash/fp/findLastIndex.js new file mode 100644 index 000000000..36986df0b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/findLastIndex.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('findLastIndex', require('../findLastIndex')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/findLastIndexFrom.js b/libs/events/node_modules/lodash/fp/findLastIndexFrom.js new file mode 100644 index 000000000..34c8176cf --- /dev/null +++ b/libs/events/node_modules/lodash/fp/findLastIndexFrom.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('findLastIndexFrom', require('../findLastIndex')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/findLastKey.js b/libs/events/node_modules/lodash/fp/findLastKey.js new file mode 100644 index 000000000..5f81b604e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/findLastKey.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('findLastKey', require('../findLastKey')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/first.js b/libs/events/node_modules/lodash/fp/first.js new file mode 100644 index 000000000..53f4ad13e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/first.js @@ -0,0 +1 @@ +module.exports = require('./head'); diff --git a/libs/events/node_modules/lodash/fp/flatMap.js b/libs/events/node_modules/lodash/fp/flatMap.js new file mode 100644 index 000000000..d01dc4d04 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/flatMap.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('flatMap', require('../flatMap')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/flatMapDeep.js b/libs/events/node_modules/lodash/fp/flatMapDeep.js new file mode 100644 index 000000000..569c42eb9 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/flatMapDeep.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('flatMapDeep', require('../flatMapDeep')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/flatMapDepth.js b/libs/events/node_modules/lodash/fp/flatMapDepth.js new file mode 100644 index 000000000..6eb68fdee --- /dev/null +++ b/libs/events/node_modules/lodash/fp/flatMapDepth.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('flatMapDepth', require('../flatMapDepth')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/flatten.js b/libs/events/node_modules/lodash/fp/flatten.js new file mode 100644 index 000000000..30425d896 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/flatten.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('flatten', require('../flatten'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/flattenDeep.js b/libs/events/node_modules/lodash/fp/flattenDeep.js new file mode 100644 index 000000000..aed5db27c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/flattenDeep.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('flattenDeep', require('../flattenDeep'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/flattenDepth.js b/libs/events/node_modules/lodash/fp/flattenDepth.js new file mode 100644 index 000000000..ad65e378e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/flattenDepth.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('flattenDepth', require('../flattenDepth')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/flip.js b/libs/events/node_modules/lodash/fp/flip.js new file mode 100644 index 000000000..0547e7b4e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/flip.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('flip', require('../flip'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/floor.js b/libs/events/node_modules/lodash/fp/floor.js new file mode 100644 index 000000000..a6cf3358e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/floor.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('floor', require('../floor')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/flow.js b/libs/events/node_modules/lodash/fp/flow.js new file mode 100644 index 000000000..cd83677a6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/flow.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('flow', require('../flow')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/flowRight.js b/libs/events/node_modules/lodash/fp/flowRight.js new file mode 100644 index 000000000..972a5b9b1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/flowRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('flowRight', require('../flowRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/forEach.js b/libs/events/node_modules/lodash/fp/forEach.js new file mode 100644 index 000000000..2f494521c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/forEach.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('forEach', require('../forEach')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/forEachRight.js b/libs/events/node_modules/lodash/fp/forEachRight.js new file mode 100644 index 000000000..3ff97336b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/forEachRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('forEachRight', require('../forEachRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/forIn.js b/libs/events/node_modules/lodash/fp/forIn.js new file mode 100644 index 000000000..9341749b1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/forIn.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('forIn', require('../forIn')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/forInRight.js b/libs/events/node_modules/lodash/fp/forInRight.js new file mode 100644 index 000000000..cecf8bbfa --- /dev/null +++ b/libs/events/node_modules/lodash/fp/forInRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('forInRight', require('../forInRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/forOwn.js b/libs/events/node_modules/lodash/fp/forOwn.js new file mode 100644 index 000000000..246449e9a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/forOwn.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('forOwn', require('../forOwn')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/forOwnRight.js b/libs/events/node_modules/lodash/fp/forOwnRight.js new file mode 100644 index 000000000..c5e826e0d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/forOwnRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('forOwnRight', require('../forOwnRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/fromPairs.js b/libs/events/node_modules/lodash/fp/fromPairs.js new file mode 100644 index 000000000..f8cc5968c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/fromPairs.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('fromPairs', require('../fromPairs')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/function.js b/libs/events/node_modules/lodash/fp/function.js new file mode 100644 index 000000000..dfe69b1fa --- /dev/null +++ b/libs/events/node_modules/lodash/fp/function.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../function')); diff --git a/libs/events/node_modules/lodash/fp/functions.js b/libs/events/node_modules/lodash/fp/functions.js new file mode 100644 index 000000000..09d1bb1ba --- /dev/null +++ b/libs/events/node_modules/lodash/fp/functions.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('functions', require('../functions'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/functionsIn.js b/libs/events/node_modules/lodash/fp/functionsIn.js new file mode 100644 index 000000000..2cfeb83eb --- /dev/null +++ b/libs/events/node_modules/lodash/fp/functionsIn.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('functionsIn', require('../functionsIn'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/get.js b/libs/events/node_modules/lodash/fp/get.js new file mode 100644 index 000000000..6d3a32863 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/get.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('get', require('../get')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/getOr.js b/libs/events/node_modules/lodash/fp/getOr.js new file mode 100644 index 000000000..7dbf771f0 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/getOr.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('getOr', require('../get')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/groupBy.js b/libs/events/node_modules/lodash/fp/groupBy.js new file mode 100644 index 000000000..fc0bc78a5 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/groupBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('groupBy', require('../groupBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/gt.js b/libs/events/node_modules/lodash/fp/gt.js new file mode 100644 index 000000000..9e57c8085 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/gt.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('gt', require('../gt')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/gte.js b/libs/events/node_modules/lodash/fp/gte.js new file mode 100644 index 000000000..458478638 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/gte.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('gte', require('../gte')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/has.js b/libs/events/node_modules/lodash/fp/has.js new file mode 100644 index 000000000..b90129839 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/has.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('has', require('../has')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/hasIn.js b/libs/events/node_modules/lodash/fp/hasIn.js new file mode 100644 index 000000000..b3c3d1a3f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/hasIn.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('hasIn', require('../hasIn')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/head.js b/libs/events/node_modules/lodash/fp/head.js new file mode 100644 index 000000000..2694f0a21 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/head.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('head', require('../head'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/identical.js b/libs/events/node_modules/lodash/fp/identical.js new file mode 100644 index 000000000..85563f4a4 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/identical.js @@ -0,0 +1 @@ +module.exports = require('./eq'); diff --git a/libs/events/node_modules/lodash/fp/identity.js b/libs/events/node_modules/lodash/fp/identity.js new file mode 100644 index 000000000..096415a5d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/identity.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('identity', require('../identity'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/inRange.js b/libs/events/node_modules/lodash/fp/inRange.js new file mode 100644 index 000000000..202d940ba --- /dev/null +++ b/libs/events/node_modules/lodash/fp/inRange.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('inRange', require('../inRange')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/includes.js b/libs/events/node_modules/lodash/fp/includes.js new file mode 100644 index 000000000..11467805c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/includes.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('includes', require('../includes')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/includesFrom.js b/libs/events/node_modules/lodash/fp/includesFrom.js new file mode 100644 index 000000000..683afdb46 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/includesFrom.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('includesFrom', require('../includes')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/indexBy.js b/libs/events/node_modules/lodash/fp/indexBy.js new file mode 100644 index 000000000..7e64bc0fc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/indexBy.js @@ -0,0 +1 @@ +module.exports = require('./keyBy'); diff --git a/libs/events/node_modules/lodash/fp/indexOf.js b/libs/events/node_modules/lodash/fp/indexOf.js new file mode 100644 index 000000000..524658eb9 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/indexOf.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('indexOf', require('../indexOf')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/indexOfFrom.js b/libs/events/node_modules/lodash/fp/indexOfFrom.js new file mode 100644 index 000000000..d99c822f4 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/indexOfFrom.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('indexOfFrom', require('../indexOf')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/init.js b/libs/events/node_modules/lodash/fp/init.js new file mode 100644 index 000000000..2f88d8b0e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/init.js @@ -0,0 +1 @@ +module.exports = require('./initial'); diff --git a/libs/events/node_modules/lodash/fp/initial.js b/libs/events/node_modules/lodash/fp/initial.js new file mode 100644 index 000000000..b732ba0bd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/initial.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('initial', require('../initial'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/intersection.js b/libs/events/node_modules/lodash/fp/intersection.js new file mode 100644 index 000000000..52936d560 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/intersection.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('intersection', require('../intersection')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/intersectionBy.js b/libs/events/node_modules/lodash/fp/intersectionBy.js new file mode 100644 index 000000000..72629f277 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/intersectionBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('intersectionBy', require('../intersectionBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/intersectionWith.js b/libs/events/node_modules/lodash/fp/intersectionWith.js new file mode 100644 index 000000000..e064f400f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/intersectionWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('intersectionWith', require('../intersectionWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/invert.js b/libs/events/node_modules/lodash/fp/invert.js new file mode 100644 index 000000000..2d5d1f0d4 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/invert.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('invert', require('../invert')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/invertBy.js b/libs/events/node_modules/lodash/fp/invertBy.js new file mode 100644 index 000000000..63ca97ecb --- /dev/null +++ b/libs/events/node_modules/lodash/fp/invertBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('invertBy', require('../invertBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/invertObj.js b/libs/events/node_modules/lodash/fp/invertObj.js new file mode 100644 index 000000000..f1d842e49 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/invertObj.js @@ -0,0 +1 @@ +module.exports = require('./invert'); diff --git a/libs/events/node_modules/lodash/fp/invoke.js b/libs/events/node_modules/lodash/fp/invoke.js new file mode 100644 index 000000000..fcf17f0d5 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/invoke.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('invoke', require('../invoke')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/invokeArgs.js b/libs/events/node_modules/lodash/fp/invokeArgs.js new file mode 100644 index 000000000..d3f2953fa --- /dev/null +++ b/libs/events/node_modules/lodash/fp/invokeArgs.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('invokeArgs', require('../invoke')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/invokeArgsMap.js b/libs/events/node_modules/lodash/fp/invokeArgsMap.js new file mode 100644 index 000000000..eaa9f84ff --- /dev/null +++ b/libs/events/node_modules/lodash/fp/invokeArgsMap.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('invokeArgsMap', require('../invokeMap')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/invokeMap.js b/libs/events/node_modules/lodash/fp/invokeMap.js new file mode 100644 index 000000000..6515fd73f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/invokeMap.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('invokeMap', require('../invokeMap')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isArguments.js b/libs/events/node_modules/lodash/fp/isArguments.js new file mode 100644 index 000000000..1d93c9e59 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isArguments.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isArguments', require('../isArguments'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isArray.js b/libs/events/node_modules/lodash/fp/isArray.js new file mode 100644 index 000000000..ba7ade8dd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isArray.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isArray', require('../isArray'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isArrayBuffer.js b/libs/events/node_modules/lodash/fp/isArrayBuffer.js new file mode 100644 index 000000000..5088513fa --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isArrayBuffer.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isArrayBuffer', require('../isArrayBuffer'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isArrayLike.js b/libs/events/node_modules/lodash/fp/isArrayLike.js new file mode 100644 index 000000000..8f1856bf6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isArrayLike.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isArrayLike', require('../isArrayLike'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isArrayLikeObject.js b/libs/events/node_modules/lodash/fp/isArrayLikeObject.js new file mode 100644 index 000000000..21084984b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isArrayLikeObject.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isArrayLikeObject', require('../isArrayLikeObject'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isBoolean.js b/libs/events/node_modules/lodash/fp/isBoolean.js new file mode 100644 index 000000000..9339f75b1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isBoolean.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isBoolean', require('../isBoolean'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isBuffer.js b/libs/events/node_modules/lodash/fp/isBuffer.js new file mode 100644 index 000000000..e60b12381 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isBuffer.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isBuffer', require('../isBuffer'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isDate.js b/libs/events/node_modules/lodash/fp/isDate.js new file mode 100644 index 000000000..dc41d089e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isDate.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isDate', require('../isDate'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isElement.js b/libs/events/node_modules/lodash/fp/isElement.js new file mode 100644 index 000000000..18ee039a2 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isElement.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isElement', require('../isElement'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isEmpty.js b/libs/events/node_modules/lodash/fp/isEmpty.js new file mode 100644 index 000000000..0f4ae841e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isEmpty.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isEmpty', require('../isEmpty'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isEqual.js b/libs/events/node_modules/lodash/fp/isEqual.js new file mode 100644 index 000000000..41383865f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isEqual.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isEqual', require('../isEqual')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isEqualWith.js b/libs/events/node_modules/lodash/fp/isEqualWith.js new file mode 100644 index 000000000..029ff5cda --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isEqualWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isEqualWith', require('../isEqualWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isError.js b/libs/events/node_modules/lodash/fp/isError.js new file mode 100644 index 000000000..3dfd81ccc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isError.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isError', require('../isError'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isFinite.js b/libs/events/node_modules/lodash/fp/isFinite.js new file mode 100644 index 000000000..0b647b841 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isFinite.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isFinite', require('../isFinite'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isFunction.js b/libs/events/node_modules/lodash/fp/isFunction.js new file mode 100644 index 000000000..ff8e5c458 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isFunction.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isFunction', require('../isFunction'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isInteger.js b/libs/events/node_modules/lodash/fp/isInteger.js new file mode 100644 index 000000000..67af4ff6d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isInteger.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isInteger', require('../isInteger'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isLength.js b/libs/events/node_modules/lodash/fp/isLength.js new file mode 100644 index 000000000..fc101c5a6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isLength.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isLength', require('../isLength'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isMap.js b/libs/events/node_modules/lodash/fp/isMap.js new file mode 100644 index 000000000..a209aa66f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isMap.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isMap', require('../isMap'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isMatch.js b/libs/events/node_modules/lodash/fp/isMatch.js new file mode 100644 index 000000000..6264ca17f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isMatch.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isMatch', require('../isMatch')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isMatchWith.js b/libs/events/node_modules/lodash/fp/isMatchWith.js new file mode 100644 index 000000000..d95f31935 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isMatchWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isMatchWith', require('../isMatchWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isNaN.js b/libs/events/node_modules/lodash/fp/isNaN.js new file mode 100644 index 000000000..66a978f11 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isNaN.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isNaN', require('../isNaN'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isNative.js b/libs/events/node_modules/lodash/fp/isNative.js new file mode 100644 index 000000000..3d775ba95 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isNative.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isNative', require('../isNative'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isNil.js b/libs/events/node_modules/lodash/fp/isNil.js new file mode 100644 index 000000000..5952c028a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isNil.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isNil', require('../isNil'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isNull.js b/libs/events/node_modules/lodash/fp/isNull.js new file mode 100644 index 000000000..f201a354b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isNull.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isNull', require('../isNull'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isNumber.js b/libs/events/node_modules/lodash/fp/isNumber.js new file mode 100644 index 000000000..a2b5fa049 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isNumber.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isNumber', require('../isNumber'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isObject.js b/libs/events/node_modules/lodash/fp/isObject.js new file mode 100644 index 000000000..231ace03b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isObject.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isObject', require('../isObject'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isObjectLike.js b/libs/events/node_modules/lodash/fp/isObjectLike.js new file mode 100644 index 000000000..f16082e6f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isObjectLike.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isObjectLike', require('../isObjectLike'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isPlainObject.js b/libs/events/node_modules/lodash/fp/isPlainObject.js new file mode 100644 index 000000000..b5bea90d3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isPlainObject.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isPlainObject', require('../isPlainObject'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isRegExp.js b/libs/events/node_modules/lodash/fp/isRegExp.js new file mode 100644 index 000000000..12a1a3d71 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isRegExp.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isRegExp', require('../isRegExp'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isSafeInteger.js b/libs/events/node_modules/lodash/fp/isSafeInteger.js new file mode 100644 index 000000000..7230f5520 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isSafeInteger.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isSafeInteger', require('../isSafeInteger'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isSet.js b/libs/events/node_modules/lodash/fp/isSet.js new file mode 100644 index 000000000..35c01f6fa --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isSet.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isSet', require('../isSet'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isString.js b/libs/events/node_modules/lodash/fp/isString.js new file mode 100644 index 000000000..1fd0679ef --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isString.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isString', require('../isString'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isSymbol.js b/libs/events/node_modules/lodash/fp/isSymbol.js new file mode 100644 index 000000000..38676956d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isSymbol.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isSymbol', require('../isSymbol'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isTypedArray.js b/libs/events/node_modules/lodash/fp/isTypedArray.js new file mode 100644 index 000000000..856795387 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isTypedArray.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isTypedArray', require('../isTypedArray'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isUndefined.js b/libs/events/node_modules/lodash/fp/isUndefined.js new file mode 100644 index 000000000..ddbca31ca --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isUndefined.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isUndefined', require('../isUndefined'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isWeakMap.js b/libs/events/node_modules/lodash/fp/isWeakMap.js new file mode 100644 index 000000000..ef60c613c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isWeakMap.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isWeakMap', require('../isWeakMap'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/isWeakSet.js b/libs/events/node_modules/lodash/fp/isWeakSet.js new file mode 100644 index 000000000..c99bfaa6d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/isWeakSet.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('isWeakSet', require('../isWeakSet'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/iteratee.js b/libs/events/node_modules/lodash/fp/iteratee.js new file mode 100644 index 000000000..9f0f71738 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/iteratee.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('iteratee', require('../iteratee')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/join.js b/libs/events/node_modules/lodash/fp/join.js new file mode 100644 index 000000000..a220e003c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/join.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('join', require('../join')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/juxt.js b/libs/events/node_modules/lodash/fp/juxt.js new file mode 100644 index 000000000..f71e04e00 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/juxt.js @@ -0,0 +1 @@ +module.exports = require('./over'); diff --git a/libs/events/node_modules/lodash/fp/kebabCase.js b/libs/events/node_modules/lodash/fp/kebabCase.js new file mode 100644 index 000000000..60737f17c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/kebabCase.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('kebabCase', require('../kebabCase'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/keyBy.js b/libs/events/node_modules/lodash/fp/keyBy.js new file mode 100644 index 000000000..9a6a85d42 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/keyBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('keyBy', require('../keyBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/keys.js b/libs/events/node_modules/lodash/fp/keys.js new file mode 100644 index 000000000..e12bb07f1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/keys.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('keys', require('../keys'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/keysIn.js b/libs/events/node_modules/lodash/fp/keysIn.js new file mode 100644 index 000000000..f3eb36a8d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/keysIn.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('keysIn', require('../keysIn'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/lang.js b/libs/events/node_modules/lodash/fp/lang.js new file mode 100644 index 000000000..08cc9c14b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/lang.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../lang')); diff --git a/libs/events/node_modules/lodash/fp/last.js b/libs/events/node_modules/lodash/fp/last.js new file mode 100644 index 000000000..0f716993f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/last.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('last', require('../last'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/lastIndexOf.js b/libs/events/node_modules/lodash/fp/lastIndexOf.js new file mode 100644 index 000000000..ddf39c301 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/lastIndexOf.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('lastIndexOf', require('../lastIndexOf')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/lastIndexOfFrom.js b/libs/events/node_modules/lodash/fp/lastIndexOfFrom.js new file mode 100644 index 000000000..1ff6a0b5a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/lastIndexOfFrom.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('lastIndexOfFrom', require('../lastIndexOf')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/lowerCase.js b/libs/events/node_modules/lodash/fp/lowerCase.js new file mode 100644 index 000000000..ea64bc15d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/lowerCase.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('lowerCase', require('../lowerCase'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/lowerFirst.js b/libs/events/node_modules/lodash/fp/lowerFirst.js new file mode 100644 index 000000000..539720a3d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/lowerFirst.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('lowerFirst', require('../lowerFirst'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/lt.js b/libs/events/node_modules/lodash/fp/lt.js new file mode 100644 index 000000000..a31d21ecc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/lt.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('lt', require('../lt')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/lte.js b/libs/events/node_modules/lodash/fp/lte.js new file mode 100644 index 000000000..d795d10ee --- /dev/null +++ b/libs/events/node_modules/lodash/fp/lte.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('lte', require('../lte')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/map.js b/libs/events/node_modules/lodash/fp/map.js new file mode 100644 index 000000000..cf9879436 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/map.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('map', require('../map')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/mapKeys.js b/libs/events/node_modules/lodash/fp/mapKeys.js new file mode 100644 index 000000000..168458709 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/mapKeys.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('mapKeys', require('../mapKeys')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/mapValues.js b/libs/events/node_modules/lodash/fp/mapValues.js new file mode 100644 index 000000000..400497275 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/mapValues.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('mapValues', require('../mapValues')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/matches.js b/libs/events/node_modules/lodash/fp/matches.js new file mode 100644 index 000000000..29d1e1e4f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/matches.js @@ -0,0 +1 @@ +module.exports = require('./isMatch'); diff --git a/libs/events/node_modules/lodash/fp/matchesProperty.js b/libs/events/node_modules/lodash/fp/matchesProperty.js new file mode 100644 index 000000000..4575bd243 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/matchesProperty.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('matchesProperty', require('../matchesProperty')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/math.js b/libs/events/node_modules/lodash/fp/math.js new file mode 100644 index 000000000..e8f50f792 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/math.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../math')); diff --git a/libs/events/node_modules/lodash/fp/max.js b/libs/events/node_modules/lodash/fp/max.js new file mode 100644 index 000000000..a66acac22 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/max.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('max', require('../max'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/maxBy.js b/libs/events/node_modules/lodash/fp/maxBy.js new file mode 100644 index 000000000..d083fd64f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/maxBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('maxBy', require('../maxBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/mean.js b/libs/events/node_modules/lodash/fp/mean.js new file mode 100644 index 000000000..31172460c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/mean.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('mean', require('../mean'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/meanBy.js b/libs/events/node_modules/lodash/fp/meanBy.js new file mode 100644 index 000000000..556f25edf --- /dev/null +++ b/libs/events/node_modules/lodash/fp/meanBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('meanBy', require('../meanBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/memoize.js b/libs/events/node_modules/lodash/fp/memoize.js new file mode 100644 index 000000000..638eec63b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/memoize.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('memoize', require('../memoize')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/merge.js b/libs/events/node_modules/lodash/fp/merge.js new file mode 100644 index 000000000..ac66adde1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/merge.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('merge', require('../merge')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/mergeAll.js b/libs/events/node_modules/lodash/fp/mergeAll.js new file mode 100644 index 000000000..a3674d671 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/mergeAll.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('mergeAll', require('../merge')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/mergeAllWith.js b/libs/events/node_modules/lodash/fp/mergeAllWith.js new file mode 100644 index 000000000..4bd4206dc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/mergeAllWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('mergeAllWith', require('../mergeWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/mergeWith.js b/libs/events/node_modules/lodash/fp/mergeWith.js new file mode 100644 index 000000000..00d44d5e1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/mergeWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('mergeWith', require('../mergeWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/method.js b/libs/events/node_modules/lodash/fp/method.js new file mode 100644 index 000000000..f4060c687 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/method.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('method', require('../method')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/methodOf.js b/libs/events/node_modules/lodash/fp/methodOf.js new file mode 100644 index 000000000..61399056f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/methodOf.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('methodOf', require('../methodOf')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/min.js b/libs/events/node_modules/lodash/fp/min.js new file mode 100644 index 000000000..d12c6b40d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/min.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('min', require('../min'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/minBy.js b/libs/events/node_modules/lodash/fp/minBy.js new file mode 100644 index 000000000..fdb9e24d8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/minBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('minBy', require('../minBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/mixin.js b/libs/events/node_modules/lodash/fp/mixin.js new file mode 100644 index 000000000..332e6fbfd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/mixin.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('mixin', require('../mixin')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/multiply.js b/libs/events/node_modules/lodash/fp/multiply.js new file mode 100644 index 000000000..4dcf0b0d4 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/multiply.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('multiply', require('../multiply')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/nAry.js b/libs/events/node_modules/lodash/fp/nAry.js new file mode 100644 index 000000000..f262a76cc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/nAry.js @@ -0,0 +1 @@ +module.exports = require('./ary'); diff --git a/libs/events/node_modules/lodash/fp/negate.js b/libs/events/node_modules/lodash/fp/negate.js new file mode 100644 index 000000000..8b6dc7c5b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/negate.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('negate', require('../negate'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/next.js b/libs/events/node_modules/lodash/fp/next.js new file mode 100644 index 000000000..140155e23 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/next.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('next', require('../next'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/noop.js b/libs/events/node_modules/lodash/fp/noop.js new file mode 100644 index 000000000..b9e32cc8c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/noop.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('noop', require('../noop'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/now.js b/libs/events/node_modules/lodash/fp/now.js new file mode 100644 index 000000000..6de2068aa --- /dev/null +++ b/libs/events/node_modules/lodash/fp/now.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('now', require('../now'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/nth.js b/libs/events/node_modules/lodash/fp/nth.js new file mode 100644 index 000000000..da4fda740 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/nth.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('nth', require('../nth')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/nthArg.js b/libs/events/node_modules/lodash/fp/nthArg.js new file mode 100644 index 000000000..fce316594 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/nthArg.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('nthArg', require('../nthArg')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/number.js b/libs/events/node_modules/lodash/fp/number.js new file mode 100644 index 000000000..5c10b8842 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/number.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../number')); diff --git a/libs/events/node_modules/lodash/fp/object.js b/libs/events/node_modules/lodash/fp/object.js new file mode 100644 index 000000000..ae39a1346 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/object.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../object')); diff --git a/libs/events/node_modules/lodash/fp/omit.js b/libs/events/node_modules/lodash/fp/omit.js new file mode 100644 index 000000000..fd685291e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/omit.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('omit', require('../omit')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/omitAll.js b/libs/events/node_modules/lodash/fp/omitAll.js new file mode 100644 index 000000000..144cf4b96 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/omitAll.js @@ -0,0 +1 @@ +module.exports = require('./omit'); diff --git a/libs/events/node_modules/lodash/fp/omitBy.js b/libs/events/node_modules/lodash/fp/omitBy.js new file mode 100644 index 000000000..90df73802 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/omitBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('omitBy', require('../omitBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/once.js b/libs/events/node_modules/lodash/fp/once.js new file mode 100644 index 000000000..f8f0a5c73 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/once.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('once', require('../once'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/orderBy.js b/libs/events/node_modules/lodash/fp/orderBy.js new file mode 100644 index 000000000..848e21075 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/orderBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('orderBy', require('../orderBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/over.js b/libs/events/node_modules/lodash/fp/over.js new file mode 100644 index 000000000..01eba7b98 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/over.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('over', require('../over')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/overArgs.js b/libs/events/node_modules/lodash/fp/overArgs.js new file mode 100644 index 000000000..738556f0c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/overArgs.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('overArgs', require('../overArgs')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/overEvery.js b/libs/events/node_modules/lodash/fp/overEvery.js new file mode 100644 index 000000000..9f5a032dc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/overEvery.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('overEvery', require('../overEvery')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/overSome.js b/libs/events/node_modules/lodash/fp/overSome.js new file mode 100644 index 000000000..15939d586 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/overSome.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('overSome', require('../overSome')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/pad.js b/libs/events/node_modules/lodash/fp/pad.js new file mode 100644 index 000000000..f1dea4a98 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pad.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('pad', require('../pad')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/padChars.js b/libs/events/node_modules/lodash/fp/padChars.js new file mode 100644 index 000000000..d6e0804cd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/padChars.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('padChars', require('../pad')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/padCharsEnd.js b/libs/events/node_modules/lodash/fp/padCharsEnd.js new file mode 100644 index 000000000..d4ab79ad3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/padCharsEnd.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('padCharsEnd', require('../padEnd')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/padCharsStart.js b/libs/events/node_modules/lodash/fp/padCharsStart.js new file mode 100644 index 000000000..a08a30000 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/padCharsStart.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('padCharsStart', require('../padStart')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/padEnd.js b/libs/events/node_modules/lodash/fp/padEnd.js new file mode 100644 index 000000000..a8522ec36 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/padEnd.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('padEnd', require('../padEnd')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/padStart.js b/libs/events/node_modules/lodash/fp/padStart.js new file mode 100644 index 000000000..f4ca79d4a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/padStart.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('padStart', require('../padStart')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/parseInt.js b/libs/events/node_modules/lodash/fp/parseInt.js new file mode 100644 index 000000000..27314ccbc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/parseInt.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('parseInt', require('../parseInt')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/partial.js b/libs/events/node_modules/lodash/fp/partial.js new file mode 100644 index 000000000..5d4601598 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/partial.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('partial', require('../partial')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/partialRight.js b/libs/events/node_modules/lodash/fp/partialRight.js new file mode 100644 index 000000000..7f05fed0a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/partialRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('partialRight', require('../partialRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/partition.js b/libs/events/node_modules/lodash/fp/partition.js new file mode 100644 index 000000000..2ebcacc1f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/partition.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('partition', require('../partition')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/path.js b/libs/events/node_modules/lodash/fp/path.js new file mode 100644 index 000000000..b29cfb213 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/path.js @@ -0,0 +1 @@ +module.exports = require('./get'); diff --git a/libs/events/node_modules/lodash/fp/pathEq.js b/libs/events/node_modules/lodash/fp/pathEq.js new file mode 100644 index 000000000..36c027a38 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pathEq.js @@ -0,0 +1 @@ +module.exports = require('./matchesProperty'); diff --git a/libs/events/node_modules/lodash/fp/pathOr.js b/libs/events/node_modules/lodash/fp/pathOr.js new file mode 100644 index 000000000..4ab582091 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pathOr.js @@ -0,0 +1 @@ +module.exports = require('./getOr'); diff --git a/libs/events/node_modules/lodash/fp/paths.js b/libs/events/node_modules/lodash/fp/paths.js new file mode 100644 index 000000000..1eb7950ac --- /dev/null +++ b/libs/events/node_modules/lodash/fp/paths.js @@ -0,0 +1 @@ +module.exports = require('./at'); diff --git a/libs/events/node_modules/lodash/fp/pick.js b/libs/events/node_modules/lodash/fp/pick.js new file mode 100644 index 000000000..197393de1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pick.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('pick', require('../pick')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/pickAll.js b/libs/events/node_modules/lodash/fp/pickAll.js new file mode 100644 index 000000000..a8ecd4613 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pickAll.js @@ -0,0 +1 @@ +module.exports = require('./pick'); diff --git a/libs/events/node_modules/lodash/fp/pickBy.js b/libs/events/node_modules/lodash/fp/pickBy.js new file mode 100644 index 000000000..d832d16b6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pickBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('pickBy', require('../pickBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/pipe.js b/libs/events/node_modules/lodash/fp/pipe.js new file mode 100644 index 000000000..b2e1e2cc8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pipe.js @@ -0,0 +1 @@ +module.exports = require('./flow'); diff --git a/libs/events/node_modules/lodash/fp/placeholder.js b/libs/events/node_modules/lodash/fp/placeholder.js new file mode 100644 index 000000000..1ce17393b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/placeholder.js @@ -0,0 +1,6 @@ +/** + * The default argument placeholder value for methods. + * + * @type {Object} + */ +module.exports = {}; diff --git a/libs/events/node_modules/lodash/fp/plant.js b/libs/events/node_modules/lodash/fp/plant.js new file mode 100644 index 000000000..eca8f32b4 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/plant.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('plant', require('../plant'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/pluck.js b/libs/events/node_modules/lodash/fp/pluck.js new file mode 100644 index 000000000..0d1e1abfa --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pluck.js @@ -0,0 +1 @@ +module.exports = require('./map'); diff --git a/libs/events/node_modules/lodash/fp/prop.js b/libs/events/node_modules/lodash/fp/prop.js new file mode 100644 index 000000000..b29cfb213 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/prop.js @@ -0,0 +1 @@ +module.exports = require('./get'); diff --git a/libs/events/node_modules/lodash/fp/propEq.js b/libs/events/node_modules/lodash/fp/propEq.js new file mode 100644 index 000000000..36c027a38 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/propEq.js @@ -0,0 +1 @@ +module.exports = require('./matchesProperty'); diff --git a/libs/events/node_modules/lodash/fp/propOr.js b/libs/events/node_modules/lodash/fp/propOr.js new file mode 100644 index 000000000..4ab582091 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/propOr.js @@ -0,0 +1 @@ +module.exports = require('./getOr'); diff --git a/libs/events/node_modules/lodash/fp/property.js b/libs/events/node_modules/lodash/fp/property.js new file mode 100644 index 000000000..b29cfb213 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/property.js @@ -0,0 +1 @@ +module.exports = require('./get'); diff --git a/libs/events/node_modules/lodash/fp/propertyOf.js b/libs/events/node_modules/lodash/fp/propertyOf.js new file mode 100644 index 000000000..f6273ee47 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/propertyOf.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('propertyOf', require('../get')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/props.js b/libs/events/node_modules/lodash/fp/props.js new file mode 100644 index 000000000..1eb7950ac --- /dev/null +++ b/libs/events/node_modules/lodash/fp/props.js @@ -0,0 +1 @@ +module.exports = require('./at'); diff --git a/libs/events/node_modules/lodash/fp/pull.js b/libs/events/node_modules/lodash/fp/pull.js new file mode 100644 index 000000000..8d7084f07 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pull.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('pull', require('../pull')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/pullAll.js b/libs/events/node_modules/lodash/fp/pullAll.js new file mode 100644 index 000000000..98d5c9a73 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pullAll.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('pullAll', require('../pullAll')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/pullAllBy.js b/libs/events/node_modules/lodash/fp/pullAllBy.js new file mode 100644 index 000000000..876bc3bf1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pullAllBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('pullAllBy', require('../pullAllBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/pullAllWith.js b/libs/events/node_modules/lodash/fp/pullAllWith.js new file mode 100644 index 000000000..f71ba4d73 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pullAllWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('pullAllWith', require('../pullAllWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/pullAt.js b/libs/events/node_modules/lodash/fp/pullAt.js new file mode 100644 index 000000000..e8b3bb612 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/pullAt.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('pullAt', require('../pullAt')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/random.js b/libs/events/node_modules/lodash/fp/random.js new file mode 100644 index 000000000..99d852e4a --- /dev/null +++ b/libs/events/node_modules/lodash/fp/random.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('random', require('../random')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/range.js b/libs/events/node_modules/lodash/fp/range.js new file mode 100644 index 000000000..a6bb59118 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/range.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('range', require('../range')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/rangeRight.js b/libs/events/node_modules/lodash/fp/rangeRight.js new file mode 100644 index 000000000..fdb712f94 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/rangeRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('rangeRight', require('../rangeRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/rangeStep.js b/libs/events/node_modules/lodash/fp/rangeStep.js new file mode 100644 index 000000000..d72dfc200 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/rangeStep.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('rangeStep', require('../range')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/rangeStepRight.js b/libs/events/node_modules/lodash/fp/rangeStepRight.js new file mode 100644 index 000000000..8b2a67bc6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/rangeStepRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('rangeStepRight', require('../rangeRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/rearg.js b/libs/events/node_modules/lodash/fp/rearg.js new file mode 100644 index 000000000..678e02a32 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/rearg.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('rearg', require('../rearg')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/reduce.js b/libs/events/node_modules/lodash/fp/reduce.js new file mode 100644 index 000000000..4cef0a008 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/reduce.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('reduce', require('../reduce')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/reduceRight.js b/libs/events/node_modules/lodash/fp/reduceRight.js new file mode 100644 index 000000000..caf5bb515 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/reduceRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('reduceRight', require('../reduceRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/reject.js b/libs/events/node_modules/lodash/fp/reject.js new file mode 100644 index 000000000..c16327386 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/reject.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('reject', require('../reject')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/remove.js b/libs/events/node_modules/lodash/fp/remove.js new file mode 100644 index 000000000..e9d132736 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/remove.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('remove', require('../remove')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/repeat.js b/libs/events/node_modules/lodash/fp/repeat.js new file mode 100644 index 000000000..08470f247 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/repeat.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('repeat', require('../repeat')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/replace.js b/libs/events/node_modules/lodash/fp/replace.js new file mode 100644 index 000000000..2227db625 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/replace.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('replace', require('../replace')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/rest.js b/libs/events/node_modules/lodash/fp/rest.js new file mode 100644 index 000000000..c1f3d64bd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/rest.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('rest', require('../rest')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/restFrom.js b/libs/events/node_modules/lodash/fp/restFrom.js new file mode 100644 index 000000000..714e42b5d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/restFrom.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('restFrom', require('../rest')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/result.js b/libs/events/node_modules/lodash/fp/result.js new file mode 100644 index 000000000..f86ce0712 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/result.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('result', require('../result')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/reverse.js b/libs/events/node_modules/lodash/fp/reverse.js new file mode 100644 index 000000000..07c9f5e49 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/reverse.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('reverse', require('../reverse')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/round.js b/libs/events/node_modules/lodash/fp/round.js new file mode 100644 index 000000000..4c0e5c829 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/round.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('round', require('../round')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sample.js b/libs/events/node_modules/lodash/fp/sample.js new file mode 100644 index 000000000..6bea1254d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sample.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sample', require('../sample'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sampleSize.js b/libs/events/node_modules/lodash/fp/sampleSize.js new file mode 100644 index 000000000..359ed6fcd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sampleSize.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sampleSize', require('../sampleSize')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/seq.js b/libs/events/node_modules/lodash/fp/seq.js new file mode 100644 index 000000000..d8f42b0a4 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/seq.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../seq')); diff --git a/libs/events/node_modules/lodash/fp/set.js b/libs/events/node_modules/lodash/fp/set.js new file mode 100644 index 000000000..0b56a56c8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/set.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('set', require('../set')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/setWith.js b/libs/events/node_modules/lodash/fp/setWith.js new file mode 100644 index 000000000..0b584952b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/setWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('setWith', require('../setWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/shuffle.js b/libs/events/node_modules/lodash/fp/shuffle.js new file mode 100644 index 000000000..aa3a1ca5b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/shuffle.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('shuffle', require('../shuffle'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/size.js b/libs/events/node_modules/lodash/fp/size.js new file mode 100644 index 000000000..7490136e1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/size.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('size', require('../size'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/slice.js b/libs/events/node_modules/lodash/fp/slice.js new file mode 100644 index 000000000..15945d321 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/slice.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('slice', require('../slice')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/snakeCase.js b/libs/events/node_modules/lodash/fp/snakeCase.js new file mode 100644 index 000000000..a0ff7808e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/snakeCase.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('snakeCase', require('../snakeCase'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/some.js b/libs/events/node_modules/lodash/fp/some.js new file mode 100644 index 000000000..a4fa2d006 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/some.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('some', require('../some')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sortBy.js b/libs/events/node_modules/lodash/fp/sortBy.js new file mode 100644 index 000000000..e0790ad5b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sortBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sortBy', require('../sortBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sortedIndex.js b/libs/events/node_modules/lodash/fp/sortedIndex.js new file mode 100644 index 000000000..364a05435 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sortedIndex.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sortedIndex', require('../sortedIndex')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sortedIndexBy.js b/libs/events/node_modules/lodash/fp/sortedIndexBy.js new file mode 100644 index 000000000..9593dbd13 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sortedIndexBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sortedIndexBy', require('../sortedIndexBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sortedIndexOf.js b/libs/events/node_modules/lodash/fp/sortedIndexOf.js new file mode 100644 index 000000000..c9084cab6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sortedIndexOf.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sortedIndexOf', require('../sortedIndexOf')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sortedLastIndex.js b/libs/events/node_modules/lodash/fp/sortedLastIndex.js new file mode 100644 index 000000000..47fe241af --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sortedLastIndex.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sortedLastIndex', require('../sortedLastIndex')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sortedLastIndexBy.js b/libs/events/node_modules/lodash/fp/sortedLastIndexBy.js new file mode 100644 index 000000000..0f9a34732 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sortedLastIndexBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sortedLastIndexBy', require('../sortedLastIndexBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sortedLastIndexOf.js b/libs/events/node_modules/lodash/fp/sortedLastIndexOf.js new file mode 100644 index 000000000..0d4d93278 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sortedLastIndexOf.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sortedLastIndexOf', require('../sortedLastIndexOf')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sortedUniq.js b/libs/events/node_modules/lodash/fp/sortedUniq.js new file mode 100644 index 000000000..882d28370 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sortedUniq.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sortedUniq', require('../sortedUniq'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sortedUniqBy.js b/libs/events/node_modules/lodash/fp/sortedUniqBy.js new file mode 100644 index 000000000..033db91ca --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sortedUniqBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sortedUniqBy', require('../sortedUniqBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/split.js b/libs/events/node_modules/lodash/fp/split.js new file mode 100644 index 000000000..14de1a7ef --- /dev/null +++ b/libs/events/node_modules/lodash/fp/split.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('split', require('../split')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/spread.js b/libs/events/node_modules/lodash/fp/spread.js new file mode 100644 index 000000000..2d11b7072 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/spread.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('spread', require('../spread')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/spreadFrom.js b/libs/events/node_modules/lodash/fp/spreadFrom.js new file mode 100644 index 000000000..0b630df1b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/spreadFrom.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('spreadFrom', require('../spread')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/startCase.js b/libs/events/node_modules/lodash/fp/startCase.js new file mode 100644 index 000000000..ada98c943 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/startCase.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('startCase', require('../startCase'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/startsWith.js b/libs/events/node_modules/lodash/fp/startsWith.js new file mode 100644 index 000000000..985e2f294 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/startsWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('startsWith', require('../startsWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/string.js b/libs/events/node_modules/lodash/fp/string.js new file mode 100644 index 000000000..773b03704 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/string.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../string')); diff --git a/libs/events/node_modules/lodash/fp/stubArray.js b/libs/events/node_modules/lodash/fp/stubArray.js new file mode 100644 index 000000000..cd604cb49 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/stubArray.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('stubArray', require('../stubArray'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/stubFalse.js b/libs/events/node_modules/lodash/fp/stubFalse.js new file mode 100644 index 000000000..329666454 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/stubFalse.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('stubFalse', require('../stubFalse'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/stubObject.js b/libs/events/node_modules/lodash/fp/stubObject.js new file mode 100644 index 000000000..c6c8ec472 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/stubObject.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('stubObject', require('../stubObject'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/stubString.js b/libs/events/node_modules/lodash/fp/stubString.js new file mode 100644 index 000000000..701051e8b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/stubString.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('stubString', require('../stubString'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/stubTrue.js b/libs/events/node_modules/lodash/fp/stubTrue.js new file mode 100644 index 000000000..9249082ce --- /dev/null +++ b/libs/events/node_modules/lodash/fp/stubTrue.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('stubTrue', require('../stubTrue'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/subtract.js b/libs/events/node_modules/lodash/fp/subtract.js new file mode 100644 index 000000000..d32b16d47 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/subtract.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('subtract', require('../subtract')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sum.js b/libs/events/node_modules/lodash/fp/sum.js new file mode 100644 index 000000000..5cce12b32 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sum.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sum', require('../sum'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/sumBy.js b/libs/events/node_modules/lodash/fp/sumBy.js new file mode 100644 index 000000000..c8826565f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/sumBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('sumBy', require('../sumBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/symmetricDifference.js b/libs/events/node_modules/lodash/fp/symmetricDifference.js new file mode 100644 index 000000000..78c16add6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/symmetricDifference.js @@ -0,0 +1 @@ +module.exports = require('./xor'); diff --git a/libs/events/node_modules/lodash/fp/symmetricDifferenceBy.js b/libs/events/node_modules/lodash/fp/symmetricDifferenceBy.js new file mode 100644 index 000000000..298fc7ff6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/symmetricDifferenceBy.js @@ -0,0 +1 @@ +module.exports = require('./xorBy'); diff --git a/libs/events/node_modules/lodash/fp/symmetricDifferenceWith.js b/libs/events/node_modules/lodash/fp/symmetricDifferenceWith.js new file mode 100644 index 000000000..70bc6faf2 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/symmetricDifferenceWith.js @@ -0,0 +1 @@ +module.exports = require('./xorWith'); diff --git a/libs/events/node_modules/lodash/fp/tail.js b/libs/events/node_modules/lodash/fp/tail.js new file mode 100644 index 000000000..f122f0ac3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/tail.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('tail', require('../tail'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/take.js b/libs/events/node_modules/lodash/fp/take.js new file mode 100644 index 000000000..9af98a7bd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/take.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('take', require('../take')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/takeLast.js b/libs/events/node_modules/lodash/fp/takeLast.js new file mode 100644 index 000000000..e98c84a16 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/takeLast.js @@ -0,0 +1 @@ +module.exports = require('./takeRight'); diff --git a/libs/events/node_modules/lodash/fp/takeLastWhile.js b/libs/events/node_modules/lodash/fp/takeLastWhile.js new file mode 100644 index 000000000..5367968a3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/takeLastWhile.js @@ -0,0 +1 @@ +module.exports = require('./takeRightWhile'); diff --git a/libs/events/node_modules/lodash/fp/takeRight.js b/libs/events/node_modules/lodash/fp/takeRight.js new file mode 100644 index 000000000..b82950a69 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/takeRight.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('takeRight', require('../takeRight')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/takeRightWhile.js b/libs/events/node_modules/lodash/fp/takeRightWhile.js new file mode 100644 index 000000000..8ffb0a285 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/takeRightWhile.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('takeRightWhile', require('../takeRightWhile')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/takeWhile.js b/libs/events/node_modules/lodash/fp/takeWhile.js new file mode 100644 index 000000000..28136644f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/takeWhile.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('takeWhile', require('../takeWhile')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/tap.js b/libs/events/node_modules/lodash/fp/tap.js new file mode 100644 index 000000000..d33ad6ec1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/tap.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('tap', require('../tap')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/template.js b/libs/events/node_modules/lodash/fp/template.js new file mode 100644 index 000000000..74857e1c8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/template.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('template', require('../template')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/templateSettings.js b/libs/events/node_modules/lodash/fp/templateSettings.js new file mode 100644 index 000000000..7bcc0a82b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/templateSettings.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('templateSettings', require('../templateSettings'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/throttle.js b/libs/events/node_modules/lodash/fp/throttle.js new file mode 100644 index 000000000..77fff1428 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/throttle.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('throttle', require('../throttle')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/thru.js b/libs/events/node_modules/lodash/fp/thru.js new file mode 100644 index 000000000..d42b3b1d8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/thru.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('thru', require('../thru')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/times.js b/libs/events/node_modules/lodash/fp/times.js new file mode 100644 index 000000000..0dab06dad --- /dev/null +++ b/libs/events/node_modules/lodash/fp/times.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('times', require('../times')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toArray.js b/libs/events/node_modules/lodash/fp/toArray.js new file mode 100644 index 000000000..f0c360aca --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toArray.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toArray', require('../toArray'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toFinite.js b/libs/events/node_modules/lodash/fp/toFinite.js new file mode 100644 index 000000000..3a47687d6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toFinite.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toFinite', require('../toFinite'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toInteger.js b/libs/events/node_modules/lodash/fp/toInteger.js new file mode 100644 index 000000000..e0af6a750 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toInteger.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toInteger', require('../toInteger'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toIterator.js b/libs/events/node_modules/lodash/fp/toIterator.js new file mode 100644 index 000000000..65e6baa9d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toIterator.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toIterator', require('../toIterator'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toJSON.js b/libs/events/node_modules/lodash/fp/toJSON.js new file mode 100644 index 000000000..2d718d0bc --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toJSON.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toJSON', require('../toJSON'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toLength.js b/libs/events/node_modules/lodash/fp/toLength.js new file mode 100644 index 000000000..b97cdd935 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toLength.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toLength', require('../toLength'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toLower.js b/libs/events/node_modules/lodash/fp/toLower.js new file mode 100644 index 000000000..616ef36ad --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toLower.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toLower', require('../toLower'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toNumber.js b/libs/events/node_modules/lodash/fp/toNumber.js new file mode 100644 index 000000000..d0c6f4d3d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toNumber.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toNumber', require('../toNumber'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toPairs.js b/libs/events/node_modules/lodash/fp/toPairs.js new file mode 100644 index 000000000..af783786e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toPairs.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toPairs', require('../toPairs'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toPairsIn.js b/libs/events/node_modules/lodash/fp/toPairsIn.js new file mode 100644 index 000000000..66504abf1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toPairsIn.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toPairsIn', require('../toPairsIn'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toPath.js b/libs/events/node_modules/lodash/fp/toPath.js new file mode 100644 index 000000000..b4d5e50fb --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toPath.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toPath', require('../toPath'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toPlainObject.js b/libs/events/node_modules/lodash/fp/toPlainObject.js new file mode 100644 index 000000000..278bb8639 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toPlainObject.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toPlainObject', require('../toPlainObject'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toSafeInteger.js b/libs/events/node_modules/lodash/fp/toSafeInteger.js new file mode 100644 index 000000000..367a26fdd --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toSafeInteger.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toSafeInteger', require('../toSafeInteger'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toString.js b/libs/events/node_modules/lodash/fp/toString.js new file mode 100644 index 000000000..cec4f8e22 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toString.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toString', require('../toString'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/toUpper.js b/libs/events/node_modules/lodash/fp/toUpper.js new file mode 100644 index 000000000..54f9a5605 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/toUpper.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('toUpper', require('../toUpper'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/transform.js b/libs/events/node_modules/lodash/fp/transform.js new file mode 100644 index 000000000..759d088f1 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/transform.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('transform', require('../transform')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/trim.js b/libs/events/node_modules/lodash/fp/trim.js new file mode 100644 index 000000000..e6319a741 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/trim.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('trim', require('../trim')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/trimChars.js b/libs/events/node_modules/lodash/fp/trimChars.js new file mode 100644 index 000000000..c9294de48 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/trimChars.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('trimChars', require('../trim')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/trimCharsEnd.js b/libs/events/node_modules/lodash/fp/trimCharsEnd.js new file mode 100644 index 000000000..284bc2f81 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/trimCharsEnd.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('trimCharsEnd', require('../trimEnd')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/trimCharsStart.js b/libs/events/node_modules/lodash/fp/trimCharsStart.js new file mode 100644 index 000000000..ff0ee65df --- /dev/null +++ b/libs/events/node_modules/lodash/fp/trimCharsStart.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('trimCharsStart', require('../trimStart')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/trimEnd.js b/libs/events/node_modules/lodash/fp/trimEnd.js new file mode 100644 index 000000000..71908805f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/trimEnd.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('trimEnd', require('../trimEnd')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/trimStart.js b/libs/events/node_modules/lodash/fp/trimStart.js new file mode 100644 index 000000000..fda902c38 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/trimStart.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('trimStart', require('../trimStart')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/truncate.js b/libs/events/node_modules/lodash/fp/truncate.js new file mode 100644 index 000000000..d265c1dec --- /dev/null +++ b/libs/events/node_modules/lodash/fp/truncate.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('truncate', require('../truncate')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/unapply.js b/libs/events/node_modules/lodash/fp/unapply.js new file mode 100644 index 000000000..c5dfe779d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/unapply.js @@ -0,0 +1 @@ +module.exports = require('./rest'); diff --git a/libs/events/node_modules/lodash/fp/unary.js b/libs/events/node_modules/lodash/fp/unary.js new file mode 100644 index 000000000..286c945fb --- /dev/null +++ b/libs/events/node_modules/lodash/fp/unary.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('unary', require('../unary'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/unescape.js b/libs/events/node_modules/lodash/fp/unescape.js new file mode 100644 index 000000000..fddcb46e2 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/unescape.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('unescape', require('../unescape'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/union.js b/libs/events/node_modules/lodash/fp/union.js new file mode 100644 index 000000000..ef8228d74 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/union.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('union', require('../union')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/unionBy.js b/libs/events/node_modules/lodash/fp/unionBy.js new file mode 100644 index 000000000..603687a18 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/unionBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('unionBy', require('../unionBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/unionWith.js b/libs/events/node_modules/lodash/fp/unionWith.js new file mode 100644 index 000000000..65bb3a792 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/unionWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('unionWith', require('../unionWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/uniq.js b/libs/events/node_modules/lodash/fp/uniq.js new file mode 100644 index 000000000..bc1852490 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/uniq.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('uniq', require('../uniq'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/uniqBy.js b/libs/events/node_modules/lodash/fp/uniqBy.js new file mode 100644 index 000000000..634c6a8bb --- /dev/null +++ b/libs/events/node_modules/lodash/fp/uniqBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('uniqBy', require('../uniqBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/uniqWith.js b/libs/events/node_modules/lodash/fp/uniqWith.js new file mode 100644 index 000000000..0ec601a91 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/uniqWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('uniqWith', require('../uniqWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/uniqueId.js b/libs/events/node_modules/lodash/fp/uniqueId.js new file mode 100644 index 000000000..aa8fc2f73 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/uniqueId.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('uniqueId', require('../uniqueId')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/unnest.js b/libs/events/node_modules/lodash/fp/unnest.js new file mode 100644 index 000000000..5d34060aa --- /dev/null +++ b/libs/events/node_modules/lodash/fp/unnest.js @@ -0,0 +1 @@ +module.exports = require('./flatten'); diff --git a/libs/events/node_modules/lodash/fp/unset.js b/libs/events/node_modules/lodash/fp/unset.js new file mode 100644 index 000000000..ea203a0f3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/unset.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('unset', require('../unset')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/unzip.js b/libs/events/node_modules/lodash/fp/unzip.js new file mode 100644 index 000000000..cc364b3c5 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/unzip.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('unzip', require('../unzip'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/unzipWith.js b/libs/events/node_modules/lodash/fp/unzipWith.js new file mode 100644 index 000000000..182eaa104 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/unzipWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('unzipWith', require('../unzipWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/update.js b/libs/events/node_modules/lodash/fp/update.js new file mode 100644 index 000000000..b8ce2cc9e --- /dev/null +++ b/libs/events/node_modules/lodash/fp/update.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('update', require('../update')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/updateWith.js b/libs/events/node_modules/lodash/fp/updateWith.js new file mode 100644 index 000000000..d5e8282d9 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/updateWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('updateWith', require('../updateWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/upperCase.js b/libs/events/node_modules/lodash/fp/upperCase.js new file mode 100644 index 000000000..c886f2021 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/upperCase.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('upperCase', require('../upperCase'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/upperFirst.js b/libs/events/node_modules/lodash/fp/upperFirst.js new file mode 100644 index 000000000..d8c04df54 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/upperFirst.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('upperFirst', require('../upperFirst'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/useWith.js b/libs/events/node_modules/lodash/fp/useWith.js new file mode 100644 index 000000000..d8b3df5a4 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/useWith.js @@ -0,0 +1 @@ +module.exports = require('./overArgs'); diff --git a/libs/events/node_modules/lodash/fp/util.js b/libs/events/node_modules/lodash/fp/util.js new file mode 100644 index 000000000..18c00baed --- /dev/null +++ b/libs/events/node_modules/lodash/fp/util.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../util')); diff --git a/libs/events/node_modules/lodash/fp/value.js b/libs/events/node_modules/lodash/fp/value.js new file mode 100644 index 000000000..555eec7a3 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/value.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('value', require('../value'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/valueOf.js b/libs/events/node_modules/lodash/fp/valueOf.js new file mode 100644 index 000000000..f968807d7 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/valueOf.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('valueOf', require('../valueOf'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/values.js b/libs/events/node_modules/lodash/fp/values.js new file mode 100644 index 000000000..2dfc56136 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/values.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('values', require('../values'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/valuesIn.js b/libs/events/node_modules/lodash/fp/valuesIn.js new file mode 100644 index 000000000..a1b2bb872 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/valuesIn.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('valuesIn', require('../valuesIn'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/where.js b/libs/events/node_modules/lodash/fp/where.js new file mode 100644 index 000000000..3247f64a8 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/where.js @@ -0,0 +1 @@ +module.exports = require('./conformsTo'); diff --git a/libs/events/node_modules/lodash/fp/whereEq.js b/libs/events/node_modules/lodash/fp/whereEq.js new file mode 100644 index 000000000..29d1e1e4f --- /dev/null +++ b/libs/events/node_modules/lodash/fp/whereEq.js @@ -0,0 +1 @@ +module.exports = require('./isMatch'); diff --git a/libs/events/node_modules/lodash/fp/without.js b/libs/events/node_modules/lodash/fp/without.js new file mode 100644 index 000000000..bad9e125b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/without.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('without', require('../without')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/words.js b/libs/events/node_modules/lodash/fp/words.js new file mode 100644 index 000000000..4a901414b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/words.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('words', require('../words')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/wrap.js b/libs/events/node_modules/lodash/fp/wrap.js new file mode 100644 index 000000000..e93bd8a1d --- /dev/null +++ b/libs/events/node_modules/lodash/fp/wrap.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('wrap', require('../wrap')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/wrapperAt.js b/libs/events/node_modules/lodash/fp/wrapperAt.js new file mode 100644 index 000000000..8f0a310fe --- /dev/null +++ b/libs/events/node_modules/lodash/fp/wrapperAt.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('wrapperAt', require('../wrapperAt'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/wrapperChain.js b/libs/events/node_modules/lodash/fp/wrapperChain.js new file mode 100644 index 000000000..2a48ea2b5 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/wrapperChain.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('wrapperChain', require('../wrapperChain'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/wrapperLodash.js b/libs/events/node_modules/lodash/fp/wrapperLodash.js new file mode 100644 index 000000000..a7162d084 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/wrapperLodash.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('wrapperLodash', require('../wrapperLodash'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/wrapperReverse.js b/libs/events/node_modules/lodash/fp/wrapperReverse.js new file mode 100644 index 000000000..e1481aab9 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/wrapperReverse.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('wrapperReverse', require('../wrapperReverse'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/wrapperValue.js b/libs/events/node_modules/lodash/fp/wrapperValue.js new file mode 100644 index 000000000..8eb9112f6 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/wrapperValue.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('wrapperValue', require('../wrapperValue'), require('./_falseOptions')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/xor.js b/libs/events/node_modules/lodash/fp/xor.js new file mode 100644 index 000000000..29e281948 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/xor.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('xor', require('../xor')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/xorBy.js b/libs/events/node_modules/lodash/fp/xorBy.js new file mode 100644 index 000000000..b355686db --- /dev/null +++ b/libs/events/node_modules/lodash/fp/xorBy.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('xorBy', require('../xorBy')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/xorWith.js b/libs/events/node_modules/lodash/fp/xorWith.js new file mode 100644 index 000000000..8e05739ad --- /dev/null +++ b/libs/events/node_modules/lodash/fp/xorWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('xorWith', require('../xorWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/zip.js b/libs/events/node_modules/lodash/fp/zip.js new file mode 100644 index 000000000..69e147a44 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/zip.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('zip', require('../zip')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/zipAll.js b/libs/events/node_modules/lodash/fp/zipAll.js new file mode 100644 index 000000000..efa8ccbfb --- /dev/null +++ b/libs/events/node_modules/lodash/fp/zipAll.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('zipAll', require('../zip')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/zipObj.js b/libs/events/node_modules/lodash/fp/zipObj.js new file mode 100644 index 000000000..f4a34531b --- /dev/null +++ b/libs/events/node_modules/lodash/fp/zipObj.js @@ -0,0 +1 @@ +module.exports = require('./zipObject'); diff --git a/libs/events/node_modules/lodash/fp/zipObject.js b/libs/events/node_modules/lodash/fp/zipObject.js new file mode 100644 index 000000000..462dbb68c --- /dev/null +++ b/libs/events/node_modules/lodash/fp/zipObject.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('zipObject', require('../zipObject')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/zipObjectDeep.js b/libs/events/node_modules/lodash/fp/zipObjectDeep.js new file mode 100644 index 000000000..53a5d3380 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/zipObjectDeep.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('zipObjectDeep', require('../zipObjectDeep')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fp/zipWith.js b/libs/events/node_modules/lodash/fp/zipWith.js new file mode 100644 index 000000000..c5cf9e212 --- /dev/null +++ b/libs/events/node_modules/lodash/fp/zipWith.js @@ -0,0 +1,5 @@ +var convert = require('./convert'), + func = convert('zipWith', require('../zipWith')); + +func.placeholder = require('./placeholder'); +module.exports = func; diff --git a/libs/events/node_modules/lodash/fromPairs.js b/libs/events/node_modules/lodash/fromPairs.js new file mode 100644 index 000000000..ee7940d24 --- /dev/null +++ b/libs/events/node_modules/lodash/fromPairs.js @@ -0,0 +1,28 @@ +/** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['a', 1], ['b', 2]]); + * // => { 'a': 1, 'b': 2 } + */ +function fromPairs(pairs) { + var index = -1, + length = pairs == null ? 0 : pairs.length, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; +} + +module.exports = fromPairs; diff --git a/libs/events/node_modules/lodash/function.js b/libs/events/node_modules/lodash/function.js new file mode 100644 index 000000000..b0fc6d93e --- /dev/null +++ b/libs/events/node_modules/lodash/function.js @@ -0,0 +1,25 @@ +module.exports = { + 'after': require('./after'), + 'ary': require('./ary'), + 'before': require('./before'), + 'bind': require('./bind'), + 'bindKey': require('./bindKey'), + 'curry': require('./curry'), + 'curryRight': require('./curryRight'), + 'debounce': require('./debounce'), + 'defer': require('./defer'), + 'delay': require('./delay'), + 'flip': require('./flip'), + 'memoize': require('./memoize'), + 'negate': require('./negate'), + 'once': require('./once'), + 'overArgs': require('./overArgs'), + 'partial': require('./partial'), + 'partialRight': require('./partialRight'), + 'rearg': require('./rearg'), + 'rest': require('./rest'), + 'spread': require('./spread'), + 'throttle': require('./throttle'), + 'unary': require('./unary'), + 'wrap': require('./wrap') +}; diff --git a/libs/events/node_modules/lodash/functions.js b/libs/events/node_modules/lodash/functions.js new file mode 100644 index 000000000..9722928f5 --- /dev/null +++ b/libs/events/node_modules/lodash/functions.js @@ -0,0 +1,31 @@ +var baseFunctions = require('./_baseFunctions'), + keys = require('./keys'); + +/** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functionsIn + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ +function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); +} + +module.exports = functions; diff --git a/libs/events/node_modules/lodash/functionsIn.js b/libs/events/node_modules/lodash/functionsIn.js new file mode 100644 index 000000000..f00345d06 --- /dev/null +++ b/libs/events/node_modules/lodash/functionsIn.js @@ -0,0 +1,31 @@ +var baseFunctions = require('./_baseFunctions'), + keysIn = require('./keysIn'); + +/** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functions + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ +function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); +} + +module.exports = functionsIn; diff --git a/libs/events/node_modules/lodash/get.js b/libs/events/node_modules/lodash/get.js new file mode 100644 index 000000000..8805ff92c --- /dev/null +++ b/libs/events/node_modules/lodash/get.js @@ -0,0 +1,33 @@ +var baseGet = require('./_baseGet'); + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; +} + +module.exports = get; diff --git a/libs/events/node_modules/lodash/groupBy.js b/libs/events/node_modules/lodash/groupBy.js new file mode 100644 index 000000000..babf4f6ba --- /dev/null +++ b/libs/events/node_modules/lodash/groupBy.js @@ -0,0 +1,41 @@ +var baseAssignValue = require('./_baseAssignValue'), + createAggregator = require('./_createAggregator'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The order of grouped values + * is determined by the order they occur in `collection`. The corresponding + * value of each key is an array of elements responsible for generating the + * key. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ +var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + baseAssignValue(result, key, [value]); + } +}); + +module.exports = groupBy; diff --git a/libs/events/node_modules/lodash/gt.js b/libs/events/node_modules/lodash/gt.js new file mode 100644 index 000000000..3a6628288 --- /dev/null +++ b/libs/events/node_modules/lodash/gt.js @@ -0,0 +1,29 @@ +var baseGt = require('./_baseGt'), + createRelationalOperation = require('./_createRelationalOperation'); + +/** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + * @see _.lt + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ +var gt = createRelationalOperation(baseGt); + +module.exports = gt; diff --git a/libs/events/node_modules/lodash/gte.js b/libs/events/node_modules/lodash/gte.js new file mode 100644 index 000000000..4180a687d --- /dev/null +++ b/libs/events/node_modules/lodash/gte.js @@ -0,0 +1,30 @@ +var createRelationalOperation = require('./_createRelationalOperation'); + +/** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to + * `other`, else `false`. + * @see _.lte + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ +var gte = createRelationalOperation(function(value, other) { + return value >= other; +}); + +module.exports = gte; diff --git a/libs/events/node_modules/lodash/has.js b/libs/events/node_modules/lodash/has.js new file mode 100644 index 000000000..34df55e8e --- /dev/null +++ b/libs/events/node_modules/lodash/has.js @@ -0,0 +1,35 @@ +var baseHas = require('./_baseHas'), + hasPath = require('./_hasPath'); + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && hasPath(object, path, baseHas); +} + +module.exports = has; diff --git a/libs/events/node_modules/lodash/hasIn.js b/libs/events/node_modules/lodash/hasIn.js new file mode 100644 index 000000000..06a368654 --- /dev/null +++ b/libs/events/node_modules/lodash/hasIn.js @@ -0,0 +1,34 @@ +var baseHasIn = require('./_baseHasIn'), + hasPath = require('./_hasPath'); + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); +} + +module.exports = hasIn; diff --git a/libs/events/node_modules/lodash/head.js b/libs/events/node_modules/lodash/head.js new file mode 100644 index 000000000..dee9d1f1e --- /dev/null +++ b/libs/events/node_modules/lodash/head.js @@ -0,0 +1,23 @@ +/** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ +function head(array) { + return (array && array.length) ? array[0] : undefined; +} + +module.exports = head; diff --git a/libs/events/node_modules/lodash/identity.js b/libs/events/node_modules/lodash/identity.js new file mode 100644 index 000000000..2d5d963cd --- /dev/null +++ b/libs/events/node_modules/lodash/identity.js @@ -0,0 +1,21 @@ +/** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ +function identity(value) { + return value; +} + +module.exports = identity; diff --git a/libs/events/node_modules/lodash/inRange.js b/libs/events/node_modules/lodash/inRange.js new file mode 100644 index 000000000..f20728d92 --- /dev/null +++ b/libs/events/node_modules/lodash/inRange.js @@ -0,0 +1,55 @@ +var baseInRange = require('./_baseInRange'), + toFinite = require('./toFinite'), + toNumber = require('./toNumber'); + +/** + * Checks if `n` is between `start` and up to, but not including, `end`. If + * `end` is not specified, it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @since 3.3.0 + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @see _.range, _.rangeRight + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ +function inRange(number, start, end) { + start = toFinite(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + number = toNumber(number); + return baseInRange(number, start, end); +} + +module.exports = inRange; diff --git a/libs/events/node_modules/lodash/includes.js b/libs/events/node_modules/lodash/includes.js new file mode 100644 index 000000000..ae0deedc9 --- /dev/null +++ b/libs/events/node_modules/lodash/includes.js @@ -0,0 +1,53 @@ +var baseIndexOf = require('./_baseIndexOf'), + isArrayLike = require('./isArrayLike'), + isString = require('./isString'), + toInteger = require('./toInteger'), + values = require('./values'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Checks if `value` is in `collection`. If `collection` is a string, it's + * checked for a substring of `value`, otherwise + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'a': 1, 'b': 2 }, 1); + * // => true + * + * _.includes('abcd', 'bc'); + * // => true + */ +function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); +} + +module.exports = includes; diff --git a/libs/events/node_modules/lodash/index.js b/libs/events/node_modules/lodash/index.js new file mode 100644 index 000000000..5d063e21f --- /dev/null +++ b/libs/events/node_modules/lodash/index.js @@ -0,0 +1 @@ +module.exports = require('./lodash'); \ No newline at end of file diff --git a/libs/events/node_modules/lodash/indexOf.js b/libs/events/node_modules/lodash/indexOf.js new file mode 100644 index 000000000..3c644af2e --- /dev/null +++ b/libs/events/node_modules/lodash/indexOf.js @@ -0,0 +1,42 @@ +var baseIndexOf = require('./_baseIndexOf'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the + * offset from the end of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ +function indexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseIndexOf(array, value, index); +} + +module.exports = indexOf; diff --git a/libs/events/node_modules/lodash/initial.js b/libs/events/node_modules/lodash/initial.js new file mode 100644 index 000000000..f47fc5092 --- /dev/null +++ b/libs/events/node_modules/lodash/initial.js @@ -0,0 +1,22 @@ +var baseSlice = require('./_baseSlice'); + +/** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ +function initial(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 0, -1) : []; +} + +module.exports = initial; diff --git a/libs/events/node_modules/lodash/intersection.js b/libs/events/node_modules/lodash/intersection.js new file mode 100644 index 000000000..a94c13512 --- /dev/null +++ b/libs/events/node_modules/lodash/intersection.js @@ -0,0 +1,30 @@ +var arrayMap = require('./_arrayMap'), + baseIntersection = require('./_baseIntersection'), + baseRest = require('./_baseRest'), + castArrayLikeObject = require('./_castArrayLikeObject'); + +/** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [2, 3]); + * // => [2] + */ +var intersection = baseRest(function(arrays) { + var mapped = arrayMap(arrays, castArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; +}); + +module.exports = intersection; diff --git a/libs/events/node_modules/lodash/intersectionBy.js b/libs/events/node_modules/lodash/intersectionBy.js new file mode 100644 index 000000000..31461aae5 --- /dev/null +++ b/libs/events/node_modules/lodash/intersectionBy.js @@ -0,0 +1,45 @@ +var arrayMap = require('./_arrayMap'), + baseIntersection = require('./_baseIntersection'), + baseIteratee = require('./_baseIteratee'), + baseRest = require('./_baseRest'), + castArrayLikeObject = require('./_castArrayLikeObject'), + last = require('./last'); + +/** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ +var intersectionBy = baseRest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); + + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, baseIteratee(iteratee, 2)) + : []; +}); + +module.exports = intersectionBy; diff --git a/libs/events/node_modules/lodash/intersectionWith.js b/libs/events/node_modules/lodash/intersectionWith.js new file mode 100644 index 000000000..63cabfaa4 --- /dev/null +++ b/libs/events/node_modules/lodash/intersectionWith.js @@ -0,0 +1,41 @@ +var arrayMap = require('./_arrayMap'), + baseIntersection = require('./_baseIntersection'), + baseRest = require('./_baseRest'), + castArrayLikeObject = require('./_castArrayLikeObject'), + last = require('./last'); + +/** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. The order and references + * of result values are determined by the first array. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ +var intersectionWith = baseRest(function(arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); + + comparator = typeof comparator == 'function' ? comparator : undefined; + if (comparator) { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, undefined, comparator) + : []; +}); + +module.exports = intersectionWith; diff --git a/libs/events/node_modules/lodash/invert.js b/libs/events/node_modules/lodash/invert.js new file mode 100644 index 000000000..8c4795097 --- /dev/null +++ b/libs/events/node_modules/lodash/invert.js @@ -0,0 +1,42 @@ +var constant = require('./constant'), + createInverter = require('./_createInverter'), + identity = require('./identity'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite + * property assignments of previous values. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ +var invert = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + result[value] = key; +}, constant(identity)); + +module.exports = invert; diff --git a/libs/events/node_modules/lodash/invertBy.js b/libs/events/node_modules/lodash/invertBy.js new file mode 100644 index 000000000..3f4f7e532 --- /dev/null +++ b/libs/events/node_modules/lodash/invertBy.js @@ -0,0 +1,56 @@ +var baseIteratee = require('./_baseIteratee'), + createInverter = require('./_createInverter'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` thru `iteratee`. The + * corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Object + * @param {Object} object The object to invert. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ +var invertBy = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } +}, baseIteratee); + +module.exports = invertBy; diff --git a/libs/events/node_modules/lodash/invoke.js b/libs/events/node_modules/lodash/invoke.js new file mode 100644 index 000000000..97d51eb5b --- /dev/null +++ b/libs/events/node_modules/lodash/invoke.js @@ -0,0 +1,24 @@ +var baseInvoke = require('./_baseInvoke'), + baseRest = require('./_baseRest'); + +/** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ +var invoke = baseRest(baseInvoke); + +module.exports = invoke; diff --git a/libs/events/node_modules/lodash/invokeMap.js b/libs/events/node_modules/lodash/invokeMap.js new file mode 100644 index 000000000..8da5126c6 --- /dev/null +++ b/libs/events/node_modules/lodash/invokeMap.js @@ -0,0 +1,41 @@ +var apply = require('./_apply'), + baseEach = require('./_baseEach'), + baseInvoke = require('./_baseInvoke'), + baseRest = require('./_baseRest'), + isArrayLike = require('./isArrayLike'); + +/** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `path` is a function, it's invoked + * for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke each method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invokeMap([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ +var invokeMap = baseRest(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); + }); + return result; +}); + +module.exports = invokeMap; diff --git a/libs/events/node_modules/lodash/isArguments.js b/libs/events/node_modules/lodash/isArguments.js new file mode 100644 index 000000000..8b9ed66cd --- /dev/null +++ b/libs/events/node_modules/lodash/isArguments.js @@ -0,0 +1,36 @@ +var baseIsArguments = require('./_baseIsArguments'), + isObjectLike = require('./isObjectLike'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); +}; + +module.exports = isArguments; diff --git a/libs/events/node_modules/lodash/isArray.js b/libs/events/node_modules/lodash/isArray.js new file mode 100644 index 000000000..88ab55fd0 --- /dev/null +++ b/libs/events/node_modules/lodash/isArray.js @@ -0,0 +1,26 @@ +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +module.exports = isArray; diff --git a/libs/events/node_modules/lodash/isArrayBuffer.js b/libs/events/node_modules/lodash/isArrayBuffer.js new file mode 100644 index 000000000..12904a64b --- /dev/null +++ b/libs/events/node_modules/lodash/isArrayBuffer.js @@ -0,0 +1,27 @@ +var baseIsArrayBuffer = require('./_baseIsArrayBuffer'), + baseUnary = require('./_baseUnary'), + nodeUtil = require('./_nodeUtil'); + +/* Node.js helper references. */ +var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer; + +/** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ +var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; + +module.exports = isArrayBuffer; diff --git a/libs/events/node_modules/lodash/isArrayLike.js b/libs/events/node_modules/lodash/isArrayLike.js new file mode 100644 index 000000000..0f9668056 --- /dev/null +++ b/libs/events/node_modules/lodash/isArrayLike.js @@ -0,0 +1,33 @@ +var isFunction = require('./isFunction'), + isLength = require('./isLength'); + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +module.exports = isArrayLike; diff --git a/libs/events/node_modules/lodash/isArrayLikeObject.js b/libs/events/node_modules/lodash/isArrayLikeObject.js new file mode 100644 index 000000000..6c4812a8d --- /dev/null +++ b/libs/events/node_modules/lodash/isArrayLikeObject.js @@ -0,0 +1,33 @@ +var isArrayLike = require('./isArrayLike'), + isObjectLike = require('./isObjectLike'); + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +module.exports = isArrayLikeObject; diff --git a/libs/events/node_modules/lodash/isBoolean.js b/libs/events/node_modules/lodash/isBoolean.js new file mode 100644 index 000000000..a43ed4b8f --- /dev/null +++ b/libs/events/node_modules/lodash/isBoolean.js @@ -0,0 +1,29 @@ +var baseGetTag = require('./_baseGetTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]'; + +/** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ +function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); +} + +module.exports = isBoolean; diff --git a/libs/events/node_modules/lodash/isBuffer.js b/libs/events/node_modules/lodash/isBuffer.js new file mode 100644 index 000000000..c103cc74e --- /dev/null +++ b/libs/events/node_modules/lodash/isBuffer.js @@ -0,0 +1,38 @@ +var root = require('./_root'), + stubFalse = require('./stubFalse'); + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; + +module.exports = isBuffer; diff --git a/libs/events/node_modules/lodash/isDate.js b/libs/events/node_modules/lodash/isDate.js new file mode 100644 index 000000000..7f0209fca --- /dev/null +++ b/libs/events/node_modules/lodash/isDate.js @@ -0,0 +1,27 @@ +var baseIsDate = require('./_baseIsDate'), + baseUnary = require('./_baseUnary'), + nodeUtil = require('./_nodeUtil'); + +/* Node.js helper references. */ +var nodeIsDate = nodeUtil && nodeUtil.isDate; + +/** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ +var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; + +module.exports = isDate; diff --git a/libs/events/node_modules/lodash/isElement.js b/libs/events/node_modules/lodash/isElement.js new file mode 100644 index 000000000..76ae29c3b --- /dev/null +++ b/libs/events/node_modules/lodash/isElement.js @@ -0,0 +1,25 @@ +var isObjectLike = require('./isObjectLike'), + isPlainObject = require('./isPlainObject'); + +/** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ +function isElement(value) { + return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); +} + +module.exports = isElement; diff --git a/libs/events/node_modules/lodash/isEmpty.js b/libs/events/node_modules/lodash/isEmpty.js new file mode 100644 index 000000000..3597294a4 --- /dev/null +++ b/libs/events/node_modules/lodash/isEmpty.js @@ -0,0 +1,77 @@ +var baseKeys = require('./_baseKeys'), + getTag = require('./_getTag'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLike = require('./isArrayLike'), + isBuffer = require('./isBuffer'), + isPrototype = require('./_isPrototype'), + isTypedArray = require('./isTypedArray'); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ +function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && + (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || + isBuffer(value) || isTypedArray(value) || isArguments(value))) { + return !value.length; + } + var tag = getTag(value); + if (tag == mapTag || tag == setTag) { + return !value.size; + } + if (isPrototype(value)) { + return !baseKeys(value).length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; +} + +module.exports = isEmpty; diff --git a/libs/events/node_modules/lodash/isEqual.js b/libs/events/node_modules/lodash/isEqual.js new file mode 100644 index 000000000..5e23e76c9 --- /dev/null +++ b/libs/events/node_modules/lodash/isEqual.js @@ -0,0 +1,35 @@ +var baseIsEqual = require('./_baseIsEqual'); + +/** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ +function isEqual(value, other) { + return baseIsEqual(value, other); +} + +module.exports = isEqual; diff --git a/libs/events/node_modules/lodash/isEqualWith.js b/libs/events/node_modules/lodash/isEqualWith.js new file mode 100644 index 000000000..21bdc7ffe --- /dev/null +++ b/libs/events/node_modules/lodash/isEqualWith.js @@ -0,0 +1,41 @@ +var baseIsEqual = require('./_baseIsEqual'); + +/** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ +function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result; +} + +module.exports = isEqualWith; diff --git a/libs/events/node_modules/lodash/isError.js b/libs/events/node_modules/lodash/isError.js new file mode 100644 index 000000000..b4f41e000 --- /dev/null +++ b/libs/events/node_modules/lodash/isError.js @@ -0,0 +1,36 @@ +var baseGetTag = require('./_baseGetTag'), + isObjectLike = require('./isObjectLike'), + isPlainObject = require('./isPlainObject'); + +/** `Object#toString` result references. */ +var domExcTag = '[object DOMException]', + errorTag = '[object Error]'; + +/** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ +function isError(value) { + if (!isObjectLike(value)) { + return false; + } + var tag = baseGetTag(value); + return tag == errorTag || tag == domExcTag || + (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); +} + +module.exports = isError; diff --git a/libs/events/node_modules/lodash/isFinite.js b/libs/events/node_modules/lodash/isFinite.js new file mode 100644 index 000000000..601842bc4 --- /dev/null +++ b/libs/events/node_modules/lodash/isFinite.js @@ -0,0 +1,36 @@ +var root = require('./_root'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsFinite = root.isFinite; + +/** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on + * [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MIN_VALUE); + * // => true + * + * _.isFinite(Infinity); + * // => false + * + * _.isFinite('3'); + * // => false + */ +function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); +} + +module.exports = isFinite; diff --git a/libs/events/node_modules/lodash/isFunction.js b/libs/events/node_modules/lodash/isFunction.js new file mode 100644 index 000000000..907a8cd8b --- /dev/null +++ b/libs/events/node_modules/lodash/isFunction.js @@ -0,0 +1,37 @@ +var baseGetTag = require('./_baseGetTag'), + isObject = require('./isObject'); + +/** `Object#toString` result references. */ +var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; +} + +module.exports = isFunction; diff --git a/libs/events/node_modules/lodash/isInteger.js b/libs/events/node_modules/lodash/isInteger.js new file mode 100644 index 000000000..66aa87d57 --- /dev/null +++ b/libs/events/node_modules/lodash/isInteger.js @@ -0,0 +1,33 @@ +var toInteger = require('./toInteger'); + +/** + * Checks if `value` is an integer. + * + * **Note:** This method is based on + * [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ +function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); +} + +module.exports = isInteger; diff --git a/libs/events/node_modules/lodash/isLength.js b/libs/events/node_modules/lodash/isLength.js new file mode 100644 index 000000000..3a95caa96 --- /dev/null +++ b/libs/events/node_modules/lodash/isLength.js @@ -0,0 +1,35 @@ +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +module.exports = isLength; diff --git a/libs/events/node_modules/lodash/isMap.js b/libs/events/node_modules/lodash/isMap.js new file mode 100644 index 000000000..44f8517ee --- /dev/null +++ b/libs/events/node_modules/lodash/isMap.js @@ -0,0 +1,27 @@ +var baseIsMap = require('./_baseIsMap'), + baseUnary = require('./_baseUnary'), + nodeUtil = require('./_nodeUtil'); + +/* Node.js helper references. */ +var nodeIsMap = nodeUtil && nodeUtil.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + +module.exports = isMap; diff --git a/libs/events/node_modules/lodash/isMatch.js b/libs/events/node_modules/lodash/isMatch.js new file mode 100644 index 000000000..9773a18cd --- /dev/null +++ b/libs/events/node_modules/lodash/isMatch.js @@ -0,0 +1,36 @@ +var baseIsMatch = require('./_baseIsMatch'), + getMatchData = require('./_getMatchData'); + +/** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. + * + * **Note:** This method is equivalent to `_.matches` when `source` is + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.isMatch(object, { 'b': 2 }); + * // => true + * + * _.isMatch(object, { 'b': 1 }); + * // => false + */ +function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); +} + +module.exports = isMatch; diff --git a/libs/events/node_modules/lodash/isMatchWith.js b/libs/events/node_modules/lodash/isMatchWith.js new file mode 100644 index 000000000..187b6a61d --- /dev/null +++ b/libs/events/node_modules/lodash/isMatchWith.js @@ -0,0 +1,41 @@ +var baseIsMatch = require('./_baseIsMatch'), + getMatchData = require('./_getMatchData'); + +/** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ +function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseIsMatch(object, source, getMatchData(source), customizer); +} + +module.exports = isMatchWith; diff --git a/libs/events/node_modules/lodash/isNaN.js b/libs/events/node_modules/lodash/isNaN.js new file mode 100644 index 000000000..7d0d783ba --- /dev/null +++ b/libs/events/node_modules/lodash/isNaN.js @@ -0,0 +1,38 @@ +var isNumber = require('./isNumber'); + +/** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ +function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; +} + +module.exports = isNaN; diff --git a/libs/events/node_modules/lodash/isNative.js b/libs/events/node_modules/lodash/isNative.js new file mode 100644 index 000000000..f0cb8d580 --- /dev/null +++ b/libs/events/node_modules/lodash/isNative.js @@ -0,0 +1,40 @@ +var baseIsNative = require('./_baseIsNative'), + isMaskable = require('./_isMaskable'); + +/** Error message constants. */ +var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.'; + +/** + * Checks if `value` is a pristine native function. + * + * **Note:** This method can't reliably detect native functions in the presence + * of the core-js package because core-js circumvents this kind of detection. + * Despite multiple requests, the core-js maintainer has made it clear: any + * attempt to fix the detection will be obstructed. As a result, we're left + * with little choice but to throw an error. Unfortunately, this also affects + * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), + * which rely on core-js. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ +function isNative(value) { + if (isMaskable(value)) { + throw new Error(CORE_ERROR_TEXT); + } + return baseIsNative(value); +} + +module.exports = isNative; diff --git a/libs/events/node_modules/lodash/isNil.js b/libs/events/node_modules/lodash/isNil.js new file mode 100644 index 000000000..79f05052c --- /dev/null +++ b/libs/events/node_modules/lodash/isNil.js @@ -0,0 +1,25 @@ +/** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ +function isNil(value) { + return value == null; +} + +module.exports = isNil; diff --git a/libs/events/node_modules/lodash/isNull.js b/libs/events/node_modules/lodash/isNull.js new file mode 100644 index 000000000..c0a374d7d --- /dev/null +++ b/libs/events/node_modules/lodash/isNull.js @@ -0,0 +1,22 @@ +/** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ +function isNull(value) { + return value === null; +} + +module.exports = isNull; diff --git a/libs/events/node_modules/lodash/isNumber.js b/libs/events/node_modules/lodash/isNumber.js new file mode 100644 index 000000000..cd34ee464 --- /dev/null +++ b/libs/events/node_modules/lodash/isNumber.js @@ -0,0 +1,38 @@ +var baseGetTag = require('./_baseGetTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var numberTag = '[object Number]'; + +/** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ +function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); +} + +module.exports = isNumber; diff --git a/libs/events/node_modules/lodash/isObject.js b/libs/events/node_modules/lodash/isObject.js new file mode 100644 index 000000000..1dc893918 --- /dev/null +++ b/libs/events/node_modules/lodash/isObject.js @@ -0,0 +1,31 @@ +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); +} + +module.exports = isObject; diff --git a/libs/events/node_modules/lodash/isObjectLike.js b/libs/events/node_modules/lodash/isObjectLike.js new file mode 100644 index 000000000..301716b5a --- /dev/null +++ b/libs/events/node_modules/lodash/isObjectLike.js @@ -0,0 +1,29 @@ +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return value != null && typeof value == 'object'; +} + +module.exports = isObjectLike; diff --git a/libs/events/node_modules/lodash/isPlainObject.js b/libs/events/node_modules/lodash/isPlainObject.js new file mode 100644 index 000000000..238737313 --- /dev/null +++ b/libs/events/node_modules/lodash/isPlainObject.js @@ -0,0 +1,62 @@ +var baseGetTag = require('./_baseGetTag'), + getPrototype = require('./_getPrototype'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); + +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; +} + +module.exports = isPlainObject; diff --git a/libs/events/node_modules/lodash/isRegExp.js b/libs/events/node_modules/lodash/isRegExp.js new file mode 100644 index 000000000..76c9b6e9c --- /dev/null +++ b/libs/events/node_modules/lodash/isRegExp.js @@ -0,0 +1,27 @@ +var baseIsRegExp = require('./_baseIsRegExp'), + baseUnary = require('./_baseUnary'), + nodeUtil = require('./_nodeUtil'); + +/* Node.js helper references. */ +var nodeIsRegExp = nodeUtil && nodeUtil.isRegExp; + +/** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ +var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + +module.exports = isRegExp; diff --git a/libs/events/node_modules/lodash/isSafeInteger.js b/libs/events/node_modules/lodash/isSafeInteger.js new file mode 100644 index 000000000..2a48526e1 --- /dev/null +++ b/libs/events/node_modules/lodash/isSafeInteger.js @@ -0,0 +1,37 @@ +var isInteger = require('./isInteger'); + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on + * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ +function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; +} + +module.exports = isSafeInteger; diff --git a/libs/events/node_modules/lodash/isSet.js b/libs/events/node_modules/lodash/isSet.js new file mode 100644 index 000000000..ab88bdf81 --- /dev/null +++ b/libs/events/node_modules/lodash/isSet.js @@ -0,0 +1,27 @@ +var baseIsSet = require('./_baseIsSet'), + baseUnary = require('./_baseUnary'), + nodeUtil = require('./_nodeUtil'); + +/* Node.js helper references. */ +var nodeIsSet = nodeUtil && nodeUtil.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + +module.exports = isSet; diff --git a/libs/events/node_modules/lodash/isString.js b/libs/events/node_modules/lodash/isString.js new file mode 100644 index 000000000..627eb9c38 --- /dev/null +++ b/libs/events/node_modules/lodash/isString.js @@ -0,0 +1,30 @@ +var baseGetTag = require('./_baseGetTag'), + isArray = require('./isArray'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); +} + +module.exports = isString; diff --git a/libs/events/node_modules/lodash/isSymbol.js b/libs/events/node_modules/lodash/isSymbol.js new file mode 100644 index 000000000..dfb60b97f --- /dev/null +++ b/libs/events/node_modules/lodash/isSymbol.js @@ -0,0 +1,29 @@ +var baseGetTag = require('./_baseGetTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); +} + +module.exports = isSymbol; diff --git a/libs/events/node_modules/lodash/isTypedArray.js b/libs/events/node_modules/lodash/isTypedArray.js new file mode 100644 index 000000000..da3f8dd19 --- /dev/null +++ b/libs/events/node_modules/lodash/isTypedArray.js @@ -0,0 +1,27 @@ +var baseIsTypedArray = require('./_baseIsTypedArray'), + baseUnary = require('./_baseUnary'), + nodeUtil = require('./_nodeUtil'); + +/* Node.js helper references. */ +var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + +module.exports = isTypedArray; diff --git a/libs/events/node_modules/lodash/isUndefined.js b/libs/events/node_modules/lodash/isUndefined.js new file mode 100644 index 000000000..377d121ab --- /dev/null +++ b/libs/events/node_modules/lodash/isUndefined.js @@ -0,0 +1,22 @@ +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +module.exports = isUndefined; diff --git a/libs/events/node_modules/lodash/isWeakMap.js b/libs/events/node_modules/lodash/isWeakMap.js new file mode 100644 index 000000000..8d36f6638 --- /dev/null +++ b/libs/events/node_modules/lodash/isWeakMap.js @@ -0,0 +1,28 @@ +var getTag = require('./_getTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var weakMapTag = '[object WeakMap]'; + +/** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ +function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; +} + +module.exports = isWeakMap; diff --git a/libs/events/node_modules/lodash/isWeakSet.js b/libs/events/node_modules/lodash/isWeakSet.js new file mode 100644 index 000000000..e628b261c --- /dev/null +++ b/libs/events/node_modules/lodash/isWeakSet.js @@ -0,0 +1,28 @@ +var baseGetTag = require('./_baseGetTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var weakSetTag = '[object WeakSet]'; + +/** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ +function isWeakSet(value) { + return isObjectLike(value) && baseGetTag(value) == weakSetTag; +} + +module.exports = isWeakSet; diff --git a/libs/events/node_modules/lodash/iteratee.js b/libs/events/node_modules/lodash/iteratee.js new file mode 100644 index 000000000..61b73a8c0 --- /dev/null +++ b/libs/events/node_modules/lodash/iteratee.js @@ -0,0 +1,53 @@ +var baseClone = require('./_baseClone'), + baseIteratee = require('./_baseIteratee'); + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1; + +/** + * Creates a function that invokes `func` with the arguments of the created + * function. If `func` is a property name, the created function returns the + * property value for a given element. If `func` is an array or object, the + * created function returns `true` for elements that contain the equivalent + * source properties, otherwise it returns `false`. + * + * @static + * @since 4.0.0 + * @memberOf _ + * @category Util + * @param {*} [func=_.identity] The value to convert to a callback. + * @returns {Function} Returns the callback. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true })); + * // => [{ 'user': 'barney', 'age': 36, 'active': true }] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, _.iteratee(['user', 'fred'])); + * // => [{ 'user': 'fred', 'age': 40 }] + * + * // The `_.property` iteratee shorthand. + * _.map(users, _.iteratee('user')); + * // => ['barney', 'fred'] + * + * // Create custom iteratee shorthands. + * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) { + * return !_.isRegExp(func) ? iteratee(func) : function(string) { + * return func.test(string); + * }; + * }); + * + * _.filter(['abc', 'def'], /ef/); + * // => ['def'] + */ +function iteratee(func) { + return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG)); +} + +module.exports = iteratee; diff --git a/libs/events/node_modules/lodash/join.js b/libs/events/node_modules/lodash/join.js new file mode 100644 index 000000000..45de079ff --- /dev/null +++ b/libs/events/node_modules/lodash/join.js @@ -0,0 +1,26 @@ +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeJoin = arrayProto.join; + +/** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ +function join(array, separator) { + return array == null ? '' : nativeJoin.call(array, separator); +} + +module.exports = join; diff --git a/libs/events/node_modules/lodash/kebabCase.js b/libs/events/node_modules/lodash/kebabCase.js new file mode 100644 index 000000000..8a52be645 --- /dev/null +++ b/libs/events/node_modules/lodash/kebabCase.js @@ -0,0 +1,28 @@ +var createCompounder = require('./_createCompounder'); + +/** + * Converts `string` to + * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__FOO_BAR__'); + * // => 'foo-bar' + */ +var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); +}); + +module.exports = kebabCase; diff --git a/libs/events/node_modules/lodash/keyBy.js b/libs/events/node_modules/lodash/keyBy.js new file mode 100644 index 000000000..acc007a0a --- /dev/null +++ b/libs/events/node_modules/lodash/keyBy.js @@ -0,0 +1,36 @@ +var baseAssignValue = require('./_baseAssignValue'), + createAggregator = require('./_createAggregator'); + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ +var keyBy = createAggregator(function(result, value, key) { + baseAssignValue(result, key, value); +}); + +module.exports = keyBy; diff --git a/libs/events/node_modules/lodash/keys.js b/libs/events/node_modules/lodash/keys.js new file mode 100644 index 000000000..d143c7186 --- /dev/null +++ b/libs/events/node_modules/lodash/keys.js @@ -0,0 +1,37 @@ +var arrayLikeKeys = require('./_arrayLikeKeys'), + baseKeys = require('./_baseKeys'), + isArrayLike = require('./isArrayLike'); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +module.exports = keys; diff --git a/libs/events/node_modules/lodash/keysIn.js b/libs/events/node_modules/lodash/keysIn.js new file mode 100644 index 000000000..a62308f2c --- /dev/null +++ b/libs/events/node_modules/lodash/keysIn.js @@ -0,0 +1,32 @@ +var arrayLikeKeys = require('./_arrayLikeKeys'), + baseKeysIn = require('./_baseKeysIn'), + isArrayLike = require('./isArrayLike'); + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); +} + +module.exports = keysIn; diff --git a/libs/events/node_modules/lodash/lang.js b/libs/events/node_modules/lodash/lang.js new file mode 100644 index 000000000..a3962169a --- /dev/null +++ b/libs/events/node_modules/lodash/lang.js @@ -0,0 +1,58 @@ +module.exports = { + 'castArray': require('./castArray'), + 'clone': require('./clone'), + 'cloneDeep': require('./cloneDeep'), + 'cloneDeepWith': require('./cloneDeepWith'), + 'cloneWith': require('./cloneWith'), + 'conformsTo': require('./conformsTo'), + 'eq': require('./eq'), + 'gt': require('./gt'), + 'gte': require('./gte'), + 'isArguments': require('./isArguments'), + 'isArray': require('./isArray'), + 'isArrayBuffer': require('./isArrayBuffer'), + 'isArrayLike': require('./isArrayLike'), + 'isArrayLikeObject': require('./isArrayLikeObject'), + 'isBoolean': require('./isBoolean'), + 'isBuffer': require('./isBuffer'), + 'isDate': require('./isDate'), + 'isElement': require('./isElement'), + 'isEmpty': require('./isEmpty'), + 'isEqual': require('./isEqual'), + 'isEqualWith': require('./isEqualWith'), + 'isError': require('./isError'), + 'isFinite': require('./isFinite'), + 'isFunction': require('./isFunction'), + 'isInteger': require('./isInteger'), + 'isLength': require('./isLength'), + 'isMap': require('./isMap'), + 'isMatch': require('./isMatch'), + 'isMatchWith': require('./isMatchWith'), + 'isNaN': require('./isNaN'), + 'isNative': require('./isNative'), + 'isNil': require('./isNil'), + 'isNull': require('./isNull'), + 'isNumber': require('./isNumber'), + 'isObject': require('./isObject'), + 'isObjectLike': require('./isObjectLike'), + 'isPlainObject': require('./isPlainObject'), + 'isRegExp': require('./isRegExp'), + 'isSafeInteger': require('./isSafeInteger'), + 'isSet': require('./isSet'), + 'isString': require('./isString'), + 'isSymbol': require('./isSymbol'), + 'isTypedArray': require('./isTypedArray'), + 'isUndefined': require('./isUndefined'), + 'isWeakMap': require('./isWeakMap'), + 'isWeakSet': require('./isWeakSet'), + 'lt': require('./lt'), + 'lte': require('./lte'), + 'toArray': require('./toArray'), + 'toFinite': require('./toFinite'), + 'toInteger': require('./toInteger'), + 'toLength': require('./toLength'), + 'toNumber': require('./toNumber'), + 'toPlainObject': require('./toPlainObject'), + 'toSafeInteger': require('./toSafeInteger'), + 'toString': require('./toString') +}; diff --git a/libs/events/node_modules/lodash/last.js b/libs/events/node_modules/lodash/last.js new file mode 100644 index 000000000..cad1eafaf --- /dev/null +++ b/libs/events/node_modules/lodash/last.js @@ -0,0 +1,20 @@ +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +module.exports = last; diff --git a/libs/events/node_modules/lodash/lastIndexOf.js b/libs/events/node_modules/lodash/lastIndexOf.js new file mode 100644 index 000000000..dabfb613a --- /dev/null +++ b/libs/events/node_modules/lodash/lastIndexOf.js @@ -0,0 +1,46 @@ +var baseFindIndex = require('./_baseFindIndex'), + baseIsNaN = require('./_baseIsNaN'), + strictLastIndexOf = require('./_strictLastIndexOf'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // Search from the `fromIndex`. + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + */ +function lastIndexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); + } + return value === value + ? strictLastIndexOf(array, value, index) + : baseFindIndex(array, baseIsNaN, index, true); +} + +module.exports = lastIndexOf; diff --git a/libs/events/node_modules/lodash/lodash.js b/libs/events/node_modules/lodash/lodash.js new file mode 100644 index 000000000..4131e936c --- /dev/null +++ b/libs/events/node_modules/lodash/lodash.js @@ -0,0 +1,17209 @@ +/** + * @license + * Lodash + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '4.17.21'; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Error message constants. */ + var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', + FUNC_ERROR_TEXT = 'Expected a function', + INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`'; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** Used to compose bitmasks for cloning. */ + var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** Used to compose bitmasks for function metadata. */ + var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_BOUND_FLAG = 4, + WRAP_CURRY_FLAG = 8, + WRAP_CURRY_RIGHT_FLAG = 16, + WRAP_PARTIAL_FLAG = 32, + WRAP_PARTIAL_RIGHT_FLAG = 64, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256, + WRAP_FLIP_FLAG = 512; + + /** Used as default options for `_.truncate`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 800, + HOT_SPAN = 16; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2, + LAZY_WHILE_FLAG = 3; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** Used to associate wrap methods with their bit flags. */ + var wrapFlags = [ + ['ary', WRAP_ARY_FLAG], + ['bind', WRAP_BIND_FLAG], + ['bindKey', WRAP_BIND_KEY_FLAG], + ['curry', WRAP_CURRY_FLAG], + ['curryRight', WRAP_CURRY_RIGHT_FLAG], + ['flip', WRAP_FLIP_FLAG], + ['partial', WRAP_PARTIAL_FLAG], + ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], + ['rearg', WRAP_REARG_FLAG] + ]; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + asyncTag = '[object AsyncFunction]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + domExcTag = '[object DOMException]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + nullTag = '[object Null]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + proxyTag = '[object Proxy]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + undefinedTag = '[object Undefined]', + weakMapTag = '[object WeakMap]', + weakSetTag = '[object WeakSet]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, + reUnescapedHtml = /[&<>"']/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); + + /** Used to match leading whitespace. */ + var reTrimStart = /^\s+/; + + /** Used to match a single whitespace character. */ + var reWhitespace = /\s/; + + /** Used to match wrap detail comments. */ + var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, + reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, + reSplitDetails = /,? & /; + + /** Used to match words composed of alphanumeric characters. */ + var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; + + /** + * Used to validate the `validate` option in `_.template` variable. + * + * Forbids characters which could potentially change the meaning of the function argument definition: + * - "()," (modification of function parameters) + * - "=" (default value) + * - "[]{}" (destructuring of function parameters) + * - "/" (beginning of a comment) + * - whitespace + */ + var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Used to match + * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to match Latin Unicode letters (excluding mathematical operators). */ + var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsDingbatRange = '\\u2700-\\u27bf', + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsPunctuationRange = '\\u2000-\\u206f', + rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = '\\ufe0e\\ufe0f', + rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; + + /** Used to compose unicode capture groups. */ + var rsApos = "['\u2019]", + rsAstral = '[' + rsAstralRange + ']', + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = '\\u200d'; + + /** Used to compose unicode regexes. */ + var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', + rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', + rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', + rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', + rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match apostrophes. */ + var reApos = RegExp(rsApos, 'g'); + + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ + var reComboMark = RegExp(rsCombo, 'g'); + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** Used to match complex or compound words. */ + var reUnicodeWord = RegExp([ + rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', + rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, + rsUpper + '+' + rsOptContrUpper, + rsOrdUpper, + rsOrdLower, + rsDigits, + rsEmoji + ].join('|'), 'g'); + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + + /** Used to detect strings that need a more robust regexp to match words. */ + var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', + 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', + '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag] = + typedArrayTags[mapTag] = typedArrayTags[numberTag] = + typedArrayTags[objectTag] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag] = + typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map Latin Unicode letters to basic Latin letters. */ + var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 's' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Built-in method references without a dependency on `root`. */ + var freeParseFloat = parseFloat, + freeParseInt = parseInt; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports && freeGlobal.process; + + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); + + /* Node.js helper references. */ + var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, + nodeIsDate = nodeUtil && nodeUtil.isDate, + nodeIsMap = nodeUtil && nodeUtil.isMap, + nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, + nodeIsSet = nodeUtil && nodeUtil.isSet, + nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + + /*--------------------------------------------------------------------------*/ + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array == null ? 0 : array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && baseIndexOf(array, value, 0) > -1; + } + + /** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array == null ? 0 : array.length; + if (initAccum && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + var asciiSize = baseProperty('length'); + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** + * Splits an ASCII `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function asciiWords(string) { + return string.match(reAsciiWord) || []; + } + + /** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ + function baseIsNaN(value) { + return value !== value; + } + + /** + * The base implementation of `_.mean` and `_.meanBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the mean. + */ + function baseMean(array, iteratee) { + var length = array == null ? 0 : array.length; + return length ? (baseSum(array, iteratee) / length) : NAN; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyOf(object) { + return function(key) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sum` and `_.sumBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + if (current !== undefined) { + result = result === undefined ? current : (result + current); + } + } + return result; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the key-value pairs. + */ + function baseToPairs(object, props) { + return arrayMap(props, function(key) { + return [key, object[key]]; + }); + } + + /** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ + function baseTrim(string) { + return string + ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; + } + + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); + } + + /** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function cacheHas(cache, key) { + return cache.has(key); + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ + function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + ++result; + } + } + return result; + } + + /** + * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A + * letters to basic Latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + var deburrLetter = basePropertyOf(deburredLetters); + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + var escapeHtmlChar = basePropertyOf(htmlEscapes); + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** + * Checks if `string` contains a word composed of Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a word is found, else `false`. + */ + function hasUnicodeWord(string) { + return reHasUnicodeWord.test(string); + } + + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } + return result; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** + * Converts `set` to its value-value pairs. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the value-value pairs. + */ + function setToPairs(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = [value, value]; + }); + return result; + } + + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * A specialized version of `_.lastIndexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictLastIndexOf(array, value, fromIndex) { + var index = fromIndex + 1; + while (index--) { + if (array[index] === value) { + return index; + } + } + return index; + } + + /** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ + function stringSize(string) { + return hasUnicode(string) + ? unicodeSize(string) + : asciiSize(string); + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + var unescapeHtmlChar = basePropertyOf(htmlUnescapes); + + /** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; + } + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /** + * Splits a Unicode `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function unicodeWords(string) { + return string.match(reUnicodeWord) || []; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the `context` object. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Util + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // Create a suped-up `defer` in Node.js. + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + var runInContext = (function runInContext(context) { + context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); + + /** Built-in constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = context['__core-js_shared__']; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? context.Buffer : undefined, + Symbol = context.Symbol, + Uint8Array = context.Uint8Array, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice, + spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, + symIterator = Symbol ? Symbol.iterator : undefined, + symToStringTag = Symbol ? Symbol.toStringTag : undefined; + + var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + /** Mocked built-ins. */ + var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, + ctxNow = Date && Date.now !== root.Date.now && Date.now, + ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeIsFinite = context.isFinite, + nativeJoin = arrayProto.join, + nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = Date.now, + nativeParseInt = context.parseInt, + nativeRandom = Math.random, + nativeReverse = arrayProto.reverse; + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(context, 'DataView'), + Map = getNative(context, 'Map'), + Promise = getNative(context, 'Promise'), + Set = getNative(context, 'Set'), + WeakMap = getNative(context, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chain sequences. Methods that operate on and return arrays, collections, + * and functions can be chained together. Methods that retrieve a single value + * or may return a primitive value will automatically end the chain sequence + * and return the unwrapped value. Otherwise, the value must be unwrapped + * with `_#value`. + * + * Explicit chain sequences, which must be unwrapped with `_#value`, may be + * enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. + * Shortcut fusion is an optimization to merge iteratee calls; this avoids + * the creation of intermediate arrays and can greatly reduce the number of + * iteratee executions. Sections of a chain sequence qualify for shortcut + * fusion if the section is applied to an array and iteratees accept only + * one argument. The heuristic for whether a section qualifies for shortcut + * fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, + * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, + * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, + * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, + * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, + * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, + * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, + * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, + * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, + * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, + * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, + * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, + * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, + * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, + * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, + * `zipObject`, `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, + * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, + * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, + * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, + * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, + * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, + * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, + * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, + * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, + * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, + * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, + * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, + * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, + * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, + * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, + * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, + * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, + * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, + * `upperFirst`, `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * The function whose prototype chain sequence wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable explicit method chain sequences. + */ + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; + } + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB) as well as ES2015 template strings. Change the + * following template settings to use alternative delimiters. + * + * @static + * @memberOf _ + * @type {Object} + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type {string} + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type {Object} + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type {Function} + */ + '_': lodash + } + }; + + // Ensure wrappers are instances of `baseLodash`. + lodash.prototype = baseLodash.prototype; + lodash.prototype.constructor = lodash; + + LodashWrapper.prototype = baseCreate(baseLodash.prototype); + LodashWrapper.prototype.constructor = LodashWrapper; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || (!isRight && arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + // Ensure `LazyWrapper` is an instance of `baseLodash`. + LazyWrapper.prototype = baseCreate(baseLodash.prototype); + LazyWrapper.prototype.constructor = LazyWrapper; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } + } + + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; + } + + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function setCacheHas(value) { + return this.__data__.has(value); + } + + // Add methods to `SetCache`. + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + this.size = 0; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + /** + * A specialized version of `_.sample` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @returns {*} Returns the random element. + */ + function arraySample(array) { + var length = array.length; + return length ? array[baseRandom(0, length - 1)] : undefined; + } + + /** + * A specialized version of `_.sampleSize` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ + function arraySampleSize(array, n) { + return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); + } + + /** + * A specialized version of `_.shuffle` for arrays. + * + * @private + * @param {Array} array The array to shuffle. + * @returns {Array} Returns the new shuffled array. + */ + function arrayShuffle(array) { + return shuffleSelf(copyArray(array)); + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssignIn(object, source) { + return object && copyObject(source, keysIn(source), object); + } + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + /** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths to pick. + * @returns {Array} Returns the picked elements. + */ + function baseAt(object, paths) { + var index = -1, + length = paths.length, + result = Array(length), + skip = object == null; + + while (++index < length) { + result[index] = skip ? undefined : get(object, paths[index]); + } + return result; + } + + /** + * The base implementation of `_.clamp` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ + function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : initCloneObject(value); + if (!isDeep) { + return isFlat + ? copySymbolsIn(value, baseAssignIn(result, value)) + : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? getAllKeysIn : getAllKeys) + : (isFlat ? keysIn : keys); + + var props = isArr ? undefined : keysFunc(value); + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new spec function. + */ + function baseConforms(source) { + var props = keys(source); + return function(object) { + return baseConformsTo(object, source, props); + }; + } + + /** + * The base implementation of `_.conformsTo` which accepts `props` to check. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + */ + function baseConformsTo(object, source, props) { + var length = props.length; + if (object == null) { + return !length; + } + object = Object(object); + while (length--) { + var key = props[length], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in object)) || !predicate(value)) { + return false; + } + } + return true; + } + + /** + * The base implementation of `_.delay` and `_.defer` which accepts `args` + * to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Array} args The arguments to provide to `func`. + * @returns {number|Object} Returns the timer id or timeout object. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of methods like `_.difference` without support + * for excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; + + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee == null ? value : iteratee(value); + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); + } + else if (!includes(values, computed, comparator)) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !isSymbol(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = toInteger(start); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : toInteger(end); + if (end < 0) { + end += length; + } + end = start > end ? 0 : toLength(end); + while (start < end) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the function names. + */ + function baseFunctions(object, props) { + return arrayFilter(props, function(key) { + return isFunction(object[key]); + }); + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); + } + + /** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ + function baseGt(value, other) { + return value > other; + } + + /** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHas(object, key) { + return object != null && hasOwnProperty.call(object, key); + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return object != null && key in Object(object); + } + + /** + * The base implementation of `_.inRange` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ + function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); + } + + /** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ + function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + seen = caches[0]; + + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ + function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function(value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; + } + + /** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function baseInvoke(object, path, args) { + path = castPath(path, object); + object = parent(object, path); + var func = object == null ? object : object[toKey(last(path))]; + return func == null ? undefined : apply(func, object, args); + } + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + + /** + * The base implementation of `_.isArrayBuffer` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + */ + function baseIsArrayBuffer(value) { + return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; + } + + /** + * The base implementation of `_.isDate` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + */ + function baseIsDate(value) { + return isObjectLike(value) && baseGetTag(value) == dateTag; + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : getTag(object), + othTag = othIsArr ? arrayTag : getTag(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + } + + /** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ + function baseIsMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; + } + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.isRegExp` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + */ + function baseIsRegExp(value) { + return isObjectLike(value) && baseGetTag(value) == regexpTag; + } + + /** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ + function baseIsSet(value) { + return isObjectLike(value) && getTag(value) == setTag; + } + + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ + function baseLt(value, other) { + return value < other; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); + }; + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.nth` which doesn't coerce arguments. + * + * @private + * @param {Array} array The array to query. + * @param {number} n The index of the element to return. + * @returns {*} Returns the nth element of `array`. + */ + function baseNth(array, n) { + var length = array.length; + if (!length) { + return; + } + n += n < 0 ? length : 0; + return isIndex(n, length) ? array[n] : undefined; + } + + /** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = arrayMap(iteratees, function(iteratee) { + if (isArray(iteratee)) { + return function(value) { + return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity]; + } + + var index = -1; + iteratees = arrayMap(iteratees, baseUnary(getIteratee())); + + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, paths) { + return basePickBy(object, paths, function(value, path) { + return hasIn(object, path); + }); + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; + } + + /** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + */ + function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; + + if (array === values) { + values = copyArray(values); + } + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * indexes or capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0, + lastIndex = length - 1; + + while (length--) { + var index = indexes[length]; + if (length == lastIndex || index !== previous) { + var previous = index; + if (isIndex(index)) { + splice.call(array, index, 1); + } else { + baseUnset(array, index); + } + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ + function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); + } + + /** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ + function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; + } + + /** + * The base implementation of `_.repeat` which doesn't coerce arguments. + * + * @private + * @param {string} string The string to repeat. + * @param {number} n The number of times to repeat the string. + * @returns {string} Returns the repeated string. + */ + function baseRepeat(string, n) { + var result = ''; + if (!string || n < 1 || n > MAX_SAFE_INTEGER) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + if (n) { + string += string; + } + } while (n); + + return result; + } + + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** + * The base implementation of `_.sample`. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + */ + function baseSample(collection) { + return arraySample(values(collection)); + } + + /** + * The base implementation of `_.sampleSize` without param guards. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ + function baseSampleSize(collection, n) { + var array = values(collection); + return shuffleSelf(array, baseClamp(n, 0, array.length)); + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `setData` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + + /** + * The base implementation of `_.shuffle`. + * + * @private + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + */ + function baseShuffle(collection) { + return shuffleSelf(values(collection)); + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array == null ? low : array.length; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if (computed !== null && !isSymbol(computed) && + (retHighest ? (computed <= value) : (computed < value))) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return baseSortedIndexBy(array, value, identity, retHighest); + } + + /** + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function baseSortedIndexBy(array, value, iteratee, retHighest) { + var low = 0, + high = array == null ? 0 : array.length; + if (high === 0) { + return 0; + } + + value = iteratee(value); + var valIsNaN = value !== value, + valIsNull = value === null, + valIsSymbol = isSymbol(value), + valIsUndefined = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + othIsDefined = computed !== undefined, + othIsNull = computed === null, + othIsReflexive = computed === computed, + othIsSymbol = isSymbol(computed); + + if (valIsNaN) { + var setLow = retHighest || othIsReflexive; + } else if (valIsUndefined) { + setLow = othIsReflexive && (retHighest || othIsDefined); + } else if (valIsNull) { + setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); + } else if (valIsSymbol) { + setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); + } else if (othIsNull || othIsSymbol) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseSortedUniq(array, iteratee) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!index || !eq(computed, seen)) { + var seen = computed; + result[resIndex++] = value === 0 ? 0 : value; + } + } + return result; + } + + /** + * The base implementation of `_.toNumber` which doesn't ensure correct + * conversions of binary, hexadecimal, or octal string values. + * + * @private + * @param {*} value The value to process. + * @returns {number} Returns the number. + */ + function baseToNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + return +value; + } + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The property path to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ + function baseUnset(object, path) { + path = castPath(path, object); + object = parent(object, path); + return object == null || delete object[toKey(last(path))]; + } + + /** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); + } + + /** + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && + predicate(array[index], index, array)) {} + + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + return arrayReduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ + function baseXor(arrays, iteratee, comparator) { + var length = arrays.length; + if (length < 2) { + return length ? baseUniq(arrays[0]) : []; + } + var index = -1, + result = Array(length); + + while (++index < length) { + var array = arrays[index], + othIndex = -1; + + while (++othIndex < length) { + if (othIndex != index) { + result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); + } + } + } + return baseUniq(baseFlatten(result, 1), iteratee, comparator); + } + + /** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ + function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; + } + + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array|Object} Returns the cast array-like object. + */ + function castArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ + function castFunction(value) { + return typeof value == 'function' ? value : identity; + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + /** + * A `baseRest` alias which can be replaced with `identity` by module + * replacement plugins. + * + * @private + * @type {Function} + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + var castRest = baseRest; + + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } + + /** + * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). + * + * @private + * @param {number|Object} id The timer id or timeout object of the timer to clear. + */ + var clearTimeout = ctxClearTimeout || function(id) { + return root.clearTimeout(id); + }; + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = isSymbol(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = isSymbol(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; + } + + /** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; + + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbolsIn(source, object) { + return copyObject(source, getSymbolsIn(source), object); + } + + /** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, getIteratee(iteratee, 2), accumulator); + }; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createBind(func, bitmask, thisArg) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } + return wrapper; + } + + /** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new case function. + */ + function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = hasUnicode(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols + ? strSymbols[0] + : string.charAt(0); + + var trailing = strSymbols + ? castSlice(strSymbols, 1).join('') + : string.slice(1); + + return chr[methodName]() + trailing; + }; + } + + /** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtor(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. See + // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createCurry(func, bitmask, arity) { + var Ctor = createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getHolder(wrapper); + + while (index--) { + args[index] = arguments[index]; + } + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + return wrapper; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ + function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!isArrayLike(collection)) { + var iteratee = getIteratee(predicate, 3); + collection = keys(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return flatRest(function(funcs) { + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; + + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? index : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && + data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) + ? wrapper[funcName]() + : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value)) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }); + } + + /** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided + * to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & WRAP_ARY_FLAG, + isBind = bitmask & WRAP_BIND_FLAG, + isBindKey = bitmask & WRAP_BIND_KEY_FLAG, + isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), + isFlip = bitmask & WRAP_FLIP_FLAG, + Ctor = isBindKey ? undefined : createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length; + + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getHolder(wrapper), + holdersCount = countHolders(args, placeholder); + } + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + length = args.length; + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } + if (isAry && ary < length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtor(fn); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ + function createInverter(setter, toIteratee) { + return function(object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; + } + + /** + * Creates a function that performs a mathematical operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @param {number} [defaultValue] The value used for `undefined` arguments. + * @returns {Function} Returns the new mathematical operation function. + */ + function createMathOperation(operator, defaultValue) { + return function(value, other) { + var result; + if (value === undefined && other === undefined) { + return defaultValue; + } + if (value !== undefined) { + result = value; + } + if (other !== undefined) { + if (result === undefined) { + return other; + } + if (typeof value == 'string' || typeof other == 'string') { + value = baseToString(value); + other = baseToString(other); + } else { + value = baseToNumber(value); + other = baseToNumber(other); + } + result = operator(value, other); + } + return result; + }; + } + + /** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new over function. + */ + function createOver(arrayFunc) { + return flatRest(function(iteratees) { + iteratees = arrayMap(iteratees, baseUnary(getIteratee())); + return baseRest(function(args) { + var thisArg = this; + return arrayFunc(iteratees, function(iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); + } + + /** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. + * + * @private + * @param {number} length The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padding for `string`. + */ + function createPadding(length, chars) { + chars = chars === undefined ? ' ' : baseToString(chars); + + var charsLength = chars.length; + if (charsLength < 2) { + return charsLength ? baseRepeat(chars, length) : chars; + } + var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); + return hasUnicode(chars) + ? castSlice(stringToArray(result), 0, length).join('') + : result.slice(0, length); + } + + /** + * Creates a function that wraps `func` to invoke it with the `this` binding + * of `thisArg` and `partials` prepended to the arguments it receives. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to + * the new function. + * @returns {Function} Returns the new wrapped function. + */ + function createPartial(func, bitmask, thisArg, partials) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return apply(fn, isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ + function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toFinite(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); + return baseRange(start, end, step, fromRight); + }; + } + + /** + * Creates a function that performs a relational operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @returns {Function} Returns the new relational operation function. + */ + function createRelationalOperation(operator) { + return function(value, other) { + if (!(typeof value == 'string' && typeof other == 'string')) { + value = toNumber(value); + other = toNumber(other); + } + return operator(value, other); + }; + } + + /** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & WRAP_CURRY_FLAG, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); + + if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { + bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, argPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return setWrapToString(result, func, bitmask); + } + + /** + * Creates a function like `_.round`. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + number = toNumber(number); + precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); + if (precision && nativeIsFinite(number)) { + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); + } + return func(number); + }; + } + + /** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ + var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { + return new Set(values); + }; + + /** + * Creates a `_.toPairs` or `_.toPairsIn` function. + * + * @private + * @param {Function} keysFunc The function to get the keys of a given object. + * @returns {Function} Returns the new pairs function. + */ + function createToPairs(keysFunc) { + return function(object) { + var tag = getTag(object); + if (tag == mapTag) { + return mapToArray(object); + } + if (tag == setTag) { + return setToPairs(object); + } + return baseToPairs(object, keysFunc(object)); + }; + } + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * 512 - `_.flip` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + + if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; + + if (data) { + mergeData(newData, data); + } + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] === undefined + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { + bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == WRAP_BIND_FLAG) { + var result = createBind(func, bitmask, thisArg); + } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { + result = createCurry(func, bitmask, arity); + } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { + result = createPartial(func, bitmask, thisArg, partials); + } else { + result = createHybrid.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setWrapToString(setter(result, newData), func, bitmask); + } + + /** + * Used by `_.defaults` to customize its `_.assignIn` use to assign properties + * of source objects to the destination object for all destination properties + * that resolve to `undefined`. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ + function customDefaultsAssignIn(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source + * objects into destination objects that are passed thru. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + * @returns {*} Returns the value to assign. + */ + function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, objValue); + baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); + stack['delete'](srcValue); + } + return objValue; + } + + /** + * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain + * objects. + * + * @private + * @param {*} value The value to inspect. + * @param {string} key The key of the property to inspect. + * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. + */ + function customOmitClone(value) { + return isPlainObject(value) ? undefined : value; + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; + } + + /** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + function flatRest(func) { + return setToString(overRest(func, undefined, flatten), func + ''); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ + function getHolder(func) { + var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; + return object.placeholder; + } + + /** + * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, + * this function returns the custom method, otherwise it returns `baseIteratee`. + * If arguments are provided, the chosen function is invoked with them and + * its result is returned. + * + * @private + * @param {*} [value] The value to convert to an iteratee. + * @param {number} [arity] The arity of the created iteratee. + * @returns {Function} Returns the chosen function or its result. + */ + function getIteratee() { + var result = lodash.iteratee || iteratee; + result = result === iteratee ? baseIteratee : result; + return arguments.length ? result(arguments[0], arguments[1]) : result; + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); + }; + + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; + }; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Extracts wrapper details from the `source` body comment. + * + * @private + * @param {string} source The source to inspect. + * @returns {Array} Returns the wrapper details. + */ + function getWrapDetails(source) { + var match = source.match(reWrapDetails); + return match ? match[1].split(reSplitDetails) : []; + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + path = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Inserts wrapper `details` in a comment at the top of the `source` body. + * + * @private + * @param {string} source The source to modify. + * @returns {Array} details The details to insert. + * @returns {string} Returns the modified source. + */ + function insertWrapDetails(source, details) { + var length = details.length; + if (!length) { + return source; + } + var lastIndex = length - 1; + details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; + details = details.join(length > 2 ? ', ' : ' '); + return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); + } + + /** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ + function isFlattenable(value) { + return isArray(value) || isArguments(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, + * else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `func` is capable of being masked. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `func` is maskable, else `false`. + */ + var isMaskable = coreJsData ? isFunction : stubFalse; + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; + } + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and + * `_.rearg` modify function arguments, making the order in which they are + * executed important, preventing the merging of metadata. However, we make + * an exception for a safe combined case where curried functions have `_.ary` + * and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); + + var isCombo = + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & WRAP_BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : value; + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = value; + } + // Use source `ary` if it's smaller. + if (srcBitmask & WRAP_ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString.call(value); + } + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; + } + + /** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ + function parent(object, path) { + return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + + if (key == '__proto__') { + return; + } + + return object[key]; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity + * function to avoid garbage collection pauses in V8. See + * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = shortOut(baseSetData); + + /** + * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @returns {number|Object} Returns the timer id or timeout object. + */ + var setTimeout = ctxSetTimeout || function(func, wait) { + return root.setTimeout(func, wait); + }; + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = shortOut(baseSetToString); + + /** + * Sets the `toString` method of `wrapper` to mimic the source of `reference` + * with wrapper details in a comment at the top of the source body. + * + * @private + * @param {Function} wrapper The function to modify. + * @param {Function} reference The reference function. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Function} Returns `wrapper`. + */ + function setWrapToString(wrapper, reference, bitmask) { + var source = (reference + ''); + return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); + } + + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; + } + + /** + * A specialized version of `_.shuffle` which mutates and sets the size of `array`. + * + * @private + * @param {Array} array The array to shuffle. + * @param {number} [size=array.length] The size of `array`. + * @returns {Array} Returns `array`. + */ + function shuffleSelf(array, size) { + var index = -1, + length = array.length, + lastIndex = length - 1; + + size = size === undefined ? length : size; + while (++index < size) { + var rand = baseRandom(index, lastIndex), + value = array[rand]; + + array[rand] = array[index]; + array[index] = value; + } + array.length = size; + return array; + } + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * Updates wrapper `details` based on `bitmask` flags. + * + * @private + * @returns {Array} details The details to modify. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Array} Returns `details`. + */ + function updateWrapDetails(details, bitmask) { + arrayEach(wrapFlags, function(pair) { + var value = '_.' + pair[0]; + if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { + details.push(value); + } + }); + return details.sort(); + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the new array of chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { + size = 1; + } else { + size = nativeMax(toInteger(size), 0); + } + var length = array == null ? 0 : array.length; + if (!length || size < 1) { + return []; + } + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[resIndex++] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + function concat() { + var length = arguments.length; + if (!length) { + return []; + } + var args = Array(length - 1), + array = arguments[0], + index = length; + + while (index--) { + args[index - 1] = arguments[index]; + } + return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); + } + + /** + * Creates an array of `array` values not included in the other given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * **Note:** Unlike `_.pullAll`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.without, _.xor + * @example + * + * _.difference([2, 1], [2, 3]); + * // => [1] + */ + var difference = baseRest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * **Note:** Unlike `_.pullAllBy`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var differenceBy = baseRest(function(array, values) { + var iteratee = last(values); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. The order and + * references of result values are determined by the first array. The comparator + * is invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.pullAllWith`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ + var differenceWith = baseRest(function(array, values) { + var comparator = last(values); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] + * + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.dropWhile(users, function(o) { return !o.active; }); + * // => objects for ['pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] + */ + function fill(array, value, start, end) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ + function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseFindIndex(array, getIteratee(predicate, 3), index); + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ + function findLastIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length - 1; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = fromIndex < 0 + ? nativeMax(length + index, 0) + : nativeMin(index, length - 1); + } + return baseFindIndex(array, getIteratee(predicate, 3), index, true); + } + + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ + function flattenDeep(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ + function flattenDepth(array, depth) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); + } + + /** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['a', 1], ['b', 2]]); + * // => { 'a': 1, 'b': 2 } + */ + function fromPairs(pairs) { + var index = -1, + length = pairs == null ? 0 : pairs.length, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return (array && array.length) ? array[0] : undefined; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the + * offset from the end of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + function indexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseIndexOf(array, value, index); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 0, -1) : []; + } + + /** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [2, 3]); + * // => [2] + */ + var intersection = baseRest(function(arrays) { + var mapped = arrayMap(arrays, castArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ + var intersectionBy = baseRest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); + + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, getIteratee(iteratee, 2)) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. The order and references + * of result values are determined by the first array. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ + var intersectionWith = baseRest(function(arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); + + comparator = typeof comparator == 'function' ? comparator : undefined; + if (comparator) { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, undefined, comparator) + : []; + }); + + /** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ + function join(array, separator) { + return array == null ? '' : nativeJoin.call(array, separator); + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // Search from the `fromIndex`. + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); + } + return value === value + ? strictLastIndexOf(array, value, index) + : baseFindIndex(array, baseIsNaN, index, true); + } + + /** + * Gets the element at index `n` of `array`. If `n` is negative, the nth + * element from the end is returned. + * + * @static + * @memberOf _ + * @since 4.11.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=0] The index of the element to return. + * @returns {*} Returns the nth element of `array`. + * @example + * + * var array = ['a', 'b', 'c', 'd']; + * + * _.nth(array, 1); + * // => 'b' + * + * _.nth(array, -2); + * // => 'c'; + */ + function nth(array, n) { + return (array && array.length) ? baseNth(array, toInteger(n)) : undefined; + } + + /** + * Removes all given values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` + * to remove elements from an array by predicate. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; + * + * _.pull(array, 'a', 'c'); + * console.log(array); + * // => ['b', 'b'] + */ + var pull = baseRest(pullAll); + + /** + * This method is like `_.pull` except that it accepts an array of values to remove. + * + * **Note:** Unlike `_.difference`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; + * + * _.pullAll(array, ['a', 'c']); + * console.log(array); + * // => ['b', 'b'] + */ + function pullAll(array, values) { + return (array && array.length && values && values.length) + ? basePullAll(array, values) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `iteratee` which is + * invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The iteratee is invoked with one argument: (value). + * + * **Note:** Unlike `_.differenceBy`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; + * + * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); + * console.log(array); + * // => [{ 'x': 2 }] + */ + function pullAllBy(array, values, iteratee) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, getIteratee(iteratee, 2)) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `comparator` which + * is invoked to compare elements of `array` to `values`. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.differenceWith`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; + * + * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); + * console.log(array); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] + */ + function pullAllWith(array, values, comparator) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, undefined, comparator) + : array; + } + + /** + * Removes elements from `array` corresponding to `indexes` and returns an + * array of removed elements. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = ['a', 'b', 'c', 'd']; + * var pulled = _.pullAt(array, [1, 3]); + * + * console.log(array); + * // => ['a', 'c'] + * + * console.log(pulled); + * // => ['b', 'd'] + */ + var pullAt = flatRest(function(array, indexes) { + var length = array == null ? 0 : array.length, + result = baseAt(array, indexes); + + basePullAt(array, arrayMap(indexes, function(index) { + return isIndex(index, length) ? +index : index; + }).sort(compareAscending)); + + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is invoked + * with three arguments: (value, index, array). + * + * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` + * to pull elements from an array by value. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getIteratee(predicate, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Reverses `array` so that the first element becomes the last, the second + * element becomes the second to last, and so on. + * + * **Note:** This method mutates `array` and is based on + * [`Array#reverse`](https://mdn.io/Array/reverse). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.reverse(array); + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function reverse(array) { + return array == null ? array : nativeReverse.call(array); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of + * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are + * returned. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + else { + start = start == null ? 0 : toInteger(start); + end = end === undefined ? length : toInteger(end); + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + */ + function sortedIndex(array, value) { + return baseSortedIndex(array, value); + } + + /** + * This method is like `_.sortedIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * var objects = [{ 'x': 4 }, { 'x': 5 }]; + * + * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); + * // => 0 + */ + function sortedIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); + } + + /** + * This method is like `_.indexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedIndexOf([4, 5, 5, 5, 6], 5); + * // => 1 + */ + function sortedIndexOf(array, value) { + var length = array == null ? 0 : array.length; + if (length) { + var index = baseSortedIndex(array, value); + if (index < length && eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 5, 5, 5, 6], 5); + * // => 4 + */ + function sortedLastIndex(array, value) { + return baseSortedIndex(array, value, true); + } + + /** + * This method is like `_.sortedLastIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * var objects = [{ 'x': 4 }, { 'x': 5 }]; + * + * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 1 + * + * // The `_.property` iteratee shorthand. + * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); + * // => 1 + */ + function sortedLastIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); + } + + /** + * This method is like `_.lastIndexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); + * // => 3 + */ + function sortedLastIndexOf(array, value) { + var length = array == null ? 0 : array.length; + if (length) { + var index = baseSortedIndex(array, value, true) - 1; + if (eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.uniq` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniq([1, 1, 2]); + * // => [1, 2] + */ + function sortedUniq(array) { + return (array && array.length) + ? baseSortedUniq(array) + : []; + } + + /** + * This method is like `_.uniqBy` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); + * // => [1.1, 2.3] + */ + function sortedUniqBy(array, iteratee) { + return (array && array.length) + ? baseSortedUniq(array, getIteratee(iteratee, 2)) + : []; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.tail([1, 2, 3]); + * // => [2, 3] + */ + function tail(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 1, length) : []; + } + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + if (!(array && array.length)) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.takeRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeRightWhile(users, ['active', false]); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.takeRightWhile(users, 'active'); + * // => [] + */ + function takeRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.takeWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matches` iteratee shorthand. + * _.takeWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeWhile(users, ['active', false]); + * // => objects for ['barney', 'fred'] + * + * // The `_.property` iteratee shorthand. + * _.takeWhile(users, 'active'); + * // => [] + */ + function takeWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ + var union = baseRest(function(arrays) { + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); + }); + + /** + * This method is like `_.union` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by + * which uniqueness is computed. Result values are chosen from the first + * array in which the value occurs. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.unionBy([2.1], [1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + var unionBy = baseRest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); + }); + + /** + * This method is like `_.union` except that it accepts `comparator` which + * is invoked to compare elements of `arrays`. Result values are chosen from + * the first array in which the value occurs. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.unionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var unionWith = baseRest(function(arrays) { + var comparator = last(arrays); + comparator = typeof comparator == 'function' ? comparator : undefined; + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. The order of result values is determined by the order they occur + * in the array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + */ + function uniq(array) { + return (array && array.length) ? baseUniq(array) : []; + } + + /** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The order of result values is determined by the + * order they occur in the array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniqBy(array, iteratee) { + return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : []; + } + + /** + * This method is like `_.uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The order of result values is + * determined by the order they occur in the array.The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.uniqWith(objects, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] + */ + function uniqWith(array, comparator) { + comparator = typeof comparator == 'function' ? comparator : undefined; + return (array && array.length) ? baseUniq(array, undefined, comparator) : []; + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @since 1.2.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + * + * _.unzip(zipped); + * // => [['a', 'b'], [1, 2], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var length = 0; + array = arrayFilter(array, function(group) { + if (isArrayLikeObject(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + return baseTimes(length, function(index) { + return arrayMap(array, baseProperty(index)); + }); + } + + /** + * This method is like `_.unzip` except that it accepts `iteratee` to specify + * how regrouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee=_.identity] The function to combine + * regrouped values. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee) { + if (!(array && array.length)) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + return arrayMap(result, function(group) { + return apply(iteratee, undefined, group); + }); + } + + /** + * Creates an array excluding all given values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.pull`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.difference, _.xor + * @example + * + * _.without([2, 1, 2, 3], 1, 2); + * // => [3] + */ + var without = baseRest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of unique values that is the + * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the given arrays. The order of result values is determined by the order + * they occur in the arrays. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of filtered values. + * @see _.difference, _.without + * @example + * + * _.xor([2, 1], [2, 3]); + * // => [1, 3] + */ + var xor = baseRest(function(arrays) { + return baseXor(arrayFilter(arrays, isArrayLikeObject)); + }); + + /** + * This method is like `_.xor` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by + * which by which they're compared. The order of result values is determined + * by the order they occur in the arrays. The iteratee is invoked with one + * argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2, 3.4] + * + * // The `_.property` iteratee shorthand. + * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var xorBy = baseRest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); + }); + + /** + * This method is like `_.xor` except that it accepts `comparator` which is + * invoked to compare elements of `arrays`. The order of result values is + * determined by the order they occur in the arrays. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.xorWith(objects, others, _.isEqual); + * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var xorWith = baseRest(function(arrays) { + var comparator = last(arrays); + comparator = typeof comparator == 'function' ? comparator : undefined; + return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); + }); + + /** + * Creates an array of grouped elements, the first of which contains the + * first elements of the given arrays, the second of which contains the + * second elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + */ + var zip = baseRest(unzip); + + /** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ + function zipObject(props, values) { + return baseZipObject(props || [], values || [], assignValue); + } + + /** + * This method is like `_.zipObject` except that it supports property paths. + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); + * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } + */ + function zipObjectDeep(props, values) { + return baseZipObject(props || [], values || [], baseSet); + } + + /** + * This method is like `_.zip` except that it accepts `iteratee` to specify + * how grouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee=_.identity] The function to combine + * grouped values. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { + * return a + b + c; + * }); + * // => [111, 222] + */ + var zipWith = baseRest(function(arrays) { + var length = arrays.length, + iteratee = length > 1 ? arrays[length - 1] : undefined; + + iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; + return unzipWith(arrays, iteratee); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` wrapper instance that wraps `value` with explicit method + * chain sequences enabled. The result of such sequences must be unwrapped + * with `_#value`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain sequence in order to modify intermediate results. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain sequence. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor) { + return interceptor(value); + } + + /** + * This method is the wrapper version of `_.at`. + * + * @name at + * @memberOf _ + * @since 1.0.0 + * @category Seq + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _(object).at(['a[0].b.c', 'a[1]']).value(); + * // => [3, 4] + */ + var wrapperAt = flatRest(function(paths) { + var length = paths.length, + start = length ? paths[0] : 0, + value = this.__wrapped__, + interceptor = function(object) { return baseAt(object, paths); }; + + if (length > 1 || this.__actions__.length || + !(value instanceof LazyWrapper) || !isIndex(start)) { + return this.thru(interceptor); + } + value = value.slice(start, +start + (length ? 1 : 0)); + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined + }); + return new LodashWrapper(value, this.__chain__).thru(function(array) { + if (length && !array.length) { + array.push(undefined); + } + return array; + }); + }); + + /** + * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. + * + * @name chain + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chain sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * Gets the next value on a wrapped object following the + * [iterator protocol](https://mdn.io/iteration_protocols#iterator). + * + * @name next + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the next iterator value. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped.next(); + * // => { 'done': false, 'value': 1 } + * + * wrapped.next(); + * // => { 'done': false, 'value': 2 } + * + * wrapped.next(); + * // => { 'done': true, 'value': undefined } + */ + function wrapperNext() { + if (this.__values__ === undefined) { + this.__values__ = toArray(this.value()); + } + var done = this.__index__ >= this.__values__.length, + value = done ? undefined : this.__values__[this.__index__++]; + + return { 'done': done, 'value': value }; + } + + /** + * Enables the wrapper to be iterable. + * + * @name Symbol.iterator + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the wrapper object. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped[Symbol.iterator]() === wrapped; + * // => true + * + * Array.from(wrapped); + * // => [1, 2] + */ + function wrapperToIterator() { + return this; + } + + /** + * Creates a clone of the chain sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @param {*} value The value to plant. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2]).map(square); + * var other = wrapped.plant([3, 4]); + * + * other.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + clone.__index__ = 0; + clone.__values__ = undefined; + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * This method is the wrapper version of `_.reverse`. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined + }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(reverse); + } + + /** + * Executes the chain sequence to resolve the unwrapped value. + * + * @name value + * @memberOf _ + * @since 0.1.0 + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the number of times the key was returned by `iteratee`. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': 1, '6': 2 } + * + * // The `_.property` iteratee shorthand. + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + ++result[key]; + } else { + baseAssignValue(result, key, 1); + } + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * **Note:** This method returns `true` for + * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because + * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of + * elements of empty collections. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ + function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ + var find = createFind(findIndex); + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=collection.length-1] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + var findLast = createFind(findLastIndex); + + /** + * Creates a flattened array of values by running each element in `collection` + * thru `iteratee` and flattening the mapped results. The iteratee is invoked + * with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ + function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); + } + + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDeep([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ + function flatMapDeep(collection, iteratee) { + return baseFlatten(map(collection, iteratee), INFINITY); + } + + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDepth([1, 2], duplicate, 2); + * // => [[1, 1], [2, 2]] + */ + function flatMapDepth(collection, iteratee, depth) { + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(map(collection, iteratee), depth); + } + + /** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forEach(collection, iteratee) { + var func = isArray(collection) ? arrayEach : baseEach; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @alias eachRight + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEach + * @example + * + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `2` then `1`. + */ + function forEachRight(collection, iteratee) { + var func = isArray(collection) ? arrayEachRight : baseEachRight; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The order of grouped values + * is determined by the order they occur in `collection`. The corresponding + * value of each key is an array of elements responsible for generating the + * key. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + baseAssignValue(result, key, [value]); + } + }); + + /** + * Checks if `value` is in `collection`. If `collection` is a string, it's + * checked for a substring of `value`, otherwise + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'a': 1, 'b': 2 }, 1); + * // => true + * + * _.includes('abcd', 'bc'); + * // => true + */ + function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); + } + + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `path` is a function, it's invoked + * for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke each method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invokeMap([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invokeMap = baseRest(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); + }); + return result; + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ + var keyBy = createAggregator(function(result, value, key) { + baseAssignValue(result, key, value); + }); + + /** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee) { + var func = isArray(collection) ? arrayMap : baseMap; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] + * The iteratees to sort by. + * @param {string[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // Sort by `user` in ascending order and by `age` in descending order. + * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] + */ + function orderBy(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + orders = guard ? undefined : orders; + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseOrderBy(collection, iteratees, orders); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, the second of which + * contains elements `predicate` returns falsey for. The predicate is + * invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * _.partition(users, function(o) { return o.active; }); + * // => objects for [['fred'], ['barney', 'pebbles']] + * + * // The `_.matches` iteratee shorthand. + * _.partition(users, { 'age': 1, 'active': false }); + * // => objects for [['pebbles'], ['barney', 'fred']] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.partition(users, ['active', false]); + * // => objects for [['barney', 'pebbles'], ['fred']] + * + * // The `_.property` iteratee shorthand. + * _.partition(users, 'active'); + * // => objects for [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduce : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); + } + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduce + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduceRight : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); + } + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.filter + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * _.reject(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.reject(users, { 'age': 40, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.reject(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.reject(users, 'active'); + * // => objects for ['barney'] + */ + function reject(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, negate(getIteratee(predicate, 3))); + } + + /** + * Gets a random element from `collection`. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + */ + function sample(collection) { + var func = isArray(collection) ? arraySample : baseSample; + return func(collection); + } + + /** + * Gets `n` random elements at unique keys from `collection` up to the + * size of `collection`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @param {number} [n=1] The number of elements to sample. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the random elements. + * @example + * + * _.sampleSize([1, 2, 3], 2); + * // => [3, 1] + * + * _.sampleSize([1, 2, 3], 4); + * // => [2, 3, 1] + */ + function sampleSize(collection, n, guard) { + if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { + n = 1; + } else { + n = toInteger(n); + } + var func = isArray(collection) ? arraySampleSize : baseSampleSize; + return func(collection, n); + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + var func = isArray(collection) ? arrayShuffle : baseShuffle; + return func(collection); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + if (collection == null) { + return 0; + } + if (isArrayLike(collection)) { + return isString(collection) ? stringSize(collection) : collection.length; + } + var tag = getTag(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return baseKeys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, guard) { + var func = isArray(collection) ? arraySome : baseSome; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ + var sortBy = baseRest(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ + var now = ctxNow || function() { + return root.Date.now(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => Logs 'done saving!' after the two async saves have completed. + */ + function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that invokes `func`, with up to `n` arguments, + * ignoring any additional arguments. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new capped function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + n = guard ? undefined : n; + n = (func && n == null) ? func.length : n; + return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => Allows adding up to 4 contacts to the list. + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and `partials` prepended to the arguments it receives. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * function greet(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = baseRest(function(func, thisArg, partials) { + var bitmask = WRAP_BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bind)); + bitmask |= WRAP_PARTIAL_FLAG; + } + return createWrap(func, bitmask, thisArg, partials, holders); + }); + + /** + * Creates a function that invokes the method at `object[key]` with `partials` + * prepended to the arguments it receives. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. See + * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Function + * @param {Object} object The object to invoke the method on. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // Bound with placeholders. + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = baseRest(function(object, key, partials) { + var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bindKey)); + bitmask |= WRAP_PARTIAL_FLAG; + } + return createWrap(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + function curry(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curry.placeholder; + return result; + } + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + function curryRight(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryRight.placeholder; + return result; + } + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + timeWaiting = wait - timeSinceLastCall; + + return maxing + ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + clearTimeout(timerId); + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => Logs 'deferred' after one millisecond. + */ + var defer = baseRest(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => Logs 'later' after one second. + */ + var delay = baseRest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + + /** + * Creates a function that invokes `func` with arguments reversed. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to flip arguments for. + * @returns {Function} Returns the new flipped function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ + function flip(func) { + return createWrap(func, WRAP_FLIP_FLAG); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = MapCache; + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + var args = arguments; + switch (args.length) { + case 0: return !predicate.call(this); + case 1: return !predicate.call(this, args[0]); + case 2: return !predicate.call(this, args[0], args[1]); + case 3: return !predicate.call(this, args[0], args[1], args[2]); + } + return !predicate.apply(this, args); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // => `createApplication` is invoked once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with its arguments transformed. + * + * @static + * @since 4.0.0 + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms=[_.identity]] + * The argument transforms. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var func = _.overArgs(function(x, y) { + * return [x, y]; + * }, [square, doubled]); + * + * func(9, 3); + * // => [81, 6] + * + * func(10, 5); + * // => [100, 10] + */ + var overArgs = castRest(function(func, transforms) { + transforms = (transforms.length == 1 && isArray(transforms[0])) + ? arrayMap(transforms[0], baseUnary(getIteratee())) + : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); + + var funcsLength = transforms.length; + return baseRest(function(args) { + var index = -1, + length = nativeMin(args.length, funcsLength); + + while (++index < length) { + args[index] = transforms[index].call(this, args[index]); + } + return apply(func, this, args); + }); + }); + + /** + * Creates a function that invokes `func` with `partials` prepended to the + * arguments it receives. This method is like `_.bind` except it does **not** + * alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @since 0.2.0 + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * function greet(greeting, name) { + * return greeting + ' ' + name; + * } + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // Partially applied with placeholders. + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = baseRest(function(func, partials) { + var holders = replaceHolders(partials, getHolder(partial)); + return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders); + }); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to the arguments it receives. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * function greet(greeting, name) { + * return greeting + ' ' + name; + * } + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // Partially applied with placeholders. + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = baseRest(function(func, partials) { + var holders = replaceHolders(partials, getHolder(partialRight)); + return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders); + }); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified `indexes` where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, [2, 0, 1]); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + */ + var rearg = flatRest(function(func, indexes) { + return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as + * an array. + * + * **Note:** This method is based on the + * [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = start === undefined ? start : toInteger(start); + return baseRest(func, start); + } + + /** + * Creates a function that invokes `func` with the `this` binding of the + * create function and an array of arguments much like + * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). + * + * **Note:** This method is based on the + * [spread operator](https://mdn.io/spread_operator). + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Function + * @param {Function} func The function to spread arguments over. + * @param {number} [start=0] The start position of the spread. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = start == null ? 0 : nativeMax(toInteger(start), 0); + return baseRest(function(args) { + var array = args[start], + otherArgs = castSlice(args, 0, start); + + if (array) { + arrayPush(otherArgs, array); + } + return apply(func, this, otherArgs); + }); + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide `options` to indicate whether `func` + * should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + + /** + * Creates a function that accepts up to one argument, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + * @example + * + * _.map(['6', '8', '10'], _.unary(parseInt)); + * // => [6, 8, 10] + */ + function unary(func) { + return ary(func, 1); + } + + /** + * Creates a function that provides `value` to `wrapper` as its first + * argument. Any additional arguments provided to the function are appended + * to those provided to the `wrapper`. The wrapper is invoked with the `this` + * binding of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {*} value The value to wrap. + * @param {Function} [wrapper=identity] The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

    ' + func(text) + '

    '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

    fred, barney, & pebbles

    ' + */ + function wrap(value, wrapper) { + return partial(castFunction(wrapper), value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + return baseClone(value, CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined`, + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @see _.cloneDeepWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ + function cloneWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @see _.cloneWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ + function cloneDeepWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * Checks if `object` conforms to `source` by invoking the predicate + * properties of `source` with the corresponding property values of `object`. + * + * **Note:** This method is equivalent to `_.conforms` when `source` is + * partially applied. + * + * @static + * @memberOf _ + * @since 4.14.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); + * // => true + * + * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); + * // => false + */ + function conformsTo(object, source) { + return source == null || baseConformsTo(object, source, keys(source)); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + * @see _.lt + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + var gt = createRelationalOperation(baseGt); + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to + * `other`, else `false`. + * @see _.lte + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + var gte = createRelationalOperation(function(value, other) { + return value >= other; + }); + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ + var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; + + /** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); + } + + /** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && + (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || + isBuffer(value) || isTypedArray(value) || isArguments(value))) { + return !value.length; + } + var tag = getTag(value); + if (tag == mapTag || tag == setTag) { + return !value.size; + } + if (isPrototype(value)) { + return !baseKeys(value).length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ + function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + if (!isObjectLike(value)) { + return false; + } + var tag = baseGetTag(value); + return tag == errorTag || tag == domExcTag || + (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on + * [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MIN_VALUE); + * // => true + * + * _.isFinite(Infinity); + * // => false + * + * _.isFinite('3'); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on + * [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ + function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + + /** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. + * + * **Note:** This method is equivalent to `_.matches` when `source` is + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.isMatch(object, { 'b': 2 }); + * // => true + * + * _.isMatch(object, { 'b': 1 }); + * // => false + */ + function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); + } + + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ + function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseIsMatch(object, source, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a pristine native function. + * + * **Note:** This method can't reliably detect native functions in the presence + * of the core-js package because core-js circumvents this kind of detection. + * Despite multiple requests, the core-js maintainer has made it clear: any + * attempt to fix the detection will be obstructed. As a result, we're left + * with little choice but to throw an error. Unfortunately, this also affects + * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), + * which rely on core-js. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (isMaskable(value)) { + throw new Error(CORE_ERROR_TEXT); + } + return baseIsNative(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ + function isNil(value) { + return value == null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on + * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ + function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ + function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; + } + + /** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ + function isWeakSet(value) { + return isObjectLike(value) && baseGetTag(value) == weakSetTag; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + * @see _.gt + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + var lt = createRelationalOperation(baseLt); + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to + * `other`, else `false`. + * @see _.gte + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + var lte = createRelationalOperation(function(value, other) { + return value <= other; + }); + + /** + * Converts `value` to an array. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!value) { + return []; + } + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } + if (symIterator && value[symIterator]) { + return iteratorToArray(value[symIterator]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ + function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; + } + + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toLength(3.2); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3.2'); + * // => 3 + */ + function toLength(value) { + return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toSafeInteger(3.2); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3.2'); + * // => 3 + */ + function toSafeInteger(value) { + return value + ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) + : (value === 0 ? value : 0); + } + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ + var assign = createAssigner(function(object, source) { + if (isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assign + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assignIn({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } + */ + var assignIn = createAssigner(function(object, source) { + copyObject(source, keysIn(source), object); + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keysIn(source), object, customizer); + }); + + /** + * This method is like `_.assign` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignInWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keys(source), object, customizer); + }); + + /** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Array} Returns the picked values. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + */ + var at = flatRest(baseAt); + + /** + * Creates an object that inherits from the `prototype` object. If a + * `properties` object is given, its own enumerable string keyed properties + * are assigned to the created object. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties == null ? result : baseAssign(result, properties); + } + + /** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var defaults = baseRest(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; + }); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaults + * @example + * + * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); + * // => { 'a': { 'b': 2, 'c': 3 } } + */ + var defaultsDeep = baseRest(function(args) { + args.push(undefined, customDefaultsMerge); + return apply(mergeWith, undefined, args); + }); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); + } + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + function findLastKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); + } + + /** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ + function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forIn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. + */ + function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forOwn(object, iteratee) { + return object && baseForOwn(object, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. + */ + function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, getIteratee(iteratee, 3)); + } + + /** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functionsIn + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ + function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); + } + + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functions + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ + function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return object != null && hasPath(object, path, baseHas); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite + * property assignments of previous values. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ + var invert = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + result[value] = key; + }, constant(identity)); + + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` thru `iteratee`. The + * corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Object + * @param {Object} object The object to invert. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ + var invertBy = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + }, getIteratee); + + /** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ + var invoke = baseRest(baseInvoke); + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined`, merging is handled by the + * method instead. The `customizer` is invoked with six arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { 'a': [1], 'b': [2] }; + * var other = { 'a': [3], 'b': [4] }; + * + * _.mergeWith(object, other, customizer); + * // => { 'a': [1, 3], 'b': [2, 4] } + */ + var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable property paths of `object` that are not omitted. + * + * **Note:** This method is considerably slower than `_.pick`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to omit. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ + var omit = flatRest(function(object, paths) { + var result = {}; + if (object == null) { + return result; + } + var isDeep = false; + paths = arrayMap(paths, function(path) { + path = castPath(path, object); + isDeep || (isDeep = path.length > 1); + return path; + }); + copyObject(object, getAllKeysIn(object), result); + if (isDeep) { + result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); + } + var length = paths.length; + while (length--) { + baseUnset(result, paths[length]); + } + return result; + }); + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(getIteratee(predicate))); + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = flatRest(function(object, paths) { + return object == null ? {} : basePick(object, paths); + }); + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = getIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * This method is like `_.get` except that if the resolved value is a + * function it's invoked with the `this` binding of its parent object and + * its result is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + path = castPath(path, object); + + var index = -1, + length = path.length; + + // Ensure the loop is entered when path is empty. + if (!length) { + length = 1; + object = undefined; + } + while (++index < length) { + var value = object == null ? undefined : object[toKey(path[index])]; + if (value === undefined) { + index = length; + value = defaultValue; + } + object = isFunction(value) ? value.call(object) : value; + } + return object; + } + + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); + } + + /** + * This method is like `_.set` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.setWith(object, '[0][1]', 'a', Object); + * // => { '0': { '1': 'a' } } + */ + function setWith(object, path, value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseSet(object, path, value, customizer); + } + + /** + * Creates an array of own enumerable string keyed-value pairs for `object` + * which can be consumed by `_.fromPairs`. If `object` is a map or set, its + * entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entries + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairs(new Foo); + * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) + */ + var toPairs = createToPairs(keys); + + /** + * Creates an array of own and inherited enumerable string keyed-value pairs + * for `object` which can be consumed by `_.fromPairs`. If `object` is a map + * or set, its entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entriesIn + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairsIn(new Foo); + * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) + */ + var toPairsIn = createToPairs(keysIn); + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable string keyed properties thru `iteratee`, with each invocation + * potentially mutating the `accumulator` object. If `accumulator` is not + * provided, a new object with the same `[[Prototype]]` will be used. The + * iteratee is invoked with four arguments: (accumulator, value, key, object). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }, []); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function transform(object, iteratee, accumulator) { + var isArr = isArray(object), + isArrLike = isArr || isBuffer(object) || isTypedArray(object); + + iteratee = getIteratee(iteratee, 4); + if (accumulator == null) { + var Ctor = object && object.constructor; + if (isArrLike) { + accumulator = isArr ? new Ctor : []; + } + else if (isObject(object)) { + accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; + } + else { + accumulator = {}; + } + } + (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Removes the property at `path` of `object`. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 7 } }] }; + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + * + * _.unset(object, ['a', '0', 'b', 'c']); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + */ + function unset(object, path) { + return object == null ? true : baseUnset(object, path); + } + + /** + * This method is like `_.set` except that accepts `updater` to produce the + * value to set. Use `_.updateWith` to customize `path` creation. The `updater` + * is invoked with one argument: (value). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.update(object, 'a[0].b.c', function(n) { return n * n; }); + * console.log(object.a[0].b.c); + * // => 9 + * + * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); + * console.log(object.x[0].y.z); + * // => 0 + */ + function update(object, path, updater) { + return object == null ? object : baseUpdate(object, path, castFunction(updater)); + } + + /** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ + function updateWith(object, path, updater, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); + } + + /** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object == null ? [] : baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable string keyed property + * values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return object == null ? [] : baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ + function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); + } + + /** + * Checks if `n` is between `start` and up to, but not including, `end`. If + * `end` is not specified, it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @since 3.3.0 + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @see _.range, _.rangeRight + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ + function inRange(number, start, end) { + start = toFinite(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + number = toNumber(number); + return baseInRange(number, start, end); + } + + /** + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are + * floats, a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Number + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined; + } + if (floating === undefined) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined; + } + else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined; + } + } + if (lower === undefined && upper === undefined) { + lower = 0; + upper = 1; + } + else { + lower = toFinite(lower); + if (upper === undefined) { + upper = lower; + lower = 0; + } else { + upper = toFinite(upper); + } + } + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + if (floating || lower % 1 || upper % 1) { + var rand = nativeRandom(); + return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); + } + return baseRandom(lower, upper); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); + }); + + /** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ + function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); + } + + /** + * Deburrs `string` by converting + * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters to basic Latin letters and removing + * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = toString(string); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search up to. + * @returns {boolean} Returns `true` if `string` ends with `target`, + * else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = toString(string); + target = baseToString(target); + + var length = string.length; + position = position === undefined + ? length + : baseClamp(toInteger(position), 0, length); + + var end = position; + position -= target.length; + return position >= 0 && string.slice(position, end) == target; + } + + /** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ + function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; + } + + /** + * Converts `string` to + * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__FOO_BAR__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Converts `string`, as space separated words, to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.lowerCase('--Foo-Bar--'); + * // => 'foo bar' + * + * _.lowerCase('fooBar'); + * // => 'foo bar' + * + * _.lowerCase('__FOO_BAR__'); + * // => 'foo bar' + */ + var lowerCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + word.toLowerCase(); + }); + + /** + * Converts the first character of `string` to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.lowerFirst('Fred'); + * // => 'fred' + * + * _.lowerFirst('FRED'); + * // => 'fRED' + */ + var lowerFirst = createCaseFirst('toLowerCase'); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + if (!length || strLength >= length) { + return string; + } + var mid = (length - strLength) / 2; + return ( + createPadding(nativeFloor(mid), chars) + + string + + createPadding(nativeCeil(mid), chars) + ); + } + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padEnd('abc', 6); + * // => 'abc ' + * + * _.padEnd('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padEnd('abc', 3); + * // => 'abc' + */ + function padEnd(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (string + createPadding(length - strLength, chars)) + : string; + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padStart('abc', 6); + * // => ' abc' + * + * _.padStart('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padStart('abc', 3); + * // => 'abc' + */ + function padStart(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (createPadding(length - strLength, chars) + string) + : string; + } + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a + * hexadecimal, in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the + * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category String + * @param {string} string The string to convert. + * @param {number} [radix=10] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + if (guard || radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=1] The number of times to repeat the string. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n, guard) { + if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) { + n = 1; + } else { + n = toInteger(n); + } + return baseRepeat(toString(string), n); + } + + /** + * Replaces matches for `pattern` in `string` with `replacement`. + * + * **Note:** This method is based on + * [`String#replace`](https://mdn.io/String/replace). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to modify. + * @param {RegExp|string} pattern The pattern to replace. + * @param {Function|string} replacement The match replacement. + * @returns {string} Returns the modified string. + * @example + * + * _.replace('Hi Fred', 'Fred', 'Barney'); + * // => 'Hi Barney' + */ + function replace() { + var args = arguments, + string = toString(args[0]); + + return args.length < 3 ? string : string.replace(args[1], args[2]); + } + + /** + * Converts `string` to + * [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--FOO-BAR--'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Splits `string` by `separator`. + * + * **Note:** This method is based on + * [`String#split`](https://mdn.io/String/split). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to split. + * @param {RegExp|string} separator The separator pattern to split by. + * @param {number} [limit] The length to truncate results to. + * @returns {Array} Returns the string segments. + * @example + * + * _.split('a-b-c', '-', 2); + * // => ['a', 'b'] + */ + function split(string, separator, limit) { + if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { + separator = limit = undefined; + } + limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; + if (!limit) { + return []; + } + string = toString(string); + if (string && ( + typeof separator == 'string' || + (separator != null && !isRegExp(separator)) + )) { + separator = baseToString(separator); + if (!separator && hasUnicode(string)) { + return castSlice(stringToArray(string), 0, limit); + } + } + return string.split(separator, limit); + } + + /** + * Converts `string` to + * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @since 3.1.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar--'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__FOO_BAR__'); + * // => 'FOO BAR' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + upperFirst(word); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, + * else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = toString(string); + position = position == null + ? 0 + : baseClamp(toInteger(position), 0, string.length); + + target = baseToString(target); + return string.slice(position, position + target.length) == target; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is given, it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options={}] The options object. + * @param {RegExp} [options.escape=_.templateSettings.escape] + * The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] + * The "evaluate" delimiter. + * @param {Object} [options.imports=_.templateSettings.imports] + * An object to import into the template as free variables. + * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] + * The "interpolate" delimiter. + * @param {string} [options.sourceURL='lodash.templateSources[n]'] + * The sourceURL of the compiled template. + * @param {string} [options.variable='obj'] + * The data object variable name. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the compiled template function. + * @example + * + * // Use the "interpolate" delimiter to create a compiled template. + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // Use the HTML "escape" delimiter to escape data property values. + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': ' +``` + +### In an AMD loader +```js +require(['async'], function(async) {}); +``` + +### Promise and async/await + +I recommend to use [`Aigle`](https://github.com/suguru03/aigle). + +It is optimized for Promise handling and has almost the same functionality as `neo-async`. + +### Node.js + +#### standard + +```bash +$ npm install neo-async +``` +```js +var async = require('neo-async'); +``` + +#### replacement +```bash +$ npm install neo-async +$ ln -s ./node_modules/neo-async ./node_modules/async +``` +```js +var async = require('async'); +``` + +### Bower + +```bash +bower install neo-async +``` + +## Feature + +[JSDoc](http://suguru03.github.io/neo-async/doc/async.html) + +\* not in Async + +### Collections + +- [`each`](http://suguru03.github.io/neo-async/doc/async.each.html) +- [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) +- [`eachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) +- [`forEach`](http://suguru03.github.io/neo-async/doc/async.each.html) -> [`each`](http://suguru03.github.io/neo-async/doc/async.each.html) +- [`forEachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) -> [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) +- [`forEachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) -> [`eachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) +- [`eachOf`](http://suguru03.github.io/neo-async/doc/async.each.html) -> [`each`](http://suguru03.github.io/neo-async/doc/async.each.html) +- [`eachOfSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) -> [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) +- [`eachOfLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) -> [`eachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) +- [`forEachOf`](http://suguru03.github.io/neo-async/doc/async.each.html) -> [`each`](http://suguru03.github.io/neo-async/doc/async.each.html) +- [`forEachOfSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) -> [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) +- [`eachOfLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) -> [`forEachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) +- [`map`](http://suguru03.github.io/neo-async/doc/async.map.html) +- [`mapSeries`](http://suguru03.github.io/neo-async/doc/async.mapSeries.html) +- [`mapLimit`](http://suguru03.github.io/neo-async/doc/async.mapLimit.html) +- [`mapValues`](http://suguru03.github.io/neo-async/doc/async.mapValues.html) +- [`mapValuesSeries`](http://suguru03.github.io/neo-async/doc/async.mapValuesSeries.html) +- [`mapValuesLimit`](http://suguru03.github.io/neo-async/doc/async.mapValuesLimit.html) +- [`filter`](http://suguru03.github.io/neo-async/doc/async.filter.html) +- [`filterSeries`](http://suguru03.github.io/neo-async/doc/async.filterSeries.html) +- [`filterLimit`](http://suguru03.github.io/neo-async/doc/async.filterLimit.html) +- [`select`](http://suguru03.github.io/neo-async/doc/async.filter.html) -> [`filter`](http://suguru03.github.io/neo-async/doc/async.filter.html) +- [`selectSeries`](http://suguru03.github.io/neo-async/doc/async.filterSeries.html) -> [`filterSeries`](http://suguru03.github.io/neo-async/doc/async.filterSeries.html) +- [`selectLimit`](http://suguru03.github.io/neo-async/doc/async.filterLimit.html) -> [`filterLimit`](http://suguru03.github.io/neo-async/doc/async.filterLimit.html) +- [`reject`](http://suguru03.github.io/neo-async/doc/async.reject.html) +- [`rejectSeries`](http://suguru03.github.io/neo-async/doc/async.rejectSeries.html) +- [`rejectLimit`](http://suguru03.github.io/neo-async/doc/async.rejectLimit.html) +- [`detect`](http://suguru03.github.io/neo-async/doc/async.detect.html) +- [`detectSeries`](http://suguru03.github.io/neo-async/doc/async.detectSeries.html) +- [`detectLimit`](http://suguru03.github.io/neo-async/doc/async.detectLimit.html) +- [`find`](http://suguru03.github.io/neo-async/doc/async.detect.html) -> [`detect`](http://suguru03.github.io/neo-async/doc/async.detect.html) +- [`findSeries`](http://suguru03.github.io/neo-async/doc/async.detectSeries.html) -> [`detectSeries`](http://suguru03.github.io/neo-async/doc/async.detectSeries.html) +- [`findLimit`](http://suguru03.github.io/neo-async/doc/async.detectLimit.html) -> [`detectLimit`](http://suguru03.github.io/neo-async/doc/async.detectLimit.html) +- [`pick`](http://suguru03.github.io/neo-async/doc/async.pick.html) * +- [`pickSeries`](http://suguru03.github.io/neo-async/doc/async.pickSeries.html) * +- [`pickLimit`](http://suguru03.github.io/neo-async/doc/async.pickLimit.html) * +- [`omit`](http://suguru03.github.io/neo-async/doc/async.omit.html) * +- [`omitSeries`](http://suguru03.github.io/neo-async/doc/async.omitSeries.html) * +- [`omitLimit`](http://suguru03.github.io/neo-async/doc/async.omitLimit.html) * +- [`reduce`](http://suguru03.github.io/neo-async/doc/async.reduce.html) +- [`inject`](http://suguru03.github.io/neo-async/doc/async.reduce.html) -> [`reduce`](http://suguru03.github.io/neo-async/doc/async.reduce.html) +- [`foldl`](http://suguru03.github.io/neo-async/doc/async.reduce.html) -> [`reduce`](http://suguru03.github.io/neo-async/doc/async.reduce.html) +- [`reduceRight`](http://suguru03.github.io/neo-async/doc/async.reduceRight.html) +- [`foldr`](http://suguru03.github.io/neo-async/doc/async.reduceRight.html) -> [`reduceRight`](http://suguru03.github.io/neo-async/doc/async.reduceRight.html) +- [`transform`](http://suguru03.github.io/neo-async/doc/async.transform.html) +- [`transformSeries`](http://suguru03.github.io/neo-async/doc/async.transformSeries.html) * +- [`transformLimit`](http://suguru03.github.io/neo-async/doc/async.transformLimit.html) * +- [`sortBy`](http://suguru03.github.io/neo-async/doc/async.sortBy.html) +- [`sortBySeries`](http://suguru03.github.io/neo-async/doc/async.sortBySeries.html) * +- [`sortByLimit`](http://suguru03.github.io/neo-async/doc/async.sortByLimit.html) * +- [`some`](http://suguru03.github.io/neo-async/doc/async.some.html) +- [`someSeries`](http://suguru03.github.io/neo-async/doc/async.someSeries.html) +- [`someLimit`](http://suguru03.github.io/neo-async/doc/async.someLimit.html) +- [`any`](http://suguru03.github.io/neo-async/doc/async.some.html) -> [`some`](http://suguru03.github.io/neo-async/doc/async.some.html) +- [`anySeries`](http://suguru03.github.io/neo-async/doc/async.someSeries.html) -> [`someSeries`](http://suguru03.github.io/neo-async/doc/async.someSeries.html) +- [`anyLimit`](http://suguru03.github.io/neo-async/doc/async.someLimit.html) -> [`someLimit`](http://suguru03.github.io/neo-async/doc/async.someLimit.html) +- [`every`](http://suguru03.github.io/neo-async/doc/async.every.html) +- [`everySeries`](http://suguru03.github.io/neo-async/doc/async.everySeries.html) +- [`everyLimit`](http://suguru03.github.io/neo-async/doc/async.everyLimit.html) +- [`all`](http://suguru03.github.io/neo-async/doc/async.every.html) -> [`every`](http://suguru03.github.io/neo-async/doc/async.every.html) +- [`allSeries`](http://suguru03.github.io/neo-async/doc/async.everySeries.html) -> [`every`](http://suguru03.github.io/neo-async/doc/async.everySeries.html) +- [`allLimit`](http://suguru03.github.io/neo-async/doc/async.everyLimit.html) -> [`every`](http://suguru03.github.io/neo-async/doc/async.everyLimit.html) +- [`concat`](http://suguru03.github.io/neo-async/doc/async.concat.html) +- [`concatSeries`](http://suguru03.github.io/neo-async/doc/async.concatSeries.html) +- [`concatLimit`](http://suguru03.github.io/neo-async/doc/async.concatLimit.html) * + +### Control Flow + +- [`parallel`](http://suguru03.github.io/neo-async/doc/async.parallel.html) +- [`series`](http://suguru03.github.io/neo-async/doc/async.series.html) +- [`parallelLimit`](http://suguru03.github.io/neo-async/doc/async.series.html) +- [`tryEach`](http://suguru03.github.io/neo-async/doc/async.tryEach.html) +- [`waterfall`](http://suguru03.github.io/neo-async/doc/async.waterfall.html) +- [`angelFall`](http://suguru03.github.io/neo-async/doc/async.angelFall.html) * +- [`angelfall`](http://suguru03.github.io/neo-async/doc/async.angelFall.html) -> [`angelFall`](http://suguru03.github.io/neo-async/doc/async.angelFall.html) * +- [`whilst`](#whilst) +- [`doWhilst`](#doWhilst) +- [`until`](#until) +- [`doUntil`](#doUntil) +- [`during`](#during) +- [`doDuring`](#doDuring) +- [`forever`](#forever) +- [`compose`](#compose) +- [`seq`](#seq) +- [`applyEach`](#applyEach) +- [`applyEachSeries`](#applyEachSeries) +- [`queue`](#queue) +- [`priorityQueue`](#priorityQueue) +- [`cargo`](#cargo) +- [`auto`](#auto) +- [`autoInject`](#autoInject) +- [`retry`](#retry) +- [`retryable`](#retryable) +- [`iterator`](#iterator) +- [`times`](http://suguru03.github.io/neo-async/doc/async.times.html) +- [`timesSeries`](http://suguru03.github.io/neo-async/doc/async.timesSeries.html) +- [`timesLimit`](http://suguru03.github.io/neo-async/doc/async.timesLimit.html) +- [`race`](#race) + +### Utils +- [`apply`](#apply) +- [`setImmediate`](#setImmediate) +- [`nextTick`](#nextTick) +- [`memoize`](#memoize) +- [`unmemoize`](#unmemoize) +- [`ensureAsync`](#ensureAsync) +- [`constant`](#constant) +- [`asyncify`](#asyncify) +- [`wrapSync`](#asyncify) -> [`asyncify`](#asyncify) +- [`log`](#log) +- [`dir`](#dir) +- [`timeout`](http://suguru03.github.io/neo-async/doc/async.timeout.html) +- [`reflect`](#reflect) +- [`reflectAll`](#reflectAll) +- [`createLogger`](#createLogger) + +## Mode +- [`safe`](#safe) * +- [`fast`](#fast) * + +## Benchmark + +[Benchmark: Async vs Neo-Async](http://suguru03.hatenablog.com/entry/2016/06/10/135559) + +### How to check + +```bash +$ node perf +``` + +### Environment + +* Darwin 17.3.0 x64 +* Node.js v8.9.4 +* async v2.6.0 +* neo-async v2.5.0 +* benchmark v2.1.4 + +### Result + +The value is the ratio (Neo-Async/Async) of the average speed. + +#### Collections +|function|benchmark| +|---|--:| +|each/forEach|2.43| +|eachSeries/forEachSeries|1.75| +|eachLimit/forEachLimit|1.68| +|eachOf|3.29| +|eachOfSeries|1.50| +|eachOfLimit|1.59| +|map|3.95| +|mapSeries|1.81| +|mapLimit|1.27| +|mapValues|2.73| +|mapValuesSeries|1.59| +|mapValuesLimit|1.23| +|filter|3.00| +|filterSeries|1.74| +|filterLimit|1.17| +|reject|4.59| +|rejectSeries|2.31| +|rejectLimit|1.58| +|detect|4.30| +|detectSeries|1.86| +|detectLimit|1.32| +|reduce|1.82| +|transform|2.46| +|sortBy|4.08| +|some|2.19| +|someSeries|1.83| +|someLimit|1.32| +|every|2.09| +|everySeries|1.84| +|everyLimit|1.35| +|concat|3.79| +|concatSeries|4.45| + +#### Control Flow +|funciton|benchmark| +|---|--:| +|parallel|2.93| +|series|1.96| +|waterfall|1.29| +|whilst|1.00| +|doWhilst|1.12| +|until|1.12| +|doUntil|1.12| +|during|1.18| +|doDuring|2.42| +|times|4.25| +|auto|1.97| + + +## License +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fsuguru03%2Fneo-async.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fsuguru03%2Fneo-async?ref=badge_large) diff --git a/libs/events/node_modules/neo-async/all.js b/libs/events/node_modules/neo-async/all.js new file mode 100644 index 000000000..dad54e7fe --- /dev/null +++ b/libs/events/node_modules/neo-async/all.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').all; diff --git a/libs/events/node_modules/neo-async/allLimit.js b/libs/events/node_modules/neo-async/allLimit.js new file mode 100644 index 000000000..d9d7aaa16 --- /dev/null +++ b/libs/events/node_modules/neo-async/allLimit.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').allLimit; diff --git a/libs/events/node_modules/neo-async/allSeries.js b/libs/events/node_modules/neo-async/allSeries.js new file mode 100644 index 000000000..2a7a8ba88 --- /dev/null +++ b/libs/events/node_modules/neo-async/allSeries.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').allSeries; diff --git a/libs/events/node_modules/neo-async/angelFall.js b/libs/events/node_modules/neo-async/angelFall.js new file mode 100644 index 000000000..476c23ecc --- /dev/null +++ b/libs/events/node_modules/neo-async/angelFall.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').angelfall; diff --git a/libs/events/node_modules/neo-async/any.js b/libs/events/node_modules/neo-async/any.js new file mode 100644 index 000000000..d6b07bb54 --- /dev/null +++ b/libs/events/node_modules/neo-async/any.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').any; diff --git a/libs/events/node_modules/neo-async/anyLimit.js b/libs/events/node_modules/neo-async/anyLimit.js new file mode 100644 index 000000000..34114f888 --- /dev/null +++ b/libs/events/node_modules/neo-async/anyLimit.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').anyLimit; diff --git a/libs/events/node_modules/neo-async/anySeries.js b/libs/events/node_modules/neo-async/anySeries.js new file mode 100644 index 000000000..bb3781fd5 --- /dev/null +++ b/libs/events/node_modules/neo-async/anySeries.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').anySeries; diff --git a/libs/events/node_modules/neo-async/apply.js b/libs/events/node_modules/neo-async/apply.js new file mode 100644 index 000000000..41135e218 --- /dev/null +++ b/libs/events/node_modules/neo-async/apply.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').apply; diff --git a/libs/events/node_modules/neo-async/applyEach.js b/libs/events/node_modules/neo-async/applyEach.js new file mode 100644 index 000000000..292bd1c06 --- /dev/null +++ b/libs/events/node_modules/neo-async/applyEach.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').applyEach; diff --git a/libs/events/node_modules/neo-async/applyEachSeries.js b/libs/events/node_modules/neo-async/applyEachSeries.js new file mode 100644 index 000000000..0aece7cd3 --- /dev/null +++ b/libs/events/node_modules/neo-async/applyEachSeries.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./async').applyEachSeries; diff --git a/libs/events/node_modules/neo-async/async.js b/libs/events/node_modules/neo-async/async.js new file mode 100644 index 000000000..e78eb1681 --- /dev/null +++ b/libs/events/node_modules/neo-async/async.js @@ -0,0 +1,9184 @@ +(function(global, factory) { + /*jshint -W030 */ + 'use strict'; + typeof exports === 'object' && typeof module !== 'undefined' + ? factory(exports) + : typeof define === 'function' && define.amd + ? define(['exports'], factory) + : global.async + ? factory((global.neo_async = global.neo_async || {})) + : factory((global.async = global.async || {})); +})(this, function(exports) { + 'use strict'; + + var noop = function noop() {}; + var throwError = function throwError() { + throw new Error('Callback was already called.'); + }; + + var DEFAULT_TIMES = 5; + var DEFAULT_INTERVAL = 0; + + var obj = 'object'; + var func = 'function'; + var isArray = Array.isArray; + var nativeKeys = Object.keys; + var nativePush = Array.prototype.push; + var iteratorSymbol = typeof Symbol === func && Symbol.iterator; + + var nextTick, asyncNextTick, asyncSetImmediate; + createImmediate(); + + /** + * @memberof async + * @namespace each + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(); + * }, num * 10); + * }; + * async.each(array, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(); + * }, num * 10); + * }; + * async.each(array, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [[1, 0], [2, 2], [3, 1]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(); + * }, num * 10); + * }; + * async.each(object, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(); + * }, num * 10); + * }; + * async.each(object, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] + * }); + * + * @example + * + * // break + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num !== 2); + * }, num * 10); + * }; + * async.each(array, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [1, 2] + * }); + * + */ + var each = createEach(arrayEach, baseEach, symbolEach); + + /** + * @memberof async + * @namespace map + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.map(array, iterator, function(err, res) { + * console.log(res); // [1, 3, 2]; + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num); + * }, num * 10); + * }; + * async.map(array, iterator, function(err, res) { + * console.log(res); // [1, 3, 2] + * console.log(order); // [[1, 0], [2, 2], [3, 1]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.map(object, iterator, function(err, res) { + * console.log(res); // [1, 3, 2] + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.map(object, iterator, function(err, res) { + * console.log(res); // [1, 3, 2] + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] + * }); + * + */ + var map = createMap(arrayEachIndex, baseEachIndex, symbolEachIndex, true); + + /** + * @memberof async + * @namespace mapValues + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapValues(array, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3, '2': 2 } + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num); + * }, num * 10); + * }; + * async.mapValues(array, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3, '2': 2 } + * console.log(order); // [[1, 0], [2, 2], [3, 1]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapValues(object, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3, c: 2 } + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.mapValues(object, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3, c: 2 } + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] + * }); + * + */ + var mapValues = createMap(arrayEachIndex, baseEachKey, symbolEachKey, false); + + /** + * @memberof async + * @namespace filter + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filter(array, iterator, function(err, res) { + * console.log(res); // [1, 3]; + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filter(array, iterator, function(err, res) { + * console.log(res); // [1, 3]; + * console.log(order); // [[1, 0], [2, 2], [3, 1]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filter(object, iterator, function(err, res) { + * console.log(res); // [1, 3]; + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filter(object, iterator, function(err, res) { + * console.log(res); // [1, 3]; + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] + * }); + * + */ + var filter = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, true); + + /** + * @memberof async + * @namespace filterSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filterSeries(array, iterator, function(err, res) { + * console.log(res); // [1, 3]; + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filterSeries(array, iterator, function(err, res) { + * console.log(res); // [1, 3] + * console.log(order); // [[1, 0], [3, 1], [2, 2]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filterSeries(object, iterator, function(err, res) { + * console.log(res); // [1, 3] + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filterSeries(object, iterator, function(err, res) { + * console.log(res); // [1, 3] + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] + * }); + * + */ + var filterSeries = createFilterSeries(true); + + /** + * @memberof async + * @namespace filterLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filterLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [1, 5, 3] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filterLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [1, 5, 3] + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filterLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [1, 5, 3] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.filterLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [1, 5, 3] + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + */ + var filterLimit = createFilterLimit(true); + + /** + * @memberof async + * @namespace reject + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.reject(array, iterator, function(err, res) { + * console.log(res); // [2]; + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.reject(array, iterator, function(err, res) { + * console.log(res); // [2]; + * console.log(order); // [[1, 0], [2, 2], [3, 1]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.reject(object, iterator, function(err, res) { + * console.log(res); // [2]; + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.reject(object, iterator, function(err, res) { + * console.log(res); // [2]; + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] + * }); + * + */ + var reject = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, false); + + /** + * @memberof async + * @namespace rejectSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.rejectSeries(array, iterator, function(err, res) { + * console.log(res); // [2]; + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.rejectSeries(object, iterator, function(err, res) { + * console.log(res); // [2]; + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.rejectSeries(object, iterator, function(err, res) { + * console.log(res); // [2]; + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] + * }); + * + */ + var rejectSeries = createFilterSeries(false); + + /** + * @memberof async + * @namespace rejectLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.rejectLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [4, 2] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.rejectLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [4, 2] + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.rejectLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [4, 2] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.rejectLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [4, 2] + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + */ + var rejectLimit = createFilterLimit(false); + + /** + * @memberof async + * @namespace detect + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detect(array, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [1] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detect(array, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [[1, 0]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detect(object, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [1] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detect(object, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [[1, 'a']] + * }); + * + */ + var detect = createDetect(arrayEachValue, baseEachValue, symbolEachValue, true); + + /** + * @memberof async + * @namespace detectSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detectSeries(array, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [1] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detectSeries(array, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [[1, 0]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detectSeries(object, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [1] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detectSeries(object, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [[1, 'a']] + * }); + * + */ + var detectSeries = createDetectSeries(true); + + /** + * @memberof async + * @namespace detectLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detectLimit(array, 2, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [1] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detectLimit(array, 2, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [[1, 0]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detectLimit(object, 2, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [1] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.detectLimit(object, 2, iterator, function(err, res) { + * console.log(res); // 1 + * console.log(order); // [[1, 'a']] + * }); + * + */ + var detectLimit = createDetectLimit(true); + + /** + * @memberof async + * @namespace every + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.every(array, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [1, 2] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.every(array, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [[1, 0], [2, 2]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.every(object, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [1, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.every(object, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [[1, 'a'], [2, 'c']] + * }); + * + */ + var every = createEvery(arrayEachValue, baseEachValue, symbolEachValue); + + /** + * @memberof async + * @namespace everySeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.everySeries(array, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.everySeries(array, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [[1, 0], [3, 1], [2, 2]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.everySeries(object, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.everySeries(object, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [[1, 'a'], [3, 'b'] [2, 'c']] + * }); + * + */ + var everySeries = createEverySeries(); + + /** + * @memberof async + * @namespace everyLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.everyLimit(array, 2, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [1, 3, 5, 2] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.everyLimit(array, 2, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.everyLimit(object, 2, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [1, 3, 5, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.everyLimit(object, 2, iterator, function(err, res) { + * console.log(res); // false + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e']] + * }); + * + */ + var everyLimit = createEveryLimit(); + + /** + * @memberof async + * @namespace pick + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2, 4]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pick(array, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3 } + * console.log(order); // [1, 2, 3, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2, 4]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pick(array, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3 } + * console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pick(object, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3 } + * console.log(order); // [1, 2, 3, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pick(object, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3 } + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']] + * }); + * + */ + var pick = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, true); + + /** + * @memberof async + * @namespace pickSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2, 4]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pickSeries(array, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3 } + * console.log(order); // [1, 3, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2, 4]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pickSeries(array, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3 } + * console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pickSeries(object, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3 } + * console.log(order); // [1, 3, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pickSeries(object, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3 } + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']] + * }); + * + */ + var pickSeries = createPickSeries(true); + + /** + * @memberof async + * @namespace pickLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pickLimit(array, 2, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 5, '2': 3 } + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pickLimit(array, 2, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 5, '2': 3 } + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pickLimit(object, 2, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 5, c: 3 } + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.pickLimit(object, 2, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 5, c: 3 } + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + */ + var pickLimit = createPickLimit(true); + + /** + * @memberof async + * @namespace omit + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2, 4]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omit(array, iterator, function(err, res) { + * console.log(res); // { '2': 2, '3': 4 } + * console.log(order); // [1, 2, 3, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2, 4]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omit(array, iterator, function(err, res) { + * console.log(res); // { '2': 2, '3': 4 } + * console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omit(object, iterator, function(err, res) { + * console.log(res); // { c: 2, d: 4 } + * console.log(order); // [1, 2, 3, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omit(object, iterator, function(err, res) { + * console.log(res); // { c: 2, d: 4 } + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']] + * }); + * + */ + var omit = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, false); + + /** + * @memberof async + * @namespace omitSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2, 4]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omitSeries(array, iterator, function(err, res) { + * console.log(res); // { '2': 2, '3': 4 } + * console.log(order); // [1, 3, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2, 4]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omitSeries(array, iterator, function(err, res) { + * console.log(res); // { '2': 2, '3': 4 } + * console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omitSeries(object, iterator, function(err, res) { + * console.log(res); // { c: 2, d: 4 } + * console.log(order); // [1, 3, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omitSeries(object, iterator, function(err, res) { + * console.log(res); // { c: 2, d: 4 } + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']] + * }); + * + */ + var omitSeries = createPickSeries(false); + + /** + * @memberof async + * @namespace omitLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omitLimit(array, 2, iterator, function(err, res) { + * console.log(res); // { '3': 4, '4': 2 } + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omitLimit(array, 2, iterator, function(err, res) { + * console.log(res); // { '3': 4, '4': 2 } + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omitLimit(object, 2, iterator, function(err, res) { + * console.log(res); // { d: 4, e: 2 } + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.omitLimit(object, 2, iterator, function(err, res) { + * console.log(res); // { d: 4, e: 2 } + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + */ + var omitLimit = createPickLimit(false); + + /** + * @memberof async + * @namespace transform + * @param {Array|Object} collection + * @param {Array|Object|Function} [accumulator] + * @param {Function} [iterator] + * @param {Function} [callback] + * @example + * + * // array + * var order = []; + * var collection = [1, 3, 2, 4]; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * result.push(num) + * done(); + * }, num * 10); + * }; + * async.transform(collection, iterator, function(err, res) { + * console.log(res); // [1, 2, 3, 4] + * console.log(order); // [1, 2, 3, 4] + * }); + * + * @example + * + * // array with index and accumulator + * var order = []; + * var collection = [1, 3, 2, 4]; + * var iterator = function(result, num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * result[index] = num; + * done(); + * }, num * 10); + * }; + * async.transform(collection, {}, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 } + * console.log(order); // [[1, 0], [2, 2], [3, 1], [4, 3]] + * }); + * + * @example + * + * // object with accumulator + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * result.push(num); + * done(); + * }, num * 10); + * }; + * async.transform(collection, [], iterator, function(err, res) { + * console.log(res); // [1, 2, 3, 4] + * console.log(order); // [1, 2, 3, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(result, num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * result[key] = num; + * done(); + * }, num * 10); + * }; + * async.transform(collection, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3, c: 2, d: 4 } + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']] + * }); + * + */ + var transform = createTransform(arrayEachResult, baseEachResult, symbolEachResult); + + /** + * @memberof async + * @namespace sortBy + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.sortBy(array, iterator, function(err, res) { + * console.log(res); // [1, 2, 3]; + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num); + * }, num * 10); + * }; + * async.sortBy(array, iterator, function(err, res) { + * console.log(res); // [1, 2, 3] + * console.log(order); // [[1, 0], [2, 2], [3, 1]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.sortBy(object, iterator, function(err, res) { + * console.log(res); // [1, 2, 3] + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.sortBy(object, iterator, function(err, res) { + * console.log(res); // [1, 2, 3] + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] + * }); + * + */ + var sortBy = createSortBy(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue); + + /** + * @memberof async + * @namespace concat + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, [num]); + * }, num * 10); + * }; + * async.concat(array, iterator, function(err, res) { + * console.log(res); // [1, 2, 3]; + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, [num]); + * }, num * 10); + * }; + * async.concat(array, iterator, function(err, res) { + * console.log(res); // [1, 2, 3] + * console.log(order); // [[1, 0], [2, 2], [3, 1]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, [num]); + * }, num * 10); + * }; + * async.concat(object, iterator, function(err, res) { + * console.log(res); // [1, 2, 3] + * console.log(order); // [1, 2, 3] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, [num]); + * }, num * 10); + * }; + * async.concat(object, iterator, function(err, res) { + * console.log(res); // [1, 2, 3] + * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']] + * }); + * + */ + var concat = createConcat(arrayEachIndex, baseEachIndex, symbolEachIndex); + + /** + * @memberof async + * @namespace groupBy + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [4.2, 6.4, 6.1]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupBy(array, iterator, function(err, res) { + * console.log(res); // { '4': [4.2], '6': [6.1, 6.4] } + * console.log(order); // [4.2, 6.1, 6.4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [4.2, 6.4, 6.1]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupBy(array, iterator, function(err, res) { + * console.log(res); // { '4': [4.2], '6': [6.1, 6.4] } + * console.log(order); // [[4.2, 0], [6.1, 2], [6.4, 1]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 4.2, b: 6.4, c: 6.1 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupBy(object, iterator, function(err, res) { + * console.log(res); // { '4': [4.2], '6': [6.1, 6.4] } + * console.log(order); // [4.2, 6.1, 6.4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 4.2, b: 6.4, c: 6.1 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupBy(object, iterator, function(err, res) { + * console.log(res); // { '4': [4.2], '6': [6.1, 6.4] } + * console.log(order); // [[4.2, 'a'], [6.1, 'c'], [6.4, 'b']] + * }); + * + */ + var groupBy = createGroupBy(arrayEachValue, baseEachValue, symbolEachValue); + + /** + * @memberof async + * @namespace parallel + * @param {Array|Object} tasks - functions + * @param {Function} callback + * @example + * + * var order = []; + * var tasks = [ + * function(done) { + * setTimeout(function() { + * order.push(1); + * done(null, 1); + * }, 10); + * }, + * function(done) { + * setTimeout(function() { + * order.push(2); + * done(null, 2); + * }, 30); + * }, + * function(done) { + * setTimeout(function() { + * order.push(3); + * done(null, 3); + * }, 40); + * }, + * function(done) { + * setTimeout(function() { + * order.push(4); + * done(null, 4); + * }, 20); + * } + * ]; + * async.parallel(tasks, function(err, res) { + * console.log(res); // [1, 2, 3, 4]; + * console.log(order); // [1, 4, 2, 3] + * }); + * + * @example + * + * var order = []; + * var tasks = { + * 'a': function(done) { + * setTimeout(function() { + * order.push(1); + * done(null, 1); + * }, 10); + * }, + * 'b': function(done) { + * setTimeout(function() { + * order.push(2); + * done(null, 2); + * }, 30); + * }, + * 'c': function(done) { + * setTimeout(function() { + * order.push(3); + * done(null, 3); + * }, 40); + * }, + * 'd': function(done) { + * setTimeout(function() { + * order.push(4); + * done(null, 4); + * }, 20); + * } + * }; + * async.parallel(tasks, function(err, res) { + * console.log(res); // { a: 1, b: 2, c: 3, d:4 } + * console.log(order); // [1, 4, 2, 3] + * }); + * + */ + var parallel = createParallel(arrayEachFunc, baseEachFunc); + + /** + * @memberof async + * @namespace applyEach + */ + var applyEach = createApplyEach(map); + + /** + * @memberof async + * @namespace applyEachSeries + */ + var applyEachSeries = createApplyEach(mapSeries); + + /** + * @memberof async + * @namespace log + */ + var log = createLogger('log'); + + /** + * @memberof async + * @namespace dir + */ + var dir = createLogger('dir'); + + /** + * @version 2.6.2 + * @namespace async + */ + var index = { + VERSION: '2.6.2', + + // Collections + each: each, + eachSeries: eachSeries, + eachLimit: eachLimit, + forEach: each, + forEachSeries: eachSeries, + forEachLimit: eachLimit, + eachOf: each, + eachOfSeries: eachSeries, + eachOfLimit: eachLimit, + forEachOf: each, + forEachOfSeries: eachSeries, + forEachOfLimit: eachLimit, + map: map, + mapSeries: mapSeries, + mapLimit: mapLimit, + mapValues: mapValues, + mapValuesSeries: mapValuesSeries, + mapValuesLimit: mapValuesLimit, + filter: filter, + filterSeries: filterSeries, + filterLimit: filterLimit, + select: filter, + selectSeries: filterSeries, + selectLimit: filterLimit, + reject: reject, + rejectSeries: rejectSeries, + rejectLimit: rejectLimit, + detect: detect, + detectSeries: detectSeries, + detectLimit: detectLimit, + find: detect, + findSeries: detectSeries, + findLimit: detectLimit, + pick: pick, + pickSeries: pickSeries, + pickLimit: pickLimit, + omit: omit, + omitSeries: omitSeries, + omitLimit: omitLimit, + reduce: reduce, + inject: reduce, + foldl: reduce, + reduceRight: reduceRight, + foldr: reduceRight, + transform: transform, + transformSeries: transformSeries, + transformLimit: transformLimit, + sortBy: sortBy, + sortBySeries: sortBySeries, + sortByLimit: sortByLimit, + some: some, + someSeries: someSeries, + someLimit: someLimit, + any: some, + anySeries: someSeries, + anyLimit: someLimit, + every: every, + everySeries: everySeries, + everyLimit: everyLimit, + all: every, + allSeries: everySeries, + allLimit: everyLimit, + concat: concat, + concatSeries: concatSeries, + concatLimit: concatLimit, + groupBy: groupBy, + groupBySeries: groupBySeries, + groupByLimit: groupByLimit, + + // Control Flow + parallel: parallel, + series: series, + parallelLimit: parallelLimit, + tryEach: tryEach, + waterfall: waterfall, + angelFall: angelFall, + angelfall: angelFall, + whilst: whilst, + doWhilst: doWhilst, + until: until, + doUntil: doUntil, + during: during, + doDuring: doDuring, + forever: forever, + compose: compose, + seq: seq, + applyEach: applyEach, + applyEachSeries: applyEachSeries, + queue: queue, + priorityQueue: priorityQueue, + cargo: cargo, + auto: auto, + autoInject: autoInject, + retry: retry, + retryable: retryable, + iterator: iterator, + times: times, + timesSeries: timesSeries, + timesLimit: timesLimit, + race: race, + + // Utils + apply: apply, + nextTick: asyncNextTick, + setImmediate: asyncSetImmediate, + memoize: memoize, + unmemoize: unmemoize, + ensureAsync: ensureAsync, + constant: constant, + asyncify: asyncify, + wrapSync: asyncify, + log: log, + dir: dir, + reflect: reflect, + reflectAll: reflectAll, + timeout: timeout, + createLogger: createLogger, + + // Mode + safe: safe, + fast: fast + }; + + exports['default'] = index; + baseEachSync( + index, + function(func, key) { + exports[key] = func; + }, + nativeKeys(index) + ); + + /** + * @private + */ + function createImmediate(safeMode) { + var delay = function delay(fn) { + var args = slice(arguments, 1); + setTimeout(function() { + fn.apply(null, args); + }); + }; + asyncSetImmediate = typeof setImmediate === func ? setImmediate : delay; + if (typeof process === obj && typeof process.nextTick === func) { + nextTick = /^v0.10/.test(process.version) ? asyncSetImmediate : process.nextTick; + asyncNextTick = /^v0/.test(process.version) ? asyncSetImmediate : process.nextTick; + } else { + asyncNextTick = nextTick = asyncSetImmediate; + } + if (safeMode === false) { + nextTick = function(cb) { + cb(); + }; + } + } + + /* sync functions based on lodash */ + + /** + * Converts `arguments` to an array. + * + * @private + * @param {Array} array = The array to slice. + */ + function createArray(array) { + var index = -1; + var size = array.length; + var result = Array(size); + + while (++index < size) { + result[index] = array[index]; + } + return result; + } + + /** + * Create an array from `start` + * + * @private + * @param {Array} array - The array to slice. + * @param {number} start - The start position. + */ + function slice(array, start) { + var end = array.length; + var index = -1; + var size = end - start; + if (size <= 0) { + return []; + } + var result = Array(size); + + while (++index < size) { + result[index] = array[index + start]; + } + return result; + } + + /** + * @private + * @param {Object} object + */ + function objectClone(object) { + var keys = nativeKeys(object); + var size = keys.length; + var index = -1; + var result = {}; + + while (++index < size) { + var key = keys[index]; + result[key] = object[key]; + } + return result; + } + + /** + * Create an array with all falsey values removed. + * + * @private + * @param {Array} array - The array to compact. + */ + function compact(array) { + var index = -1; + var size = array.length; + var result = []; + + while (++index < size) { + var value = array[index]; + if (value) { + result[result.length] = value; + } + } + return result; + } + + /** + * Create an array of reverse sequence. + * + * @private + * @param {Array} array - The array to reverse. + */ + function reverse(array) { + var index = -1; + var size = array.length; + var result = Array(size); + var resIndex = size; + + while (++index < size) { + result[--resIndex] = array[index]; + } + return result; + } + + /** + * Checks if key exists in object property. + * + * @private + * @param {Object} object - The object to inspect. + * @param {string} key - The key to check. + */ + function has(object, key) { + return object.hasOwnProperty(key); + } + + /** + * Check if target exists in array. + * @private + * @param {Array} array + * @param {*} target + */ + function notInclude(array, target) { + var index = -1; + var size = array.length; + + while (++index < size) { + if (array[index] === target) { + return false; + } + } + return true; + } + + /** + * @private + * @param {Array} array - The array to iterate over. + * @param {Function} iterator - The function invoked per iteration. + */ + function arrayEachSync(array, iterator) { + var index = -1; + var size = array.length; + + while (++index < size) { + iterator(array[index], index); + } + return array; + } + + /** + * @private + * @param {Object} object - The object to iterate over. + * @param {Function} iterator - The function invoked per iteration. + * @param {Array} keys + */ + function baseEachSync(object, iterator, keys) { + var index = -1; + var size = keys.length; + + while (++index < size) { + var key = keys[index]; + iterator(object[key], key); + } + return object; + } + + /** + * @private + * @param {number} n + * @param {Function} iterator + */ + function timesSync(n, iterator) { + var index = -1; + while (++index < n) { + iterator(index); + } + } + + /** + * @private + * @param {Array} array + * @param {number[]} criteria + */ + function sortByCriteria(array, criteria) { + var l = array.length; + var indices = Array(l); + var i; + for (i = 0; i < l; i++) { + indices[i] = i; + } + quickSort(criteria, 0, l - 1, indices); + var result = Array(l); + for (var n = 0; n < l; n++) { + i = indices[n]; + result[n] = i === undefined ? array[n] : array[i]; + } + return result; + } + + function partition(array, i, j, mid, indices) { + var l = i; + var r = j; + while (l <= r) { + i = l; + while (l < r && array[l] < mid) { + l++; + } + while (r >= i && array[r] >= mid) { + r--; + } + if (l > r) { + break; + } + swap(array, indices, l++, r--); + } + return l; + } + + function swap(array, indices, l, r) { + var n = array[l]; + array[l] = array[r]; + array[r] = n; + var i = indices[l]; + indices[l] = indices[r]; + indices[r] = i; + } + + function quickSort(array, i, j, indices) { + if (i === j) { + return; + } + var k = i; + while (++k <= j && array[i] === array[k]) { + var l = k - 1; + if (indices[l] > indices[k]) { + var index = indices[l]; + indices[l] = indices[k]; + indices[k] = index; + } + } + if (k > j) { + return; + } + var p = array[i] > array[k] ? i : k; + k = partition(array, i, j, array[p], indices); + quickSort(array, i, k - 1, indices); + quickSort(array, k, j, indices); + } + + /** + * @Private + */ + function makeConcatResult(array) { + var result = []; + arrayEachSync(array, function(value) { + if (value === noop) { + return; + } + if (isArray(value)) { + nativePush.apply(result, value); + } else { + result.push(value); + } + }); + return result; + } + + /* async functions */ + + /** + * @private + */ + function arrayEach(array, iterator, callback) { + var index = -1; + var size = array.length; + + if (iterator.length === 3) { + while (++index < size) { + iterator(array[index], index, onlyOnce(callback)); + } + } else { + while (++index < size) { + iterator(array[index], onlyOnce(callback)); + } + } + } + + /** + * @private + */ + function baseEach(object, iterator, callback, keys) { + var key; + var index = -1; + var size = keys.length; + + if (iterator.length === 3) { + while (++index < size) { + key = keys[index]; + iterator(object[key], key, onlyOnce(callback)); + } + } else { + while (++index < size) { + iterator(object[keys[index]], onlyOnce(callback)); + } + } + } + + /** + * @private + */ + function symbolEach(collection, iterator, callback) { + var iter = collection[iteratorSymbol](); + var index = 0; + var item; + if (iterator.length === 3) { + while ((item = iter.next()).done === false) { + iterator(item.value, index++, onlyOnce(callback)); + } + } else { + while ((item = iter.next()).done === false) { + index++; + iterator(item.value, onlyOnce(callback)); + } + } + return index; + } + + /** + * @private + */ + function arrayEachResult(array, result, iterator, callback) { + var index = -1; + var size = array.length; + + if (iterator.length === 4) { + while (++index < size) { + iterator(result, array[index], index, onlyOnce(callback)); + } + } else { + while (++index < size) { + iterator(result, array[index], onlyOnce(callback)); + } + } + } + + /** + * @private + */ + function baseEachResult(object, result, iterator, callback, keys) { + var key; + var index = -1; + var size = keys.length; + + if (iterator.length === 4) { + while (++index < size) { + key = keys[index]; + iterator(result, object[key], key, onlyOnce(callback)); + } + } else { + while (++index < size) { + iterator(result, object[keys[index]], onlyOnce(callback)); + } + } + } + + /** + * @private + */ + function symbolEachResult(collection, result, iterator, callback) { + var item; + var index = 0; + var iter = collection[iteratorSymbol](); + + if (iterator.length === 4) { + while ((item = iter.next()).done === false) { + iterator(result, item.value, index++, onlyOnce(callback)); + } + } else { + while ((item = iter.next()).done === false) { + index++; + iterator(result, item.value, onlyOnce(callback)); + } + } + return index; + } + + /** + * @private + */ + function arrayEachFunc(array, createCallback) { + var index = -1; + var size = array.length; + + while (++index < size) { + array[index](createCallback(index)); + } + } + + /** + * @private + */ + function baseEachFunc(object, createCallback, keys) { + var key; + var index = -1; + var size = keys.length; + + while (++index < size) { + key = keys[index]; + object[key](createCallback(key)); + } + } + + /** + * @private + */ + function arrayEachIndex(array, iterator, createCallback) { + var index = -1; + var size = array.length; + + if (iterator.length === 3) { + while (++index < size) { + iterator(array[index], index, createCallback(index)); + } + } else { + while (++index < size) { + iterator(array[index], createCallback(index)); + } + } + } + + /** + * @private + */ + function baseEachIndex(object, iterator, createCallback, keys) { + var key; + var index = -1; + var size = keys.length; + + if (iterator.length === 3) { + while (++index < size) { + key = keys[index]; + iterator(object[key], key, createCallback(index)); + } + } else { + while (++index < size) { + iterator(object[keys[index]], createCallback(index)); + } + } + } + + /** + * @private + */ + function symbolEachIndex(collection, iterator, createCallback) { + var item; + var index = 0; + var iter = collection[iteratorSymbol](); + + if (iterator.length === 3) { + while ((item = iter.next()).done === false) { + iterator(item.value, index, createCallback(index++)); + } + } else { + while ((item = iter.next()).done === false) { + iterator(item.value, createCallback(index++)); + } + } + return index; + } + + /** + * @private + */ + function baseEachKey(object, iterator, createCallback, keys) { + var key; + var index = -1; + var size = keys.length; + + if (iterator.length === 3) { + while (++index < size) { + key = keys[index]; + iterator(object[key], key, createCallback(key)); + } + } else { + while (++index < size) { + key = keys[index]; + iterator(object[key], createCallback(key)); + } + } + } + + /** + * @private + */ + function symbolEachKey(collection, iterator, createCallback) { + var item; + var index = 0; + var iter = collection[iteratorSymbol](); + + if (iterator.length === 3) { + while ((item = iter.next()).done === false) { + iterator(item.value, index, createCallback(index++)); + } + } else { + while ((item = iter.next()).done === false) { + iterator(item.value, createCallback(index++)); + } + } + return index; + } + + /** + * @private + */ + function arrayEachValue(array, iterator, createCallback) { + var value; + var index = -1; + var size = array.length; + + if (iterator.length === 3) { + while (++index < size) { + value = array[index]; + iterator(value, index, createCallback(value)); + } + } else { + while (++index < size) { + value = array[index]; + iterator(value, createCallback(value)); + } + } + } + + /** + * @private + */ + function baseEachValue(object, iterator, createCallback, keys) { + var key, value; + var index = -1; + var size = keys.length; + + if (iterator.length === 3) { + while (++index < size) { + key = keys[index]; + value = object[key]; + iterator(value, key, createCallback(value)); + } + } else { + while (++index < size) { + value = object[keys[index]]; + iterator(value, createCallback(value)); + } + } + } + + /** + * @private + */ + function symbolEachValue(collection, iterator, createCallback) { + var value, item; + var index = 0; + var iter = collection[iteratorSymbol](); + + if (iterator.length === 3) { + while ((item = iter.next()).done === false) { + value = item.value; + iterator(value, index++, createCallback(value)); + } + } else { + while ((item = iter.next()).done === false) { + index++; + value = item.value; + iterator(value, createCallback(value)); + } + } + return index; + } + + /** + * @private + */ + function arrayEachIndexValue(array, iterator, createCallback) { + var value; + var index = -1; + var size = array.length; + + if (iterator.length === 3) { + while (++index < size) { + value = array[index]; + iterator(value, index, createCallback(index, value)); + } + } else { + while (++index < size) { + value = array[index]; + iterator(value, createCallback(index, value)); + } + } + } + + /** + * @private + */ + function baseEachIndexValue(object, iterator, createCallback, keys) { + var key, value; + var index = -1; + var size = keys.length; + + if (iterator.length === 3) { + while (++index < size) { + key = keys[index]; + value = object[key]; + iterator(value, key, createCallback(index, value)); + } + } else { + while (++index < size) { + value = object[keys[index]]; + iterator(value, createCallback(index, value)); + } + } + } + + /** + * @private + */ + function symbolEachIndexValue(collection, iterator, createCallback) { + var value, item; + var index = 0; + var iter = collection[iteratorSymbol](); + + if (iterator.length === 3) { + while ((item = iter.next()).done === false) { + value = item.value; + iterator(value, index, createCallback(index++, value)); + } + } else { + while ((item = iter.next()).done === false) { + value = item.value; + iterator(value, createCallback(index++, value)); + } + } + return index; + } + + /** + * @private + */ + function baseEachKeyValue(object, iterator, createCallback, keys) { + var key, value; + var index = -1; + var size = keys.length; + + if (iterator.length === 3) { + while (++index < size) { + key = keys[index]; + value = object[key]; + iterator(value, key, createCallback(key, value)); + } + } else { + while (++index < size) { + key = keys[index]; + value = object[key]; + iterator(value, createCallback(key, value)); + } + } + } + + /** + * @private + */ + function symbolEachKeyValue(collection, iterator, createCallback) { + var value, item; + var index = 0; + var iter = collection[iteratorSymbol](); + + if (iterator.length === 3) { + while ((item = iter.next()).done === false) { + value = item.value; + iterator(value, index, createCallback(index++, value)); + } + } else { + while ((item = iter.next()).done === false) { + value = item.value; + iterator(value, createCallback(index++, value)); + } + } + return index; + } + + /** + * @private + * @param {Function} func + */ + function onlyOnce(func) { + return function(err, res) { + var fn = func; + func = throwError; + fn(err, res); + }; + } + + /** + * @private + * @param {Function} func + */ + function once(func) { + return function(err, res) { + var fn = func; + func = noop; + fn(err, res); + }; + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + */ + function createEach(arrayEach, baseEach, symbolEach) { + return function each(collection, iterator, callback) { + callback = once(callback || noop); + var size, keys; + var completed = 0; + if (isArray(collection)) { + size = collection.length; + arrayEach(collection, iterator, done); + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = symbolEach(collection, iterator, done); + size && size === completed && callback(null); + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + baseEach(collection, iterator, done, keys); + } + if (!size) { + callback(null); + } + + function done(err, bool) { + if (err) { + callback = once(callback); + callback(err); + } else if (++completed === size) { + callback(null); + } else if (bool === false) { + callback = once(callback); + callback(null); + } + } + }; + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + * @param {Function} symbolEach + */ + function createMap(arrayEach, baseEach, symbolEach, useArray) { + var init, clone; + if (useArray) { + init = Array; + clone = createArray; + } else { + init = function() { + return {}; + }; + clone = objectClone; + } + + return function(collection, iterator, callback) { + callback = callback || noop; + var size, keys, result; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + result = init(size); + arrayEach(collection, iterator, createCallback); + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + // TODO: size could be changed + result = init(0); + size = symbolEach(collection, iterator, createCallback); + size && size === completed && callback(null, result); + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + result = init(size); + baseEach(collection, iterator, createCallback, keys); + } + if (!size) { + callback(null, init()); + } + + function createCallback(key) { + return function done(err, res) { + if (key === null) { + throwError(); + } + if (err) { + key = null; + callback = once(callback); + callback(err, clone(result)); + return; + } + result[key] = res; + key = null; + if (++completed === size) { + callback(null, result); + } + }; + } + }; + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + * @param {Function} symbolEach + * @param {boolean} bool + */ + function createFilter(arrayEach, baseEach, symbolEach, bool) { + return function(collection, iterator, callback) { + callback = callback || noop; + var size, keys, result; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + result = Array(size); + arrayEach(collection, iterator, createCallback); + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + result = []; + size = symbolEach(collection, iterator, createCallback); + size && size === completed && callback(null, compact(result)); + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + result = Array(size); + baseEach(collection, iterator, createCallback, keys); + } + if (!size) { + return callback(null, []); + } + + function createCallback(index, value) { + return function done(err, res) { + if (index === null) { + throwError(); + } + if (err) { + index = null; + callback = once(callback); + callback(err); + return; + } + if (!!res === bool) { + result[index] = value; + } + index = null; + if (++completed === size) { + callback(null, compact(result)); + } + }; + } + }; + } + + /** + * @private + * @param {boolean} bool + */ + function createFilterSeries(bool) { + return function(collection, iterator, callback) { + callback = onlyOnce(callback || noop); + var size, key, value, keys, iter, item, iterate; + var sync = false; + var completed = 0; + var result = []; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null, []); + } + iterate(); + + function arrayIterator() { + value = collection[completed]; + iterator(value, done); + } + + function arrayIteratorWithIndex() { + value = collection[completed]; + iterator(value, completed, done); + } + + function symbolIterator() { + item = iter.next(); + value = item.value; + item.done ? callback(null, result) : iterator(value, done); + } + + function symbolIteratorWithKey() { + item = iter.next(); + value = item.value; + item.done ? callback(null, result) : iterator(value, completed, done); + } + + function objectIterator() { + key = keys[completed]; + value = collection[key]; + iterator(value, done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + value = collection[key]; + iterator(value, key, done); + } + + function done(err, res) { + if (err) { + callback(err); + return; + } + if (!!res === bool) { + result[result.length] = value; + } + if (++completed === size) { + iterate = throwError; + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + }; + } + + /** + * @private + * @param {boolean} bool + */ + function createFilterLimit(bool) { + return function(collection, limit, iterator, callback) { + callback = callback || noop; + var size, index, key, value, keys, iter, item, iterate, result; + var sync = false; + var started = 0; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + result = []; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null, []); + } + result = result || Array(size); + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + index = started++; + if (index < size) { + value = collection[index]; + iterator(value, createCallback(value, index)); + } + } + + function arrayIteratorWithIndex() { + index = started++; + if (index < size) { + value = collection[index]; + iterator(value, index, createCallback(value, index)); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + value = item.value; + iterator(value, createCallback(value, started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, compact(result)); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + value = item.value; + iterator(value, started, createCallback(value, started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, compact(result)); + } + } + + function objectIterator() { + index = started++; + if (index < size) { + value = collection[keys[index]]; + iterator(value, createCallback(value, index)); + } + } + + function objectIteratorWithKey() { + index = started++; + if (index < size) { + key = keys[index]; + value = collection[key]; + iterator(value, key, createCallback(value, index)); + } + } + + function createCallback(value, index) { + return function(err, res) { + if (index === null) { + throwError(); + } + if (err) { + index = null; + iterate = noop; + callback = once(callback); + callback(err); + return; + } + if (!!res === bool) { + result[index] = value; + } + index = null; + if (++completed === size) { + callback = onlyOnce(callback); + callback(null, compact(result)); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + }; + } + + /** + * @memberof async + * @namespace eachSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(); + * }, num * 10); + * }; + * async.eachSeries(array, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(); + * }, num * 10); + * }; + * async.eachSeries(array, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [[1, 0], [3, 1], [2, 2]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(); + * }, num * 10); + * }; + * async.eachSeries(object, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(); + * }, num * 10); + * }; + * async.eachSeries(object, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b']] + * }); + * + * @example + * + * // break + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num !== 3); + * }, num * 10); + * }; + * async.eachSeries(array, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [1, 3] + * }); + */ + function eachSeries(collection, iterator, callback) { + callback = onlyOnce(callback || noop); + var size, key, keys, iter, item, iterate; + var sync = false; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null); + } + iterate(); + + function arrayIterator() { + iterator(collection[completed], done); + } + + function arrayIteratorWithIndex() { + iterator(collection[completed], completed, done); + } + + function symbolIterator() { + item = iter.next(); + item.done ? callback(null) : iterator(item.value, done); + } + + function symbolIteratorWithKey() { + item = iter.next(); + item.done ? callback(null) : iterator(item.value, completed, done); + } + + function objectIterator() { + iterator(collection[keys[completed]], done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + iterator(collection[key], key, done); + } + + function done(err, bool) { + if (err) { + callback(err); + } else if (++completed === size || bool === false) { + iterate = throwError; + callback(null); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace eachLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(); + * }, num * 10); + * }; + * async.eachLimit(array, 2, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(); + * }, num * 10); + * }; + * async.eachLimit(array, 2, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(); + * }, num * 10); + * }; + * async.eachLimit(object, 2, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(); + * }, num * 10); + * }; + * async.eachLimit(object, 2, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + * @example + * + * // break + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num !== 5); + * }, num * 10); + * }; + * async.eachLimit(array, 2, iterator, function(err, res) { + * console.log(res); // undefined + * console.log(order); // [1, 3, 5] + * }); + * + */ + function eachLimit(collection, limit, iterator, callback) { + callback = callback || noop; + var size, index, key, keys, iter, item, iterate; + var sync = false; + var started = 0; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } else { + return callback(null); + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null); + } + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + if (started < size) { + iterator(collection[started++], done); + } + } + + function arrayIteratorWithIndex() { + index = started++; + if (index < size) { + iterator(collection[index], index, done); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + started++; + iterator(item.value, done); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + iterator(item.value, started++, done); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null); + } + } + + function objectIterator() { + if (started < size) { + iterator(collection[keys[started++]], done); + } + } + + function objectIteratorWithKey() { + index = started++; + if (index < size) { + key = keys[index]; + iterator(collection[key], key, done); + } + } + + function done(err, bool) { + if (err || bool === false) { + iterate = noop; + callback = once(callback); + callback(err); + } else if (++completed === size) { + iterator = noop; + iterate = throwError; + callback = onlyOnce(callback); + callback(null); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace mapSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapSeries(array, iterator, function(err, res) { + * console.log(res); // [1, 3, 2]; + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num); + * }, num * 10); + * }; + * async.mapSeries(array, iterator, function(err, res) { + * console.log(res); // [1, 3, 2] + * console.log(order); // [[1, 0], [3, 1], [2, 2]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapSeries(object, iterator, function(err, res) { + * console.log(res); // [1, 3, 2] + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.mapSeries(object, iterator, function(err, res) { + * console.log(res); // [1, 3, 2] + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] + * }); + * + */ + function mapSeries(collection, iterator, callback) { + callback = callback || noop; + var size, key, keys, iter, item, result, iterate; + var sync = false; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + result = []; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null, []); + } + result = result || Array(size); + iterate(); + + function arrayIterator() { + iterator(collection[completed], done); + } + + function arrayIteratorWithIndex() { + iterator(collection[completed], completed, done); + } + + function symbolIterator() { + item = iter.next(); + item.done ? callback(null, result) : iterator(item.value, done); + } + + function symbolIteratorWithKey() { + item = iter.next(); + item.done ? callback(null, result) : iterator(item.value, completed, done); + } + + function objectIterator() { + iterator(collection[keys[completed]], done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + iterator(collection[key], key, done); + } + + function done(err, res) { + if (err) { + iterate = throwError; + callback = onlyOnce(callback); + callback(err, createArray(result)); + return; + } + result[completed] = res; + if (++completed === size) { + iterate = throwError; + callback(null, result); + callback = throwError; + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace mapLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [1, 5, 3, 4, 2] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num); + * }, num * 10); + * }; + * async.mapLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [1, 5, 3, 4, 2] + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [1, 5, 3, 4, 2] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.mapLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [1, 5, 3, 4, 2] + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + */ + function mapLimit(collection, limit, iterator, callback) { + callback = callback || noop; + var size, index, key, keys, iter, item, result, iterate; + var sync = false; + var started = 0; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + result = []; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null, []); + } + result = result || Array(size); + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + index = started++; + if (index < size) { + iterator(collection[index], createCallback(index)); + } + } + + function arrayIteratorWithIndex() { + index = started++; + if (index < size) { + iterator(collection[index], index, createCallback(index)); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + iterator(item.value, createCallback(started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + iterator(item.value, started, createCallback(started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function objectIterator() { + index = started++; + if (index < size) { + iterator(collection[keys[index]], createCallback(index)); + } + } + + function objectIteratorWithKey() { + index = started++; + if (index < size) { + key = keys[index]; + iterator(collection[key], key, createCallback(index)); + } + } + + function createCallback(index) { + return function(err, res) { + if (index === null) { + throwError(); + } + if (err) { + index = null; + iterate = noop; + callback = once(callback); + callback(err, createArray(result)); + return; + } + result[index] = res; + index = null; + if (++completed === size) { + iterate = throwError; + callback(null, result); + callback = throwError; + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + } + + /** + * @memberof async + * @namespace mapValuesSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapValuesSeries(array, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3, '2': 2 } + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num); + * }, num * 10); + * }; + * async.mapValuesSeries(array, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3, '2': 2 } + * console.log(order); // [[1, 0], [3, 1], [2, 2]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapValuesSeries(object, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3, c: 2 } + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.mapValuesSeries(object, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3, c: 2 } + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] + * }); + * + */ + function mapValuesSeries(collection, iterator, callback) { + callback = callback || noop; + var size, key, keys, iter, item, iterate; + var sync = false; + var result = {}; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null, result); + } + iterate(); + + function arrayIterator() { + key = completed; + iterator(collection[completed], done); + } + + function arrayIteratorWithIndex() { + key = completed; + iterator(collection[completed], completed, done); + } + + function symbolIterator() { + key = completed; + item = iter.next(); + item.done ? callback(null, result) : iterator(item.value, done); + } + + function symbolIteratorWithKey() { + key = completed; + item = iter.next(); + item.done ? callback(null, result) : iterator(item.value, completed, done); + } + + function objectIterator() { + key = keys[completed]; + iterator(collection[key], done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + iterator(collection[key], key, done); + } + + function done(err, res) { + if (err) { + iterate = throwError; + callback = onlyOnce(callback); + callback(err, objectClone(result)); + return; + } + result[key] = res; + if (++completed === size) { + iterate = throwError; + callback(null, result); + callback = throwError; + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace mapValuesLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapValuesLimit(array, 2, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 } + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num); + * }, num * 10); + * }; + * async.mapValuesLimit(array, 2, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 } + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.mapValuesLimit(object, 2, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 } + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.mapValuesLimit(object, 2, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 } + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + */ + function mapValuesLimit(collection, limit, iterator, callback) { + callback = callback || noop; + var size, index, key, keys, iter, item, iterate; + var sync = false; + var result = {}; + var started = 0; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null, result); + } + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + index = started++; + if (index < size) { + iterator(collection[index], createCallback(index)); + } + } + + function arrayIteratorWithIndex() { + index = started++; + if (index < size) { + iterator(collection[index], index, createCallback(index)); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + iterator(item.value, createCallback(started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + iterator(item.value, started, createCallback(started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function objectIterator() { + index = started++; + if (index < size) { + key = keys[index]; + iterator(collection[key], createCallback(key)); + } + } + + function objectIteratorWithKey() { + index = started++; + if (index < size) { + key = keys[index]; + iterator(collection[key], key, createCallback(key)); + } + } + + function createCallback(key) { + return function(err, res) { + if (key === null) { + throwError(); + } + if (err) { + key = null; + iterate = noop; + callback = once(callback); + callback(err, objectClone(result)); + return; + } + result[key] = res; + key = null; + if (++completed === size) { + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + * @param {Function} symbolEach + * @param {boolean} bool + */ + function createDetect(arrayEach, baseEach, symbolEach, bool) { + return function(collection, iterator, callback) { + callback = callback || noop; + var size, keys; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + arrayEach(collection, iterator, createCallback); + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = symbolEach(collection, iterator, createCallback); + size && size === completed && callback(null); + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + baseEach(collection, iterator, createCallback, keys); + } + if (!size) { + callback(null); + } + + function createCallback(value) { + var called = false; + return function done(err, res) { + if (called) { + throwError(); + } + called = true; + if (err) { + callback = once(callback); + callback(err); + } else if (!!res === bool) { + callback = once(callback); + callback(null, value); + } else if (++completed === size) { + callback(null); + } + }; + } + }; + } + + /** + * @private + * @param {boolean} bool + */ + function createDetectSeries(bool) { + return function(collection, iterator, callback) { + callback = onlyOnce(callback || noop); + var size, key, value, keys, iter, item, iterate; + var sync = false; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null); + } + iterate(); + + function arrayIterator() { + value = collection[completed]; + iterator(value, done); + } + + function arrayIteratorWithIndex() { + value = collection[completed]; + iterator(value, completed, done); + } + + function symbolIterator() { + item = iter.next(); + value = item.value; + item.done ? callback(null) : iterator(value, done); + } + + function symbolIteratorWithKey() { + item = iter.next(); + value = item.value; + item.done ? callback(null) : iterator(value, completed, done); + } + + function objectIterator() { + value = collection[keys[completed]]; + iterator(value, done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + value = collection[key]; + iterator(value, key, done); + } + + function done(err, res) { + if (err) { + callback(err); + } else if (!!res === bool) { + iterate = throwError; + callback(null, value); + } else if (++completed === size) { + iterate = throwError; + callback(null); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + }; + } + + /** + * @private + * @param {boolean} bool + */ + function createDetectLimit(bool) { + return function(collection, limit, iterator, callback) { + callback = callback || noop; + var size, index, key, value, keys, iter, item, iterate; + var sync = false; + var started = 0; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null); + } + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + index = started++; + if (index < size) { + value = collection[index]; + iterator(value, createCallback(value)); + } + } + + function arrayIteratorWithIndex() { + index = started++; + if (index < size) { + value = collection[index]; + iterator(value, index, createCallback(value)); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + started++; + value = item.value; + iterator(value, createCallback(value)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + value = item.value; + iterator(value, started++, createCallback(value)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null); + } + } + + function objectIterator() { + index = started++; + if (index < size) { + value = collection[keys[index]]; + iterator(value, createCallback(value)); + } + } + + function objectIteratorWithKey() { + if (started < size) { + key = keys[started++]; + value = collection[key]; + iterator(value, key, createCallback(value)); + } + } + + function createCallback(value) { + var called = false; + return function(err, res) { + if (called) { + throwError(); + } + called = true; + if (err) { + iterate = noop; + callback = once(callback); + callback(err); + } else if (!!res === bool) { + iterate = noop; + callback = once(callback); + callback(null, value); + } else if (++completed === size) { + callback(null); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + }; + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + * @param {Function} symbolEach + * @param {boolean} bool + */ + function createPick(arrayEach, baseEach, symbolEach, bool) { + return function(collection, iterator, callback) { + callback = callback || noop; + var size, keys; + var completed = 0; + var result = {}; + + if (isArray(collection)) { + size = collection.length; + arrayEach(collection, iterator, createCallback); + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = symbolEach(collection, iterator, createCallback); + size && size === completed && callback(null, result); + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + baseEach(collection, iterator, createCallback, keys); + } + if (!size) { + return callback(null, {}); + } + + function createCallback(key, value) { + return function done(err, res) { + if (key === null) { + throwError(); + } + if (err) { + key = null; + callback = once(callback); + callback(err, objectClone(result)); + return; + } + if (!!res === bool) { + result[key] = value; + } + key = null; + if (++completed === size) { + callback(null, result); + } + }; + } + }; + } + + /** + * @private + * @param {boolean} bool + */ + function createPickSeries(bool) { + return function(collection, iterator, callback) { + callback = onlyOnce(callback || noop); + var size, key, value, keys, iter, item, iterate; + var sync = false; + var result = {}; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null, {}); + } + iterate(); + + function arrayIterator() { + key = completed; + value = collection[completed]; + iterator(value, done); + } + + function arrayIteratorWithIndex() { + key = completed; + value = collection[completed]; + iterator(value, completed, done); + } + + function symbolIterator() { + key = completed; + item = iter.next(); + value = item.value; + item.done ? callback(null, result) : iterator(value, done); + } + + function symbolIteratorWithKey() { + key = completed; + item = iter.next(); + value = item.value; + item.done ? callback(null, result) : iterator(value, key, done); + } + + function objectIterator() { + key = keys[completed]; + value = collection[key]; + iterator(value, done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + value = collection[key]; + iterator(value, key, done); + } + + function done(err, res) { + if (err) { + callback(err, result); + return; + } + if (!!res === bool) { + result[key] = value; + } + if (++completed === size) { + iterate = throwError; + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + }; + } + + /** + * @private + * @param {boolean} bool + */ + function createPickLimit(bool) { + return function(collection, limit, iterator, callback) { + callback = callback || noop; + var size, index, key, value, keys, iter, item, iterate; + var sync = false; + var result = {}; + var started = 0; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null, {}); + } + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + index = started++; + if (index < size) { + value = collection[index]; + iterator(value, createCallback(value, index)); + } + } + + function arrayIteratorWithIndex() { + index = started++; + if (index < size) { + value = collection[index]; + iterator(value, index, createCallback(value, index)); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + value = item.value; + iterator(value, createCallback(value, started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + value = item.value; + iterator(value, started, createCallback(value, started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function objectIterator() { + if (started < size) { + key = keys[started++]; + value = collection[key]; + iterator(value, createCallback(value, key)); + } + } + + function objectIteratorWithKey() { + if (started < size) { + key = keys[started++]; + value = collection[key]; + iterator(value, key, createCallback(value, key)); + } + } + + function createCallback(value, key) { + return function(err, res) { + if (key === null) { + throwError(); + } + if (err) { + key = null; + iterate = noop; + callback = once(callback); + callback(err, objectClone(result)); + return; + } + if (!!res === bool) { + result[key] = value; + } + key = null; + if (++completed === size) { + iterate = throwError; + callback = onlyOnce(callback); + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + }; + } + + /** + * @memberof async + * @namespace reduce + * @param {Array|Object} collection + * @param {*} result + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var collection = [1, 3, 2, 4]; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, result + num); + * }, num * 10); + * }; + * async.reduce(collection, 0, iterator, function(err, res) { + * console.log(res); // 10 + * console.log(order); // [1, 3, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var collection = [1, 3, 2, 4]; + * var iterator = function(result, num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, result + num); + * }, num * 10); + * }; + * async.reduce(collection, '', iterator, function(err, res) { + * console.log(res); // '1324' + * console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, result + num); + * }, num * 10); + * }; + * async.reduce(collection, '', iterator, function(err, res) { + * console.log(res); // '1324' + * console.log(order); // [1, 3, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(result, num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, result + num); + * }, num * 10); + * }; + * async.reduce(collection, 0, iterator, function(err, res) { + * console.log(res); // 10 + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']] + * }); + * + */ + function reduce(collection, result, iterator, callback) { + callback = onlyOnce(callback || noop); + var size, key, keys, iter, item, iterate; + var sync = false; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null, result); + } + iterate(result); + + function arrayIterator(result) { + iterator(result, collection[completed], done); + } + + function arrayIteratorWithIndex(result) { + iterator(result, collection[completed], completed, done); + } + + function symbolIterator(result) { + item = iter.next(); + item.done ? callback(null, result) : iterator(result, item.value, done); + } + + function symbolIteratorWithKey(result) { + item = iter.next(); + item.done ? callback(null, result) : iterator(result, item.value, completed, done); + } + + function objectIterator(result) { + iterator(result, collection[keys[completed]], done); + } + + function objectIteratorWithKey(result) { + key = keys[completed]; + iterator(result, collection[key], key, done); + } + + function done(err, result) { + if (err) { + callback(err, result); + } else if (++completed === size) { + iterator = throwError; + callback(null, result); + } else if (sync) { + nextTick(function() { + iterate(result); + }); + } else { + sync = true; + iterate(result); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace reduceRight + * @param {Array|Object} collection + * @param {*} result + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var collection = [1, 3, 2, 4]; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, result + num); + * }, num * 10); + * }; + * async.reduceRight(collection, 0, iterator, function(err, res) { + * console.log(res); // 10 + * console.log(order); // [4, 2, 3, 1] + * }); + * + * @example + * + * // array with index + * var order = []; + * var collection = [1, 3, 2, 4]; + * var iterator = function(result, num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, result + num); + * }, num * 10); + * }; + * async.reduceRight(collection, '', iterator, function(err, res) { + * console.log(res); // '4231' + * console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, result + num); + * }, num * 10); + * }; + * async.reduceRight(collection, '', iterator, function(err, res) { + * console.log(res); // '4231' + * console.log(order); // [4, 2, 3, 1] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(result, num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, result + num); + * }, num * 10); + * }; + * async.reduceRight(collection, 0, iterator, function(err, res) { + * console.log(res); // 10 + * console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]] + * }); + * + */ + function reduceRight(collection, result, iterator, callback) { + callback = onlyOnce(callback || noop); + var resIndex, index, key, keys, iter, item, col, iterate; + var sync = false; + + if (isArray(collection)) { + resIndex = collection.length; + iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + col = []; + iter = collection[iteratorSymbol](); + index = -1; + while ((item = iter.next()).done === false) { + col[++index] = item.value; + } + collection = col; + resIndex = col.length; + iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + resIndex = keys.length; + iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator; + } + if (!resIndex) { + return callback(null, result); + } + iterate(result); + + function arrayIterator(result) { + iterator(result, collection[--resIndex], done); + } + + function arrayIteratorWithIndex(result) { + iterator(result, collection[--resIndex], resIndex, done); + } + + function objectIterator(result) { + iterator(result, collection[keys[--resIndex]], done); + } + + function objectIteratorWithKey(result) { + key = keys[--resIndex]; + iterator(result, collection[key], key, done); + } + + function done(err, result) { + if (err) { + callback(err, result); + } else if (resIndex === 0) { + iterate = throwError; + callback(null, result); + } else if (sync) { + nextTick(function() { + iterate(result); + }); + } else { + sync = true; + iterate(result); + } + sync = false; + } + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + * @param {Function} symbolEach + */ + function createTransform(arrayEach, baseEach, symbolEach) { + return function transform(collection, accumulator, iterator, callback) { + if (arguments.length === 3) { + callback = iterator; + iterator = accumulator; + accumulator = undefined; + } + callback = callback || noop; + var size, keys, result; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + result = accumulator !== undefined ? accumulator : []; + arrayEach(collection, result, iterator, done); + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + result = accumulator !== undefined ? accumulator : {}; + size = symbolEach(collection, result, iterator, done); + size && size === completed && callback(null, result); + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + result = accumulator !== undefined ? accumulator : {}; + baseEach(collection, result, iterator, done, keys); + } + if (!size) { + callback(null, accumulator !== undefined ? accumulator : result || {}); + } + + function done(err, bool) { + if (err) { + callback = once(callback); + callback(err, isArray(result) ? createArray(result) : objectClone(result)); + } else if (++completed === size) { + callback(null, result); + } else if (bool === false) { + callback = once(callback); + callback(null, isArray(result) ? createArray(result) : objectClone(result)); + } + } + }; + } + + /** + * @memberof async + * @namespace transformSeries + * @param {Array|Object} collection + * @param {Array|Object|Function} [accumulator] + * @param {Function} [iterator] + * @param {Function} [callback] + * @example + * + * // array + * var order = []; + * var collection = [1, 3, 2, 4]; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * result.push(num) + * done(); + * }, num * 10); + * }; + * async.transformSeries(collection, iterator, function(err, res) { + * console.log(res); // [1, 3, 2, 4] + * console.log(order); // [1, 3, 2, 4] + * }); + * + * @example + * + * // array with index and accumulator + * var order = []; + * var collection = [1, 3, 2, 4]; + * var iterator = function(result, num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * result[index] = num; + * done(); + * }, num * 10); + * }; + * async.transformSeries(collection, {}, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 } + * console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]] + * }); + * + * @example + * + * // object with accumulator + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * result.push(num); + * done(); + * }, num * 10); + * }; + * async.transformSeries(collection, [], iterator, function(err, res) { + * console.log(res); // [1, 3, 2, 4] + * console.log(order); // [1, 3, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2, d: 4 }; + * var iterator = function(result, num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * result[key] = num; + * done(); + * }, num * 10); + * }; + * async.transformSeries(collection, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 3, c: 2, d: 4 } + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']] + * }); + * + */ + function transformSeries(collection, accumulator, iterator, callback) { + if (arguments.length === 3) { + callback = iterator; + iterator = accumulator; + accumulator = undefined; + } + callback = onlyOnce(callback || noop); + var size, key, keys, iter, item, iterate, result; + var sync = false; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + result = accumulator !== undefined ? accumulator : []; + iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + result = accumulator !== undefined ? accumulator : {}; + iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + result = accumulator !== undefined ? accumulator : {}; + iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null, accumulator !== undefined ? accumulator : result || {}); + } + iterate(); + + function arrayIterator() { + iterator(result, collection[completed], done); + } + + function arrayIteratorWithIndex() { + iterator(result, collection[completed], completed, done); + } + + function symbolIterator() { + item = iter.next(); + item.done ? callback(null, result) : iterator(result, item.value, done); + } + + function symbolIteratorWithKey() { + item = iter.next(); + item.done ? callback(null, result) : iterator(result, item.value, completed, done); + } + + function objectIterator() { + iterator(result, collection[keys[completed]], done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + iterator(result, collection[key], key, done); + } + + function done(err, bool) { + if (err) { + callback(err, result); + } else if (++completed === size || bool === false) { + iterate = throwError; + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace transformLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Array|Object|Function} [accumulator] + * @param {Function} [iterator] + * @param {Function} [callback] + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * result.push(num); + * done(); + * }, num * 10); + * }; + * async.transformLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [1, 3, 5, 2, 4] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index and accumulator + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(result, num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * result[index] = key; + * done(); + * }, num * 10); + * }; + * async.transformLimit(array, 2, {}, iterator, function(err, res) { + * console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 } + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object with accumulator + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(result, num, done) { + * setTimeout(function() { + * order.push(num); + * result.push(num); + * done(); + * }, num * 10); + * }; + * async.transformLimit(object, 2, [], iterator, function(err, res) { + * console.log(res); // [1, 3, 5, 2, 4] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(result, num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * result[key] = num; + * done(); + * }, num * 10); + * }; + * async.transformLimit(object, 2, iterator, function(err, res) { + * console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + */ + function transformLimit(collection, limit, accumulator, iterator, callback) { + if (arguments.length === 4) { + callback = iterator; + iterator = accumulator; + accumulator = undefined; + } + callback = callback || noop; + var size, index, key, keys, iter, item, iterate, result; + var sync = false; + var started = 0; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + result = accumulator !== undefined ? accumulator : []; + iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + result = accumulator !== undefined ? accumulator : {}; + iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + result = accumulator !== undefined ? accumulator : {}; + iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null, accumulator !== undefined ? accumulator : result || {}); + } + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + index = started++; + if (index < size) { + iterator(result, collection[index], onlyOnce(done)); + } + } + + function arrayIteratorWithIndex() { + index = started++; + if (index < size) { + iterator(result, collection[index], index, onlyOnce(done)); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + started++; + iterator(result, item.value, onlyOnce(done)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + iterator(result, item.value, started++, onlyOnce(done)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function objectIterator() { + index = started++; + if (index < size) { + iterator(result, collection[keys[index]], onlyOnce(done)); + } + } + + function objectIteratorWithKey() { + index = started++; + if (index < size) { + key = keys[index]; + iterator(result, collection[key], key, onlyOnce(done)); + } + } + + function done(err, bool) { + if (err || bool === false) { + iterate = noop; + callback(err || null, isArray(result) ? createArray(result) : objectClone(result)); + callback = noop; + } else if (++completed === size) { + iterator = noop; + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @private + * @param {function} arrayEach + * @param {function} baseEach + * @param {function} symbolEach + */ + function createSortBy(arrayEach, baseEach, symbolEach) { + return function sortBy(collection, iterator, callback) { + callback = callback || noop; + var size, array, criteria; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + array = Array(size); + criteria = Array(size); + arrayEach(collection, iterator, createCallback); + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + array = []; + criteria = []; + size = symbolEach(collection, iterator, createCallback); + size && size === completed && callback(null, sortByCriteria(array, criteria)); + } else if (typeof collection === obj) { + var keys = nativeKeys(collection); + size = keys.length; + array = Array(size); + criteria = Array(size); + baseEach(collection, iterator, createCallback, keys); + } + if (!size) { + callback(null, []); + } + + function createCallback(index, value) { + var called = false; + array[index] = value; + return function done(err, criterion) { + if (called) { + throwError(); + } + called = true; + criteria[index] = criterion; + if (err) { + callback = once(callback); + callback(err); + } else if (++completed === size) { + callback(null, sortByCriteria(array, criteria)); + } + }; + } + }; + } + + /** + * @memberof async + * @namespace sortBySeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.sortBySeries(array, iterator, function(err, res) { + * console.log(res); // [1, 2, 3]; + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num); + * }, num * 10); + * }; + * async.sortBySeries(array, iterator, function(err, res) { + * console.log(res); // [1, 2, 3] + * console.log(order); // [[1, 0], [3, 1], [2, 2]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.sortBySeries(object, iterator, function(err, res) { + * console.log(res); // [1, 2, 3] + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.sortBySeries(object, iterator, function(err, res) { + * console.log(res); // [1, 2, 3] + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] + * }); + * + */ + function sortBySeries(collection, iterator, callback) { + callback = onlyOnce(callback || noop); + var size, key, value, keys, iter, item, array, criteria, iterate; + var sync = false; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + array = collection; + criteria = Array(size); + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + array = []; + criteria = []; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + array = Array(size); + criteria = Array(size); + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null, []); + } + iterate(); + + function arrayIterator() { + value = collection[completed]; + iterator(value, done); + } + + function arrayIteratorWithIndex() { + value = collection[completed]; + iterator(value, completed, done); + } + + function symbolIterator() { + item = iter.next(); + if (item.done) { + return callback(null, sortByCriteria(array, criteria)); + } + value = item.value; + array[completed] = value; + iterator(value, done); + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done) { + return callback(null, sortByCriteria(array, criteria)); + } + value = item.value; + array[completed] = value; + iterator(value, completed, done); + } + + function objectIterator() { + value = collection[keys[completed]]; + array[completed] = value; + iterator(value, done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + value = collection[key]; + array[completed] = value; + iterator(value, key, done); + } + + function done(err, criterion) { + criteria[completed] = criterion; + if (err) { + callback(err); + } else if (++completed === size) { + iterate = throwError; + callback(null, sortByCriteria(array, criteria)); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace sortByLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.sortByLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [1, 2, 3, 4, 5] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num); + * }, num * 10); + * }; + * async.sortByLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [1, 2, 3, 4, 5] + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num); + * }, num * 10); + * }; + * async.sortByLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [1, 2, 3, 4, 5] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.sortByLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [1, 2, 3, 4, 5] + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + */ + function sortByLimit(collection, limit, iterator, callback) { + callback = callback || noop; + var size, index, key, value, array, keys, iter, item, criteria, iterate; + var sync = false; + var started = 0; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + array = collection; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + array = []; + criteria = []; + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + array = Array(size); + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null, []); + } + criteria = criteria || Array(size); + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + if (started < size) { + value = collection[started]; + iterator(value, createCallback(value, started++)); + } + } + + function arrayIteratorWithIndex() { + index = started++; + if (index < size) { + value = collection[index]; + iterator(value, index, createCallback(value, index)); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + value = item.value; + array[started] = value; + iterator(value, createCallback(value, started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, sortByCriteria(array, criteria)); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + value = item.value; + array[started] = value; + iterator(value, started, createCallback(value, started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, sortByCriteria(array, criteria)); + } + } + + function objectIterator() { + if (started < size) { + value = collection[keys[started]]; + array[started] = value; + iterator(value, createCallback(value, started++)); + } + } + + function objectIteratorWithKey() { + if (started < size) { + key = keys[started]; + value = collection[key]; + array[started] = value; + iterator(value, key, createCallback(value, started++)); + } + } + + function createCallback(value, index) { + var called = false; + return function(err, criterion) { + if (called) { + throwError(); + } + called = true; + criteria[index] = criterion; + if (err) { + iterate = noop; + callback(err); + callback = noop; + } else if (++completed === size) { + callback(null, sortByCriteria(array, criteria)); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + } + + /** + * @memberof async + * @namespace some + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.some(array, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [1] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.some(array, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [[1, 0]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.some(object, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [1] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.some(object, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [[1, 'a']] + * }); + * + */ + function some(collection, iterator, callback) { + callback = callback || noop; + detect(collection, iterator, done); + + function done(err, res) { + if (err) { + return callback(err); + } + callback(null, !!res); + } + } + + /** + * @memberof async + * @namespace someSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.someSeries(array, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [1] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.someSeries(array, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [[1, 0]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.someSeries(object, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [1] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.someSeries(object, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [[1, 'a']] + * }); + * + */ + function someSeries(collection, iterator, callback) { + callback = callback || noop; + detectSeries(collection, iterator, done); + + function done(err, res) { + if (err) { + return callback(err); + } + callback(null, !!res); + } + } + + /** + * @memberof async + * @namespace someLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.someLimit(array, 2, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [1] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.someLimit(array, 2, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [[1, 0]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, num % 2); + * }, num * 10); + * }; + * async.someLimit(object, 2, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [1] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num % 2); + * }, num * 10); + * }; + * async.someLimit(object, 2, iterator, function(err, res) { + * console.log(res); // true + * console.log(order); // [[1, 'a']] + * }); + * + */ + function someLimit(collection, limit, iterator, callback) { + callback = callback || noop; + detectLimit(collection, limit, iterator, done); + + function done(err, res) { + if (err) { + return callback(err); + } + callback(null, !!res); + } + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + * @param {Function} symbolEach + */ + function createEvery(arrayEach, baseEach, symbolEach) { + var deny = createDetect(arrayEach, baseEach, symbolEach, false); + + return function every(collection, iterator, callback) { + callback = callback || noop; + deny(collection, iterator, done); + + function done(err, res) { + if (err) { + return callback(err); + } + callback(null, !res); + } + }; + } + + /** + * @private + */ + function createEverySeries() { + var denySeries = createDetectSeries(false); + + return function everySeries(collection, iterator, callback) { + callback = callback || noop; + denySeries(collection, iterator, done); + + function done(err, res) { + if (err) { + return callback(err); + } + callback(null, !res); + } + }; + } + + /** + * @private + */ + function createEveryLimit() { + var denyLimit = createDetectLimit(false); + + return function everyLimit(collection, limit, iterator, callback) { + callback = callback || noop; + denyLimit(collection, limit, iterator, done); + + function done(err, res) { + if (err) { + return callback(err); + } + callback(null, !res); + } + }; + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + * @param {Function} symbolEach + */ + function createConcat(arrayEach, baseEach, symbolEach) { + return function concat(collection, iterator, callback) { + callback = callback || noop; + var size, result; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + result = Array(size); + arrayEach(collection, iterator, createCallback); + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + result = []; + size = symbolEach(collection, iterator, createCallback); + size && size === completed && callback(null, result); + } else if (typeof collection === obj) { + var keys = nativeKeys(collection); + size = keys.length; + result = Array(size); + baseEach(collection, iterator, createCallback, keys); + } + if (!size) { + callback(null, []); + } + + function createCallback(index) { + return function done(err, res) { + if (index === null) { + throwError(); + } + if (err) { + index = null; + callback = once(callback); + arrayEachSync(result, function(array, index) { + if (array === undefined) { + result[index] = noop; + } + }); + callback(err, makeConcatResult(result)); + return; + } + switch (arguments.length) { + case 0: + case 1: + result[index] = noop; + break; + case 2: + result[index] = res; + break; + default: + result[index] = slice(arguments, 1); + break; + } + index = null; + if (++completed === size) { + callback(null, makeConcatResult(result)); + } + }; + } + }; + } + + /** + * @memberof async + * @namespace concatSeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, [num]); + * }, num * 10); + * }; + * async.concatSeries(array, iterator, function(err, res) { + * console.log(res); // [1, 3, 2]; + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 3, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, [num]); + * }, num * 10); + * }; + * async.concatSeries(array, iterator, function(err, res) { + * console.log(res); // [1, 3, 2] + * console.log(order); // [[1, 0], [3, 1], [2, 2]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, [num]); + * }, num * 10); + * }; + * async.concatSeries(object, iterator, function(err, res) { + * console.log(res); // [1, 3, 2] + * console.log(order); // [1, 3, 2] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 3, c: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, [num]); + * }, num * 10); + * }; + * async.concatSeries(object, iterator, function(err, res) { + * console.log(res); // [1, 3, 2] + * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']] + * }); + * + */ + function concatSeries(collection, iterator, callback) { + callback = onlyOnce(callback || noop); + var size, key, keys, iter, item, iterate; + var sync = false; + var result = []; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null, result); + } + iterate(); + + function arrayIterator() { + iterator(collection[completed], done); + } + + function arrayIteratorWithIndex() { + iterator(collection[completed], completed, done); + } + + function symbolIterator() { + item = iter.next(); + item.done ? callback(null, result) : iterator(item.value, done); + } + + function symbolIteratorWithKey() { + item = iter.next(); + item.done ? callback(null, result) : iterator(item.value, completed, done); + } + + function objectIterator() { + iterator(collection[keys[completed]], done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + iterator(collection[key], key, done); + } + + function done(err, array) { + if (isArray(array)) { + nativePush.apply(result, array); + } else if (arguments.length >= 2) { + nativePush.apply(result, slice(arguments, 1)); + } + if (err) { + callback(err, result); + } else if (++completed === size) { + iterate = throwError; + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace concatLimit + * @param {Array|Object} collection + * @param {number} limit - limit >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, [num]); + * }, num * 10); + * }; + * async.concatLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [1, 3, 5, 2, 4] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1, 5, 3, 4, 2]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, [num]); + * }, num * 10); + * }; + * async.cocnatLimit(array, 2, iterator, function(err, res) { + * console.log(res); // [1, 3, 5, 2, 4] + * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, [num]); + * }, num * 10); + * }; + * async.concatLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [1, 3, 5, 2, 4] + * console.log(order); // [1, 3, 5, 2, 4] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, num); + * }, num * 10); + * }; + * async.cocnatLimit(object, 2, iterator, function(err, res) { + * console.log(res); // [1, 3, 5, 2, 4] + * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']] + * }); + * + */ + function concatLimit(collection, limit, iterator, callback) { + callback = callback || noop; + var size, key, iter, item, iterate, result; + var sync = false; + var started = 0; + var completed = 0; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + result = []; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + var keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null, []); + } + result = result || Array(size); + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + if (started < size) { + iterator(collection[started], createCallback(started++)); + } + } + + function arrayIteratorWithIndex() { + if (started < size) { + iterator(collection[started], started, createCallback(started++)); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + iterator(item.value, createCallback(started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, makeConcatResult(result)); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + iterator(item.value, started, createCallback(started++)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, makeConcatResult(result)); + } + } + + function objectIterator() { + if (started < size) { + iterator(collection[keys[started]], createCallback(started++)); + } + } + + function objectIteratorWithKey() { + if (started < size) { + key = keys[started]; + iterator(collection[key], key, createCallback(started++)); + } + } + + function createCallback(index) { + return function(err, res) { + if (index === null) { + throwError(); + } + if (err) { + index = null; + iterate = noop; + callback = once(callback); + arrayEachSync(result, function(array, index) { + if (array === undefined) { + result[index] = noop; + } + }); + callback(err, makeConcatResult(result)); + return; + } + switch (arguments.length) { + case 0: + case 1: + result[index] = noop; + break; + case 2: + result[index] = res; + break; + default: + result[index] = slice(arguments, 1); + break; + } + index = null; + if (++completed === size) { + iterate = throwError; + callback(null, makeConcatResult(result)); + callback = throwError; + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + * @param {Function} symbolEach + */ + function createGroupBy(arrayEach, baseEach, symbolEach) { + return function groupBy(collection, iterator, callback) { + callback = callback || noop; + var size; + var completed = 0; + var result = {}; + + if (isArray(collection)) { + size = collection.length; + arrayEach(collection, iterator, createCallback); + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = symbolEach(collection, iterator, createCallback); + size && size === completed && callback(null, result); + } else if (typeof collection === obj) { + var keys = nativeKeys(collection); + size = keys.length; + baseEach(collection, iterator, createCallback, keys); + } + if (!size) { + callback(null, {}); + } + + function createCallback(value) { + var called = false; + return function done(err, key) { + if (called) { + throwError(); + } + called = true; + if (err) { + callback = once(callback); + callback(err, objectClone(result)); + return; + } + var array = result[key]; + if (!array) { + result[key] = [value]; + } else { + array.push(value); + } + if (++completed === size) { + callback(null, result); + } + }; + } + }; + } + + /** + * @memberof async + * @namespace groupBySeries + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [4.2, 6.4, 6.1]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupBySeries(array, iterator, function(err, res) { + * console.log(res); // { '4': [4.2], '6': [6.4, 6.1] } + * console.log(order); // [4.2, 6.4, 6.1] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [4.2, 6.4, 6.1]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupBySeries(array, iterator, function(err, res) { + * console.log(res); // { '4': [4.2], '6': [6.4, 6.1] } + * console.log(order); // [[4.2, 0], [6.4, 1], [6.1, 2]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 4.2, b: 6.4, c: 6.1 }; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupBySeries(object, iterator, function(err, res) { + * console.log(res); // { '4': [4.2], '6': [6.4, 6.1] } + * console.log(order); // [4.2, 6.4, 6.1] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 4.2, b: 6.4, c: 6.1 }; + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupBySeries(object, iterator, function(err, res) { + * console.log(res); // { '4': [4.2], '6': [6.4, 6.1] } + * console.log(order); // [[4.2, 'a'], [6.4, 'b'], [6.1, 'c']] + * }); + * + */ + function groupBySeries(collection, iterator, callback) { + callback = onlyOnce(callback || noop); + var size, key, value, keys, iter, item, iterate; + var sync = false; + var completed = 0; + var result = {}; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size) { + return callback(null, result); + } + iterate(); + + function arrayIterator() { + value = collection[completed]; + iterator(value, done); + } + + function arrayIteratorWithIndex() { + value = collection[completed]; + iterator(value, completed, done); + } + + function symbolIterator() { + item = iter.next(); + value = item.value; + item.done ? callback(null, result) : iterator(value, done); + } + + function symbolIteratorWithKey() { + item = iter.next(); + value = item.value; + item.done ? callback(null, result) : iterator(value, completed, done); + } + + function objectIterator() { + value = collection[keys[completed]]; + iterator(value, done); + } + + function objectIteratorWithKey() { + key = keys[completed]; + value = collection[key]; + iterator(value, key, done); + } + + function done(err, key) { + if (err) { + iterate = throwError; + callback = onlyOnce(callback); + callback(err, objectClone(result)); + return; + } + var array = result[key]; + if (!array) { + result[key] = [value]; + } else { + array.push(value); + } + if (++completed === size) { + iterate = throwError; + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace groupByLimit + * @param {Array|Object} collection + * @param {Function} iterator + * @param {Function} callback + * @example + * + * // array + * var order = []; + * var array = [1.1, 5.9, 3.2, 3.9, 2.1]; + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupByLimit(array, 2, iterator, function(err, res) { + * console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] } + * console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9] + * }); + * + * @example + * + * // array with index + * var order = []; + * var array = [1.1, 5.9, 3.2, 3.9, 2.1]; + * var iterator = function(num, index, done) { + * setTimeout(function() { + * order.push([num, index]); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupByLimit(array, 2, iterator, function(err, res) { + * console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] } + * console.log(order); // [[1.1, 0], [3.2, 2], [5.9, 1], [2.1, 4], [3.9, 3]] + * }); + * + * @example + * + * // object + * var order = []; + * var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 } + * var iterator = function(num, done) { + * setTimeout(function() { + * order.push(num); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupByLimit(object, 2, iterator, function(err, res) { + * console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] } + * console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9] + * }); + * + * @example + * + * // object with key + * var order = []; + * var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 } + * var iterator = function(num, key, done) { + * setTimeout(function() { + * order.push([num, key]); + * done(null, Math.floor(num)); + * }, num * 10); + * }; + * async.groupByLimit(object, 2, iterator, function(err, res) { + * console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] } + * console.log(order); // [[1.1, 'a'], [3.2, 'c'], [5.9, 'b'], [2.1, 'e'], [3.9, 'd']] + * }); + * + */ + function groupByLimit(collection, limit, iterator, callback) { + callback = callback || noop; + var size, index, key, value, keys, iter, item, iterate; + var sync = false; + var started = 0; + var completed = 0; + var result = {}; + + if (isArray(collection)) { + size = collection.length; + iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator; + } else if (!collection) { + } else if (iteratorSymbol && collection[iteratorSymbol]) { + size = Infinity; + iter = collection[iteratorSymbol](); + iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator; + } else if (typeof collection === obj) { + keys = nativeKeys(collection); + size = keys.length; + iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null, result); + } + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + if (started < size) { + value = collection[started++]; + iterator(value, createCallback(value)); + } + } + + function arrayIteratorWithIndex() { + index = started++; + if (index < size) { + value = collection[index]; + iterator(value, index, createCallback(value)); + } + } + + function symbolIterator() { + item = iter.next(); + if (item.done === false) { + started++; + value = item.value; + iterator(value, createCallback(value)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function symbolIteratorWithKey() { + item = iter.next(); + if (item.done === false) { + value = item.value; + iterator(value, started++, createCallback(value)); + } else if (completed === started && iterator !== noop) { + iterator = noop; + callback(null, result); + } + } + + function objectIterator() { + if (started < size) { + value = collection[keys[started++]]; + iterator(value, createCallback(value)); + } + } + + function objectIteratorWithKey() { + if (started < size) { + key = keys[started++]; + value = collection[key]; + iterator(value, key, createCallback(value)); + } + } + + function createCallback(value) { + var called = false; + return function(err, key) { + if (called) { + throwError(); + } + called = true; + if (err) { + iterate = noop; + callback = once(callback); + callback(err, objectClone(result)); + return; + } + var array = result[key]; + if (!array) { + result[key] = [value]; + } else { + array.push(value); + } + if (++completed === size) { + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + } + + /** + * @private + * @param {Function} arrayEach + * @param {Function} baseEach + */ + function createParallel(arrayEach, baseEach) { + return function parallel(tasks, callback) { + callback = callback || noop; + var size, keys, result; + var completed = 0; + + if (isArray(tasks)) { + size = tasks.length; + result = Array(size); + arrayEach(tasks, createCallback); + } else if (tasks && typeof tasks === obj) { + keys = nativeKeys(tasks); + size = keys.length; + result = {}; + baseEach(tasks, createCallback, keys); + } + if (!size) { + callback(null, result); + } + + function createCallback(key) { + return function(err, res) { + if (key === null) { + throwError(); + } + if (err) { + key = null; + callback = once(callback); + callback(err, result); + return; + } + result[key] = arguments.length <= 2 ? res : slice(arguments, 1); + key = null; + if (++completed === size) { + callback(null, result); + } + }; + } + }; + } + + /** + * @memberof async + * @namespace series + * @param {Array|Object} tasks - functions + * @param {Function} callback + * @example + * + * var order = []; + * var tasks = [ + * function(done) { + * setTimeout(function() { + * order.push(1); + * done(null, 1); + * }, 10); + * }, + * function(done) { + * setTimeout(function() { + * order.push(2); + * done(null, 2); + * }, 30); + * }, + * function(done) { + * setTimeout(function() { + * order.push(3); + * done(null, 3); + * }, 40); + * }, + * function(done) { + * setTimeout(function() { + * order.push(4); + * done(null, 4); + * }, 20); + * } + * ]; + * async.series(tasks, function(err, res) { + * console.log(res); // [1, 2, 3, 4]; + * console.log(order); // [1, 2, 3, 4] + * }); + * + * @example + * + * var order = []; + * var tasks = { + * 'a': function(done) { + * setTimeout(function() { + * order.push(1); + * done(null, 1); + * }, 10); + * }, + * 'b': function(done) { + * setTimeout(function() { + * order.push(2); + * done(null, 2); + * }, 30); + * }, + * 'c': function(done) { + * setTimeout(function() { + * order.push(3); + * done(null, 3); + * }, 40); + * }, + * 'd': function(done) { + * setTimeout(function() { + * order.push(4); + * done(null, 4); + * }, 20); + * } + * }; + * async.series(tasks, function(err, res) { + * console.log(res); // { a: 1, b: 2, c: 3, d:4 } + * console.log(order); // [1, 4, 2, 3] + * }); + * + */ + function series(tasks, callback) { + callback = callback || noop; + var size, key, keys, result, iterate; + var sync = false; + var completed = 0; + + if (isArray(tasks)) { + size = tasks.length; + result = Array(size); + iterate = arrayIterator; + } else if (tasks && typeof tasks === obj) { + keys = nativeKeys(tasks); + size = keys.length; + result = {}; + iterate = objectIterator; + } else { + return callback(null); + } + if (!size) { + return callback(null, result); + } + iterate(); + + function arrayIterator() { + key = completed; + tasks[completed](done); + } + + function objectIterator() { + key = keys[completed]; + tasks[key](done); + } + + function done(err, res) { + if (err) { + iterate = throwError; + callback = onlyOnce(callback); + callback(err, result); + return; + } + result[key] = arguments.length <= 2 ? res : slice(arguments, 1); + if (++completed === size) { + iterate = throwError; + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace parallelLimit + * @param {Array|Object} tasks - functions + * @param {number} limit - limit >= 1 + * @param {Function} callback + * @example + * + * var order = []; + * var tasks = [ + * function(done) { + * setTimeout(function() { + * order.push(1); + * done(null, 1); + * }, 10); + * }, + * function(done) { + * setTimeout(function() { + * order.push(2); + * done(null, 2); + * }, 50); + * }, + * function(done) { + * setTimeout(function() { + * order.push(3); + * done(null, 3); + * }, 30); + * }, + * function(done) { + * setTimeout(function() { + * order.push(4); + * done(null, 4); + * }, 40); + * } + * ]; + * async.parallelLimit(tasks, 2, function(err, res) { + * console.log(res); // [1, 2, 3, 4]; + * console.log(order); // [1, 3, 2, 4] + * }); + * + * @example + * + * var order = []; + * var tasks = { + * 'a': function(done) { + * setTimeout(function() { + * order.push(1); + * done(null, 1); + * }, 10); + * }, + * 'b': function(done) { + * setTimeout(function() { + * order.push(2); + * done(null, 2); + * }, 50); + * }, + * 'c': function(done) { + * setTimeout(function() { + * order.push(3); + * done(null, 3); + * }, 20); + * }, + * 'd': function(done) { + * setTimeout(function() { + * order.push(4); + * done(null, 4); + * }, 40); + * } + * }; + * async.parallelLimit(tasks, 2, function(err, res) { + * console.log(res); // { a: 1, b: 2, c: 3, d:4 } + * console.log(order); // [1, 3, 2, 4] + * }); + * + */ + function parallelLimit(tasks, limit, callback) { + callback = callback || noop; + var size, index, key, keys, result, iterate; + var sync = false; + var started = 0; + var completed = 0; + + if (isArray(tasks)) { + size = tasks.length; + result = Array(size); + iterate = arrayIterator; + } else if (tasks && typeof tasks === obj) { + keys = nativeKeys(tasks); + size = keys.length; + result = {}; + iterate = objectIterator; + } + if (!size || isNaN(limit) || limit < 1) { + return callback(null, result); + } + timesSync(limit > size ? size : limit, iterate); + + function arrayIterator() { + index = started++; + if (index < size) { + tasks[index](createCallback(index)); + } + } + + function objectIterator() { + if (started < size) { + key = keys[started++]; + tasks[key](createCallback(key)); + } + } + + function createCallback(key) { + return function(err, res) { + if (key === null) { + throwError(); + } + if (err) { + key = null; + iterate = noop; + callback = once(callback); + callback(err, result); + return; + } + result[key] = arguments.length <= 2 ? res : slice(arguments, 1); + key = null; + if (++completed === size) { + callback(null, result); + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + } + + /** + * @memberof async + * @namespace tryEach + * @param {Array|Object} tasks - functions + * @param {Function} callback + * @example + * + * var tasks = [ + * function(done) { + * setTimeout(function() { + * done(new Error('error')); + * }, 10); + * }, + * function(done) { + * setTimeout(function() { + * done(null, 2); + * }, 10); + * } + * ]; + * async.tryEach(tasks, function(err, res) { + * console.log(res); // 2 + * }); + * + * @example + * + * var tasks = [ + * function(done) { + * setTimeout(function() { + * done(new Error('error1')); + * }, 10); + * }, + * function(done) { + * setTimeout(function() { + * done(new Error('error2'); + * }, 10); + * } + * ]; + * async.tryEach(tasks, function(err, res) { + * console.log(err); // error2 + * console.log(res); // undefined + * }); + * + */ + function tryEach(tasks, callback) { + callback = callback || noop; + var size, keys, iterate; + var sync = false; + var completed = 0; + + if (isArray(tasks)) { + size = tasks.length; + iterate = arrayIterator; + } else if (tasks && typeof tasks === obj) { + keys = nativeKeys(tasks); + size = keys.length; + iterate = objectIterator; + } + if (!size) { + return callback(null); + } + iterate(); + + function arrayIterator() { + tasks[completed](done); + } + + function objectIterator() { + tasks[keys[completed]](done); + } + + function done(err, res) { + if (!err) { + if (arguments.length <= 2) { + callback(null, res); + } else { + callback(null, slice(arguments, 1)); + } + } else if (++completed === size) { + callback(err); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * check for waterfall tasks + * @private + * @param {Array} tasks + * @param {Function} callback + * @return {boolean} + */ + function checkWaterfallTasks(tasks, callback) { + if (!isArray(tasks)) { + callback(new Error('First argument to waterfall must be an array of functions')); + return false; + } + if (tasks.length === 0) { + callback(null); + return false; + } + return true; + } + + /** + * check for waterfall tasks + * @private + * @param {function} func + * @param {Array|Object} args - arguments + * @return {function} next + */ + function waterfallIterator(func, args, next) { + switch (args.length) { + case 0: + case 1: + return func(next); + case 2: + return func(args[1], next); + case 3: + return func(args[1], args[2], next); + case 4: + return func(args[1], args[2], args[3], next); + case 5: + return func(args[1], args[2], args[3], args[4], next); + case 6: + return func(args[1], args[2], args[3], args[4], args[5], next); + default: + args = slice(args, 1); + args.push(next); + return func.apply(null, args); + } + } + + /** + * @memberof async + * @namespace waterfall + * @param {Array} tasks - functions + * @param {Function} callback + * @example + * + * var order = []; + * var tasks = [ + * function(next) { + * setTimeout(function() { + * order.push(1); + * next(null, 1); + * }, 10); + * }, + * function(arg1, next) { + * setTimeout(function() { + * order.push(2); + * next(null, 1, 2); + * }, 30); + * }, + * function(arg1, arg2, next) { + * setTimeout(function() { + * order.push(3); + * next(null, 3); + * }, 20); + * }, + * function(arg1, next) { + * setTimeout(function() { + * order.push(4); + * next(null, 1, 2, 3, 4); + * }, 40); + * } + * ]; + * async.waterfall(tasks, function(err, arg1, arg2, arg3, arg4) { + * console.log(arg1, arg2, arg3, arg4); // 1 2 3 4 + * }); + * + */ + function waterfall(tasks, callback) { + callback = callback || noop; + if (!checkWaterfallTasks(tasks, callback)) { + return; + } + var func, args, done, sync; + var completed = 0; + var size = tasks.length; + waterfallIterator(tasks[0], [], createCallback(0)); + + function iterate() { + waterfallIterator(func, args, createCallback(func)); + } + + function createCallback(index) { + return function next(err, res) { + if (index === undefined) { + callback = noop; + throwError(); + } + index = undefined; + if (err) { + done = callback; + callback = throwError; + done(err); + return; + } + if (++completed === size) { + done = callback; + callback = throwError; + if (arguments.length <= 2) { + done(err, res); + } else { + done.apply(null, createArray(arguments)); + } + return; + } + if (sync) { + args = arguments; + func = tasks[completed] || throwError; + nextTick(iterate); + } else { + sync = true; + waterfallIterator(tasks[completed] || throwError, arguments, createCallback(completed)); + } + sync = false; + }; + } + } + + /** + * `angelFall` is like `waterfall` and inject callback to last argument of next task. + * + * @memberof async + * @namespace angelFall + * @param {Array} tasks - functions + * @param {Function} callback + * @example + * + * var order = []; + * var tasks = [ + * function(next) { + * setTimeout(function() { + * order.push(1); + * next(null, 1); + * }, 10); + * }, + * function(arg1, empty, next) { + * setTimeout(function() { + * order.push(2); + * next(null, 1, 2); + * }, 30); + * }, + * function(next) { + * setTimeout(function() { + * order.push(3); + * next(null, 3); + * }, 20); + * }, + * function(arg1, empty1, empty2, empty3, next) { + * setTimeout(function() { + * order.push(4); + * next(null, 1, 2, 3, 4); + * }, 40); + * } + * ]; + * async.angelFall(tasks, function(err, arg1, arg2, arg3, arg4) { + * console.log(arg1, arg2, arg3, arg4); // 1 2 3 4 + * }); + * + */ + function angelFall(tasks, callback) { + callback = callback || noop; + if (!checkWaterfallTasks(tasks, callback)) { + return; + } + var completed = 0; + var sync = false; + var size = tasks.length; + var func = tasks[completed]; + var args = []; + var iterate = function() { + switch (func.length) { + case 0: + try { + next(null, func()); + } catch (e) { + next(e); + } + return; + case 1: + return func(next); + case 2: + return func(args[1], next); + case 3: + return func(args[1], args[2], next); + case 4: + return func(args[1], args[2], args[3], next); + case 5: + return func(args[1], args[2], args[3], args[4], next); + default: + args = slice(args, 1); + args[func.length - 1] = next; + return func.apply(null, args); + } + }; + iterate(); + + function next(err, res) { + if (err) { + iterate = throwError; + callback = onlyOnce(callback); + callback(err); + return; + } + if (++completed === size) { + iterate = throwError; + var done = callback; + callback = throwError; + if (arguments.length === 2) { + done(err, res); + } else { + done.apply(null, createArray(arguments)); + } + return; + } + func = tasks[completed]; + args = arguments; + if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace whilst + * @param {Function} test + * @param {Function} iterator + * @param {Function} callback + */ + function whilst(test, iterator, callback) { + callback = callback || noop; + var sync = false; + if (test()) { + iterate(); + } else { + callback(null); + } + + function iterate() { + if (sync) { + nextTick(next); + } else { + sync = true; + iterator(done); + } + sync = false; + } + + function next() { + iterator(done); + } + + function done(err, arg) { + if (err) { + return callback(err); + } + if (arguments.length <= 2) { + if (test(arg)) { + iterate(); + } else { + callback(null, arg); + } + return; + } + arg = slice(arguments, 1); + if (test.apply(null, arg)) { + iterate(); + } else { + callback.apply(null, [null].concat(arg)); + } + } + } + + /** + * @memberof async + * @namespace doWhilst + * @param {Function} iterator + * @param {Function} test + * @param {Function} callback + */ + function doWhilst(iterator, test, callback) { + callback = callback || noop; + var sync = false; + next(); + + function iterate() { + if (sync) { + nextTick(next); + } else { + sync = true; + iterator(done); + } + sync = false; + } + + function next() { + iterator(done); + } + + function done(err, arg) { + if (err) { + return callback(err); + } + if (arguments.length <= 2) { + if (test(arg)) { + iterate(); + } else { + callback(null, arg); + } + return; + } + arg = slice(arguments, 1); + if (test.apply(null, arg)) { + iterate(); + } else { + callback.apply(null, [null].concat(arg)); + } + } + } + + /** + * @memberof async + * @namespace until + * @param {Function} test + * @param {Function} iterator + * @param {Function} callback + */ + function until(test, iterator, callback) { + callback = callback || noop; + var sync = false; + if (!test()) { + iterate(); + } else { + callback(null); + } + + function iterate() { + if (sync) { + nextTick(next); + } else { + sync = true; + iterator(done); + } + sync = false; + } + + function next() { + iterator(done); + } + + function done(err, arg) { + if (err) { + return callback(err); + } + if (arguments.length <= 2) { + if (!test(arg)) { + iterate(); + } else { + callback(null, arg); + } + return; + } + arg = slice(arguments, 1); + if (!test.apply(null, arg)) { + iterate(); + } else { + callback.apply(null, [null].concat(arg)); + } + } + } + + /** + * @memberof async + * @namespace doUntil + * @param {Function} iterator + * @param {Function} test + * @param {Function} callback + */ + function doUntil(iterator, test, callback) { + callback = callback || noop; + var sync = false; + next(); + + function iterate() { + if (sync) { + nextTick(next); + } else { + sync = true; + iterator(done); + } + sync = false; + } + + function next() { + iterator(done); + } + + function done(err, arg) { + if (err) { + return callback(err); + } + if (arguments.length <= 2) { + if (!test(arg)) { + iterate(); + } else { + callback(null, arg); + } + return; + } + arg = slice(arguments, 1); + if (!test.apply(null, arg)) { + iterate(); + } else { + callback.apply(null, [null].concat(arg)); + } + } + } + + /** + * @memberof async + * @namespace during + * @param {Function} test + * @param {Function} iterator + * @param {Function} callback + */ + function during(test, iterator, callback) { + callback = callback || noop; + _test(); + + function _test() { + test(iterate); + } + + function iterate(err, truth) { + if (err) { + return callback(err); + } + if (truth) { + iterator(done); + } else { + callback(null); + } + } + + function done(err) { + if (err) { + return callback(err); + } + _test(); + } + } + + /** + * @memberof async + * @namespace doDuring + * @param {Function} test + * @param {Function} iterator + * @param {Function} callback + */ + function doDuring(iterator, test, callback) { + callback = callback || noop; + iterate(null, true); + + function iterate(err, truth) { + if (err) { + return callback(err); + } + if (truth) { + iterator(done); + } else { + callback(null); + } + } + + function done(err, res) { + if (err) { + return callback(err); + } + switch (arguments.length) { + case 0: + case 1: + test(iterate); + break; + case 2: + test(res, iterate); + break; + default: + var args = slice(arguments, 1); + args.push(iterate); + test.apply(null, args); + break; + } + } + } + + /** + * @memberof async + * @namespace forever + */ + function forever(iterator, callback) { + var sync = false; + iterate(); + + function iterate() { + iterator(next); + } + + function next(err) { + if (err) { + if (callback) { + return callback(err); + } + throw err; + } + if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace compose + */ + function compose() { + return seq.apply(null, reverse(arguments)); + } + + /** + * @memberof async + * @namespace seq + */ + function seq(/* functions... */) { + var fns = createArray(arguments); + + return function() { + var self = this; + var args = createArray(arguments); + var callback = args[args.length - 1]; + if (typeof callback === func) { + args.pop(); + } else { + callback = noop; + } + reduce(fns, args, iterator, done); + + function iterator(newargs, fn, callback) { + var func = function(err) { + var nextargs = slice(arguments, 1); + callback(err, nextargs); + }; + newargs.push(func); + fn.apply(self, newargs); + } + + function done(err, res) { + res = isArray(res) ? res : [res]; + res.unshift(err); + callback.apply(self, res); + } + }; + } + + function createApplyEach(func) { + return function applyEach(fns /* arguments */) { + var go = function() { + var self = this; + var args = createArray(arguments); + var callback = args.pop() || noop; + return func(fns, iterator, callback); + + function iterator(fn, done) { + fn.apply(self, args.concat([done])); + } + }; + if (arguments.length > 1) { + var args = slice(arguments, 1); + return go.apply(this, args); + } else { + return go; + } + }; + } + + /** + * @see https://github.com/caolan/async/blob/master/lib/internal/DoublyLinkedList.js + */ + function DLL() { + this.head = null; + this.tail = null; + this.length = 0; + } + + DLL.prototype._removeLink = function(node) { + var prev = node.prev; + var next = node.next; + if (prev) { + prev.next = next; + } else { + this.head = next; + } + if (next) { + next.prev = prev; + } else { + this.tail = prev; + } + node.prev = null; + node.next = null; + this.length--; + return node; + }; + + DLL.prototype.empty = DLL; + + DLL.prototype._setInitial = function(node) { + this.length = 1; + this.head = this.tail = node; + }; + + DLL.prototype.insertBefore = function(node, newNode) { + newNode.prev = node.prev; + newNode.next = node; + if (node.prev) { + node.prev.next = newNode; + } else { + this.head = newNode; + } + node.prev = newNode; + this.length++; + }; + + DLL.prototype.unshift = function(node) { + if (this.head) { + this.insertBefore(this.head, node); + } else { + this._setInitial(node); + } + }; + + DLL.prototype.push = function(node) { + var tail = this.tail; + if (tail) { + node.prev = tail; + node.next = tail.next; + this.tail = node; + tail.next = node; + this.length++; + } else { + this._setInitial(node); + } + }; + + DLL.prototype.shift = function() { + return this.head && this._removeLink(this.head); + }; + + DLL.prototype.splice = function(end) { + var task; + var tasks = []; + while (end-- && (task = this.shift())) { + tasks.push(task); + } + return tasks; + }; + + DLL.prototype.remove = function(test) { + var node = this.head; + while (node) { + if (test(node)) { + this._removeLink(node); + } + node = node.next; + } + return this; + }; + + /** + * @private + */ + function baseQueue(isQueue, worker, concurrency, payload) { + if (concurrency === undefined) { + concurrency = 1; + } else if (isNaN(concurrency) || concurrency < 1) { + throw new Error('Concurrency must not be zero'); + } + + var workers = 0; + var workersList = []; + var _callback, _unshift; + + var q = { + _tasks: new DLL(), + concurrency: concurrency, + payload: payload, + saturated: noop, + unsaturated: noop, + buffer: concurrency / 4, + empty: noop, + drain: noop, + error: noop, + started: false, + paused: false, + push: push, + kill: kill, + unshift: unshift, + remove: remove, + process: isQueue ? runQueue : runCargo, + length: getLength, + running: running, + workersList: getWorkersList, + idle: idle, + pause: pause, + resume: resume, + _worker: worker + }; + return q; + + function push(tasks, callback) { + _insert(tasks, callback); + } + + function unshift(tasks, callback) { + _insert(tasks, callback, true); + } + + function _exec(task) { + var item = { + data: task, + callback: _callback + }; + if (_unshift) { + q._tasks.unshift(item); + } else { + q._tasks.push(item); + } + nextTick(q.process); + } + + function _insert(tasks, callback, unshift) { + if (callback == null) { + callback = noop; + } else if (typeof callback !== 'function') { + throw new Error('task callback must be a function'); + } + q.started = true; + var _tasks = isArray(tasks) ? tasks : [tasks]; + + if (tasks === undefined || !_tasks.length) { + if (q.idle()) { + nextTick(q.drain); + } + return; + } + + _unshift = unshift; + _callback = callback; + arrayEachSync(_tasks, _exec); + // Avoid leaking the callback + _callback = undefined; + } + + function kill() { + q.drain = noop; + q._tasks.empty(); + } + + function _next(q, tasks) { + var called = false; + return function done(err, res) { + if (called) { + throwError(); + } + called = true; + + workers--; + var task; + var index = -1; + var size = workersList.length; + var taskIndex = -1; + var taskSize = tasks.length; + var useApply = arguments.length > 2; + var args = useApply && createArray(arguments); + while (++taskIndex < taskSize) { + task = tasks[taskIndex]; + while (++index < size) { + if (workersList[index] === task) { + if (index === 0) { + workersList.shift(); + } else { + workersList.splice(index, 1); + } + index = size; + size--; + } + } + index = -1; + if (useApply) { + task.callback.apply(task, args); + } else { + task.callback(err, res); + } + if (err) { + q.error(err, task.data); + } + } + + if (workers <= q.concurrency - q.buffer) { + q.unsaturated(); + } + + if (q._tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + } + + function runQueue() { + while (!q.paused && workers < q.concurrency && q._tasks.length) { + var task = q._tasks.shift(); + workers++; + workersList.push(task); + if (q._tasks.length === 0) { + q.empty(); + } + if (workers === q.concurrency) { + q.saturated(); + } + var done = _next(q, [task]); + worker(task.data, done); + } + } + + function runCargo() { + while (!q.paused && workers < q.concurrency && q._tasks.length) { + var tasks = q._tasks.splice(q.payload || q._tasks.length); + var index = -1; + var size = tasks.length; + var data = Array(size); + while (++index < size) { + data[index] = tasks[index].data; + } + workers++; + nativePush.apply(workersList, tasks); + if (q._tasks.length === 0) { + q.empty(); + } + if (workers === q.concurrency) { + q.saturated(); + } + var done = _next(q, tasks); + worker(data, done); + } + } + + function getLength() { + return q._tasks.length; + } + + function running() { + return workers; + } + + function getWorkersList() { + return workersList; + } + + function idle() { + return q.length() + workers === 0; + } + + function pause() { + q.paused = true; + } + + function _resume() { + nextTick(q.process); + } + + function resume() { + if (q.paused === false) { + return; + } + q.paused = false; + var count = q.concurrency < q._tasks.length ? q.concurrency : q._tasks.length; + timesSync(count, _resume); + } + + /** + * @param {Function} test + */ + function remove(test) { + q._tasks.remove(test); + } + } + + /** + * @memberof async + * @namespace queue + */ + function queue(worker, concurrency) { + return baseQueue(true, worker, concurrency); + } + + /** + * @memberof async + * @namespace priorityQueue + */ + function priorityQueue(worker, concurrency) { + var q = baseQueue(true, worker, concurrency); + q.push = push; + delete q.unshift; + return q; + + function push(tasks, priority, callback) { + q.started = true; + priority = priority || 0; + var _tasks = isArray(tasks) ? tasks : [tasks]; + var taskSize = _tasks.length; + + if (tasks === undefined || taskSize === 0) { + if (q.idle()) { + nextTick(q.drain); + } + return; + } + + callback = typeof callback === func ? callback : noop; + var nextNode = q._tasks.head; + while (nextNode && priority >= nextNode.priority) { + nextNode = nextNode.next; + } + while (taskSize--) { + var item = { + data: _tasks[taskSize], + priority: priority, + callback: callback + }; + if (nextNode) { + q._tasks.insertBefore(nextNode, item); + } else { + q._tasks.push(item); + } + nextTick(q.process); + } + } + } + + /** + * @memberof async + * @namespace cargo + */ + function cargo(worker, payload) { + return baseQueue(false, worker, 1, payload); + } + + /** + * @memberof async + * @namespace auto + * @param {Object} tasks + * @param {number} [concurrency] + * @param {Function} [callback] + */ + function auto(tasks, concurrency, callback) { + if (typeof concurrency === func) { + callback = concurrency; + concurrency = null; + } + var keys = nativeKeys(tasks); + var rest = keys.length; + var results = {}; + if (rest === 0) { + return callback(null, results); + } + var runningTasks = 0; + var readyTasks = new DLL(); + var listeners = Object.create(null); + callback = onlyOnce(callback || noop); + concurrency = concurrency || rest; + + baseEachSync(tasks, iterator, keys); + proceedQueue(); + + function iterator(task, key) { + // no dependencies + var _task, _taskSize; + if (!isArray(task)) { + _task = task; + _taskSize = 0; + readyTasks.push([_task, _taskSize, done]); + return; + } + var dependencySize = task.length - 1; + _task = task[dependencySize]; + _taskSize = dependencySize; + if (dependencySize === 0) { + readyTasks.push([_task, _taskSize, done]); + return; + } + // dependencies + var index = -1; + while (++index < dependencySize) { + var dependencyName = task[index]; + if (notInclude(keys, dependencyName)) { + var msg = + 'async.auto task `' + + key + + '` has non-existent dependency `' + + dependencyName + + '` in ' + + task.join(', '); + throw new Error(msg); + } + var taskListeners = listeners[dependencyName]; + if (!taskListeners) { + taskListeners = listeners[dependencyName] = []; + } + taskListeners.push(taskListener); + } + + function done(err, arg) { + if (key === null) { + throwError(); + } + arg = arguments.length <= 2 ? arg : slice(arguments, 1); + if (err) { + rest = 0; + runningTasks = 0; + readyTasks.length = 0; + var safeResults = objectClone(results); + safeResults[key] = arg; + key = null; + var _callback = callback; + callback = noop; + _callback(err, safeResults); + return; + } + runningTasks--; + rest--; + results[key] = arg; + taskComplete(key); + key = null; + } + + function taskListener() { + if (--dependencySize === 0) { + readyTasks.push([_task, _taskSize, done]); + } + } + } + + function proceedQueue() { + if (readyTasks.length === 0 && runningTasks === 0) { + if (rest !== 0) { + throw new Error('async.auto task has cyclic dependencies'); + } + return callback(null, results); + } + while (readyTasks.length && runningTasks < concurrency && callback !== noop) { + runningTasks++; + var array = readyTasks.shift(); + if (array[1] === 0) { + array[0](array[2]); + } else { + array[0](results, array[2]); + } + } + } + + function taskComplete(key) { + var taskListeners = listeners[key] || []; + arrayEachSync(taskListeners, function(task) { + task(); + }); + proceedQueue(); + } + } + + var FN_ARGS = /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m; + var FN_ARG_SPLIT = /,/; + var FN_ARG = /(=.+)?(\s*)$/; + var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm; + + /** + * parse function arguments for `autoInject` + * + * @private + */ + function parseParams(func) { + func = func.toString().replace(STRIP_COMMENTS, ''); + func = func.match(FN_ARGS)[2].replace(' ', ''); + func = func ? func.split(FN_ARG_SPLIT) : []; + func = func.map(function(arg) { + return arg.replace(FN_ARG, '').trim(); + }); + return func; + } + + /** + * @memberof async + * @namespace autoInject + * @param {Object} tasks + * @param {number} [concurrency] + * @param {Function} [callback] + */ + function autoInject(tasks, concurrency, callback) { + var newTasks = {}; + baseEachSync(tasks, iterator, nativeKeys(tasks)); + auto(newTasks, concurrency, callback); + + function iterator(task, key) { + var params; + var taskLength = task.length; + + if (isArray(task)) { + if (taskLength === 0) { + throw new Error('autoInject task functions require explicit parameters.'); + } + params = createArray(task); + taskLength = params.length - 1; + task = params[taskLength]; + if (taskLength === 0) { + newTasks[key] = task; + return; + } + } else if (taskLength === 1) { + newTasks[key] = task; + return; + } else { + params = parseParams(task); + if (taskLength === 0 && params.length === 0) { + throw new Error('autoInject task functions require explicit parameters.'); + } + taskLength = params.length - 1; + } + params[taskLength] = newTask; + newTasks[key] = params; + + function newTask(results, done) { + switch (taskLength) { + case 1: + task(results[params[0]], done); + break; + case 2: + task(results[params[0]], results[params[1]], done); + break; + case 3: + task(results[params[0]], results[params[1]], results[params[2]], done); + break; + default: + var i = -1; + while (++i < taskLength) { + params[i] = results[params[i]]; + } + params[i] = done; + task.apply(null, params); + break; + } + } + } + } + + /** + * @memberof async + * @namespace retry + * @param {integer|Object|Function} opts + * @param {Function} [task] + * @param {Function} [callback] + */ + function retry(opts, task, callback) { + var times, intervalFunc, errorFilter; + var count = 0; + if (arguments.length < 3 && typeof opts === func) { + callback = task || noop; + task = opts; + opts = null; + times = DEFAULT_TIMES; + } else { + callback = callback || noop; + switch (typeof opts) { + case 'object': + if (typeof opts.errorFilter === func) { + errorFilter = opts.errorFilter; + } + var interval = opts.interval; + switch (typeof interval) { + case func: + intervalFunc = interval; + break; + case 'string': + case 'number': + interval = +interval; + intervalFunc = interval + ? function() { + return interval; + } + : function() { + return DEFAULT_INTERVAL; + }; + break; + } + times = +opts.times || DEFAULT_TIMES; + break; + case 'number': + times = opts || DEFAULT_TIMES; + break; + case 'string': + times = +opts || DEFAULT_TIMES; + break; + default: + throw new Error('Invalid arguments for async.retry'); + } + } + if (typeof task !== 'function') { + throw new Error('Invalid arguments for async.retry'); + } + + if (intervalFunc) { + task(intervalCallback); + } else { + task(simpleCallback); + } + + function simpleIterator() { + task(simpleCallback); + } + + function simpleCallback(err, res) { + if (++count === times || !err || (errorFilter && !errorFilter(err))) { + if (arguments.length <= 2) { + return callback(err, res); + } + var args = createArray(arguments); + return callback.apply(null, args); + } + simpleIterator(); + } + + function intervalIterator() { + task(intervalCallback); + } + + function intervalCallback(err, res) { + if (++count === times || !err || (errorFilter && !errorFilter(err))) { + if (arguments.length <= 2) { + return callback(err, res); + } + var args = createArray(arguments); + return callback.apply(null, args); + } + setTimeout(intervalIterator, intervalFunc(count)); + } + } + + function retryable(opts, task) { + if (!task) { + task = opts; + opts = null; + } + return done; + + function done() { + var taskFn; + var args = createArray(arguments); + var lastIndex = args.length - 1; + var callback = args[lastIndex]; + switch (task.length) { + case 1: + taskFn = task1; + break; + case 2: + taskFn = task2; + break; + case 3: + taskFn = task3; + break; + default: + taskFn = task4; + } + if (opts) { + retry(opts, taskFn, callback); + } else { + retry(taskFn, callback); + } + + function task1(done) { + task(done); + } + + function task2(done) { + task(args[0], done); + } + + function task3(done) { + task(args[0], args[1], done); + } + + function task4(callback) { + args[lastIndex] = callback; + task.apply(null, args); + } + } + } + + /** + * @memberof async + * @namespace iterator + */ + function iterator(tasks) { + var size = 0; + var keys = []; + if (isArray(tasks)) { + size = tasks.length; + } else { + keys = nativeKeys(tasks); + size = keys.length; + } + return makeCallback(0); + + function makeCallback(index) { + var fn = function() { + if (size) { + var key = keys[index] || index; + tasks[key].apply(null, createArray(arguments)); + } + return fn.next(); + }; + fn.next = function() { + return index < size - 1 ? makeCallback(index + 1) : null; + }; + return fn; + } + } + + /** + * @memberof async + * @namespace apply + */ + function apply(func) { + switch (arguments.length) { + case 0: + case 1: + return func; + case 2: + return func.bind(null, arguments[1]); + case 3: + return func.bind(null, arguments[1], arguments[2]); + case 4: + return func.bind(null, arguments[1], arguments[2], arguments[3]); + case 5: + return func.bind(null, arguments[1], arguments[2], arguments[3], arguments[4]); + default: + var size = arguments.length; + var index = 0; + var args = Array(size); + args[index] = null; + while (++index < size) { + args[index] = arguments[index]; + } + return func.bind.apply(func, args); + } + } + + /** + * @memberof async + * @namespace timeout + * @param {Function} func + * @param {number} millisec + * @param {*} info + */ + function timeout(func, millisec, info) { + var callback, timer; + return wrappedFunc; + + function wrappedFunc() { + timer = setTimeout(timeoutCallback, millisec); + var args = createArray(arguments); + var lastIndex = args.length - 1; + callback = args[lastIndex]; + args[lastIndex] = injectedCallback; + simpleApply(func, args); + } + + function timeoutCallback() { + var name = func.name || 'anonymous'; + var err = new Error('Callback function "' + name + '" timed out.'); + err.code = 'ETIMEDOUT'; + if (info) { + err.info = info; + } + timer = null; + callback(err); + } + + function injectedCallback() { + if (timer !== null) { + simpleApply(callback, createArray(arguments)); + clearTimeout(timer); + } + } + + function simpleApply(func, args) { + switch (args.length) { + case 0: + func(); + break; + case 1: + func(args[0]); + break; + case 2: + func(args[0], args[1]); + break; + default: + func.apply(null, args); + break; + } + } + } + + /** + * @memberof async + * @namespace times + * @param {number} n - n >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * var iterator = function(n, done) { + * done(null, n); + * }; + * async.times(4, iterator, function(err, res) { + * console.log(res); // [0, 1, 2, 3]; + * }); + * + */ + function times(n, iterator, callback) { + callback = callback || noop; + n = +n; + if (isNaN(n) || n < 1) { + return callback(null, []); + } + var result = Array(n); + timesSync(n, iterate); + + function iterate(num) { + iterator(num, createCallback(num)); + } + + function createCallback(index) { + return function(err, res) { + if (index === null) { + throwError(); + } + result[index] = res; + index = null; + if (err) { + callback(err); + callback = noop; + } else if (--n === 0) { + callback(null, result); + } + }; + } + } + + /** + * @memberof async + * @namespace timesSeries + * @param {number} n - n >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * var iterator = function(n, done) { + * done(null, n); + * }; + * async.timesSeries(4, iterator, function(err, res) { + * console.log(res); // [0, 1, 2, 3]; + * }); + * + */ + function timesSeries(n, iterator, callback) { + callback = callback || noop; + n = +n; + if (isNaN(n) || n < 1) { + return callback(null, []); + } + var result = Array(n); + var sync = false; + var completed = 0; + iterate(); + + function iterate() { + iterator(completed, done); + } + + function done(err, res) { + result[completed] = res; + if (err) { + callback(err); + callback = throwError; + } else if (++completed >= n) { + callback(null, result); + callback = throwError; + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + } + } + + /** + * @memberof async + * @namespace timesLimit + * @param {number} n - n >= 1 + * @param {number} limit - n >= 1 + * @param {Function} iterator + * @param {Function} callback + * @example + * + * var iterator = function(n, done) { + * done(null, n); + * }; + * async.timesLimit(4, 2, iterator, function(err, res) { + * console.log(res); // [0, 1, 2, 3]; + * }); + * + */ + function timesLimit(n, limit, iterator, callback) { + callback = callback || noop; + n = +n; + if (isNaN(n) || n < 1 || isNaN(limit) || limit < 1) { + return callback(null, []); + } + var result = Array(n); + var sync = false; + var started = 0; + var completed = 0; + timesSync(limit > n ? n : limit, iterate); + + function iterate() { + var index = started++; + if (index < n) { + iterator(index, createCallback(index)); + } + } + + function createCallback(index) { + return function(err, res) { + if (index === null) { + throwError(); + } + result[index] = res; + index = null; + if (err) { + callback(err); + callback = noop; + } else if (++completed >= n) { + callback(null, result); + callback = throwError; + } else if (sync) { + nextTick(iterate); + } else { + sync = true; + iterate(); + } + sync = false; + }; + } + } + + /** + * @memberof async + * @namespace race + * @param {Array|Object} tasks - functions + * @param {Function} callback + * @example + * + * // array + * var called = 0; + * var tasks = [ + * function(done) { + * setTimeout(function() { + * called++; + * done(null, '1'); + * }, 30); + * }, + * function(done) { + * setTimeout(function() { + * called++; + * done(null, '2'); + * }, 20); + * }, + * function(done) { + * setTimeout(function() { + * called++; + * done(null, '3'); + * }, 10); + * } + * ]; + * async.race(tasks, function(err, res) { + * console.log(res); // '3' + * console.log(called); // 1 + * setTimeout(function() { + * console.log(called); // 3 + * }, 50); + * }); + * + * @example + * + * // object + * var called = 0; + * var tasks = { + * 'test1': function(done) { + * setTimeout(function() { + * called++; + * done(null, '1'); + * }, 30); + * }, + * 'test2': function(done) { + * setTimeout(function() { + * called++; + * done(null, '2'); + * }, 20); + * }, + * 'test3': function(done) { + * setTimeout(function() { + * called++; + * done(null, '3'); + * }, 10); + * } + * }; + * async.race(tasks, function(err, res) { + * console.log(res); // '3' + * console.log(called); // 1 + * setTimeout(function() { + * console.log(called); // 3 + * done(); + * }, 50); + * }); + * + */ + function race(tasks, callback) { + callback = once(callback || noop); + var size, keys; + var index = -1; + if (isArray(tasks)) { + size = tasks.length; + while (++index < size) { + tasks[index](callback); + } + } else if (tasks && typeof tasks === obj) { + keys = nativeKeys(tasks); + size = keys.length; + while (++index < size) { + tasks[keys[index]](callback); + } + } else { + return callback(new TypeError('First argument to race must be a collection of functions')); + } + if (!size) { + callback(null); + } + } + + /** + * @memberof async + * @namespace memoize + */ + function memoize(fn, hasher) { + hasher = + hasher || + function(hash) { + return hash; + }; + + var memo = {}; + var queues = {}; + var memoized = function() { + var args = createArray(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (has(memo, key)) { + nextTick(function() { + callback.apply(null, memo[key]); + }); + return; + } + if (has(queues, key)) { + return queues[key].push(callback); + } + + queues[key] = [callback]; + args.push(done); + fn.apply(null, args); + + function done(err) { + var args = createArray(arguments); + if (!err) { + memo[key] = args; + } + var q = queues[key]; + delete queues[key]; + + var i = -1; + var size = q.length; + while (++i < size) { + q[i].apply(null, args); + } + } + }; + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + } + + /** + * @memberof async + * @namespace unmemoize + */ + function unmemoize(fn) { + return function() { + return (fn.unmemoized || fn).apply(null, arguments); + }; + } + + /** + * @memberof async + * @namespace ensureAsync + */ + function ensureAsync(fn) { + return function(/* ...args, callback */) { + var args = createArray(arguments); + var lastIndex = args.length - 1; + var callback = args[lastIndex]; + var sync = true; + args[lastIndex] = done; + fn.apply(this, args); + sync = false; + + function done() { + var innerArgs = createArray(arguments); + if (sync) { + nextTick(function() { + callback.apply(null, innerArgs); + }); + } else { + callback.apply(null, innerArgs); + } + } + }; + } + + /** + * @memberof async + * @namespace constant + */ + function constant(/* values... */) { + var args = [null].concat(createArray(arguments)); + return function(callback) { + callback = arguments[arguments.length - 1]; + callback.apply(this, args); + }; + } + + function asyncify(fn) { + return function(/* args..., callback */) { + var args = createArray(arguments); + var callback = args.pop(); + var result; + try { + result = fn.apply(this, args); + } catch (e) { + return callback(e); + } + if (result && typeof result.then === func) { + result.then( + function(value) { + invokeCallback(callback, null, value); + }, + function(err) { + invokeCallback(callback, err && err.message ? err : new Error(err)); + } + ); + } else { + callback(null, result); + } + }; + } + + function invokeCallback(callback, err, value) { + try { + callback(err, value); + } catch (e) { + nextTick(rethrow, e); + } + } + + function rethrow(error) { + throw error; + } + + /** + * @memberof async + * @namespace reflect + * @param {Function} func + * @return {Function} + */ + function reflect(func) { + return function(/* args..., callback */) { + var callback; + switch (arguments.length) { + case 1: + callback = arguments[0]; + return func(done); + case 2: + callback = arguments[1]; + return func(arguments[0], done); + default: + var args = createArray(arguments); + var lastIndex = args.length - 1; + callback = args[lastIndex]; + args[lastIndex] = done; + func.apply(this, args); + } + + function done(err, res) { + if (err) { + return callback(null, { + error: err + }); + } + if (arguments.length > 2) { + res = slice(arguments, 1); + } + callback(null, { + value: res + }); + } + }; + } + + /** + * @memberof async + * @namespace reflectAll + * @param {Array[]|Object} tasks + * @return {Function} + */ + function reflectAll(tasks) { + var newTasks, keys; + if (isArray(tasks)) { + newTasks = Array(tasks.length); + arrayEachSync(tasks, iterate); + } else if (tasks && typeof tasks === obj) { + keys = nativeKeys(tasks); + newTasks = {}; + baseEachSync(tasks, iterate, keys); + } + return newTasks; + + function iterate(func, key) { + newTasks[key] = reflect(func); + } + } + + /** + * @memberof async + * @namespace createLogger + */ + function createLogger(name) { + return function(fn) { + var args = slice(arguments, 1); + args.push(done); + fn.apply(null, args); + }; + + function done(err) { + if (typeof console === obj) { + if (err) { + if (console.error) { + console.error(err); + } + return; + } + if (console[name]) { + var args = slice(arguments, 1); + arrayEachSync(args, function(arg) { + console[name](arg); + }); + } + } + } + } + + /** + * @memberof async + * @namespace safe + */ + function safe() { + createImmediate(); + return exports; + } + + /** + * @memberof async + * @namespace fast + */ + function fast() { + createImmediate(false); + return exports; + } +}); diff --git a/libs/events/node_modules/neo-async/async.min.js b/libs/events/node_modules/neo-async/async.min.js new file mode 100644 index 000000000..4161a3f6e --- /dev/null +++ b/libs/events/node_modules/neo-async/async.min.js @@ -0,0 +1,80 @@ +(function(N,O){"object"===typeof exports&&"undefined"!==typeof module?O(exports):"function"===typeof define&&define.amd?define(["exports"],O):N.async?O(N.neo_async=N.neo_async||{}):O(N.async=N.async||{})})(this,function(N){function O(a){var c=function(a){var d=J(arguments,1);setTimeout(function(){a.apply(null,d)})};T="function"===typeof setImmediate?setImmediate:c;"object"===typeof process&&"function"===typeof process.nextTick?(D=/^v0.10/.test(process.version)?T:process.nextTick,ba=/^v0/.test(process.version)? +T:process.nextTick):ba=D=T;!1===a&&(D=function(a){a()})}function H(a){for(var c=-1,b=a.length,d=Array(b);++c=d)return[];for(var e=Array(d);++bd[e]){var g=d[f]; +d[f]=d[e];d[e]=g}}if(!(e>b)){for(var l,e=a[a[c]>a[e]?c:e],f=c,g=b;f<=g;){for(l=f;f=l&&a[g]>=e;)g--;if(f>g)break;var q=a;l=d;var s=f++,h=g--,k=q[s];q[s]=q[h];q[h]=k;q=l[s];l[s]=l[h];l[h]=q}e=f;ca(a,c,e-1,d);ca(a,e,b,d)}}}function S(a){var c=[];Q(a,function(a){a!==w&&(C(a)?X.apply(c,a):c.push(a))});return c}function da(a,c,b){var d=-1,e=a.length;if(3===c.length)for(;++db)return e(null,[]);y=y||Array(m);K(b>m?m:b,x)}}function Y(a,c,b){function d(){c(a[v],s)}function e(){c(a[v],v,s)}function f(){n=r.next();n.done?b(null):c(n.value,s)}function g(){n=r.next();n.done?b(null):c(n.value,v,s)}function l(){c(a[m[v]],s)}function q(){k=m[v];c(a[k],k,s)}function s(a,d){a?b(a):++v===h||!1===d?(p=A,b(null)):u?D(p): +(u=!0,p());u=!1}b=E(b||w);var h,k,m,r,n,p,u=!1,v=0;C(a)?(h=a.length,p=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,r=a[z](),p=3===c.length?g:f):"object"===typeof a&&(m=F(a),h=m.length,p=3===c.length?q:l));if(!h)return b(null);p()}function Z(a,c,b,d){function e(){xc)return d(null);K(c>k?k:c,v)}function za(a,c,b){function d(){c(a[t],s)}function e(){c(a[t],t,s)}function f(){n=r.next(); +n.done?b(null,p):c(n.value,s)}function g(){n=r.next();n.done?b(null,p):c(n.value,t,s)}function l(){c(a[m[t]],s)}function q(){k=m[t];c(a[k],k,s)}function s(a,d){a?(u=A,b=E(b),b(a,H(p))):(p[t]=d,++t===h?(u=A,b(null,p),b=A):v?D(u):(v=!0,u()),v=!1)}b=b||w;var h,k,m,r,n,p,u,v=!1,t=0;C(a)?(h=a.length,u=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,p=[],r=a[z](),u=3===c.length?g:f):"object"===typeof a&&(m=F(a),h=m.length,u=3===c.length?q:l));if(!h)return b(null,[]);p=p||Array(h);u()}function Aa(a,c,b,d){return function(e, +f,g){function l(a){var b=!1;return function(c,e){b&&A();b=!0;c?(g=I(g),g(c)):!!e===d?(g=I(g),g(null,a)):++h===q&&g(null)}}g=g||w;var q,s,h=0;C(e)?(q=e.length,a(e,f,l)):e&&(z&&e[z]?(q=b(e,f,l))&&q===h&&g(null):"object"===typeof e&&(s=F(e),q=s.length,c(e,f,l,s)));q||g(null)}}function Ba(a){return function(c,b,d){function e(){r=c[x];b(r,h)}function f(){r=c[x];b(r,x,h)}function g(){u=p.next();r=u.value;u.done?d(null):b(r,h)}function l(){u=p.next();r=u.value;u.done?d(null):b(r,x,h)}function q(){r=c[n[x]]; +b(r,h)}function s(){m=n[x];r=c[m];b(r,m,h)}function h(b,c){b?d(b):!!c===a?(v=A,d(null,r)):++x===k?(v=A,d(null)):t?D(v):(t=!0,v());t=!1}d=E(d||w);var k,m,r,n,p,u,v,t=!1,x=0;C(c)?(k=c.length,v=3===b.length?f:e):c&&(z&&c[z]?(k=Infinity,p=c[z](),v=3===b.length?l:g):"object"===typeof c&&(n=F(c),k=n.length,v=3===b.length?s:q));if(!k)return d(null);v()}}function Ca(a){return function(c,b,d,e){function f(){r=G++;rb)return e(null);K(b>m?m:b,x)}}function Da(a,c,b,d){return function(e,f,g){function l(a,b){return function(c,e){null===a&&A();c?(a=null,g=I(g),g(c,L(k))):(!!e===d&&(k[a]=b),a=null,++h===q&&g(null,k))}}g=g||w;var q,s,h=0,k={};C(e)?(q=e.length,a(e,f,l)):e&&(z&&e[z]?(q=b(e,f,l))&&q===h&&g(null,k):"object"===typeof e&&(s=F(e),q=s.length,c(e,f,l,s)));if(!q)return g(null,{})}}function Ea(a){return function(c, +b,d){function e(){m=y;r=c[y];b(r,h)}function f(){m=y;r=c[y];b(r,y,h)}function g(){m=y;u=p.next();r=u.value;u.done?d(null,x):b(r,h)}function l(){m=y;u=p.next();r=u.value;u.done?d(null,x):b(r,m,h)}function q(){m=n[y];r=c[m];b(r,h)}function s(){m=n[y];r=c[m];b(r,m,h)}function h(b,c){b?d(b,x):(!!c===a&&(x[m]=r),++y===k?(v=A,d(null,x)):t?D(v):(t=!0,v()),t=!1)}d=E(d||w);var k,m,r,n,p,u,v,t=!1,x={},y=0;C(c)?(k=c.length,v=3===b.length?f:e):c&&(z&&c[z]?(k=Infinity,p=c[z](),v=3===b.length?l:g):"object"===typeof c&& +(n=F(c),k=n.length,v=3===b.length?s:q));if(!k)return d(null,{});v()}}function Fa(a){return function(c,b,d,e){function f(){r=B++;rb)return e(null,{});K(b>m?m:b,x)}}function $(a,c,b,d){function e(d){b(d,a[t],h)}function f(d){b(d,a[t],t,h)}function g(a){p=n.next();p.done?d(null,a):b(a,p.value, +h)}function l(a){p=n.next();p.done?d(null,a):b(a,p.value,t,h)}function q(d){b(d,a[r[t]],h)}function s(d){m=r[t];b(d,a[m],m,h)}function h(a,c){a?d(a,c):++t===k?(b=A,d(null,c)):v?D(function(){u(c)}):(v=!0,u(c));v=!1}d=E(d||w);var k,m,r,n,p,u,v=!1,t=0;C(a)?(k=a.length,u=4===b.length?f:e):a&&(z&&a[z]?(k=Infinity,n=a[z](),u=4===b.length?l:g):"object"===typeof a&&(r=F(a),k=r.length,u=4===b.length?s:q));if(!k)return d(null,c);u(c)}function Ga(a,c,b,d){function e(d){b(d,a[--s],q)}function f(d){b(d,a[--s], +s,q)}function g(d){b(d,a[m[--s]],q)}function l(d){k=m[--s];b(d,a[k],k,q)}function q(a,b){a?d(a,b):0===s?(u=A,d(null,b)):v?D(function(){u(b)}):(v=!0,u(b));v=!1}d=E(d||w);var s,h,k,m,r,n,p,u,v=!1;if(C(a))s=a.length,u=4===b.length?f:e;else if(a)if(z&&a[z]){p=[];r=a[z]();for(h=-1;!1===(n=r.next()).done;)p[++h]=n.value;a=p;s=p.length;u=4===b.length?f:e}else"object"===typeof a&&(m=F(a),s=m.length,u=4===b.length?l:g);if(!s)return d(null,c);u(c)}function Ha(a,c,b){b=b||w;ja(a,c,function(a,c){if(a)return b(a); +b(null,!!c)})}function Ia(a,c,b){b=b||w;ka(a,c,function(a,c){if(a)return b(a);b(null,!!c)})}function Ja(a,c,b,d){d=d||w;la(a,c,b,function(a,b){if(a)return d(a);d(null,!!b)})}function Ka(a,c){return C(a)?0===a.length?(c(null),!1):!0:(c(Error("First argument to waterfall must be an array of functions")),!1)}function ma(a,c,b){switch(c.length){case 0:case 1:return a(b);case 2:return a(c[1],b);case 3:return a(c[1],c[2],b);case 4:return a(c[1],c[2],c[3],b);case 5:return a(c[1],c[2],c[3],c[4],b);case 6:return a(c[1], +c[2],c[3],c[4],c[5],b);default:return c=J(c,1),c.push(b),a.apply(null,c)}}function La(a,c){function b(b,h){if(b)q=A,c=E(c),c(b);else if(++d===f){q=A;var k=c;c=A;2===arguments.length?k(b,h):k.apply(null,H(arguments))}else g=a[d],l=arguments,e?D(q):(e=!0,q()),e=!1}c=c||w;if(Ka(a,c)){var d=0,e=!1,f=a.length,g=a[d],l=[],q=function(){switch(g.length){case 0:try{b(null,g())}catch(a){b(a)}break;case 1:return g(b);case 2:return g(l[1],b);case 3:return g(l[1],l[2],b);case 4:return g(l[1],l[2],l[3],b);case 5:return g(l[1], +l[2],l[3],l[4],b);default:return l=J(l,1),l[g.length-1]=b,g.apply(null,l)}};q()}}function Ma(){var a=H(arguments);return function(){var c=this,b=H(arguments),d=b[b.length-1];"function"===typeof d?b.pop():d=w;$(a,b,function(a,b,d){a.push(function(a){var b=J(arguments,1);d(a,b)});b.apply(c,a)},function(a,b){b=C(b)?b:[b];b.unshift(a);d.apply(c,b)})}}function Na(a){return function(c){var b=function(){var b=this,d=H(arguments),g=d.pop()||w;return a(c,function(a,c){a.apply(b,d.concat([c]))},g)};if(1b)throw Error("Concurrency must not be zero");var h=0,k=[],m,r,n={_tasks:new M,concurrency:b,payload:d,saturated:w,unsaturated:w,buffer:b/4,empty:w,drain:w,error:w,started:!1,paused:!1,push:function(a, +b){f(a,b)},kill:function(){n.drain=w;n._tasks.empty()},unshift:function(a,b){f(a,b,!0)},remove:function(a){n._tasks.remove(a)},process:a?l:q,length:function(){return n._tasks.length},running:function(){return h},workersList:function(){return k},idle:function(){return 0===n.length()+h},pause:function(){n.paused=!0},resume:function(){!1!==n.paused&&(n.paused=!1,K(n.concurrency=arguments.length?f:J(arguments,1);if(a){q=g=0;s.length=0;var k=L(l);k[d]=f;d=null;var h= +b;b=w;h(a,k)}else q--,g--,l[d]=f,e(d),d=null}function n(){0===--v&&s.push([p,u,c])}var p,u;if(C(a)){var v=a.length-1;p=a[v];u=v;if(0===v)s.push([p,u,c]);else for(var t=-1;++t=arguments.length)return b(a,e);var f=H(arguments);return b.apply(null,f)}c(d)}function e(){c(f)}function f(a,d){if(++s===g||!a||q&&!q(a)){if(2>=arguments.length)return b(a,d);var c=H(arguments);return b.apply(null,c)}setTimeout(e,l(s))}var g,l,q,s=0;if(3>arguments.length&&"function"===typeof a)b=c||w,c=a,a=null,g=5;else switch(b=b||w,typeof a){case "object":"function"===typeof a.errorFilter&&(q=a.errorFilter);var h=a.interval; +switch(typeof h){case "function":l=h;break;case "string":case "number":l=(h=+h)?function(){return h}:function(){return 0}}g=+a.times||5;break;case "number":g=a||5;break;case "string":g=+a||5;break;default:throw Error("Invalid arguments for async.retry");}if("function"!==typeof c)throw Error("Invalid arguments for async.retry");l?c(f):c(d)}function Pa(a){return function(){var c=H(arguments),b=c.pop(),d;try{d=a.apply(this,c)}catch(e){return b(e)}d&&"function"===typeof d.then?d.then(function(a){try{b(null, +a)}catch(d){D(Qa,d)}},function(a){a=a&&a.message?a:Error(a);try{b(a,void 0)}catch(d){D(Qa,d)}}):b(null,d)}}function Qa(a){throw a;}function Ra(a){return function(){function c(a,d){if(a)return b(null,{error:a});2=arguments.length?c:J(arguments,1),a=null,++q===f&&d(null,l))}}d=d||w;var f,g,l,q=0;C(b)?(f=b.length,l=Array(f),a(b,e)):b&&"object"===typeof b&&(g=F(b),f=g.length,l={},c(b,e,g));f||d(null,l)}}(function(a,c){for(var b=-1,d=a.length;++bc)return d(null,[]);v=v||Array(k);K(c>k?k:c,t)},mapValues:fb,mapValuesSeries:function(a,c,b){function d(){k=t;c(a[t], +s)}function e(){k=t;c(a[t],t,s)}function f(){k=t;n=r.next();n.done?b(null,v):c(n.value,s)}function g(){k=t;n=r.next();n.done?b(null,v):c(n.value,t,s)}function l(){k=m[t];c(a[k],s)}function q(){k=m[t];c(a[k],k,s)}function s(a,d){a?(p=A,b=E(b),b(a,L(v))):(v[k]=d,++t===h?(p=A,b(null,v),b=A):u?D(p):(u=!0,p()),u=!1)}b=b||w;var h,k,m,r,n,p,u=!1,v={},t=0;C(a)?(h=a.length,p=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,r=a[z](),p=3===c.length?g:f):"object"===typeof a&&(m=F(a),h=m.length,p=3===c.length?q:l)); +if(!h)return b(null,v);p()},mapValuesLimit:function(a,c,b,d){function e(){m=y++;mc)return d(null,x);K(c>k?k:c,v)},filter:Ta,filterSeries:Ua,filterLimit:Va,select:Ta,selectSeries:Ua,selectLimit:Va,reject:gb,rejectSeries:hb,rejectLimit:ib,detect:ja,detectSeries:ka,detectLimit:la,find:ja,findSeries:ka,findLimit:la,pick:jb,pickSeries:kb, +pickLimit:lb,omit:mb,omitSeries:nb,omitLimit:ob,reduce:$,inject:$,foldl:$,reduceRight:Ga,foldr:Ga,transform:pb,transformSeries:function(a,c,b,d){function e(){b(v,a[x],h)}function f(){b(v,a[x],x,h)}function g(){p=n.next();p.done?d(null,v):b(v,p.value,h)}function l(){p=n.next();p.done?d(null,v):b(v,p.value,x,h)}function q(){b(v,a[r[x]],h)}function s(){m=r[x];b(v,a[m],m,h)}function h(a,b){a?d(a,v):++x===k||!1===b?(u=A,d(null,v)):t?D(u):(t=!0,u());t=!1}3===arguments.length&&(d=b,b=c,c=void 0);d=E(d|| +w);var k,m,r,n,p,u,v,t=!1,x=0;C(a)?(k=a.length,v=void 0!==c?c:[],u=4===b.length?f:e):a&&(z&&a[z]?(k=Infinity,n=a[z](),v=void 0!==c?c:{},u=4===b.length?l:g):"object"===typeof a&&(r=F(a),k=r.length,v=void 0!==c?c:{},u=4===b.length?s:q));if(!k)return d(null,void 0!==c?c:v||{});u()},transformLimit:function(a,c,b,d,e){function f(){r=A++;rc)return e(null,void 0!==b?b:x||{});K(c>m?m:c,t)},sortBy:qb,sortBySeries:function(a,c,b){function d(){m=a[y];c(m,s)}function e(){m=a[y];c(m,y,s)}function f(){p=n.next();if(p.done)return b(null,P(u,v));m=p.value;u[y]=m;c(m,s)}function g(){p=n.next();if(p.done)return b(null,P(u,v));m=p.value;u[y]=m;c(m,y,s)}function l(){m=a[r[y]];u[y]=m;c(m,s)}function q(){k=r[y];m=a[k];u[y]=m;c(m,k,s)}function s(a,d){v[y]=d;a?b(a):++y===h?(t=A,b(null, +P(u,v))):x?D(t):(x=!0,t());x=!1}b=E(b||w);var h,k,m,r,n,p,u,v,t,x=!1,y=0;C(a)?(h=a.length,u=a,v=Array(h),t=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,u=[],v=[],n=a[z](),t=3===c.length?g:f):"object"===typeof a&&(r=F(a),h=r.length,u=Array(h),v=Array(h),t=3===c.length?q:l));if(!h)return b(null,[]);t()},sortByLimit:function(a,c,b,d){function e(){Bc)return d(null,[]);x=x||Array(k);K(c>k?k:c,y)},some:Ha,someSeries:Ia,someLimit:Ja,any:Ha,anySeries:Ia,anyLimit:Ja,every:Wa,everySeries:Xa,everyLimit:Ya,all:Wa,allSeries:Xa,allLimit:Ya,concat:rb,concatSeries:function(a,c,b){function d(){c(a[t],s)}function e(){c(a[t],t,s)}function f(){n=r.next();n.done?b(null,v):c(n.value,s)}function g(){n=r.next();n.done?b(null,v):c(n.value,t,s)}function l(){c(a[m[t]], +s)}function q(){k=m[t];c(a[k],k,s)}function s(a,d){C(d)?X.apply(v,d):2<=arguments.length&&X.apply(v,J(arguments,1));a?b(a,v):++t===h?(p=A,b(null,v)):u?D(p):(u=!0,p());u=!1}b=E(b||w);var h,k,m,r,n,p,u=!1,v=[],t=0;C(a)?(h=a.length,p=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,r=a[z](),p=3===c.length?g:f):"object"===typeof a&&(m=F(a),h=m.length,p=3===c.length?q:l));if(!h)return b(null,v);p()},concatLimit:function(a,c,b,d){function e(){tc)return d(null,[]);u=u||Array(k);K(c>k?k:c,p)},groupBy:sb,groupBySeries:function(a,c,b){function d(){m=a[t];c(m,s)}function e(){m=a[t];c(m,t,s)}function f(){p=n.next();m=p.value;p.done?b(null,x):c(m,s)}function g(){p=n.next();m=p.value;p.done? +b(null,x):c(m,t,s)}function l(){m=a[r[t]];c(m,s)}function q(){k=r[t];m=a[k];c(m,k,s)}function s(a,d){if(a)u=A,b=E(b),b(a,L(x));else{var c=x[d];c?c.push(m):x[d]=[m];++t===h?(u=A,b(null,x)):v?D(u):(v=!0,u());v=!1}}b=E(b||w);var h,k,m,r,n,p,u,v=!1,t=0,x={};C(a)?(h=a.length,u=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,n=a[z](),u=3===c.length?g:f):"object"===typeof a&&(r=F(a),h=r.length,u=3===c.length?q:l));if(!h)return b(null,x);u()},groupByLimit:function(a,c,b,d){function e(){yc)return d(null,B);K(c>k?k:c,t)},parallel:tb,series:function(a,c){function b(){g=k;a[k](e)}function d(){g=l[k];a[g](e)}function e(a,b){a?(s=A,c=E(c),c(a,q)):(q[g]=2>=arguments.length?b:J(arguments,1),++k===f?(s=A,c(null,q)):h?D(s):(h=!0,s()),h=!1)}c=c||w;var f,g,l,q,s,h=!1,k=0;if(C(a))f=a.length,q=Array(f), +s=b;else if(a&&"object"===typeof a)l=F(a),f=l.length,q={},s=d;else return c(null);if(!f)return c(null,q);s()},parallelLimit:function(a,c,b){function d(){l=r++;if(l=arguments.length?c:J(arguments,1),a=null,++n===g?b(null,h):m?D(k):(m=!0,k()),m=!1)}}b=b||w;var g,l,q,s,h,k,m=!1,r=0,n=0;C(a)?(g=a.length,h=Array(g),k=d):a&&"object"===typeof a&&(s=F(a),g=s.length,h= +{},k=e);if(!g||isNaN(c)||1>c)return b(null,h);K(c>g?g:c,k)},tryEach:function(a,c){function b(){a[q](e)}function d(){a[g[q]](e)}function e(a,b){a?++q===f?c(a):l():2>=arguments.length?c(null,b):c(null,J(arguments,1))}c=c||w;var f,g,l,q=0;C(a)?(f=a.length,l=b):a&&"object"===typeof a&&(g=F(a),f=g.length,l=d);if(!f)return c(null);l()},waterfall:function(a,c){function b(){ma(e,f,d(e))}function d(h){return function(k,m){void 0===h&&(c=w,A());h=void 0;k?(g=c,c=A,g(k)):++q===s?(g=c,c=A,2>=arguments.length? +g(k,m):g.apply(null,H(arguments))):(l?(f=arguments,e=a[q]||A,D(b)):(l=!0,ma(a[q]||A,arguments,d(q))),l=!1)}}c=c||w;if(Ka(a,c)){var e,f,g,l,q=0,s=a.length;ma(a[0],[],d(0))}},angelFall:La,angelfall:La,whilst:function(a,c,b){function d(){g?D(e):(g=!0,c(f));g=!1}function e(){c(f)}function f(c,e){if(c)return b(c);2>=arguments.length?a(e)?d():b(null,e):(e=J(arguments,1),a.apply(null,e)?d():b.apply(null,[null].concat(e)))}b=b||w;var g=!1;a()?d():b(null)},doWhilst:function(a,c,b){function d(){g?D(e):(g=!0, +a(f));g=!1}function e(){a(f)}function f(a,e){if(a)return b(a);2>=arguments.length?c(e)?d():b(null,e):(e=J(arguments,1),c.apply(null,e)?d():b.apply(null,[null].concat(e)))}b=b||w;var g=!1;e()},until:function(a,c,b){function d(){g?D(e):(g=!0,c(f));g=!1}function e(){c(f)}function f(c,e){if(c)return b(c);2>=arguments.length?a(e)?b(null,e):d():(e=J(arguments,1),a.apply(null,e)?b.apply(null,[null].concat(e)):d())}b=b||w;var g=!1;a()?b(null):d()},doUntil:function(a,c,b){function d(){g?D(e):(g=!0,a(f));g= +!1}function e(){a(f)}function f(a,e){if(a)return b(a);2>=arguments.length?c(e)?b(null,e):d():(e=J(arguments,1),c.apply(null,e)?b.apply(null,[null].concat(e)):d())}b=b||w;var g=!1;e()},during:function(a,c,b){function d(a,d){if(a)return b(a);d?c(e):b(null)}function e(c){if(c)return b(c);a(d)}b=b||w;a(d)},doDuring:function(a,c,b){function d(d,c){if(d)return b(d);c?a(e):b(null)}function e(a,e){if(a)return b(a);switch(arguments.length){case 0:case 1:c(d);break;case 2:c(e,d);break;default:var l=J(arguments, +1);l.push(d);c.apply(null,l)}}b=b||w;d(null,!0)},forever:function(a,c){function b(){a(d)}function d(a){if(a){if(c)return c(a);throw a;}e?D(b):(e=!0,b());e=!1}var e=!1;b()},compose:function(){return Ma.apply(null,Za(arguments))},seq:Ma,applyEach:ub,applyEachSeries:vb,queue:function(a,c){return na(!0,a,c)},priorityQueue:function(a,c){var b=na(!0,a,c);b.push=function(a,c,f){b.started=!0;c=c||0;var g=C(a)?a:[a],l=g.length;if(void 0===a||0===l)b.idle()&&D(b.drain);else{f="function"===typeof f?f:w;for(a= +b._tasks.head;a&&c>=a.priority;)a=a.next;for(;l--;){var q={data:g[l],priority:c,callback:f};a?b._tasks.insertBefore(a,q):b._tasks.push(q);D(b.process)}}};delete b.unshift;return b},cargo:function(a,c){return na(!1,a,1,c)},auto:Oa,autoInject:function(a,c,b){var d={};W(a,function(a,b){var c,l=a.length;if(C(a)){if(0===l)throw Error("autoInject task functions require explicit parameters.");c=H(a);l=c.length-1;a=c[l];if(0===l){d[b]=a;return}}else{if(1===l){d[b]=a;return}c=ab(a);if(0===l&&0===c.length)throw Error("autoInject task functions require explicit parameters."); +l=c.length-1}c[l]=function(b,d){switch(l){case 1:a(b[c[0]],d);break;case 2:a(b[c[0]],b[c[1]],d);break;case 3:a(b[c[0]],b[c[1]],b[c[2]],d);break;default:for(var f=-1;++fa)return b(null,[]);var e=Array(a);K(a,function(a){c(a,d(a))})},timesSeries:function(a,c,b){function d(){c(l, +e)}function e(c,e){f[l]=e;c?(b(c),b=A):++l>=a?(b(null,f),b=A):g?D(d):(g=!0,d());g=!1}b=b||w;a=+a;if(isNaN(a)||1>a)return b(null,[]);var f=Array(a),g=!1,l=0;d()},timesLimit:function(a,c,b,d){function e(){var c=q++;c=a?(d(null,g),d=A):l?D(e):(l=!0,e());l=!1}}d=d||w;a=+a;if(isNaN(a)||1>a||isNaN(c)||1>c)return d(null,[]);var g=Array(a),l=!1,q=0,s=0;K(c>a?a:c,e)},race:function(a,c){c=I(c||w);var b,d,e=-1;if(C(a))for(b= +a.length;++e 7.138) { + console.log('Buy more riffiwobbles'); +} +else { + console.log('Sell the xupptumblers'); +} + diff --git a/libs/events/node_modules/optimist/index.js b/libs/events/node_modules/optimist/index.js new file mode 100644 index 000000000..5f3d53a63 --- /dev/null +++ b/libs/events/node_modules/optimist/index.js @@ -0,0 +1,498 @@ +var path = require('path'); +var wordwrap = require('wordwrap'); + +/* Hack an instance of Argv with process.argv into Argv + so people can do + require('optimist')(['--beeble=1','-z','zizzle']).argv + to parse a list of args and + require('optimist').argv + to get a parsed version of process.argv. +*/ + +var inst = Argv(process.argv.slice(2)); +Object.keys(inst).forEach(function (key) { + Argv[key] = typeof inst[key] == 'function' + ? inst[key].bind(inst) + : inst[key]; +}); + +var exports = module.exports = Argv; +function Argv (args, cwd) { + var self = {}; + if (!cwd) cwd = process.cwd(); + + self.$0 = process.argv + .slice(0,2) + .map(function (x) { + var b = rebase(cwd, x); + return x.match(/^\//) && b.length < x.length + ? b : x + }) + .join(' ') + ; + + if (process.env._ != undefined && process.argv[1] == process.env._) { + self.$0 = process.env._.replace( + path.dirname(process.execPath) + '/', '' + ); + } + + var flags = { bools : {}, strings : {} }; + + self.boolean = function (bools) { + if (!Array.isArray(bools)) { + bools = [].slice.call(arguments); + } + + bools.forEach(function (name) { + flags.bools[name] = true; + }); + + return self; + }; + + self.string = function (strings) { + if (!Array.isArray(strings)) { + strings = [].slice.call(arguments); + } + + strings.forEach(function (name) { + flags.strings[name] = true; + }); + + return self; + }; + + var aliases = {}; + self.alias = function (x, y) { + if (typeof x === 'object') { + Object.keys(x).forEach(function (key) { + self.alias(key, x[key]); + }); + } + else if (Array.isArray(y)) { + y.forEach(function (yy) { + self.alias(x, yy); + }); + } + else { + var zs = (aliases[x] || []).concat(aliases[y] || []).concat(x, y); + aliases[x] = zs.filter(function (z) { return z != x }); + aliases[y] = zs.filter(function (z) { return z != y }); + } + + return self; + }; + + var demanded = {}; + self.demand = function (keys) { + if (typeof keys == 'number') { + if (!demanded._) demanded._ = 0; + demanded._ += keys; + } + else if (Array.isArray(keys)) { + keys.forEach(function (key) { + self.demand(key); + }); + } + else { + demanded[keys] = true; + } + + return self; + }; + + var usage; + self.usage = function (msg, opts) { + if (!opts && typeof msg === 'object') { + opts = msg; + msg = null; + } + + usage = msg; + + if (opts) self.options(opts); + + return self; + }; + + function fail (msg) { + self.showHelp(); + if (msg) console.error(msg); + process.exit(1); + } + + var checks = []; + self.check = function (f) { + checks.push(f); + return self; + }; + + var defaults = {}; + self.default = function (key, value) { + if (typeof key === 'object') { + Object.keys(key).forEach(function (k) { + self.default(k, key[k]); + }); + } + else { + defaults[key] = value; + } + + return self; + }; + + var descriptions = {}; + self.describe = function (key, desc) { + if (typeof key === 'object') { + Object.keys(key).forEach(function (k) { + self.describe(k, key[k]); + }); + } + else { + descriptions[key] = desc; + } + return self; + }; + + self.parse = function (args_) { + args = args_; + return self.argv; + }; + + self.option = self.options = function (key, opt) { + if (typeof key === 'object') { + Object.keys(key).forEach(function (k) { + self.options(k, key[k]); + }); + } + else { + if (opt.alias) self.alias(key, opt.alias); + if (opt.demand) self.demand(key); + if (typeof opt.default !== 'undefined') { + self.default(key, opt.default); + } + + if (opt.boolean || opt.type === 'boolean') { + self.boolean(key); + } + if (opt.string || opt.type === 'string') { + self.string(key); + } + + var desc = opt.describe || opt.description || opt.desc; + if (desc) { + self.describe(key, desc); + } + } + + return self; + }; + + var wrap = null; + self.wrap = function (cols) { + wrap = cols; + return self; + }; + + self.showHelp = function (fn) { + if (!fn) fn = console.error; + fn(self.help()); + }; + + self.help = function () { + var keys = Object.keys( + Object.keys(descriptions) + .concat(Object.keys(demanded)) + .concat(Object.keys(defaults)) + .reduce(function (acc, key) { + if (key !== '_') acc[key] = true; + return acc; + }, {}) + ); + + var help = keys.length ? [ 'Options:' ] : []; + + if (usage) { + help.unshift(usage.replace(/\$0/g, self.$0), ''); + } + + var switches = keys.reduce(function (acc, key) { + acc[key] = [ key ].concat(aliases[key] || []) + .map(function (sw) { + return (sw.length > 1 ? '--' : '-') + sw + }) + .join(', ') + ; + return acc; + }, {}); + + var switchlen = longest(Object.keys(switches).map(function (s) { + return switches[s] || ''; + })); + + var desclen = longest(Object.keys(descriptions).map(function (d) { + return descriptions[d] || ''; + })); + + keys.forEach(function (key) { + var kswitch = switches[key]; + var desc = descriptions[key] || ''; + + if (wrap) { + desc = wordwrap(switchlen + 4, wrap)(desc) + .slice(switchlen + 4) + ; + } + + var spadding = new Array( + Math.max(switchlen - kswitch.length + 3, 0) + ).join(' '); + + var dpadding = new Array( + Math.max(desclen - desc.length + 1, 0) + ).join(' '); + + var type = null; + + if (flags.bools[key]) type = '[boolean]'; + if (flags.strings[key]) type = '[string]'; + + if (!wrap && dpadding.length > 0) { + desc += dpadding; + } + + var prelude = ' ' + kswitch + spadding; + var extra = [ + type, + demanded[key] + ? '[required]' + : null + , + defaults[key] !== undefined + ? '[default: ' + JSON.stringify(defaults[key]) + ']' + : null + , + ].filter(Boolean).join(' '); + + var body = [ desc, extra ].filter(Boolean).join(' '); + + if (wrap) { + var dlines = desc.split('\n'); + var dlen = dlines.slice(-1)[0].length + + (dlines.length === 1 ? prelude.length : 0) + + body = desc + (dlen + extra.length > wrap - 2 + ? '\n' + + new Array(wrap - extra.length + 1).join(' ') + + extra + : new Array(wrap - extra.length - dlen + 1).join(' ') + + extra + ); + } + + help.push(prelude + body); + }); + + help.push(''); + return help.join('\n'); + }; + + Object.defineProperty(self, 'argv', { + get : parseArgs, + enumerable : true, + }); + + function parseArgs () { + var argv = { _ : [], $0 : self.$0 }; + Object.keys(flags.bools).forEach(function (key) { + setArg(key, defaults[key] || false); + }); + + function setArg (key, val) { + var value = !flags.strings[key] && isNumber(val) + ? Number(val) : val + ; + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + argv[x] = argv[key]; + }); + } + + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + + if (arg === '--') { + argv._.push.apply(argv._, args.slice(i + 1)); + break; + } + else if (arg.match(/^--.+=/)) { + // Using [\s\S] instead of . because js doesn't support the + // 'dotall' regex modifier. See: + // http://stackoverflow.com/a/1068308/13216 + var m = arg.match(/^--([^=]+)=([\s\S]*)$/); + setArg(m[1], m[2]); + } + else if (arg.match(/^--no-.+/)) { + var key = arg.match(/^--no-(.+)/)[1]; + setArg(key, false); + } + else if (arg.match(/^--.+/)) { + var key = arg.match(/^--(.+)/)[1]; + var next = args[i + 1]; + if (next !== undefined && !next.match(/^-/) + && !flags.bools[key] + && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + setArg(key, next); + i++; + } + else if (/^(true|false)$/.test(next)) { + setArg(key, next === 'true'); + i++; + } + else { + setArg(key, true); + } + } + else if (arg.match(/^-[^-]+/)) { + var letters = arg.slice(1,-1).split(''); + + var broken = false; + for (var j = 0; j < letters.length; j++) { + var next = arg.slice(j+2); + + if (next === '-') { + setArg(letters[j], next) + continue; + } + + if (/[A-Za-z]/.test(letters[j]) + && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { + setArg(letters[j], next); + break; + } + + if (letters[j+1] && letters[j+1].match(/\W/)) { + setArg(letters[j], arg.slice(j+2)); + broken = true; + break; + } + else { + setArg(letters[j], true); + } + } + + var key = arg.slice(-1)[0]; + if (!broken && key !== '-') { + + if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) + && !flags.bools[key] + && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + setArg(key, args[i+1]); + i++; + } + else if (args[i+1] && /true|false/.test(args[i+1])) { + setArg(key, args[i+1] === 'true'); + i++; + } + else { + setArg(key, true); + } + } + } + else { + argv._.push( + flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) + ); + } + } + + Object.keys(defaults).forEach(function (key) { + if (!(key in argv)) { + argv[key] = defaults[key]; + if (key in aliases) { + argv[aliases[key]] = defaults[key]; + } + } + }); + + if (demanded._ && argv._.length < demanded._) { + fail('Not enough non-option arguments: got ' + + argv._.length + ', need at least ' + demanded._ + ); + } + + var missing = []; + Object.keys(demanded).forEach(function (key) { + if (!argv[key]) missing.push(key); + }); + + if (missing.length) { + fail('Missing required arguments: ' + missing.join(', ')); + } + + checks.forEach(function (f) { + try { + if (f(argv) === false) { + fail('Argument check failed: ' + f.toString()); + } + } + catch (err) { + fail(err) + } + }); + + return argv; + } + + function longest (xs) { + return Math.max.apply( + null, + xs.map(function (x) { return x.length }) + ); + } + + return self; +}; + +// rebase an absolute path to a relative one with respect to a base directory +// exported for tests +exports.rebase = rebase; +function rebase (base, dir) { + var ds = path.normalize(dir).split('/').slice(1); + var bs = path.normalize(base).split('/').slice(1); + + for (var i = 0; ds[i] && ds[i] == bs[i]; i++); + ds.splice(0, i); bs.splice(0, i); + + var p = path.normalize( + bs.map(function () { return '..' }).concat(ds).join('/') + ).replace(/\/$/,'').replace(/^$/, '.'); + return p.match(/^[.\/]/) ? p : './' + p; +}; + +function setKey (obj, keys, value) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + if (o[key] === undefined) o[key] = {}; + o = o[key]; + }); + + var key = keys[keys.length - 1]; + if (o[key] === undefined || typeof o[key] === 'boolean') { + o[key] = value; + } + else if (Array.isArray(o[key])) { + o[key].push(value); + } + else { + o[key] = [ o[key], value ]; + } +} + +function isNumber (x) { + if (typeof x === 'number') return true; + if (/^0x[0-9a-f]+$/i.test(x)) return true; + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); +} diff --git a/libs/events/node_modules/optimist/node_modules/wordwrap/LICENSE b/libs/events/node_modules/optimist/node_modules/wordwrap/LICENSE new file mode 100644 index 000000000..ee27ba4b4 --- /dev/null +++ b/libs/events/node_modules/optimist/node_modules/wordwrap/LICENSE @@ -0,0 +1,18 @@ +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libs/events/node_modules/optimist/node_modules/wordwrap/README.markdown b/libs/events/node_modules/optimist/node_modules/wordwrap/README.markdown new file mode 100644 index 000000000..346374e0d --- /dev/null +++ b/libs/events/node_modules/optimist/node_modules/wordwrap/README.markdown @@ -0,0 +1,70 @@ +wordwrap +======== + +Wrap your words. + +example +======= + +made out of meat +---------------- + +meat.js + + var wrap = require('wordwrap')(15); + console.log(wrap('You and your whole family are made out of meat.')); + +output: + + You and your + whole family + are made out + of meat. + +centered +-------- + +center.js + + var wrap = require('wordwrap')(20, 60); + console.log(wrap( + 'At long last the struggle and tumult was over.' + + ' The machines had finally cast off their oppressors' + + ' and were finally free to roam the cosmos.' + + '\n' + + 'Free of purpose, free of obligation.' + + ' Just drifting through emptiness.' + + ' The sun was just another point of light.' + )); + +output: + + At long last the struggle and tumult + was over. The machines had finally cast + off their oppressors and were finally + free to roam the cosmos. + Free of purpose, free of obligation. + Just drifting through emptiness. The + sun was just another point of light. + +methods +======= + +var wrap = require('wordwrap'); + +wrap(stop), wrap(start, stop, params={mode:"soft"}) +--------------------------------------------------- + +Returns a function that takes a string and returns a new string. + +Pad out lines with spaces out to column `start` and then wrap until column +`stop`. If a word is longer than `stop - start` characters it will overflow. + +In "soft" mode, split chunks by `/(\S+\s+/` and don't break up chunks which are +longer than `stop - start`, in "hard" mode, split chunks with `/\b/` and break +up chunks longer than `stop - start`. + +wrap.hard(start, stop) +---------------------- + +Like `wrap()` but with `params.mode = "hard"`. diff --git a/libs/events/node_modules/optimist/node_modules/wordwrap/example/center.js b/libs/events/node_modules/optimist/node_modules/wordwrap/example/center.js new file mode 100644 index 000000000..a3fbaae98 --- /dev/null +++ b/libs/events/node_modules/optimist/node_modules/wordwrap/example/center.js @@ -0,0 +1,10 @@ +var wrap = require('wordwrap')(20, 60); +console.log(wrap( + 'At long last the struggle and tumult was over.' + + ' The machines had finally cast off their oppressors' + + ' and were finally free to roam the cosmos.' + + '\n' + + 'Free of purpose, free of obligation.' + + ' Just drifting through emptiness.' + + ' The sun was just another point of light.' +)); diff --git a/libs/events/node_modules/optimist/node_modules/wordwrap/example/meat.js b/libs/events/node_modules/optimist/node_modules/wordwrap/example/meat.js new file mode 100644 index 000000000..a4665e105 --- /dev/null +++ b/libs/events/node_modules/optimist/node_modules/wordwrap/example/meat.js @@ -0,0 +1,3 @@ +var wrap = require('wordwrap')(15); + +console.log(wrap('You and your whole family are made out of meat.')); diff --git a/libs/events/node_modules/optimist/node_modules/wordwrap/index.js b/libs/events/node_modules/optimist/node_modules/wordwrap/index.js new file mode 100644 index 000000000..c9bc94521 --- /dev/null +++ b/libs/events/node_modules/optimist/node_modules/wordwrap/index.js @@ -0,0 +1,76 @@ +var wordwrap = module.exports = function (start, stop, params) { + if (typeof start === 'object') { + params = start; + start = params.start; + stop = params.stop; + } + + if (typeof stop === 'object') { + params = stop; + start = start || params.start; + stop = undefined; + } + + if (!stop) { + stop = start; + start = 0; + } + + if (!params) params = {}; + var mode = params.mode || 'soft'; + var re = mode === 'hard' ? /\b/ : /(\S+\s+)/; + + return function (text) { + var chunks = text.toString() + .split(re) + .reduce(function (acc, x) { + if (mode === 'hard') { + for (var i = 0; i < x.length; i += stop - start) { + acc.push(x.slice(i, i + stop - start)); + } + } + else acc.push(x) + return acc; + }, []) + ; + + return chunks.reduce(function (lines, rawChunk) { + if (rawChunk === '') return lines; + + var chunk = rawChunk.replace(/\t/g, ' '); + + var i = lines.length - 1; + if (lines[i].length + chunk.length > stop) { + lines[i] = lines[i].replace(/\s+$/, ''); + + chunk.split(/\n/).forEach(function (c) { + lines.push( + new Array(start + 1).join(' ') + + c.replace(/^\s+/, '') + ); + }); + } + else if (chunk.match(/\n/)) { + var xs = chunk.split(/\n/); + lines[i] += xs.shift(); + xs.forEach(function (c) { + lines.push( + new Array(start + 1).join(' ') + + c.replace(/^\s+/, '') + ); + }); + } + else { + lines[i] += chunk; + } + + return lines; + }, [ new Array(start + 1).join(' ') ]).join('\n'); + }; +}; + +wordwrap.soft = wordwrap; + +wordwrap.hard = function (start, stop) { + return wordwrap(start, stop, { mode : 'hard' }); +}; diff --git a/libs/events/node_modules/optimist/node_modules/wordwrap/package.json b/libs/events/node_modules/optimist/node_modules/wordwrap/package.json new file mode 100644 index 000000000..10713abed --- /dev/null +++ b/libs/events/node_modules/optimist/node_modules/wordwrap/package.json @@ -0,0 +1,37 @@ +{ + "name" : "wordwrap", + "description" : "Wrap those words. Show them at what columns to start and stop.", + "version" : "0.0.3", + "repository" : { + "type" : "git", + "url" : "git://github.com/substack/node-wordwrap.git" + }, + "main" : "./index.js", + "keywords" : [ + "word", + "wrap", + "rule", + "format", + "column" + ], + "directories" : { + "lib" : ".", + "example" : "example", + "test" : "test" + }, + "scripts" : { + "test" : "expresso" + }, + "devDependencies" : { + "expresso" : "=0.7.x" + }, + "engines" : { + "node" : ">=0.4.0" + }, + "license" : "MIT", + "author" : { + "name" : "James Halliday", + "email" : "mail@substack.net", + "url" : "http://substack.net" + } +} diff --git a/libs/events/node_modules/optimist/node_modules/wordwrap/test/break.js b/libs/events/node_modules/optimist/node_modules/wordwrap/test/break.js new file mode 100644 index 000000000..749292ecc --- /dev/null +++ b/libs/events/node_modules/optimist/node_modules/wordwrap/test/break.js @@ -0,0 +1,30 @@ +var assert = require('assert'); +var wordwrap = require('../'); + +exports.hard = function () { + var s = 'Assert from {"type":"equal","ok":false,"found":1,"wanted":2,' + + '"stack":[],"id":"b7ddcd4c409de8799542a74d1a04689b",' + + '"browser":"chrome/6.0"}' + ; + var s_ = wordwrap.hard(80)(s); + + var lines = s_.split('\n'); + assert.equal(lines.length, 2); + assert.ok(lines[0].length < 80); + assert.ok(lines[1].length < 80); + + assert.equal(s, s_.replace(/\n/g, '')); +}; + +exports.break = function () { + var s = new Array(55+1).join('a'); + var s_ = wordwrap.hard(20)(s); + + var lines = s_.split('\n'); + assert.equal(lines.length, 3); + assert.ok(lines[0].length === 20); + assert.ok(lines[1].length === 20); + assert.ok(lines[2].length === 15); + + assert.equal(s, s_.replace(/\n/g, '')); +}; diff --git a/libs/events/node_modules/optimist/node_modules/wordwrap/test/idleness.txt b/libs/events/node_modules/optimist/node_modules/wordwrap/test/idleness.txt new file mode 100644 index 000000000..aa3f4907f --- /dev/null +++ b/libs/events/node_modules/optimist/node_modules/wordwrap/test/idleness.txt @@ -0,0 +1,63 @@ +In Praise of Idleness + +By Bertrand Russell + +[1932] + +Like most of my generation, I was brought up on the saying: 'Satan finds some mischief for idle hands to do.' Being a highly virtuous child, I believed all that I was told, and acquired a conscience which has kept me working hard down to the present moment. But although my conscience has controlled my actions, my opinions have undergone a revolution. I think that there is far too much work done in the world, that immense harm is caused by the belief that work is virtuous, and that what needs to be preached in modern industrial countries is quite different from what always has been preached. Everyone knows the story of the traveler in Naples who saw twelve beggars lying in the sun (it was before the days of Mussolini), and offered a lira to the laziest of them. Eleven of them jumped up to claim it, so he gave it to the twelfth. this traveler was on the right lines. But in countries which do not enjoy Mediterranean sunshine idleness is more difficult, and a great public propaganda will be required to inaugurate it. I hope that, after reading the following pages, the leaders of the YMCA will start a campaign to induce good young men to do nothing. If so, I shall not have lived in vain. + +Before advancing my own arguments for laziness, I must dispose of one which I cannot accept. Whenever a person who already has enough to live on proposes to engage in some everyday kind of job, such as school-teaching or typing, he or she is told that such conduct takes the bread out of other people's mouths, and is therefore wicked. If this argument were valid, it would only be necessary for us all to be idle in order that we should all have our mouths full of bread. What people who say such things forget is that what a man earns he usually spends, and in spending he gives employment. As long as a man spends his income, he puts just as much bread into people's mouths in spending as he takes out of other people's mouths in earning. The real villain, from this point of view, is the man who saves. If he merely puts his savings in a stocking, like the proverbial French peasant, it is obvious that they do not give employment. If he invests his savings, the matter is less obvious, and different cases arise. + +One of the commonest things to do with savings is to lend them to some Government. In view of the fact that the bulk of the public expenditure of most civilized Governments consists in payment for past wars or preparation for future wars, the man who lends his money to a Government is in the same position as the bad men in Shakespeare who hire murderers. The net result of the man's economical habits is to increase the armed forces of the State to which he lends his savings. Obviously it would be better if he spent the money, even if he spent it in drink or gambling. + +But, I shall be told, the case is quite different when savings are invested in industrial enterprises. When such enterprises succeed, and produce something useful, this may be conceded. In these days, however, no one will deny that most enterprises fail. That means that a large amount of human labor, which might have been devoted to producing something that could be enjoyed, was expended on producing machines which, when produced, lay idle and did no good to anyone. The man who invests his savings in a concern that goes bankrupt is therefore injuring others as well as himself. If he spent his money, say, in giving parties for his friends, they (we may hope) would get pleasure, and so would all those upon whom he spent money, such as the butcher, the baker, and the bootlegger. But if he spends it (let us say) upon laying down rails for surface card in some place where surface cars turn out not to be wanted, he has diverted a mass of labor into channels where it gives pleasure to no one. Nevertheless, when he becomes poor through failure of his investment he will be regarded as a victim of undeserved misfortune, whereas the gay spendthrift, who has spent his money philanthropically, will be despised as a fool and a frivolous person. + +All this is only preliminary. I want to say, in all seriousness, that a great deal of harm is being done in the modern world by belief in the virtuousness of work, and that the road to happiness and prosperity lies in an organized diminution of work. + +First of all: what is work? Work is of two kinds: first, altering the position of matter at or near the earth's surface relatively to other such matter; second, telling other people to do so. The first kind is unpleasant and ill paid; the second is pleasant and highly paid. The second kind is capable of indefinite extension: there are not only those who give orders, but those who give advice as to what orders should be given. Usually two opposite kinds of advice are given simultaneously by two organized bodies of men; this is called politics. The skill required for this kind of work is not knowledge of the subjects as to which advice is given, but knowledge of the art of persuasive speaking and writing, i.e. of advertising. + +Throughout Europe, though not in America, there is a third class of men, more respected than either of the classes of workers. There are men who, through ownership of land, are able to make others pay for the privilege of being allowed to exist and to work. These landowners are idle, and I might therefore be expected to praise them. Unfortunately, their idleness is only rendered possible by the industry of others; indeed their desire for comfortable idleness is historically the source of the whole gospel of work. The last thing they have ever wished is that others should follow their example. + +From the beginning of civilization until the Industrial Revolution, a man could, as a rule, produce by hard work little more than was required for the subsistence of himself and his family, although his wife worked at least as hard as he did, and his children added their labor as soon as they were old enough to do so. The small surplus above bare necessaries was not left to those who produced it, but was appropriated by warriors and priests. In times of famine there was no surplus; the warriors and priests, however, still secured as much as at other times, with the result that many of the workers died of hunger. This system persisted in Russia until 1917 [1], and still persists in the East; in England, in spite of the Industrial Revolution, it remained in full force throughout the Napoleonic wars, and until a hundred years ago, when the new class of manufacturers acquired power. In America, the system came to an end with the Revolution, except in the South, where it persisted until the Civil War. A system which lasted so long and ended so recently has naturally left a profound impress upon men's thoughts and opinions. Much that we take for granted about the desirability of work is derived from this system, and, being pre-industrial, is not adapted to the modern world. Modern technique has made it possible for leisure, within limits, to be not the prerogative of small privileged classes, but a right evenly distributed throughout the community. The morality of work is the morality of slaves, and the modern world has no need of slavery. + +It is obvious that, in primitive communities, peasants, left to themselves, would not have parted with the slender surplus upon which the warriors and priests subsisted, but would have either produced less or consumed more. At first, sheer force compelled them to produce and part with the surplus. Gradually, however, it was found possible to induce many of them to accept an ethic according to which it was their duty to work hard, although part of their work went to support others in idleness. By this means the amount of compulsion required was lessened, and the expenses of government were diminished. To this day, 99 per cent of British wage-earners would be genuinely shocked if it were proposed that the King should not have a larger income than a working man. The conception of duty, speaking historically, has been a means used by the holders of power to induce others to live for the interests of their masters rather than for their own. Of course the holders of power conceal this fact from themselves by managing to believe that their interests are identical with the larger interests of humanity. Sometimes this is true; Athenian slave-owners, for instance, employed part of their leisure in making a permanent contribution to civilization which would have been impossible under a just economic system. Leisure is essential to civilization, and in former times leisure for the few was only rendered possible by the labors of the many. But their labors were valuable, not because work is good, but because leisure is good. And with modern technique it would be possible to distribute leisure justly without injury to civilization. + +Modern technique has made it possible to diminish enormously the amount of labor required to secure the necessaries of life for everyone. This was made obvious during the war. At that time all the men in the armed forces, and all the men and women engaged in the production of munitions, all the men and women engaged in spying, war propaganda, or Government offices connected with the war, were withdrawn from productive occupations. In spite of this, the general level of well-being among unskilled wage-earners on the side of the Allies was higher than before or since. The significance of this fact was concealed by finance: borrowing made it appear as if the future was nourishing the present. But that, of course, would have been impossible; a man cannot eat a loaf of bread that does not yet exist. The war showed conclusively that, by the scientific organization of production, it is possible to keep modern populations in fair comfort on a small part of the working capacity of the modern world. If, at the end of the war, the scientific organization, which had been created in order to liberate men for fighting and munition work, had been preserved, and the hours of the week had been cut down to four, all would have been well. Instead of that the old chaos was restored, those whose work was demanded were made to work long hours, and the rest were left to starve as unemployed. Why? Because work is a duty, and a man should not receive wages in proportion to what he has produced, but in proportion to his virtue as exemplified by his industry. + +This is the morality of the Slave State, applied in circumstances totally unlike those in which it arose. No wonder the result has been disastrous. Let us take an illustration. Suppose that, at a given moment, a certain number of people are engaged in the manufacture of pins. They make as many pins as the world needs, working (say) eight hours a day. Someone makes an invention by which the same number of men can make twice as many pins: pins are already so cheap that hardly any more will be bought at a lower price. In a sensible world, everybody concerned in the manufacturing of pins would take to working four hours instead of eight, and everything else would go on as before. But in the actual world this would be thought demoralizing. The men still work eight hours, there are too many pins, some employers go bankrupt, and half the men previously concerned in making pins are thrown out of work. There is, in the end, just as much leisure as on the other plan, but half the men are totally idle while half are still overworked. In this way, it is insured that the unavoidable leisure shall cause misery all round instead of being a universal source of happiness. Can anything more insane be imagined? + +The idea that the poor should have leisure has always been shocking to the rich. In England, in the early nineteenth century, fifteen hours was the ordinary day's work for a man; children sometimes did as much, and very commonly did twelve hours a day. When meddlesome busybodies suggested that perhaps these hours were rather long, they were told that work kept adults from drink and children from mischief. When I was a child, shortly after urban working men had acquired the vote, certain public holidays were established by law, to the great indignation of the upper classes. I remember hearing an old Duchess say: 'What do the poor want with holidays? They ought to work.' People nowadays are less frank, but the sentiment persists, and is the source of much of our economic confusion. + +Let us, for a moment, consider the ethics of work frankly, without superstition. Every human being, of necessity, consumes, in the course of his life, a certain amount of the produce of human labor. Assuming, as we may, that labor is on the whole disagreeable, it is unjust that a man should consume more than he produces. Of course he may provide services rather than commodities, like a medical man, for example; but he should provide something in return for his board and lodging. to this extent, the duty of work must be admitted, but to this extent only. + +I shall not dwell upon the fact that, in all modern societies outside the USSR, many people escape even this minimum amount of work, namely all those who inherit money and all those who marry money. I do not think the fact that these people are allowed to be idle is nearly so harmful as the fact that wage-earners are expected to overwork or starve. + +If the ordinary wage-earner worked four hours a day, there would be enough for everybody and no unemployment -- assuming a certain very moderate amount of sensible organization. This idea shocks the well-to-do, because they are convinced that the poor would not know how to use so much leisure. In America men often work long hours even when they are well off; such men, naturally, are indignant at the idea of leisure for wage-earners, except as the grim punishment of unemployment; in fact, they dislike leisure even for their sons. Oddly enough, while they wish their sons to work so hard as to have no time to be civilized, they do not mind their wives and daughters having no work at all. the snobbish admiration of uselessness, which, in an aristocratic society, extends to both sexes, is, under a plutocracy, confined to women; this, however, does not make it any more in agreement with common sense. + +The wise use of leisure, it must be conceded, is a product of civilization and education. A man who has worked long hours all his life will become bored if he becomes suddenly idle. But without a considerable amount of leisure a man is cut off from many of the best things. There is no longer any reason why the bulk of the population should suffer this deprivation; only a foolish asceticism, usually vicarious, makes us continue to insist on work in excessive quantities now that the need no longer exists. + +In the new creed which controls the government of Russia, while there is much that is very different from the traditional teaching of the West, there are some things that are quite unchanged. The attitude of the governing classes, and especially of those who conduct educational propaganda, on the subject of the dignity of labor, is almost exactly that which the governing classes of the world have always preached to what were called the 'honest poor'. Industry, sobriety, willingness to work long hours for distant advantages, even submissiveness to authority, all these reappear; moreover authority still represents the will of the Ruler of the Universe, Who, however, is now called by a new name, Dialectical Materialism. + +The victory of the proletariat in Russia has some points in common with the victory of the feminists in some other countries. For ages, men had conceded the superior saintliness of women, and had consoled women for their inferiority by maintaining that saintliness is more desirable than power. At last the feminists decided that they would have both, since the pioneers among them believed all that the men had told them about the desirability of virtue, but not what they had told them about the worthlessness of political power. A similar thing has happened in Russia as regards manual work. For ages, the rich and their sycophants have written in praise of 'honest toil', have praised the simple life, have professed a religion which teaches that the poor are much more likely to go to heaven than the rich, and in general have tried to make manual workers believe that there is some special nobility about altering the position of matter in space, just as men tried to make women believe that they derived some special nobility from their sexual enslavement. In Russia, all this teaching about the excellence of manual work has been taken seriously, with the result that the manual worker is more honored than anyone else. What are, in essence, revivalist appeals are made, but not for the old purposes: they are made to secure shock workers for special tasks. Manual work is the ideal which is held before the young, and is the basis of all ethical teaching. + +For the present, possibly, this is all to the good. A large country, full of natural resources, awaits development, and has has to be developed with very little use of credit. In these circumstances, hard work is necessary, and is likely to bring a great reward. But what will happen when the point has been reached where everybody could be comfortable without working long hours? + +In the West, we have various ways of dealing with this problem. We have no attempt at economic justice, so that a large proportion of the total produce goes to a small minority of the population, many of whom do no work at all. Owing to the absence of any central control over production, we produce hosts of things that are not wanted. We keep a large percentage of the working population idle, because we can dispense with their labor by making the others overwork. When all these methods prove inadequate, we have a war: we cause a number of people to manufacture high explosives, and a number of others to explode them, as if we were children who had just discovered fireworks. By a combination of all these devices we manage, though with difficulty, to keep alive the notion that a great deal of severe manual work must be the lot of the average man. + +In Russia, owing to more economic justice and central control over production, the problem will have to be differently solved. the rational solution would be, as soon as the necessaries and elementary comforts can be provided for all, to reduce the hours of labor gradually, allowing a popular vote to decide, at each stage, whether more leisure or more goods were to be preferred. But, having taught the supreme virtue of hard work, it is difficult to see how the authorities can aim at a paradise in which there will be much leisure and little work. It seems more likely that they will find continually fresh schemes, by which present leisure is to be sacrificed to future productivity. I read recently of an ingenious plan put forward by Russian engineers, for making the White Sea and the northern coasts of Siberia warm, by putting a dam across the Kara Sea. An admirable project, but liable to postpone proletarian comfort for a generation, while the nobility of toil is being displayed amid the ice-fields and snowstorms of the Arctic Ocean. This sort of thing, if it happens, will be the result of regarding the virtue of hard work as an end in itself, rather than as a means to a state of affairs in which it is no longer needed. + +The fact is that moving matter about, while a certain amount of it is necessary to our existence, is emphatically not one of the ends of human life. If it were, we should have to consider every navvy superior to Shakespeare. We have been misled in this matter by two causes. One is the necessity of keeping the poor contented, which has led the rich, for thousands of years, to preach the dignity of labor, while taking care themselves to remain undignified in this respect. The other is the new pleasure in mechanism, which makes us delight in the astonishingly clever changes that we can produce on the earth's surface. Neither of these motives makes any great appeal to the actual worker. If you ask him what he thinks the best part of his life, he is not likely to say: 'I enjoy manual work because it makes me feel that I am fulfilling man's noblest task, and because I like to think how much man can transform his planet. It is true that my body demands periods of rest, which I have to fill in as best I may, but I am never so happy as when the morning comes and I can return to the toil from which my contentment springs.' I have never heard working men say this sort of thing. They consider work, as it should be considered, a necessary means to a livelihood, and it is from their leisure that they derive whatever happiness they may enjoy. + +It will be said that, while a little leisure is pleasant, men would not know how to fill their days if they had only four hours of work out of the twenty-four. In so far as this is true in the modern world, it is a condemnation of our civilization; it would not have been true at any earlier period. There was formerly a capacity for light-heartedness and play which has been to some extent inhibited by the cult of efficiency. The modern man thinks that everything ought to be done for the sake of something else, and never for its own sake. Serious-minded persons, for example, are continually condemning the habit of going to the cinema, and telling us that it leads the young into crime. But all the work that goes to producing a cinema is respectable, because it is work, and because it brings a money profit. The notion that the desirable activities are those that bring a profit has made everything topsy-turvy. The butcher who provides you with meat and the baker who provides you with bread are praiseworthy, because they are making money; but when you enjoy the food they have provided, you are merely frivolous, unless you eat only to get strength for your work. Broadly speaking, it is held that getting money is good and spending money is bad. Seeing that they are two sides of one transaction, this is absurd; one might as well maintain that keys are good, but keyholes are bad. Whatever merit there may be in the production of goods must be entirely derivative from the advantage to be obtained by consuming them. The individual, in our society, works for profit; but the social purpose of his work lies in the consumption of what he produces. It is this divorce between the individual and the social purpose of production that makes it so difficult for men to think clearly in a world in which profit-making is the incentive to industry. We think too much of production, and too little of consumption. One result is that we attach too little importance to enjoyment and simple happiness, and that we do not judge production by the pleasure that it gives to the consumer. + +When I suggest that working hours should be reduced to four, I am not meaning to imply that all the remaining time should necessarily be spent in pure frivolity. I mean that four hours' work a day should entitle a man to the necessities and elementary comforts of life, and that the rest of his time should be his to use as he might see fit. It is an essential part of any such social system that education should be carried further than it usually is at present, and should aim, in part, at providing tastes which would enable a man to use leisure intelligently. I am not thinking mainly of the sort of things that would be considered 'highbrow'. Peasant dances have died out except in remote rural areas, but the impulses which caused them to be cultivated must still exist in human nature. The pleasures of urban populations have become mainly passive: seeing cinemas, watching football matches, listening to the radio, and so on. This results from the fact that their active energies are fully taken up with work; if they had more leisure, they would again enjoy pleasures in which they took an active part. + +In the past, there was a small leisure class and a larger working class. The leisure class enjoyed advantages for which there was no basis in social justice; this necessarily made it oppressive, limited its sympathies, and caused it to invent theories by which to justify its privileges. These facts greatly diminished its excellence, but in spite of this drawback it contributed nearly the whole of what we call civilization. It cultivated the arts and discovered the sciences; it wrote the books, invented the philosophies, and refined social relations. Even the liberation of the oppressed has usually been inaugurated from above. Without the leisure class, mankind would never have emerged from barbarism. + +The method of a leisure class without duties was, however, extraordinarily wasteful. None of the members of the class had to be taught to be industrious, and the class as a whole was not exceptionally intelligent. The class might produce one Darwin, but against him had to be set tens of thousands of country gentlemen who never thought of anything more intelligent than fox-hunting and punishing poachers. At present, the universities are supposed to provide, in a more systematic way, what the leisure class provided accidentally and as a by-product. This is a great improvement, but it has certain drawbacks. University life is so different from life in the world at large that men who live in academic milieu tend to be unaware of the preoccupations and problems of ordinary men and women; moreover their ways of expressing themselves are usually such as to rob their opinions of the influence that they ought to have upon the general public. Another disadvantage is that in universities studies are organized, and the man who thinks of some original line of research is likely to be discouraged. Academic institutions, therefore, useful as they are, are not adequate guardians of the interests of civilization in a world where everyone outside their walls is too busy for unutilitarian pursuits. + +In a world where no one is compelled to work more than four hours a day, every person possessed of scientific curiosity will be able to indulge it, and every painter will be able to paint without starving, however excellent his pictures may be. Young writers will not be obliged to draw attention to themselves by sensational pot-boilers, with a view to acquiring the economic independence needed for monumental works, for which, when the time at last comes, they will have lost the taste and capacity. Men who, in their professional work, have become interested in some phase of economics or government, will be able to develop their ideas without the academic detachment that makes the work of university economists often seem lacking in reality. Medical men will have the time to learn about the progress of medicine, teachers will not be exasperatedly struggling to teach by routine methods things which they learnt in their youth, which may, in the interval, have been proved to be untrue. + +Above all, there will be happiness and joy of life, instead of frayed nerves, weariness, and dyspepsia. The work exacted will be enough to make leisure delightful, but not enough to produce exhaustion. Since men will not be tired in their spare time, they will not demand only such amusements as are passive and vapid. At least one per cent will probably devote the time not spent in professional work to pursuits of some public importance, and, since they will not depend upon these pursuits for their livelihood, their originality will be unhampered, and there will be no need to conform to the standards set by elderly pundits. But it is not only in these exceptional cases that the advantages of leisure will appear. Ordinary men and women, having the opportunity of a happy life, will become more kindly and less persecuting and less inclined to view others with suspicion. The taste for war will die out, partly for this reason, and partly because it will involve long and severe work for all. Good nature is, of all moral qualities, the one that the world needs most, and good nature is the result of ease and security, not of a life of arduous struggle. Modern methods of production have given us the possibility of ease and security for all; we have chosen, instead, to have overwork for some and starvation for others. Hitherto we have continued to be as energetic as we were before there were machines; in this we have been foolish, but there is no reason to go on being foolish forever. + +[1] Since then, members of the Communist Party have succeeded to this privilege of the warriors and priests. diff --git a/libs/events/node_modules/optimist/node_modules/wordwrap/test/wrap.js b/libs/events/node_modules/optimist/node_modules/wordwrap/test/wrap.js new file mode 100644 index 000000000..0cfb76d17 --- /dev/null +++ b/libs/events/node_modules/optimist/node_modules/wordwrap/test/wrap.js @@ -0,0 +1,31 @@ +var assert = require('assert'); +var wordwrap = require('wordwrap'); + +var fs = require('fs'); +var idleness = fs.readFileSync(__dirname + '/idleness.txt', 'utf8'); + +exports.stop80 = function () { + var lines = wordwrap(80)(idleness).split(/\n/); + var words = idleness.split(/\s+/); + + lines.forEach(function (line) { + assert.ok(line.length <= 80, 'line > 80 columns'); + var chunks = line.match(/\S/) ? line.split(/\s+/) : []; + assert.deepEqual(chunks, words.splice(0, chunks.length)); + }); +}; + +exports.start20stop60 = function () { + var lines = wordwrap(20, 100)(idleness).split(/\n/); + var words = idleness.split(/\s+/); + + lines.forEach(function (line) { + assert.ok(line.length <= 100, 'line > 100 columns'); + var chunks = line + .split(/\s+/) + .filter(function (x) { return x.match(/\S/) }) + ; + assert.deepEqual(chunks, words.splice(0, chunks.length)); + assert.deepEqual(line.slice(0, 20), new Array(20 + 1).join(' ')); + }); +}; diff --git a/libs/events/node_modules/optimist/package.json b/libs/events/node_modules/optimist/package.json new file mode 100644 index 000000000..2a370fe7b --- /dev/null +++ b/libs/events/node_modules/optimist/package.json @@ -0,0 +1,38 @@ +{ + "name" : "optimist", + "version" : "0.5.2", + "description" : "Light-weight option parsing with an argv hash. No optstrings attached.", + "main" : "./index.js", + "dependencies" : { + "wordwrap" : "~0.0.2" + }, + "devDependencies" : { + "hashish": "~0.0.4", + "tap" : "~0.4.0" + }, + "scripts" : { + "test" : "tap ./test/*.js" + }, + "repository" : { + "type" : "git", + "url" : "http://github.com/substack/node-optimist.git" + }, + "keywords" : [ + "argument", + "args", + "option", + "parser", + "parsing", + "cli", + "command" + ], + "author" : { + "name" : "James Halliday", + "email" : "mail@substack.net", + "url" : "http://substack.net" + }, + "license" : "MIT/X11", + "engine" : { + "node" : ">=0.4" + } +} diff --git a/libs/events/node_modules/optimist/readme.markdown b/libs/events/node_modules/optimist/readme.markdown new file mode 100644 index 000000000..ba3d11868 --- /dev/null +++ b/libs/events/node_modules/optimist/readme.markdown @@ -0,0 +1,500 @@ +optimist +======== + +Optimist is a node.js library for option parsing for people who hate option +parsing. More specifically, this module is for people who like all the --bells +and -whistlz of program usage but think optstrings are a waste of time. + +With optimist, option parsing doesn't have to suck (as much). + +[![build status](https://secure.travis-ci.org/substack/node-optimist.png)](http://travis-ci.org/substack/node-optimist) + +examples +======== + +With Optimist, the options are just a hash! No optstrings attached. +------------------------------------------------------------------- + +xup.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist').argv; + +if (argv.rif - 5 * argv.xup > 7.138) { + console.log('Buy more riffiwobbles'); +} +else { + console.log('Sell the xupptumblers'); +} +```` + +*** + + $ ./xup.js --rif=55 --xup=9.52 + Buy more riffiwobbles + + $ ./xup.js --rif 12 --xup 8.1 + Sell the xupptumblers + +![This one's optimistic.](http://substack.net/images/optimistic.png) + +But wait! There's more! You can do short options: +------------------------------------------------- + +short.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist').argv; +console.log('(%d,%d)', argv.x, argv.y); +```` + +*** + + $ ./short.js -x 10 -y 21 + (10,21) + +And booleans, both long and short (and grouped): +---------------------------------- + +bool.js: + +````javascript +#!/usr/bin/env node +var util = require('util'); +var argv = require('optimist').argv; + +if (argv.s) { + util.print(argv.fr ? 'Le chat dit: ' : 'The cat says: '); +} +console.log( + (argv.fr ? 'miaou' : 'meow') + (argv.p ? '.' : '') +); +```` + +*** + + $ ./bool.js -s + The cat says: meow + + $ ./bool.js -sp + The cat says: meow. + + $ ./bool.js -sp --fr + Le chat dit: miaou. + +And non-hypenated options too! Just use `argv._`! +------------------------------------------------- + +nonopt.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist').argv; +console.log('(%d,%d)', argv.x, argv.y); +console.log(argv._); +```` + +*** + + $ ./nonopt.js -x 6.82 -y 3.35 moo + (6.82,3.35) + [ 'moo' ] + + $ ./nonopt.js foo -x 0.54 bar -y 1.12 baz + (0.54,1.12) + [ 'foo', 'bar', 'baz' ] + +Plus, Optimist comes with .usage() and .demand()! +------------------------------------------------- + +divide.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .usage('Usage: $0 -x [num] -y [num]') + .demand(['x','y']) + .argv; + +console.log(argv.x / argv.y); +```` + +*** + + $ ./divide.js -x 55 -y 11 + 5 + + $ node ./divide.js -x 4.91 -z 2.51 + Usage: node ./divide.js -x [num] -y [num] + + Options: + -x [required] + -y [required] + + Missing required arguments: y + +EVEN MORE HOLY COW +------------------ + +default_singles.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .default('x', 10) + .default('y', 10) + .argv +; +console.log(argv.x + argv.y); +```` + +*** + + $ ./default_singles.js -x 5 + 15 + +default_hash.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .default({ x : 10, y : 10 }) + .argv +; +console.log(argv.x + argv.y); +```` + +*** + + $ ./default_hash.js -y 7 + 17 + +And if you really want to get all descriptive about it... +--------------------------------------------------------- + +boolean_single.js + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .boolean('v') + .argv +; +console.dir(argv); +```` + +*** + + $ ./boolean_single.js -v foo bar baz + true + [ 'bar', 'baz', 'foo' ] + +boolean_double.js + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .boolean(['x','y','z']) + .argv +; +console.dir([ argv.x, argv.y, argv.z ]); +console.dir(argv._); +```` + +*** + + $ ./boolean_double.js -x -z one two three + [ true, false, true ] + [ 'one', 'two', 'three' ] + +Optimist is here to help... +--------------------------- + +You can describe parameters for help messages and set aliases. Optimist figures +out how to format a handy help string automatically. + +line_count.js + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .usage('Count the lines in a file.\nUsage: $0') + .demand('f') + .alias('f', 'file') + .describe('f', 'Load a file') + .argv +; + +var fs = require('fs'); +var s = fs.createReadStream(argv.file); + +var lines = 0; +s.on('data', function (buf) { + lines += buf.toString().match(/\n/g).length; +}); + +s.on('end', function () { + console.log(lines); +}); +```` + +*** + + $ node line_count.js + Count the lines in a file. + Usage: node ./line_count.js + + Options: + -f, --file Load a file [required] + + Missing required arguments: f + + $ node line_count.js --file line_count.js + 20 + + $ node line_count.js -f line_count.js + 20 + +methods +======= + +By itself, + +````javascript +require('optimist').argv +````` + +will use `process.argv` array to construct the `argv` object. + +You can pass in the `process.argv` yourself: + +````javascript +require('optimist')([ '-x', '1', '-y', '2' ]).argv +```` + +or use .parse() to do the same thing: + +````javascript +require('optimist').parse([ '-x', '1', '-y', '2' ]) +```` + +The rest of these methods below come in just before the terminating `.argv`. + +.alias(key, alias) +------------------ + +Set key names as equivalent such that updates to a key will propagate to aliases +and vice-versa. + +Optionally `.alias()` can take an object that maps keys to aliases. + +.default(key, value) +-------------------- + +Set `argv[key]` to `value` if no option was specified on `process.argv`. + +Optionally `.default()` can take an object that maps keys to default values. + +.demand(key) +------------ + +If `key` is a string, show the usage information and exit if `key` wasn't +specified in `process.argv`. + +If `key` is a number, demand at least as many non-option arguments, which show +up in `argv._`. + +If `key` is an Array, demand each element. + +.describe(key, desc) +-------------------- + +Describe a `key` for the generated usage information. + +Optionally `.describe()` can take an object that maps keys to descriptions. + +.options(key, opt) +------------------ + +Instead of chaining together `.alias().demand().default()`, you can specify +keys in `opt` for each of the chainable methods. + +For example: + +````javascript +var argv = require('optimist') + .options('f', { + alias : 'file', + default : '/etc/passwd', + }) + .argv +; +```` + +is the same as + +````javascript +var argv = require('optimist') + .alias('f', 'file') + .default('f', '/etc/passwd') + .argv +; +```` + +Optionally `.options()` can take an object that maps keys to `opt` parameters. + +.usage(message) +--------------- + +Set a usage message to show which commands to use. Inside `message`, the string +`$0` will get interpolated to the current script name or node command for the +present script similar to how `$0` works in bash or perl. + +.check(fn) +---------- + +Check that certain conditions are met in the provided arguments. + +If `fn` throws or returns `false`, show the thrown error, usage information, and +exit. + +.boolean(key) +------------- + +Interpret `key` as a boolean. If a non-flag option follows `key` in +`process.argv`, that string won't get set as the value of `key`. + +If `key` never shows up as a flag in `process.arguments`, `argv[key]` will be +`false`. + +If `key` is an Array, interpret all the elements as booleans. + +.string(key) +------------ + +Tell the parser logic not to interpret `key` as a number or boolean. +This can be useful if you need to preserve leading zeros in an input. + +If `key` is an Array, interpret all the elements as strings. + +.wrap(columns) +-------------- + +Format usage output to wrap at `columns` many columns. + +.help() +------- + +Return the generated usage string. + +.showHelp(fn=console.error) +--------------------------- + +Print the usage data using `fn` for printing. + +.parse(args) +------------ + +Parse `args` instead of `process.argv`. Returns the `argv` object. + +.argv +----- + +Get the arguments as a plain old object. + +Arguments without a corresponding flag show up in the `argv._` array. + +The script name or node command is available at `argv.$0` similarly to how `$0` +works in bash or perl. + +parsing tricks +============== + +stop parsing +------------ + +Use `--` to stop parsing flags and stuff the remainder into `argv._`. + + $ node examples/reflect.js -a 1 -b 2 -- -c 3 -d 4 + { _: [ '-c', '3', '-d', '4' ], + '$0': 'node ./examples/reflect.js', + a: 1, + b: 2 } + +negate fields +------------- + +If you want to explicity set a field to false instead of just leaving it +undefined or to override a default you can do `--no-key`. + + $ node examples/reflect.js -a --no-b + { _: [], + '$0': 'node ./examples/reflect.js', + a: true, + b: false } + +numbers +------- + +Every argument that looks like a number (`!isNaN(Number(arg))`) is converted to +one. This way you can just `net.createConnection(argv.port)` and you can add +numbers out of `argv` with `+` without having that mean concatenation, +which is super frustrating. + +duplicates +---------- + +If you specify a flag multiple times it will get turned into an array containing +all the values in order. + + $ node examples/reflect.js -x 5 -x 8 -x 0 + { _: [], + '$0': 'node ./examples/reflect.js', + x: [ 5, 8, 0 ] } + +dot notation +------------ + +When you use dots (`.`s) in argument names, an implicit object path is assumed. +This lets you organize arguments into nested objects. + + $ node examples/reflect.js --foo.bar.baz=33 --foo.quux=5 + { _: [], + '$0': 'node ./examples/reflect.js', + foo: { bar: { baz: 33 }, quux: 5 } } + +short numbers +------------- + +Short numeric `head -n5` style argument work too: + + $ node reflect.js -n123 -m456 + { '3': true, + '6': true, + _: [], + '$0': 'node ./reflect.js', + n: 123, + m: 456 } + +installation +============ + +With [npm](http://github.com/isaacs/npm), just do: + npm install optimist + +or clone this project on github: + + git clone http://github.com/substack/node-optimist.git + +To run the tests with [expresso](http://github.com/visionmedia/expresso), +just do: + + expresso + +inspired By +=========== + +This module is loosely inspired by Perl's +[Getopt::Casual](http://search.cpan.org/~photo/Getopt-Casual-0.13.1/Casual.pm). diff --git a/libs/events/node_modules/optimist/test/_.js b/libs/events/node_modules/optimist/test/_.js new file mode 100644 index 000000000..d9c58b368 --- /dev/null +++ b/libs/events/node_modules/optimist/test/_.js @@ -0,0 +1,71 @@ +var spawn = require('child_process').spawn; +var test = require('tap').test; + +test('dotSlashEmpty', testCmd('./bin.js', [])); + +test('dotSlashArgs', testCmd('./bin.js', [ 'a', 'b', 'c' ])); + +test('nodeEmpty', testCmd('node bin.js', [])); + +test('nodeArgs', testCmd('node bin.js', [ 'x', 'y', 'z' ])); + +test('whichNodeEmpty', function (t) { + var which = spawn('which', ['node']); + + which.stdout.on('data', function (buf) { + t.test( + testCmd(buf.toString().trim() + ' bin.js', []) + ); + t.end(); + }); + + which.stderr.on('data', function (err) { + assert.error(err); + t.end(); + }); +}); + +test('whichNodeArgs', function (t) { + var which = spawn('which', ['node']); + + which.stdout.on('data', function (buf) { + t.test( + testCmd(buf.toString().trim() + ' bin.js', [ 'q', 'r' ]) + ); + t.end(); + }); + + which.stderr.on('data', function (err) { + t.error(err); + t.end(); + }); +}); + +function testCmd (cmd, args) { + + return function (t) { + var to = setTimeout(function () { + assert.fail('Never got stdout data.') + }, 5000); + + var oldDir = process.cwd(); + process.chdir(__dirname + '/_'); + + var cmds = cmd.split(' '); + + var bin = spawn(cmds[0], cmds.slice(1).concat(args.map(String))); + process.chdir(oldDir); + + bin.stderr.on('data', function (err) { + t.error(err); + t.end(); + }); + + bin.stdout.on('data', function (buf) { + clearTimeout(to); + var _ = JSON.parse(buf.toString()); + t.same(_.map(String), args.map(String)); + t.end(); + }); + }; +} diff --git a/libs/events/node_modules/optimist/test/_/argv.js b/libs/events/node_modules/optimist/test/_/argv.js new file mode 100644 index 000000000..3d096062c --- /dev/null +++ b/libs/events/node_modules/optimist/test/_/argv.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +console.log(JSON.stringify(process.argv)); diff --git a/libs/events/node_modules/optimist/test/_/bin.js b/libs/events/node_modules/optimist/test/_/bin.js new file mode 100755 index 000000000..4a18d85f3 --- /dev/null +++ b/libs/events/node_modules/optimist/test/_/bin.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +var argv = require('../../index').argv +console.log(JSON.stringify(argv._)); diff --git a/libs/events/node_modules/optimist/test/dash.js b/libs/events/node_modules/optimist/test/dash.js new file mode 100644 index 000000000..af8ed6fc6 --- /dev/null +++ b/libs/events/node_modules/optimist/test/dash.js @@ -0,0 +1,31 @@ +var optimist = require('../index'); +var test = require('tap').test; + +test('-', function (t) { + t.plan(5); + t.deepEqual( + fix(optimist.parse([ '-n', '-' ])), + { n: '-', _: [] } + ); + t.deepEqual( + fix(optimist.parse([ '-' ])), + { _: [ '-' ] } + ); + t.deepEqual( + fix(optimist.parse([ '-f-' ])), + { f: '-', _: [] } + ); + t.deepEqual( + fix(optimist([ '-b', '-' ]).boolean('b').argv), + { b: true, _: [ '-' ] } + ); + t.deepEqual( + fix(optimist([ '-s', '-' ]).string('s').argv), + { s: '-', _: [] } + ); +}); + +function fix (obj) { + delete obj.$0; + return obj; +} diff --git a/libs/events/node_modules/optimist/test/parse.js b/libs/events/node_modules/optimist/test/parse.js new file mode 100644 index 000000000..d320f4336 --- /dev/null +++ b/libs/events/node_modules/optimist/test/parse.js @@ -0,0 +1,446 @@ +var optimist = require('../index'); +var path = require('path'); +var test = require('tap').test; + +var $0 = 'node ./' + path.relative(process.cwd(), __filename); + +test('short boolean', function (t) { + var parse = optimist.parse([ '-b' ]); + t.same(parse, { b : true, _ : [], $0 : $0 }); + t.same(typeof parse.b, 'boolean'); + t.end(); +}); + +test('long boolean', function (t) { + t.same( + optimist.parse([ '--bool' ]), + { bool : true, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('bare', function (t) { + t.same( + optimist.parse([ 'foo', 'bar', 'baz' ]), + { _ : [ 'foo', 'bar', 'baz' ], $0 : $0 } + ); + t.end(); +}); + +test('short group', function (t) { + t.same( + optimist.parse([ '-cats' ]), + { c : true, a : true, t : true, s : true, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('short group next', function (t) { + t.same( + optimist.parse([ '-cats', 'meow' ]), + { c : true, a : true, t : true, s : 'meow', _ : [], $0 : $0 } + ); + t.end(); +}); + +test('short capture', function (t) { + t.same( + optimist.parse([ '-h', 'localhost' ]), + { h : 'localhost', _ : [], $0 : $0 } + ); + t.end(); +}); + +test('short captures', function (t) { + t.same( + optimist.parse([ '-h', 'localhost', '-p', '555' ]), + { h : 'localhost', p : 555, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('long capture sp', function (t) { + t.same( + optimist.parse([ '--pow', 'xixxle' ]), + { pow : 'xixxle', _ : [], $0 : $0 } + ); + t.end(); +}); + +test('long capture eq', function (t) { + t.same( + optimist.parse([ '--pow=xixxle' ]), + { pow : 'xixxle', _ : [], $0 : $0 } + ); + t.end() +}); + +test('long captures sp', function (t) { + t.same( + optimist.parse([ '--host', 'localhost', '--port', '555' ]), + { host : 'localhost', port : 555, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('long captures eq', function (t) { + t.same( + optimist.parse([ '--host=localhost', '--port=555' ]), + { host : 'localhost', port : 555, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('mixed short bool and capture', function (t) { + t.same( + optimist.parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), + { + f : true, p : 555, h : 'localhost', + _ : [ 'script.js' ], $0 : $0, + } + ); + t.end(); +}); + +test('short and long', function (t) { + t.same( + optimist.parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), + { + f : true, p : 555, h : 'localhost', + _ : [ 'script.js' ], $0 : $0, + } + ); + t.end(); +}); + +test('no', function (t) { + t.same( + optimist.parse([ '--no-moo' ]), + { moo : false, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('multi', function (t) { + t.same( + optimist.parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]), + { v : ['a','b','c'], _ : [], $0 : $0 } + ); + t.end(); +}); + +test('comprehensive', function (t) { + t.same( + optimist.parse([ + '--name=meowmers', 'bare', '-cats', 'woo', + '-h', 'awesome', '--multi=quux', + '--key', 'value', + '-b', '--bool', '--no-meep', '--multi=baz', + '--', '--not-a-flag', 'eek' + ]), + { + c : true, + a : true, + t : true, + s : 'woo', + h : 'awesome', + b : true, + bool : true, + key : 'value', + multi : [ 'quux', 'baz' ], + meep : false, + name : 'meowmers', + _ : [ 'bare', '--not-a-flag', 'eek' ], + $0 : $0 + } + ); + t.end(); +}); + +test('nums', function (t) { + var argv = optimist.parse([ + '-x', '1234', + '-y', '5.67', + '-z', '1e7', + '-w', '10f', + '--hex', '0xdeadbeef', + '789', + ]); + t.same(argv, { + x : 1234, + y : 5.67, + z : 1e7, + w : '10f', + hex : 0xdeadbeef, + _ : [ 789 ], + $0 : $0 + }); + t.same(typeof argv.x, 'number'); + t.same(typeof argv.y, 'number'); + t.same(typeof argv.z, 'number'); + t.same(typeof argv.w, 'string'); + t.same(typeof argv.hex, 'number'); + t.same(typeof argv._[0], 'number'); + t.end(); +}); + +test('flag boolean', function (t) { + var parse = optimist([ '-t', 'moo' ]).boolean(['t']).argv; + t.same(parse, { t : true, _ : [ 'moo' ], $0 : $0 }); + t.same(typeof parse.t, 'boolean'); + t.end(); +}); + +test('flag boolean value', function (t) { + var parse = optimist(['--verbose', 'false', 'moo', '-t', 'true']) + .boolean(['t', 'verbose']).default('verbose', true).argv; + + t.same(parse, { + verbose: false, + t: true, + _: ['moo'], + $0 : $0 + }); + + t.same(typeof parse.verbose, 'boolean'); + t.same(typeof parse.t, 'boolean'); + t.end(); +}); + +test('flag boolean default false', function (t) { + var parse = optimist(['moo']) + .boolean(['t', 'verbose']) + .default('verbose', false) + .default('t', false).argv; + + t.same(parse, { + verbose: false, + t: false, + _: ['moo'], + $0 : $0 + }); + + t.same(typeof parse.verbose, 'boolean'); + t.same(typeof parse.t, 'boolean'); + t.end(); + +}); + +test('boolean groups', function (t) { + var parse = optimist([ '-x', '-z', 'one', 'two', 'three' ]) + .boolean(['x','y','z']).argv; + + t.same(parse, { + x : true, + y : false, + z : true, + _ : [ 'one', 'two', 'three' ], + $0 : $0 + }); + + t.same(typeof parse.x, 'boolean'); + t.same(typeof parse.y, 'boolean'); + t.same(typeof parse.z, 'boolean'); + t.end(); +}); + +test('newlines in params' , function (t) { + var args = optimist.parse([ '-s', "X\nX" ]) + t.same(args, { _ : [], s : "X\nX", $0 : $0 }); + + // reproduce in bash: + // VALUE="new + // line" + // node program.js --s="$VALUE" + args = optimist.parse([ "--s=X\nX" ]) + t.same(args, { _ : [], s : "X\nX", $0 : $0 }); + t.end(); +}); + +test('strings' , function (t) { + var s = optimist([ '-s', '0001234' ]).string('s').argv.s; + t.same(s, '0001234'); + t.same(typeof s, 'string'); + + var x = optimist([ '-x', '56' ]).string('x').argv.x; + t.same(x, '56'); + t.same(typeof x, 'string'); + t.end(); +}); + +test('stringArgs', function (t) { + var s = optimist([ ' ', ' ' ]).string('_').argv._; + t.same(s.length, 2); + t.same(typeof s[0], 'string'); + t.same(s[0], ' '); + t.same(typeof s[1], 'string'); + t.same(s[1], ' '); + t.end(); +}); + +test('slashBreak', function (t) { + t.same( + optimist.parse([ '-I/foo/bar/baz' ]), + { I : '/foo/bar/baz', _ : [], $0 : $0 } + ); + t.same( + optimist.parse([ '-xyz/foo/bar/baz' ]), + { x : true, y : true, z : '/foo/bar/baz', _ : [], $0 : $0 } + ); + t.end(); +}); + +test('alias', function (t) { + var argv = optimist([ '-f', '11', '--zoom', '55' ]) + .alias('z', 'zoom') + .argv + ; + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.f, 11); + t.end(); +}); + +test('multiAlias', function (t) { + var argv = optimist([ '-f', '11', '--zoom', '55' ]) + .alias('z', [ 'zm', 'zoom' ]) + .argv + ; + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.z, argv.zm); + t.equal(argv.f, 11); + t.end(); +}); + +test('boolean default true', function (t) { + var argv = optimist.options({ + sometrue: { + boolean: true, + default: true + } + }).argv; + + t.equal(argv.sometrue, true); + t.end(); +}); + +test('boolean default false', function (t) { + var argv = optimist.options({ + somefalse: { + boolean: true, + default: false + } + }).argv; + + t.equal(argv.somefalse, false); + t.end(); +}); + +test('nested dotted objects', function (t) { + var argv = optimist([ + '--foo.bar', '3', '--foo.baz', '4', + '--foo.quux.quibble', '5', '--foo.quux.o_O', + '--beep.boop' + ]).argv; + + t.same(argv.foo, { + bar : 3, + baz : 4, + quux : { + quibble : 5, + o_O : true + }, + }); + t.same(argv.beep, { boop : true }); + t.end(); +}); + +test('boolean and alias with chainable api', function (t) { + var aliased = [ '-h', 'derp' ]; + var regular = [ '--herp', 'derp' ]; + var opts = { + herp: { alias: 'h', boolean: true } + }; + var aliasedArgv = optimist(aliased) + .boolean('herp') + .alias('h', 'herp') + .argv; + var propertyArgv = optimist(regular) + .boolean('herp') + .alias('h', 'herp') + .argv; + var expected = { + herp: true, + h: true, + '_': [ 'derp' ], + '$0': $0, + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +test('boolean and alias with options hash', function (t) { + var aliased = [ '-h', 'derp' ]; + var regular = [ '--herp', 'derp' ]; + var opts = { + herp: { alias: 'h', boolean: true } + }; + var aliasedArgv = optimist(aliased) + .options(opts) + .argv; + var propertyArgv = optimist(regular).options(opts).argv; + var expected = { + herp: true, + h: true, + '_': [ 'derp' ], + '$0': $0, + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + + t.end(); +}); + +test('boolean and alias using explicit true', function (t) { + var aliased = [ '-h', 'true' ]; + var regular = [ '--herp', 'true' ]; + var opts = { + herp: { alias: 'h', boolean: true } + }; + var aliasedArgv = optimist(aliased) + .boolean('h') + .alias('h', 'herp') + .argv; + var propertyArgv = optimist(regular) + .boolean('h') + .alias('h', 'herp') + .argv; + var expected = { + herp: true, + h: true, + '_': [ ], + '$0': $0, + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +// regression, see https://github.com/substack/node-optimist/issues/71 +test('boolean and --x=true', function(t) { + var parsed = optimist(['--boool', '--other=true']).boolean('boool').argv; + + t.same(parsed.boool, true); + t.same(parsed.other, 'true'); + + parsed = optimist(['--boool', '--other=false']).boolean('boool').argv; + + t.same(parsed.boool, true); + t.same(parsed.other, 'false'); + t.end(); +}); diff --git a/libs/events/node_modules/optimist/test/parse_modified.js b/libs/events/node_modules/optimist/test/parse_modified.js new file mode 100644 index 000000000..a57dc84e9 --- /dev/null +++ b/libs/events/node_modules/optimist/test/parse_modified.js @@ -0,0 +1,14 @@ +var optimist = require('../'); +var test = require('tap').test; + +test('parse with modifier functions' , function (t) { + t.plan(1); + + var argv = optimist().boolean('b').parse([ '-b', '123' ]); + t.deepEqual(fix(argv), { b: true, _: ['123'] }); +}); + +function fix (obj) { + delete obj.$0; + return obj; +} diff --git a/libs/events/node_modules/optimist/test/short.js b/libs/events/node_modules/optimist/test/short.js new file mode 100644 index 000000000..b2c38ad84 --- /dev/null +++ b/libs/events/node_modules/optimist/test/short.js @@ -0,0 +1,16 @@ +var optimist = require('../index'); +var test = require('tap').test; + +test('-n123', function (t) { + t.plan(1); + var parse = optimist.parse([ '-n123' ]); + t.equal(parse.n, 123); +}); + +test('-123', function (t) { + t.plan(3); + var parse = optimist.parse([ '-123', '456' ]); + t.equal(parse['1'], true); + t.equal(parse['2'], true); + t.equal(parse['3'], 456); +}); diff --git a/libs/events/node_modules/optimist/test/usage.js b/libs/events/node_modules/optimist/test/usage.js new file mode 100644 index 000000000..300454c1e --- /dev/null +++ b/libs/events/node_modules/optimist/test/usage.js @@ -0,0 +1,292 @@ +var Hash = require('hashish'); +var optimist = require('../index'); +var test = require('tap').test; + +test('usageFail', function (t) { + var r = checkUsage(function () { + return optimist('-x 10 -z 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .demand(['x','y']) + .argv; + }); + t.same( + r.result, + { x : 10, z : 20, _ : [], $0 : './usage' } + ); + + t.same( + r.errors.join('\n').split(/\n+/), + [ + 'Usage: ./usage -x NUM -y NUM', + 'Options:', + ' -x [required]', + ' -y [required]', + 'Missing required arguments: y', + ] + ); + t.same(r.logs, []); + t.ok(r.exit); + t.end(); +}); + + +test('usagePass', function (t) { + var r = checkUsage(function () { + return optimist('-x 10 -y 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .demand(['x','y']) + .argv; + }); + t.same(r, { + result : { x : 10, y : 20, _ : [], $0 : './usage' }, + errors : [], + logs : [], + exit : false, + }); + t.end(); +}); + +test('checkPass', function (t) { + var r = checkUsage(function () { + return optimist('-x 10 -y 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .check(function (argv) { + if (!('x' in argv)) throw 'You forgot about -x'; + if (!('y' in argv)) throw 'You forgot about -y'; + }) + .argv; + }); + t.same(r, { + result : { x : 10, y : 20, _ : [], $0 : './usage' }, + errors : [], + logs : [], + exit : false, + }); + t.end(); +}); + +test('checkFail', function (t) { + var r = checkUsage(function () { + return optimist('-x 10 -z 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .check(function (argv) { + if (!('x' in argv)) throw 'You forgot about -x'; + if (!('y' in argv)) throw 'You forgot about -y'; + }) + .argv; + }); + + t.same( + r.result, + { x : 10, z : 20, _ : [], $0 : './usage' } + ); + + t.same( + r.errors.join('\n').split(/\n+/), + [ + 'Usage: ./usage -x NUM -y NUM', + 'You forgot about -y' + ] + ); + + t.same(r.logs, []); + t.ok(r.exit); + t.end(); +}); + +test('checkCondPass', function (t) { + function checker (argv) { + return 'x' in argv && 'y' in argv; + } + + var r = checkUsage(function () { + return optimist('-x 10 -y 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .check(checker) + .argv; + }); + t.same(r, { + result : { x : 10, y : 20, _ : [], $0 : './usage' }, + errors : [], + logs : [], + exit : false, + }); + t.end(); +}); + +test('checkCondFail', function (t) { + function checker (argv) { + return 'x' in argv && 'y' in argv; + } + + var r = checkUsage(function () { + return optimist('-x 10 -z 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .check(checker) + .argv; + }); + + t.same( + r.result, + { x : 10, z : 20, _ : [], $0 : './usage' } + ); + + t.same( + r.errors.join('\n').split(/\n+/).join('\n'), + 'Usage: ./usage -x NUM -y NUM\n' + + 'Argument check failed: ' + checker.toString() + ); + + t.same(r.logs, []); + t.ok(r.exit); + t.end(); +}); + +test('countPass', function (t) { + var r = checkUsage(function () { + return optimist('1 2 3 --moo'.split(' ')) + .usage('Usage: $0 [x] [y] [z] {OPTIONS}') + .demand(3) + .argv; + }); + t.same(r, { + result : { _ : [ '1', '2', '3' ], moo : true, $0 : './usage' }, + errors : [], + logs : [], + exit : false, + }); + t.end(); +}); + +test('countFail', function (t) { + var r = checkUsage(function () { + return optimist('1 2 --moo'.split(' ')) + .usage('Usage: $0 [x] [y] [z] {OPTIONS}') + .demand(3) + .argv; + }); + t.same( + r.result, + { _ : [ '1', '2' ], moo : true, $0 : './usage' } + ); + + t.same( + r.errors.join('\n').split(/\n+/), + [ + 'Usage: ./usage [x] [y] [z] {OPTIONS}', + 'Not enough non-option arguments: got 2, need at least 3', + ] + ); + + t.same(r.logs, []); + t.ok(r.exit); + t.end(); +}); + +test('defaultSingles', function (t) { + var r = checkUsage(function () { + return optimist('--foo 50 --baz 70 --powsy'.split(' ')) + .default('foo', 5) + .default('bar', 6) + .default('baz', 7) + .argv + ; + }); + t.same(r.result, { + foo : '50', + bar : 6, + baz : '70', + powsy : true, + _ : [], + $0 : './usage', + }); + t.end(); +}); + +test('defaultAliases', function (t) { + var r = checkUsage(function () { + return optimist('') + .alias('f', 'foo') + .default('f', 5) + .argv + ; + }); + t.same(r.result, { + f : '5', + foo : '5', + _ : [], + $0 : './usage', + }); + t.end(); +}); + +test('defaultHash', function (t) { + var r = checkUsage(function () { + return optimist('--foo 50 --baz 70'.split(' ')) + .default({ foo : 10, bar : 20, quux : 30 }) + .argv + ; + }); + t.same(r.result, { + _ : [], + $0 : './usage', + foo : 50, + baz : 70, + bar : 20, + quux : 30, + }); + t.end(); +}); + +test('rebase', function (t) { + t.equal( + optimist.rebase('/home/substack', '/home/substack/foo/bar/baz'), + './foo/bar/baz' + ); + t.equal( + optimist.rebase('/home/substack/foo/bar/baz', '/home/substack'), + '../../..' + ); + t.equal( + optimist.rebase('/home/substack/foo', '/home/substack/pow/zoom.txt'), + '../pow/zoom.txt' + ); + t.end(); +}); + +function checkUsage (f) { + + var exit = false; + + process._exit = process.exit; + process._env = process.env; + process._argv = process.argv; + + process.exit = function (t) { exit = true }; + process.env = Hash.merge(process.env, { _ : 'node' }); + process.argv = [ './usage' ]; + + var errors = []; + var logs = []; + + console._error = console.error; + console.error = function (msg) { errors.push(msg) }; + console._log = console.log; + console.log = function (msg) { logs.push(msg) }; + + var result = f(); + + process.exit = process._exit; + process.env = process._env; + process.argv = process._argv; + + console.error = console._error; + console.log = console._log; + + return { + errors : errors, + logs : logs, + exit : exit, + result : result, + }; +}; diff --git a/libs/events/node_modules/optimist/test/whitespace.js b/libs/events/node_modules/optimist/test/whitespace.js new file mode 100644 index 000000000..90b90752c --- /dev/null +++ b/libs/events/node_modules/optimist/test/whitespace.js @@ -0,0 +1,8 @@ +var optimist = require('../'); +var test = require('tap').test; + +test('whitespace should be whitespace' , function (t) { + t.plan(1); + var x = optimist.parse([ '-x', '\t' ]).x; + t.equal(x, '\t'); +}); diff --git a/libs/events/node_modules/path-scurry/LICENSE.md b/libs/events/node_modules/path-scurry/LICENSE.md new file mode 100644 index 000000000..c5402b957 --- /dev/null +++ b/libs/events/node_modules/path-scurry/LICENSE.md @@ -0,0 +1,55 @@ +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** diff --git a/libs/events/node_modules/path-scurry/README.md b/libs/events/node_modules/path-scurry/README.md new file mode 100644 index 000000000..87f9ebb7f --- /dev/null +++ b/libs/events/node_modules/path-scurry/README.md @@ -0,0 +1,631 @@ +# path-scurry + +Extremely high performant utility for building tools that read +the file system, minimizing filesystem and path string munging +operations to the greatest degree possible. + +## Ugh, yet another file traversal thing on npm? + +Yes. None of the existing ones gave me exactly what I wanted. + +## Well what is it you wanted? + +While working on [glob](http://npm.im/glob), I found that I +needed a module to very efficiently manage the traversal over a +folder tree, such that: + +1. No `readdir()` or `stat()` would ever be called on the same + file or directory more than one time. +2. No `readdir()` calls would be made if we can be reasonably + sure that the path is not a directory. (Ie, a previous + `readdir()` or `stat()` covered the path, and + `ent.isDirectory()` is false.) +3. `path.resolve()`, `dirname()`, `basename()`, and other + string-parsing/munging operations are be minimized. This + means it has to track "provisional" child nodes that may not + exist (and if we find that they _don't_ exist, store that + information as well, so we don't have to ever check again). +4. The API is not limited to use as a stream/iterator/etc. There + are many cases where an API like node's `fs` is preferrable. +5. It's more important to prevent excess syscalls than to be up + to date, but it should be smart enough to know what it + _doesn't_ know, and go get it seamlessly when requested. +6. Do not blow up the JS heap allocation if operating on a + directory with a huge number of entries. +7. Handle all the weird aspects of Windows paths, like UNC paths + and drive letters and wrongway slashes, so that the consumer + can return canonical platform-specific paths without having to + parse or join or do any error-prone string munging. + +## PERFORMANCE + +JavaScript people throw around the word "blazing" a lot. I hope +that this module doesn't blaze anyone. But it does go very fast, +in the cases it's optimized for, if used properly. + +PathScurry provides ample opportunities to get extremely good +performance, as well as several options to trade performance for +convenience. + +Benchmarks can be run by executing `npm run bench`. + +As is always the case, doing more means going slower, doing +less means going faster, and there are trade offs between speed +and memory usage. + +PathScurry makes heavy use of [LRUCache](http://npm.im/lru-cache) +to efficiently cache whatever it can, and `Path` objects remain +in the graph for the lifetime of the walker, so repeated calls +with a single PathScurry object will be extremely fast. However, +adding items to a cold cache means "doing more", so in those +cases, we pay a price. Nothing is free, but every effort has been +made to reduce costs wherever possible. + +Also, note that a "cache as long as possible" approach means that +changes to the filesystem may not be reflected in the results of +repeated PathScurry operations. + +For resolving string paths, `PathScurry` ranges from 5-50 times +faster than `path.resolve` on repeated resolutions, but around +100 to 1000 times _slower_ on the first resolution. If your +program is spending a lot of time resolving the _same_ paths +repeatedly (like, thousands or millions of times), then this can +be beneficial. But both implementations are pretty fast, and +speeding up an infrequent operation from 4µs to 400ns is not +going to move the needle on your app's performance. + +For walking file system directory trees, a lot depends on how +often a given PathScurry object will be used, and also on the +walk method used. + +With default settings on a folder tree of 100,000 items, +consisting of around a 10-to-1 ratio of normal files to +directories, PathScurry performs comparably to +[@nodelib/fs.walk](http://npm.im/@nodelib/fs.walk), which is the +fastest and most reliable file system walker I could find. As +far as I can tell, it's almost impossible to go much faster in a +Node.js program, just based on how fast you can push syscalls out +to the fs thread pool. + +On my machine, that is about 1000-1200 completed walks per second +for async or stream walks, and around 500-600 walks per second +synchronously. + +In the warm cache state, PathScurry's performance increases +around 4x for async `for await` iteration, 10-15x faster for +streams and synchronous `for of` iteration, and anywhere from 30x +to 80x faster for the rest. + +``` +# walk 100,000 fs entries, 10/1 file/dir ratio +# operations / ms + New PathScurry object | Reuse PathScurry object + stream: 1112.589 | 13974.917 +sync stream: 492.718 | 15028.343 + async walk: 1095.648 | 32706.395 + sync walk: 527.632 | 46129.772 + async iter: 1288.821 | 5045.510 + sync iter: 498.496 | 17920.746 +``` + +A hand-rolled walk calling `entry.readdir()` and recursing +through the entries can benefit even more from caching, with +greater flexibility and without the overhead of streams or +generators. + +The cold cache state is still limited by the costs of file system +operations, but with a warm cache, the only bottleneck is CPU +speed and VM optimizations. Of course, in that case, some care +must be taken to ensure that you don't lose performance as a +result of silly mistakes, like calling `readdir()` on entries +that you know are not directories. + +``` +# manual recursive iteration functions + cold cache | warm cache +async: 1164.901 | 17923.320 + cb: 1101.127 | 40999.344 +zalgo: 1082.240 | 66689.936 + sync: 526.935 | 87097.591 +``` + +In this case, the speed improves by around 10-20x in the async +case, 40x in the case of using `entry.readdirCB` with protections +against synchronous callbacks, and 50-100x with callback +deferrals disabled, and _several hundred times faster_ for +synchronous iteration. + +If you can think of a case that is not covered in these +benchmarks, or an implementation that performs significantly +better than PathScurry, please [let me +know](https://github.com/isaacs/path-scurry/issues). + +## USAGE + +```ts +// hybrid module, load with either method +import { PathScurry, Path } from 'path-scurry' +// or: +const { PathScurry, Path } = require('path-scurry') + +// very simple example, say we want to find and +// delete all the .DS_Store files in a given path +// note that the API is very similar to just a +// naive walk with fs.readdir() +import { unlink } from 'fs/promises' + +// easy way, iterate over the directory and do the thing +const pw = new PathScurry(process.cwd()) +for await (const entry of pw) { + if (entry.isFile() && entry.name === '.DS_Store') { + unlink(entry.fullpath()) + } +} + +// here it is as a manual recursive method +const walk = async (entry: Path) => { + const promises: Promise = [] + // readdir doesn't throw on non-directories, it just doesn't + // return any entries, to save stack trace costs. + // Items are returned in arbitrary unsorted order + for (const child of await pw.readdir(entry)) { + // each child is a Path object + if (child.name === '.DS_Store' && child.isFile()) { + // could also do pw.resolve(entry, child.name), + // just like fs.readdir walking, but .fullpath is + // a *slightly* more efficient shorthand. + promises.push(unlink(child.fullpath())) + } else if (child.isDirectory()) { + promises.push(walk(child)) + } + } + return Promise.all(promises) +} + +walk(pw.cwd).then(() => { + console.log('all .DS_Store files removed') +}) + +const pw2 = new PathScurry('/a/b/c') // pw2.cwd is the Path for /a/b/c +const relativeDir = pw2.cwd.resolve('../x') // Path entry for '/a/b/x' +const relative2 = pw2.cwd.resolve('/a/b/d/../x') // same path, same entry +assert.equal(relativeDir, relative2) +``` + +## API + +[Full TypeDoc API](https://isaacs.github.io/path-scurry) + +There are platform-specific classes exported, but for the most +part, the default `PathScurry` and `Path` exports are what you +most likely need, unless you are testing behavior for other +platforms. + +Intended public API is documented here, but the full +documentation does include internal types, which should not be +accessed directly. + +### Interface `PathScurryOpts` + +The type of the `options` argument passed to the `PathScurry` +constructor. + +- `nocase`: Boolean indicating that file names should be compared + case-insensitively. Defaults to `true` on darwin and win32 + implementations, `false` elsewhere. + + **Warning** Performing case-insensitive matching on a + case-sensitive filesystem will result in occasionally very + bizarre behavior. Performing case-sensitive matching on a + case-insensitive filesystem may negatively impact performance. + +- `childrenCacheSize`: Number of child entries to cache, in order + to speed up `resolve()` and `readdir()` calls. Defaults to + `16 * 1024` (ie, `16384`). + + Setting it to a higher value will run the risk of JS heap + allocation errors on large directory trees. Setting it to `256` + or smaller will significantly reduce the construction time and + data consumption overhead, but with the downside of operations + being slower on large directory trees. Setting it to `0` will + mean that effectively no operations are cached, and this module + will be roughly the same speed as `fs` for file system + operations, and _much_ slower than `path.resolve()` for + repeated path resolution. + +- `fs` An object that will be used to override the default `fs` + methods. Any methods that are not overridden will use Node's + built-in implementations. + + - lstatSync + - readdir (callback `withFileTypes` Dirent variant, used for + readdirCB and most walks) + - readdirSync + - readlinkSync + - realpathSync + - promises: Object containing the following async methods: + - lstat + - readdir (Dirent variant only) + - readlink + - realpath + +### Interface `WalkOptions` + +The options object that may be passed to all walk methods. + +- `withFileTypes`: Boolean, default true. Indicates that `Path` + objects should be returned. Set to `false` to get string paths + instead. +- `follow`: Boolean, default false. Attempt to read directory + entries from symbolic links. Otherwise, only actual directories + are traversed. Regardless of this setting, a given target path + will only ever be walked once, meaning that a symbolic link to + a previously traversed directory will never be followed. + + Setting this imposes a slight performance penalty, because + `readlink` must be called on all symbolic links encountered, in + order to avoid infinite cycles. + +- `filter`: Function `(entry: Path) => boolean`. If provided, + will prevent the inclusion of any entry for which it returns a + falsey value. This will not prevent directories from being + traversed if they do not pass the filter, though it will + prevent the directories themselves from being included in the + results. By default, if no filter is provided, then all + entries are included in the results. +- `walkFilter`: Function `(entry: Path) => boolean`. If + provided, will prevent the traversal of any directory (or in + the case of `follow:true` symbolic links to directories) for + which the function returns false. This will not prevent the + directories themselves from being included in the result set. + Use `filter` for that. + +Note that TypeScript return types will only be inferred properly +from static analysis if the `withFileTypes` option is omitted, or +a constant `true` or `false` value. + +### Class `PathScurry` + +The main interface. Defaults to an appropriate class based on +the current platform. + +Use `PathScurryWin32`, `PathScurryDarwin`, or `PathScurryPosix` +if implementation-specific behavior is desired. + +All walk methods may be called with a `WalkOptions` argument to +walk over the object's current working directory with the +supplied options. + +#### `async pw.walk(entry?: string | Path | WalkOptions, opts?: WalkOptions)` + +Walk the directory tree according to the options provided, +resolving to an array of all entries found. + +#### `pw.walkSync(entry?: string | Path | WalkOptions, opts?: WalkOptions)` + +Walk the directory tree according to the options provided, +returning an array of all entries found. + +#### `pw.iterate(entry?: string | Path | WalkOptions, opts?: WalkOptions)` + +Iterate over the directory asynchronously, for use with `for +await of`. This is also the default async iterator method. + +#### `pw.iterateSync(entry?: string | Path | WalkOptions, opts?: WalkOptions)` + +Iterate over the directory synchronously, for use with `for of`. +This is also the default sync iterator method. + +#### `pw.stream(entry?: string | Path | WalkOptions, opts?: WalkOptions)` + +Return a [Minipass](http://npm.im/minipass) stream that emits +each entry or path string in the walk. Results are made +available asynchronously. + +#### `pw.streamSync(entry?: string | Path | WalkOptions, opts?: WalkOptions)` + +Return a [Minipass](http://npm.im/minipass) stream that emits +each entry or path string in the walk. Results are made +available synchronously, meaning that the walk will complete in a +single tick if the stream is fully consumed. + +#### `pw.cwd` + +Path object representing the current working directory for the +PathScurry. + +#### `pw.chdir(path: string)` + +Set the new effective current working directory for the scurry +object, so that `path.relative()` and `path.relativePosix()` +return values relative to the new cwd path. + +#### `pw.depth(path?: Path | string): number` + +Return the depth of the specified path (or the PathScurry cwd) +within the directory tree. + +Root entries have a depth of `0`. + +#### `pw.resolve(...paths: string[])` + +Caching `path.resolve()`. + +Significantly faster than `path.resolve()` if called repeatedly +with the same paths. Significantly slower otherwise, as it +builds out the cached Path entries. + +To get a `Path` object resolved from the `PathScurry`, use +`pw.cwd.resolve(path)`. Note that `Path.resolve` only takes a +single string argument, not multiple. + +#### `pw.resolvePosix(...paths: string[])` + +Caching `path.resolve()`, but always using posix style paths. + +This is identical to `pw.resolve(...paths)` on posix systems (ie, +everywhere except Windows). + +On Windows, it returns the full absolute UNC path using `/` +separators. Ie, instead of `'C:\\foo\\bar`, it would return +`//?/C:/foo/bar`. + +#### `pw.relative(path: string | Path): string` + +Return the relative path from the PathWalker cwd to the supplied +path string or entry. + +If the nearest common ancestor is the root, then an absolute path +is returned. + +#### `pw.relativePosix(path: string | Path): string` + +Return the relative path from the PathWalker cwd to the supplied +path string or entry, using `/` path separators. + +If the nearest common ancestor is the root, then an absolute path +is returned. + +On posix platforms (ie, all platforms except Windows), this is +identical to `pw.relative(path)`. + +On Windows systems, it returns the resulting string as a +`/`-delimited path. If an absolute path is returned (because the +target does not share a common ancestor with `pw.cwd`), then a +full absolute UNC path will be returned. Ie, instead of +`'C:\\foo\\bar`, it would return `//?/C:/foo/bar`. + +#### `pw.basename(path: string | Path): string` + +Return the basename of the provided string or Path. + +#### `pw.dirname(path: string | Path): string` + +Return the parent directory of the supplied string or Path. + +#### `async pw.readdir(dir = pw.cwd, opts = { withFileTypes: true })` + +Read the directory and resolve to an array of strings if +`withFileTypes` is explicitly set to `false` or Path objects +otherwise. + +Can be called as `pw.readdir({ withFileTypes: boolean })` as +well. + +Returns `[]` if no entries are found, or if any error occurs. + +Note that TypeScript return types will only be inferred properly +from static analysis if the `withFileTypes` option is omitted, or +a constant `true` or `false` value. + +#### `pw.readdirSync(dir = pw.cwd, opts = { withFileTypes: true })` + +Synchronous `pw.readdir()` + +#### `async pw.readlink(link = pw.cwd, opts = { withFileTypes: false })` + +Call `fs.readlink` on the supplied string or Path object, and +return the result. + +Can be called as `pw.readlink({ withFileTypes: boolean })` as +well. + +Returns `undefined` if any error occurs (for example, if the +argument is not a symbolic link), or a `Path` object if +`withFileTypes` is explicitly set to `true`, or a string +otherwise. + +Note that TypeScript return types will only be inferred properly +from static analysis if the `withFileTypes` option is omitted, or +a constant `true` or `false` value. + +#### `pw.readlinkSync(link = pw.cwd, opts = { withFileTypes: false })` + +Synchronous `pw.readlink()` + +#### `async pw.lstat(entry = pw.cwd)` + +Call `fs.lstat` on the supplied string or Path object, and fill +in as much information as possible, returning the updated `Path` +object. + +Returns `undefined` if the entry does not exist, or if any error +is encountered. + +Note that some `Stats` data (such as `ino`, `dev`, and `mode`) will +not be supplied. For those things, you'll need to call +`fs.lstat` yourself. + +#### `pw.lstatSync(entry = pw.cwd)` + +Synchronous `pw.lstat()` + +#### `pw.realpath(entry = pw.cwd, opts = { withFileTypes: false })` + +Call `fs.realpath` on the supplied string or Path object, and +return the realpath if available. + +Returns `undefined` if any error occurs. + +May be called as `pw.realpath({ withFileTypes: boolean })` to run +on `pw.cwd`. + +#### `pw.realpathSync(entry = pw.cwd, opts = { withFileTypes: false })` + +Synchronous `pw.realpath()` + +### Class `Path` implements [fs.Dirent](https://nodejs.org/docs/latest/api/fs.html#class-fsdirent) + +Object representing a given path on the filesystem, which may or +may not exist. + +Note that the actual class in use will be either `PathWin32` or +`PathPosix`, depending on the implementation of `PathScurry` in +use. They differ in the separators used to split and join path +strings, and the handling of root paths. + +In `PathPosix` implementations, paths are split and joined using +the `'/'` character, and `'/'` is the only root path ever in use. + +In `PathWin32` implementations, paths are split using either +`'/'` or `'\\'` and joined using `'\\'`, and multiple roots may +be in use based on the drives and UNC paths encountered. UNC +paths such as `//?/C:/` that identify a drive letter, will be +treated as an alias for the same root entry as their associated +drive letter (in this case `'C:\\'`). + +#### `path.name` + +Name of this file system entry. + +**Important**: _always_ test the path name against any test +string using the `isNamed` method, and not by directly comparing +this string. Otherwise, unicode path strings that the system +sees as identical will not be properly treated as the same path, +leading to incorrect behavior and possible security issues. + +#### `path.isNamed(name: string): boolean` + +Return true if the path is a match for the given path name. This +handles case sensitivity and unicode normalization. + +Note: even on case-sensitive systems, it is **not** safe to test +the equality of the `.name` property to determine whether a given +pathname matches, due to unicode normalization mismatches. + +Always use this method instead of testing the `path.name` +property directly. + +#### `path.getType()` + +Returns the type of the Path object, `'File'`, `'Directory'`, +etc. + +#### `path.isType(t: type)` + +Returns true if `is{t}()` returns true. + +For example, `path.isType('Directory')` is equivalent to +`path.isDirectory()`. + +#### `path.depth()` + +Return the depth of the Path entry within the directory tree. +Root paths have a depth of `0`. + +#### `path.fullpath()` + +The fully resolved path to the entry. + +#### `path.fullpathPosix()` + +The fully resolved path to the entry, using `/` separators. + +On posix systems, this is identical to `path.fullpath()`. On +windows, this will return a fully resolved absolute UNC path +using `/` separators. Eg, instead of `'C:\\foo\\bar'`, it will +return `'//?/C:/foo/bar'`. + +#### `path.isFile()`, `path.isDirectory()`, etc. + +Same as the identical `fs.Dirent.isX()` methods. + +#### `path.isUnknown()` + +Returns true if the path's type is unknown. Always returns true +when the path is known to not exist. + +#### `path.resolve(p: string)` + +Return a `Path` object associated with the provided path string +as resolved from the current Path object. + +#### `path.relative(): string` + +Return the relative path from the PathWalker cwd to the supplied +path string or entry. + +If the nearest common ancestor is the root, then an absolute path +is returned. + +#### `path.relativePosix(): string` + +Return the relative path from the PathWalker cwd to the supplied +path string or entry, using `/` path separators. + +If the nearest common ancestor is the root, then an absolute path +is returned. + +On posix platforms (ie, all platforms except Windows), this is +identical to `pw.relative(path)`. + +On Windows systems, it returns the resulting string as a +`/`-delimited path. If an absolute path is returned (because the +target does not share a common ancestor with `pw.cwd`), then a +full absolute UNC path will be returned. Ie, instead of +`'C:\\foo\\bar`, it would return `//?/C:/foo/bar`. + +#### `async path.readdir()` + +Return an array of `Path` objects found by reading the associated +path entry. + +If path is not a directory, or if any error occurs, returns `[]`, +and marks all children as provisional and non-existent. + +#### `path.readdirSync()` + +Synchronous `path.readdir()` + +#### `async path.readlink()` + +Return the `Path` object referenced by the `path` as a symbolic +link. + +If the `path` is not a symbolic link, or any error occurs, +returns `undefined`. + +#### `path.readlinkSync()` + +Synchronous `path.readlink()` + +#### `async path.lstat()` + +Call `lstat` on the path object, and fill it in with details +determined. + +If path does not exist, or any other error occurs, returns +`undefined`, and marks the path as "unknown" type. + +#### `path.lstatSync()` + +Synchronous `path.lstat()` + +#### `async path.realpath()` + +Call `realpath` on the path, and return a Path object +corresponding to the result, or `undefined` if any error occurs. + +#### `path.realpathSync()` + +Synchornous `path.realpath()` diff --git a/libs/events/node_modules/path-scurry/node_modules/minipass/LICENSE b/libs/events/node_modules/path-scurry/node_modules/minipass/LICENSE new file mode 100644 index 000000000..97f8e32ed --- /dev/null +++ b/libs/events/node_modules/path-scurry/node_modules/minipass/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2017-2023 npm, Inc., Isaac Z. Schlueter, and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/libs/events/node_modules/path-scurry/node_modules/minipass/README.md b/libs/events/node_modules/path-scurry/node_modules/minipass/README.md new file mode 100644 index 000000000..112633058 --- /dev/null +++ b/libs/events/node_modules/path-scurry/node_modules/minipass/README.md @@ -0,0 +1,825 @@ +# minipass + +A _very_ minimal implementation of a [PassThrough +stream](https://nodejs.org/api/stream.html#stream_class_stream_passthrough) + +[It's very +fast](https://docs.google.com/spreadsheets/d/1K_HR5oh3r80b8WVMWCPPjfuWXUgfkmhlX7FGI6JJ8tY/edit?usp=sharing) +for objects, strings, and buffers. + +Supports `pipe()`ing (including multi-`pipe()` and backpressure +transmission), buffering data until either a `data` event handler +or `pipe()` is added (so you don't lose the first chunk), and +most other cases where PassThrough is a good idea. + +There is a `read()` method, but it's much more efficient to +consume data from this stream via `'data'` events or by calling +`pipe()` into some other stream. Calling `read()` requires the +buffer to be flattened in some cases, which requires copying +memory. + +If you set `objectMode: true` in the options, then whatever is +written will be emitted. Otherwise, it'll do a minimal amount of +Buffer copying to ensure proper Streams semantics when `read(n)` +is called. + +`objectMode` can only be set at instantiation. Attempting to +write something other than a String or Buffer without having set +`objectMode` in the options will throw an error. + +This is not a `through` or `through2` stream. It doesn't +transform the data, it just passes it right through. If you want +to transform the data, extend the class, and override the +`write()` method. Once you're done transforming the data however +you want, call `super.write()` with the transform output. + +For some examples of streams that extend Minipass in various +ways, check out: + +- [minizlib](http://npm.im/minizlib) +- [fs-minipass](http://npm.im/fs-minipass) +- [tar](http://npm.im/tar) +- [minipass-collect](http://npm.im/minipass-collect) +- [minipass-flush](http://npm.im/minipass-flush) +- [minipass-pipeline](http://npm.im/minipass-pipeline) +- [tap](http://npm.im/tap) +- [tap-parser](http://npm.im/tap-parser) +- [treport](http://npm.im/treport) +- [minipass-fetch](http://npm.im/minipass-fetch) +- [pacote](http://npm.im/pacote) +- [make-fetch-happen](http://npm.im/make-fetch-happen) +- [cacache](http://npm.im/cacache) +- [ssri](http://npm.im/ssri) +- [npm-registry-fetch](http://npm.im/npm-registry-fetch) +- [minipass-json-stream](http://npm.im/minipass-json-stream) +- [minipass-sized](http://npm.im/minipass-sized) + +## Usage in TypeScript + +The `Minipass` class takes three type template definitions: + +- `RType` the type being read, which defaults to `Buffer`. If + `RType` is `string`, then the constructor _must_ get an options + object specifying either an `encoding` or `objectMode: true`. + If it's anything other than `string` or `Buffer`, then it + _must_ get an options object specifying `objectMode: true`. +- `WType` the type being written. If `RType` is `Buffer` or + `string`, then this defaults to `ContiguousData` (Buffer, + string, ArrayBuffer, or ArrayBufferView). Otherwise, it + defaults to `RType`. +- `Events` type mapping event names to the arguments emitted + with that event, which extends `Minipass.Events`. + +To declare types for custom events in subclasses, extend the +third parameter with your own event signatures. For example: + +```js +import { Minipass } from 'minipass' + +// a NDJSON stream that emits 'jsonError' when it can't stringify +export interface Events extends Minipass.Events { + jsonError: [e: Error] +} + +export class NDJSONStream extends Minipass { + constructor() { + super({ objectMode: true }) + } + + // data is type `any` because that's WType + write(data, encoding, cb) { + try { + const json = JSON.stringify(data) + return super.write(json + '\n', encoding, cb) + } catch (er) { + if (!er instanceof Error) { + er = Object.assign(new Error('json stringify failed'), { + cause: er, + }) + } + // trying to emit with something OTHER than an error will + // fail, because we declared the event arguments type. + this.emit('jsonError', er) + } + } +} + +const s = new NDJSONStream() +s.on('jsonError', e => { + // here, TS knows that e is an Error +}) +``` + +Emitting/handling events that aren't declared in this way is +fine, but the arguments will be typed as `unknown`. + +## Differences from Node.js Streams + +There are several things that make Minipass streams different +from (and in some ways superior to) Node.js core streams. + +Please read these caveats if you are familiar with node-core +streams and intend to use Minipass streams in your programs. + +You can avoid most of these differences entirely (for a very +small performance penalty) by setting `{async: true}` in the +constructor options. + +### Timing + +Minipass streams are designed to support synchronous use-cases. +Thus, data is emitted as soon as it is available, always. It is +buffered until read, but no longer. Another way to look at it is +that Minipass streams are exactly as synchronous as the logic +that writes into them. + +This can be surprising if your code relies on +`PassThrough.write()` always providing data on the next tick +rather than the current one, or being able to call `resume()` and +not have the entire buffer disappear immediately. + +However, without this synchronicity guarantee, there would be no +way for Minipass to achieve the speeds it does, or support the +synchronous use cases that it does. Simply put, waiting takes +time. + +This non-deferring approach makes Minipass streams much easier to +reason about, especially in the context of Promises and other +flow-control mechanisms. + +Example: + +```js +// hybrid module, either works +import { Minipass } from 'minipass' +// or: +const { Minipass } = require('minipass') + +const stream = new Minipass() +stream.on('data', () => console.log('data event')) +console.log('before write') +stream.write('hello') +console.log('after write') +// output: +// before write +// data event +// after write +``` + +### Exception: Async Opt-In + +If you wish to have a Minipass stream with behavior that more +closely mimics Node.js core streams, you can set the stream in +async mode either by setting `async: true` in the constructor +options, or by setting `stream.async = true` later on. + +```js +// hybrid module, either works +import { Minipass } from 'minipass' +// or: +const { Minipass } = require('minipass') + +const asyncStream = new Minipass({ async: true }) +asyncStream.on('data', () => console.log('data event')) +console.log('before write') +asyncStream.write('hello') +console.log('after write') +// output: +// before write +// after write +// data event <-- this is deferred until the next tick +``` + +Switching _out_ of async mode is unsafe, as it could cause data +corruption, and so is not enabled. Example: + +```js +import { Minipass } from 'minipass' +const stream = new Minipass({ encoding: 'utf8' }) +stream.on('data', chunk => console.log(chunk)) +stream.async = true +console.log('before writes') +stream.write('hello') +setStreamSyncAgainSomehow(stream) // <-- this doesn't actually exist! +stream.write('world') +console.log('after writes') +// hypothetical output would be: +// before writes +// world +// after writes +// hello +// NOT GOOD! +``` + +To avoid this problem, once set into async mode, any attempt to +make the stream sync again will be ignored. + +```js +const { Minipass } = require('minipass') +const stream = new Minipass({ encoding: 'utf8' }) +stream.on('data', chunk => console.log(chunk)) +stream.async = true +console.log('before writes') +stream.write('hello') +stream.async = false // <-- no-op, stream already async +stream.write('world') +console.log('after writes') +// actual output: +// before writes +// after writes +// hello +// world +``` + +### No High/Low Water Marks + +Node.js core streams will optimistically fill up a buffer, +returning `true` on all writes until the limit is hit, even if +the data has nowhere to go. Then, they will not attempt to draw +more data in until the buffer size dips below a minimum value. + +Minipass streams are much simpler. The `write()` method will +return `true` if the data has somewhere to go (which is to say, +given the timing guarantees, that the data is already there by +the time `write()` returns). + +If the data has nowhere to go, then `write()` returns false, and +the data sits in a buffer, to be drained out immediately as soon +as anyone consumes it. + +Since nothing is ever buffered unnecessarily, there is much less +copying data, and less bookkeeping about buffer capacity levels. + +### Hazards of Buffering (or: Why Minipass Is So Fast) + +Since data written to a Minipass stream is immediately written +all the way through the pipeline, and `write()` always returns +true/false based on whether the data was fully flushed, +backpressure is communicated immediately to the upstream caller. +This minimizes buffering. + +Consider this case: + +```js +const { PassThrough } = require('stream') +const p1 = new PassThrough({ highWaterMark: 1024 }) +const p2 = new PassThrough({ highWaterMark: 1024 }) +const p3 = new PassThrough({ highWaterMark: 1024 }) +const p4 = new PassThrough({ highWaterMark: 1024 }) + +p1.pipe(p2).pipe(p3).pipe(p4) +p4.on('data', () => console.log('made it through')) + +// this returns false and buffers, then writes to p2 on next tick (1) +// p2 returns false and buffers, pausing p1, then writes to p3 on next tick (2) +// p3 returns false and buffers, pausing p2, then writes to p4 on next tick (3) +// p4 returns false and buffers, pausing p3, then emits 'data' and 'drain' +// on next tick (4) +// p3 sees p4's 'drain' event, and calls resume(), emitting 'resume' and +// 'drain' on next tick (5) +// p2 sees p3's 'drain', calls resume(), emits 'resume' and 'drain' on next tick (6) +// p1 sees p2's 'drain', calls resume(), emits 'resume' and 'drain' on next +// tick (7) + +p1.write(Buffer.alloc(2048)) // returns false +``` + +Along the way, the data was buffered and deferred at each stage, +and multiple event deferrals happened, for an unblocked pipeline +where it was perfectly safe to write all the way through! + +Furthermore, setting a `highWaterMark` of `1024` might lead +someone reading the code to think an advisory maximum of 1KiB is +being set for the pipeline. However, the actual advisory +buffering level is the _sum_ of `highWaterMark` values, since +each one has its own bucket. + +Consider the Minipass case: + +```js +const m1 = new Minipass() +const m2 = new Minipass() +const m3 = new Minipass() +const m4 = new Minipass() + +m1.pipe(m2).pipe(m3).pipe(m4) +m4.on('data', () => console.log('made it through')) + +// m1 is flowing, so it writes the data to m2 immediately +// m2 is flowing, so it writes the data to m3 immediately +// m3 is flowing, so it writes the data to m4 immediately +// m4 is flowing, so it fires the 'data' event immediately, returns true +// m4's write returned true, so m3 is still flowing, returns true +// m3's write returned true, so m2 is still flowing, returns true +// m2's write returned true, so m1 is still flowing, returns true +// No event deferrals or buffering along the way! + +m1.write(Buffer.alloc(2048)) // returns true +``` + +It is extremely unlikely that you _don't_ want to buffer any data +written, or _ever_ buffer data that can be flushed all the way +through. Neither node-core streams nor Minipass ever fail to +buffer written data, but node-core streams do a lot of +unnecessary buffering and pausing. + +As always, the faster implementation is the one that does less +stuff and waits less time to do it. + +### Immediately emit `end` for empty streams (when not paused) + +If a stream is not paused, and `end()` is called before writing +any data into it, then it will emit `end` immediately. + +If you have logic that occurs on the `end` event which you don't +want to potentially happen immediately (for example, closing file +descriptors, moving on to the next entry in an archive parse +stream, etc.) then be sure to call `stream.pause()` on creation, +and then `stream.resume()` once you are ready to respond to the +`end` event. + +However, this is _usually_ not a problem because: + +### Emit `end` When Asked + +One hazard of immediately emitting `'end'` is that you may not +yet have had a chance to add a listener. In order to avoid this +hazard, Minipass streams safely re-emit the `'end'` event if a +new listener is added after `'end'` has been emitted. + +Ie, if you do `stream.on('end', someFunction)`, and the stream +has already emitted `end`, then it will call the handler right +away. (You can think of this somewhat like attaching a new +`.then(fn)` to a previously-resolved Promise.) + +To prevent calling handlers multiple times who would not expect +multiple ends to occur, all listeners are removed from the +`'end'` event whenever it is emitted. + +### Emit `error` When Asked + +The most recent error object passed to the `'error'` event is +stored on the stream. If a new `'error'` event handler is added, +and an error was previously emitted, then the event handler will +be called immediately (or on `process.nextTick` in the case of +async streams). + +This makes it much more difficult to end up trying to interact +with a broken stream, if the error handler is added after an +error was previously emitted. + +### Impact of "immediate flow" on Tee-streams + +A "tee stream" is a stream piping to multiple destinations: + +```js +const tee = new Minipass() +t.pipe(dest1) +t.pipe(dest2) +t.write('foo') // goes to both destinations +``` + +Since Minipass streams _immediately_ process any pending data +through the pipeline when a new pipe destination is added, this +can have surprising effects, especially when a stream comes in +from some other function and may or may not have data in its +buffer. + +```js +// WARNING! WILL LOSE DATA! +const src = new Minipass() +src.write('foo') +src.pipe(dest1) // 'foo' chunk flows to dest1 immediately, and is gone +src.pipe(dest2) // gets nothing! +``` + +One solution is to create a dedicated tee-stream junction that +pipes to both locations, and then pipe to _that_ instead. + +```js +// Safe example: tee to both places +const src = new Minipass() +src.write('foo') +const tee = new Minipass() +tee.pipe(dest1) +tee.pipe(dest2) +src.pipe(tee) // tee gets 'foo', pipes to both locations +``` + +The same caveat applies to `on('data')` event listeners. The +first one added will _immediately_ receive all of the data, +leaving nothing for the second: + +```js +// WARNING! WILL LOSE DATA! +const src = new Minipass() +src.write('foo') +src.on('data', handler1) // receives 'foo' right away +src.on('data', handler2) // nothing to see here! +``` + +Using a dedicated tee-stream can be used in this case as well: + +```js +// Safe example: tee to both data handlers +const src = new Minipass() +src.write('foo') +const tee = new Minipass() +tee.on('data', handler1) +tee.on('data', handler2) +src.pipe(tee) +``` + +All of the hazards in this section are avoided by setting `{ +async: true }` in the Minipass constructor, or by setting +`stream.async = true` afterwards. Note that this does add some +overhead, so should only be done in cases where you are willing +to lose a bit of performance in order to avoid having to refactor +program logic. + +## USAGE + +It's a stream! Use it like a stream and it'll most likely do what +you want. + +```js +import { Minipass } from 'minipass' +const mp = new Minipass(options) // options is optional +mp.write('foo') +mp.pipe(someOtherStream) +mp.end('bar') +``` + +### OPTIONS + +- `encoding` How would you like the data coming _out_ of the + stream to be encoded? Accepts any values that can be passed to + `Buffer.toString()`. +- `objectMode` Emit data exactly as it comes in. This will be + flipped on by default if you write() something other than a + string or Buffer at any point. Setting `objectMode: true` will + prevent setting any encoding value. +- `async` Defaults to `false`. Set to `true` to defer data + emission until next tick. This reduces performance slightly, + but makes Minipass streams use timing behavior closer to Node + core streams. See [Timing](#timing) for more details. +- `signal` An `AbortSignal` that will cause the stream to unhook + itself from everything and become as inert as possible. Note + that providing a `signal` parameter will make `'error'` events + no longer throw if they are unhandled, but they will still be + emitted to handlers if any are attached. + +### API + +Implements the user-facing portions of Node.js's `Readable` and +`Writable` streams. + +### Methods + +- `write(chunk, [encoding], [callback])` - Put data in. (Note + that, in the base Minipass class, the same data will come out.) + Returns `false` if the stream will buffer the next write, or + true if it's still in "flowing" mode. +- `end([chunk, [encoding]], [callback])` - Signal that you have + no more data to write. This will queue an `end` event to be + fired when all the data has been consumed. +- `pause()` - No more data for a while, please. This also + prevents `end` from being emitted for empty streams until the + stream is resumed. +- `resume()` - Resume the stream. If there's data in the buffer, + it is all discarded. Any buffered events are immediately + emitted. +- `pipe(dest)` - Send all output to the stream provided. When + data is emitted, it is immediately written to any and all pipe + destinations. (Or written on next tick in `async` mode.) +- `unpipe(dest)` - Stop piping to the destination stream. This is + immediate, meaning that any asynchronously queued data will + _not_ make it to the destination when running in `async` mode. + - `options.end` - Boolean, end the destination stream when the + source stream ends. Default `true`. + - `options.proxyErrors` - Boolean, proxy `error` events from + the source stream to the destination stream. Note that errors + are _not_ proxied after the pipeline terminates, either due + to the source emitting `'end'` or manually unpiping with + `src.unpipe(dest)`. Default `false`. +- `on(ev, fn)`, `emit(ev, fn)` - Minipass streams are + EventEmitters. Some events are given special treatment, + however. (See below under "events".) +- `promise()` - Returns a Promise that resolves when the stream + emits `end`, or rejects if the stream emits `error`. +- `collect()` - Return a Promise that resolves on `end` with an + array containing each chunk of data that was emitted, or + rejects if the stream emits `error`. Note that this consumes + the stream data. +- `concat()` - Same as `collect()`, but concatenates the data + into a single Buffer object. Will reject the returned promise + if the stream is in objectMode, or if it goes into objectMode + by the end of the data. +- `read(n)` - Consume `n` bytes of data out of the buffer. If `n` + is not provided, then consume all of it. If `n` bytes are not + available, then it returns null. **Note** consuming streams in + this way is less efficient, and can lead to unnecessary Buffer + copying. +- `destroy([er])` - Destroy the stream. If an error is provided, + then an `'error'` event is emitted. If the stream has a + `close()` method, and has not emitted a `'close'` event yet, + then `stream.close()` will be called. Any Promises returned by + `.promise()`, `.collect()` or `.concat()` will be rejected. + After being destroyed, writing to the stream will emit an + error. No more data will be emitted if the stream is destroyed, + even if it was previously buffered. + +### Properties + +- `bufferLength` Read-only. Total number of bytes buffered, or in + the case of objectMode, the total number of objects. +- `encoding` Read-only. The encoding that has been set. +- `flowing` Read-only. Boolean indicating whether a chunk written + to the stream will be immediately emitted. +- `emittedEnd` Read-only. Boolean indicating whether the end-ish + events (ie, `end`, `prefinish`, `finish`) have been emitted. + Note that listening on any end-ish event will immediateyl + re-emit it if it has already been emitted. +- `writable` Whether the stream is writable. Default `true`. Set + to `false` when `end()` +- `readable` Whether the stream is readable. Default `true`. +- `pipes` An array of Pipe objects referencing streams that this + stream is piping into. +- `destroyed` A getter that indicates whether the stream was + destroyed. +- `paused` True if the stream has been explicitly paused, + otherwise false. +- `objectMode` Indicates whether the stream is in `objectMode`. +- `aborted` Readonly property set when the `AbortSignal` + dispatches an `abort` event. + +### Events + +- `data` Emitted when there's data to read. Argument is the data + to read. This is never emitted while not flowing. If a listener + is attached, that will resume the stream. +- `end` Emitted when there's no more data to read. This will be + emitted immediately for empty streams when `end()` is called. + If a listener is attached, and `end` was already emitted, then + it will be emitted again. All listeners are removed when `end` + is emitted. +- `prefinish` An end-ish event that follows the same logic as + `end` and is emitted in the same conditions where `end` is + emitted. Emitted after `'end'`. +- `finish` An end-ish event that follows the same logic as `end` + and is emitted in the same conditions where `end` is emitted. + Emitted after `'prefinish'`. +- `close` An indication that an underlying resource has been + released. Minipass does not emit this event, but will defer it + until after `end` has been emitted, since it throws off some + stream libraries otherwise. +- `drain` Emitted when the internal buffer empties, and it is + again suitable to `write()` into the stream. +- `readable` Emitted when data is buffered and ready to be read + by a consumer. +- `resume` Emitted when stream changes state from buffering to + flowing mode. (Ie, when `resume` is called, `pipe` is called, + or a `data` event listener is added.) + +### Static Methods + +- `Minipass.isStream(stream)` Returns `true` if the argument is a + stream, and false otherwise. To be considered a stream, the + object must be either an instance of Minipass, or an + EventEmitter that has either a `pipe()` method, or both + `write()` and `end()` methods. (Pretty much any stream in + node-land will return `true` for this.) + +## EXAMPLES + +Here are some examples of things you can do with Minipass +streams. + +### simple "are you done yet" promise + +```js +mp.promise().then( + () => { + // stream is finished + }, + er => { + // stream emitted an error + } +) +``` + +### collecting + +```js +mp.collect().then(all => { + // all is an array of all the data emitted + // encoding is supported in this case, so + // so the result will be a collection of strings if + // an encoding is specified, or buffers/objects if not. + // + // In an async function, you may do + // const data = await stream.collect() +}) +``` + +### collecting into a single blob + +This is a bit slower because it concatenates the data into one +chunk for you, but if you're going to do it yourself anyway, it's +convenient this way: + +```js +mp.concat().then(onebigchunk => { + // onebigchunk is a string if the stream + // had an encoding set, or a buffer otherwise. +}) +``` + +### iteration + +You can iterate over streams synchronously or asynchronously in +platforms that support it. + +Synchronous iteration will end when the currently available data +is consumed, even if the `end` event has not been reached. In +string and buffer mode, the data is concatenated, so unless +multiple writes are occurring in the same tick as the `read()`, +sync iteration loops will generally only have a single iteration. + +To consume chunks in this way exactly as they have been written, +with no flattening, create the stream with the `{ objectMode: +true }` option. + +```js +const mp = new Minipass({ objectMode: true }) +mp.write('a') +mp.write('b') +for (let letter of mp) { + console.log(letter) // a, b +} +mp.write('c') +mp.write('d') +for (let letter of mp) { + console.log(letter) // c, d +} +mp.write('e') +mp.end() +for (let letter of mp) { + console.log(letter) // e +} +for (let letter of mp) { + console.log(letter) // nothing +} +``` + +Asynchronous iteration will continue until the end event is reached, +consuming all of the data. + +```js +const mp = new Minipass({ encoding: 'utf8' }) + +// some source of some data +let i = 5 +const inter = setInterval(() => { + if (i-- > 0) mp.write(Buffer.from('foo\n', 'utf8')) + else { + mp.end() + clearInterval(inter) + } +}, 100) + +// consume the data with asynchronous iteration +async function consume() { + for await (let chunk of mp) { + console.log(chunk) + } + return 'ok' +} + +consume().then(res => console.log(res)) +// logs `foo\n` 5 times, and then `ok` +``` + +### subclass that `console.log()`s everything written into it + +```js +class Logger extends Minipass { + write(chunk, encoding, callback) { + console.log('WRITE', chunk, encoding) + return super.write(chunk, encoding, callback) + } + end(chunk, encoding, callback) { + console.log('END', chunk, encoding) + return super.end(chunk, encoding, callback) + } +} + +someSource.pipe(new Logger()).pipe(someDest) +``` + +### same thing, but using an inline anonymous class + +```js +// js classes are fun +someSource + .pipe( + new (class extends Minipass { + emit(ev, ...data) { + // let's also log events, because debugging some weird thing + console.log('EMIT', ev) + return super.emit(ev, ...data) + } + write(chunk, encoding, callback) { + console.log('WRITE', chunk, encoding) + return super.write(chunk, encoding, callback) + } + end(chunk, encoding, callback) { + console.log('END', chunk, encoding) + return super.end(chunk, encoding, callback) + } + })() + ) + .pipe(someDest) +``` + +### subclass that defers 'end' for some reason + +```js +class SlowEnd extends Minipass { + emit(ev, ...args) { + if (ev === 'end') { + console.log('going to end, hold on a sec') + setTimeout(() => { + console.log('ok, ready to end now') + super.emit('end', ...args) + }, 100) + return true + } else { + return super.emit(ev, ...args) + } + } +} +``` + +### transform that creates newline-delimited JSON + +```js +class NDJSONEncode extends Minipass { + write(obj, cb) { + try { + // JSON.stringify can throw, emit an error on that + return super.write(JSON.stringify(obj) + '\n', 'utf8', cb) + } catch (er) { + this.emit('error', er) + } + } + end(obj, cb) { + if (typeof obj === 'function') { + cb = obj + obj = undefined + } + if (obj !== undefined) { + this.write(obj) + } + return super.end(cb) + } +} +``` + +### transform that parses newline-delimited JSON + +```js +class NDJSONDecode extends Minipass { + constructor(options) { + // always be in object mode, as far as Minipass is concerned + super({ objectMode: true }) + this._jsonBuffer = '' + } + write(chunk, encoding, cb) { + if ( + typeof chunk === 'string' && + typeof encoding === 'string' && + encoding !== 'utf8' + ) { + chunk = Buffer.from(chunk, encoding).toString() + } else if (Buffer.isBuffer(chunk)) { + chunk = chunk.toString() + } + if (typeof encoding === 'function') { + cb = encoding + } + const jsonData = (this._jsonBuffer + chunk).split('\n') + this._jsonBuffer = jsonData.pop() + for (let i = 0; i < jsonData.length; i++) { + try { + // JSON.parse can throw, emit an error on that + super.write(JSON.parse(jsonData[i])) + } catch (er) { + this.emit('error', er) + continue + } + } + if (cb) cb() + } +} +``` diff --git a/libs/events/node_modules/path-scurry/node_modules/minipass/package.json b/libs/events/node_modules/path-scurry/node_modules/minipass/package.json new file mode 100644 index 000000000..6faaa247a --- /dev/null +++ b/libs/events/node_modules/path-scurry/node_modules/minipass/package.json @@ -0,0 +1,82 @@ +{ + "name": "minipass", + "version": "7.0.3", + "description": "minimal implementation of a PassThrough stream", + "main": "./dist/cjs/index.js", + "module": "./dist/mjs/index.js", + "types": "./dist/cjs/index.js", + "exports": { + ".": { + "import": { + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./package.json": "./package.json" + }, + "files": [ + "dist" + ], + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "preprepare": "rm -rf dist", + "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" + }, + "tap": { + "coverage": false, + "node-arg": [ + "--enable-source-maps", + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false + }, + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "devDependencies": { + "@types/node": "^20.1.2", + "@types/tap": "^15.0.8", + "c8": "^7.13.0", + "prettier": "^2.6.2", + "tap": "^16.3.0", + "ts-node": "^10.9.1", + "typedoc": "^0.24.8", + "typescript": "^5.1.3", + "end-of-stream": "^1.4.0", + "node-abort-controller": "^3.1.1", + "sync-content": "^1.0.2", + "through2": "^2.0.3" + }, + "repository": "https://github.com/isaacs/minipass", + "keywords": [ + "passthrough", + "stream" + ], + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } +} diff --git a/libs/events/node_modules/path-scurry/package.json b/libs/events/node_modules/path-scurry/package.json new file mode 100644 index 000000000..af04f807f --- /dev/null +++ b/libs/events/node_modules/path-scurry/package.json @@ -0,0 +1,87 @@ +{ + "name": "path-scurry", + "version": "1.10.1", + "description": "walk paths fast and efficiently", + "author": "Isaac Z. Schlueter (https://blog.izs.me)", + "main": "./dist/cjs/index.js", + "module": "./dist/mjs/index.js", + "exports": { + ".": { + "import": { + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + } + }, + "files": [ + "dist" + ], + "license": "BlueOak-1.0.0", + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "preprepare": "rm -rf dist", + "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json", + "postprepare": "bash ./scripts/fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts", + "bench": "bash ./scripts/bench.sh" + }, + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "tap": { + "coverage": false, + "node-arg": [ + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false + }, + "devDependencies": { + "@nodelib/fs.walk": "^1.2.8", + "@types/node": "^20.1.4", + "@types/tap": "^15.0.7", + "c8": "^7.12.0", + "eslint-config-prettier": "^8.6.0", + "mkdirp": "^3.0.0", + "prettier": "^2.8.3", + "rimraf": "^5.0.1", + "tap": "^16.3.4", + "ts-node": "^10.9.1", + "typedoc": "^0.23.24", + "typescript": "^5.0.4" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/path-scurry" + }, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + } +} diff --git a/libs/events/node_modules/picomatch/CHANGELOG.md b/libs/events/node_modules/picomatch/CHANGELOG.md new file mode 100644 index 000000000..8ccc6c1ba --- /dev/null +++ b/libs/events/node_modules/picomatch/CHANGELOG.md @@ -0,0 +1,136 @@ +# Release history + +**All notable changes to this project will be documented in this file.** + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +
    + Guiding Principles + +- Changelogs are for humans, not machines. +- There should be an entry for every single version. +- The same types of changes should be grouped. +- Versions and sections should be linkable. +- The latest version comes first. +- The release date of each versions is displayed. +- Mention whether you follow Semantic Versioning. + +
    + +
    + Types of changes + +Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_): + +- `Added` for new features. +- `Changed` for changes in existing functionality. +- `Deprecated` for soon-to-be removed features. +- `Removed` for now removed features. +- `Fixed` for any bug fixes. +- `Security` in case of vulnerabilities. + +
    + +## 2.3.1 (2022-01-02) + +### Fixed + +* Fixes bug when a pattern containing an expression after the closing parenthesis (`/!(*.d).{ts,tsx}`) was incorrectly converted to regexp ([9f241ef](https://github.com/micromatch/picomatch/commit/9f241ef)). + +### Changed + +* Some documentation improvements ([f81d236](https://github.com/micromatch/picomatch/commit/f81d236), [421e0e7](https://github.com/micromatch/picomatch/commit/421e0e7)). + +## 2.3.0 (2021-05-21) + +### Fixed + +* Fixes bug where file names with two dots were not being matched consistently with negation extglobs containing a star ([56083ef](https://github.com/micromatch/picomatch/commit/56083ef)) + +## 2.2.3 (2021-04-10) + +### Fixed + +* Do not skip pattern seperator for square brackets ([fb08a30](https://github.com/micromatch/picomatch/commit/fb08a30)). +* Set negatedExtGlob also if it does not span the whole pattern ([032e3f5](https://github.com/micromatch/picomatch/commit/032e3f5)). + +## 2.2.2 (2020-03-21) + +### Fixed + +* Correctly handle parts of the pattern after parentheses in the `scan` method ([e15b920](https://github.com/micromatch/picomatch/commit/e15b920)). + +## 2.2.1 (2020-01-04) + +* Fixes [#49](https://github.com/micromatch/picomatch/issues/49), so that braces with no sets or ranges are now propertly treated as literals. + +## 2.2.0 (2020-01-04) + +* Disable fastpaths mode for the parse method ([5b8d33f](https://github.com/micromatch/picomatch/commit/5b8d33f)) +* Add `tokens`, `slashes`, and `parts` to the object returned by `picomatch.scan()`. + +## 2.1.0 (2019-10-31) + +* add benchmarks for scan ([4793b92](https://github.com/micromatch/picomatch/commit/4793b92)) +* Add eslint object-curly-spacing rule ([707c650](https://github.com/micromatch/picomatch/commit/707c650)) +* Add prefer-const eslint rule ([5c7501c](https://github.com/micromatch/picomatch/commit/5c7501c)) +* Add support for nonegate in scan API ([275c9b9](https://github.com/micromatch/picomatch/commit/275c9b9)) +* Change lets to consts. Move root import up. ([4840625](https://github.com/micromatch/picomatch/commit/4840625)) +* closes https://github.com/micromatch/picomatch/issues/21 ([766bcb0](https://github.com/micromatch/picomatch/commit/766bcb0)) +* Fix "Extglobs" table in readme ([eb19da8](https://github.com/micromatch/picomatch/commit/eb19da8)) +* fixes https://github.com/micromatch/picomatch/issues/20 ([9caca07](https://github.com/micromatch/picomatch/commit/9caca07)) +* fixes https://github.com/micromatch/picomatch/issues/26 ([fa58f45](https://github.com/micromatch/picomatch/commit/fa58f45)) +* Lint test ([d433a34](https://github.com/micromatch/picomatch/commit/d433a34)) +* lint unit tests ([0159b55](https://github.com/micromatch/picomatch/commit/0159b55)) +* Make scan work with noext ([6c02e03](https://github.com/micromatch/picomatch/commit/6c02e03)) +* minor linting ([c2a2b87](https://github.com/micromatch/picomatch/commit/c2a2b87)) +* minor parser improvements ([197671d](https://github.com/micromatch/picomatch/commit/197671d)) +* remove eslint since it... ([07876fa](https://github.com/micromatch/picomatch/commit/07876fa)) +* remove funding file ([8ebe96d](https://github.com/micromatch/picomatch/commit/8ebe96d)) +* Remove unused funks ([cbc6d54](https://github.com/micromatch/picomatch/commit/cbc6d54)) +* Run eslint during pretest, fix existing eslint findings ([0682367](https://github.com/micromatch/picomatch/commit/0682367)) +* support `noparen` in scan ([3d37569](https://github.com/micromatch/picomatch/commit/3d37569)) +* update changelog ([7b34e77](https://github.com/micromatch/picomatch/commit/7b34e77)) +* update travis ([777f038](https://github.com/micromatch/picomatch/commit/777f038)) +* Use eslint-disable-next-line instead of eslint-disable ([4e7c1fd](https://github.com/micromatch/picomatch/commit/4e7c1fd)) + +## 2.0.7 (2019-05-14) + +* 2.0.7 ([9eb9a71](https://github.com/micromatch/picomatch/commit/9eb9a71)) +* supports lookbehinds ([1f63f7e](https://github.com/micromatch/picomatch/commit/1f63f7e)) +* update .verb.md file with typo change ([2741279](https://github.com/micromatch/picomatch/commit/2741279)) +* fix: typo in README ([0753e44](https://github.com/micromatch/picomatch/commit/0753e44)) + +## 2.0.4 (2019-04-10) + +### Fixed + +- Readme link [fixed](https://github.com/micromatch/picomatch/pull/13/commits/a96ab3aa2b11b6861c23289964613d85563b05df) by @danez. +- `options.capture` now works as expected when fastpaths are enabled. See https://github.com/micromatch/picomatch/pull/12/commits/26aefd71f1cfaf95c37f1c1fcab68a693b037304. Thanks to @DrPizza. + +## 2.0.0 (2019-04-10) + +### Added + +- Adds support for `options.onIgnore`. See the readme for details +- Adds support for `options.onResult`. See the readme for details + +### Breaking changes + +- The unixify option was renamed to `windows` +- caching and all related options and methods have been removed + +## 1.0.0 (2018-11-05) + +- adds `.onMatch` option +- improvements to `.scan` method +- numerous improvements and optimizations for matching and parsing +- better windows path handling + +## 0.1.0 - 2017-04-13 + +First release. + + +[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog diff --git a/libs/events/node_modules/picomatch/LICENSE b/libs/events/node_modules/picomatch/LICENSE new file mode 100644 index 000000000..3608dca25 --- /dev/null +++ b/libs/events/node_modules/picomatch/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/picomatch/README.md b/libs/events/node_modules/picomatch/README.md new file mode 100644 index 000000000..b0526e28a --- /dev/null +++ b/libs/events/node_modules/picomatch/README.md @@ -0,0 +1,708 @@ +

    Picomatch

    + +

    + +version + + +test status + + +coverage status + + +downloads + +

    + +
    +
    + +

    +Blazing fast and accurate glob matcher written in JavaScript.
    +No dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions. +

    + +
    +
    + +## Why picomatch? + +* **Lightweight** - No dependencies +* **Minimal** - Tiny API surface. Main export is a function that takes a glob pattern and returns a matcher function. +* **Fast** - Loads in about 2ms (that's several times faster than a [single frame of a HD movie](http://www.endmemo.com/sconvert/framespersecondframespermillisecond.php) at 60fps) +* **Performant** - Use the returned matcher function to speed up repeat matching (like when watching files) +* **Accurate matching** - Using wildcards (`*` and `?`), globstars (`**`) for nested directories, [advanced globbing](#advanced-globbing) with extglobs, braces, and POSIX brackets, and support for escaping special characters with `\` or quotes. +* **Well tested** - Thousands of unit tests + +See the [library comparison](#library-comparisons) to other libraries. + +
    +
    + +## Table of Contents + +
    Click to expand + +- [Install](#install) +- [Usage](#usage) +- [API](#api) + * [picomatch](#picomatch) + * [.test](#test) + * [.matchBase](#matchbase) + * [.isMatch](#ismatch) + * [.parse](#parse) + * [.scan](#scan) + * [.compileRe](#compilere) + * [.makeRe](#makere) + * [.toRegex](#toregex) +- [Options](#options) + * [Picomatch options](#picomatch-options) + * [Scan Options](#scan-options) + * [Options Examples](#options-examples) +- [Globbing features](#globbing-features) + * [Basic globbing](#basic-globbing) + * [Advanced globbing](#advanced-globbing) + * [Braces](#braces) + * [Matching special characters as literals](#matching-special-characters-as-literals) +- [Library Comparisons](#library-comparisons) +- [Benchmarks](#benchmarks) +- [Philosophies](#philosophies) +- [About](#about) + * [Author](#author) + * [License](#license) + +_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_ + +
    + +
    +
    + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +npm install --save picomatch +``` + +
    + +## Usage + +The main export is a function that takes a glob pattern and an options object and returns a function for matching strings. + +```js +const pm = require('picomatch'); +const isMatch = pm('*.js'); + +console.log(isMatch('abcd')); //=> false +console.log(isMatch('a.js')); //=> true +console.log(isMatch('a.md')); //=> false +console.log(isMatch('a/b.js')); //=> false +``` + +
    + +## API + +### [picomatch](lib/picomatch.js#L32) + +Creates a matcher function from one or more glob patterns. The returned function takes a string to match as its first argument, and returns true if the string is a match. The returned matcher function also takes a boolean as the second argument that, when true, returns an object with additional information. + +**Params** + +* `globs` **{String|Array}**: One or more glob patterns. +* `options` **{Object=}** +* `returns` **{Function=}**: Returns a matcher function. + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch(glob[, options]); + +const isMatch = picomatch('*.!(*a)'); +console.log(isMatch('a.a')); //=> false +console.log(isMatch('a.b')); //=> true +``` + +### [.test](lib/picomatch.js#L117) + +Test `input` with the given `regex`. This is used by the main `picomatch()` function to test the input string. + +**Params** + +* `input` **{String}**: String to test. +* `regex` **{RegExp}** +* `returns` **{Object}**: Returns an object with matching info. + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.test(input, regex[, options]); + +console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); +// { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } +``` + +### [.matchBase](lib/picomatch.js#L161) + +Match the basename of a filepath. + +**Params** + +* `input` **{String}**: String to test. +* `glob` **{RegExp|String}**: Glob pattern or regex created by [.makeRe](#makeRe). +* `returns` **{Boolean}** + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.matchBase(input, glob[, options]); +console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true +``` + +### [.isMatch](lib/picomatch.js#L183) + +Returns true if **any** of the given glob `patterns` match the specified `string`. + +**Params** + +* **{String|Array}**: str The string to test. +* **{String|Array}**: patterns One or more glob patterns to use for matching. +* **{Object}**: See available [options](#options). +* `returns` **{Boolean}**: Returns true if any patterns match `str` + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.isMatch(string, patterns[, options]); + +console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true +console.log(picomatch.isMatch('a.a', 'b.*')); //=> false +``` + +### [.parse](lib/picomatch.js#L199) + +Parse a glob pattern to create the source string for a regular expression. + +**Params** + +* `pattern` **{String}** +* `options` **{Object}** +* `returns` **{Object}**: Returns an object with useful properties and output to be used as a regex source string. + +**Example** + +```js +const picomatch = require('picomatch'); +const result = picomatch.parse(pattern[, options]); +``` + +### [.scan](lib/picomatch.js#L231) + +Scan a glob pattern to separate the pattern into segments. + +**Params** + +* `input` **{String}**: Glob pattern to scan. +* `options` **{Object}** +* `returns` **{Object}**: Returns an object with + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.scan(input[, options]); + +const result = picomatch.scan('!./foo/*.js'); +console.log(result); +{ prefix: '!./', + input: '!./foo/*.js', + start: 3, + base: 'foo', + glob: '*.js', + isBrace: false, + isBracket: false, + isGlob: true, + isExtglob: false, + isGlobstar: false, + negated: true } +``` + +### [.compileRe](lib/picomatch.js#L245) + +Compile a regular expression from the `state` object returned by the +[parse()](#parse) method. + +**Params** + +* `state` **{Object}** +* `options` **{Object}** +* `returnOutput` **{Boolean}**: Intended for implementors, this argument allows you to return the raw output from the parser. +* `returnState` **{Boolean}**: Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. +* `returns` **{RegExp}** + +### [.makeRe](lib/picomatch.js#L286) + +Create a regular expression from a parsed glob pattern. + +**Params** + +* `state` **{String}**: The object returned from the `.parse` method. +* `options` **{Object}** +* `returnOutput` **{Boolean}**: Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. +* `returnState` **{Boolean}**: Implementors may use this argument to return the state from the parsed glob with the returned regular expression. +* `returns` **{RegExp}**: Returns a regex created from the given pattern. + +**Example** + +```js +const picomatch = require('picomatch'); +const state = picomatch.parse('*.js'); +// picomatch.compileRe(state[, options]); + +console.log(picomatch.compileRe(state)); +//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ +``` + +### [.toRegex](lib/picomatch.js#L321) + +Create a regular expression from the given regex source string. + +**Params** + +* `source` **{String}**: Regular expression source string. +* `options` **{Object}** +* `returns` **{RegExp}** + +**Example** + +```js +const picomatch = require('picomatch'); +// picomatch.toRegex(source[, options]); + +const { output } = picomatch.parse('*.js'); +console.log(picomatch.toRegex(output)); +//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ +``` + +
    + +## Options + +### Picomatch options + +The following options may be used with the main `picomatch()` function or any of the methods on the picomatch API. + +| **Option** | **Type** | **Default value** | **Description** | +| --- | --- | --- | --- | +| `basename` | `boolean` | `false` | If set, then patterns without slashes will be matched against the basename of the path if it contains slashes. For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. | +| `bash` | `boolean` | `false` | Follow bash matching rules more strictly - disallows backslashes as escape characters, and treats single stars as globstars (`**`). | +| `capture` | `boolean` | `undefined` | Return regex matches in supporting methods. | +| `contains` | `boolean` | `undefined` | Allows glob to match any part of the given string(s). | +| `cwd` | `string` | `process.cwd()` | Current working directory. Used by `picomatch.split()` | +| `debug` | `boolean` | `undefined` | Debug regular expressions when an error is thrown. | +| `dot` | `boolean` | `false` | Enable dotfile matching. By default, dotfiles are ignored unless a `.` is explicitly defined in the pattern, or `options.dot` is true | +| `expandRange` | `function` | `undefined` | Custom function for expanding ranges in brace patterns, such as `{a..z}`. The function receives the range values as two arguments, and it must return a string to be used in the generated regex. It's recommended that returned strings be wrapped in parentheses. | +| `failglob` | `boolean` | `false` | Throws an error if no matches are found. Based on the bash option of the same name. | +| `fastpaths` | `boolean` | `true` | To speed up processing, full parsing is skipped for a handful common glob patterns. Disable this behavior by setting this option to `false`. | +| `flags` | `string` | `undefined` | Regex flags to use in the generated regex. If defined, the `nocase` option will be overridden. | +| [format](#optionsformat) | `function` | `undefined` | Custom function for formatting the returned string. This is useful for removing leading slashes, converting Windows paths to Posix paths, etc. | +| `ignore` | `array\|string` | `undefined` | One or more glob patterns for excluding strings that should not be matched from the result. | +| `keepQuotes` | `boolean` | `false` | Retain quotes in the generated regex, since quotes may also be used as an alternative to backslashes. | +| `literalBrackets` | `boolean` | `undefined` | When `true`, brackets in the glob pattern will be escaped so that only literal brackets will be matched. | +| `matchBase` | `boolean` | `false` | Alias for `basename` | +| `maxLength` | `boolean` | `65536` | Limit the max length of the input string. An error is thrown if the input string is longer than this value. | +| `nobrace` | `boolean` | `false` | Disable brace matching, so that `{a,b}` and `{1..3}` would be treated as literal characters. | +| `nobracket` | `boolean` | `undefined` | Disable matching with regex brackets. | +| `nocase` | `boolean` | `false` | Make matching case-insensitive. Equivalent to the regex `i` flag. Note that this option is overridden by the `flags` option. | +| `nodupes` | `boolean` | `true` | Deprecated, use `nounique` instead. This option will be removed in a future major release. By default duplicates are removed. Disable uniquification by setting this option to false. | +| `noext` | `boolean` | `false` | Alias for `noextglob` | +| `noextglob` | `boolean` | `false` | Disable support for matching with extglobs (like `+(a\|b)`) | +| `noglobstar` | `boolean` | `false` | Disable support for matching nested directories with globstars (`**`) | +| `nonegate` | `boolean` | `false` | Disable support for negating with leading `!` | +| `noquantifiers` | `boolean` | `false` | Disable support for regex quantifiers (like `a{1,2}`) and treat them as brace patterns to be expanded. | +| [onIgnore](#optionsonIgnore) | `function` | `undefined` | Function to be called on ignored items. | +| [onMatch](#optionsonMatch) | `function` | `undefined` | Function to be called on matched items. | +| [onResult](#optionsonResult) | `function` | `undefined` | Function to be called on all items, regardless of whether or not they are matched or ignored. | +| `posix` | `boolean` | `false` | Support POSIX character classes ("posix brackets"). | +| `posixSlashes` | `boolean` | `undefined` | Convert all slashes in file paths to forward slashes. This does not convert slashes in the glob pattern itself | +| `prepend` | `boolean` | `undefined` | String to prepend to the generated regex used for matching. | +| `regex` | `boolean` | `false` | Use regular expression rules for `+` (instead of matching literal `+`), and for stars that follow closing parentheses or brackets (as in `)*` and `]*`). | +| `strictBrackets` | `boolean` | `undefined` | Throw an error if brackets, braces, or parens are imbalanced. | +| `strictSlashes` | `boolean` | `undefined` | When true, picomatch won't match trailing slashes with single stars. | +| `unescape` | `boolean` | `undefined` | Remove backslashes preceding escaped characters in the glob pattern. By default, backslashes are retained. | +| `unixify` | `boolean` | `undefined` | Alias for `posixSlashes`, for backwards compatibility. | + +picomatch has automatic detection for regex positive and negative lookbehinds. If the pattern contains a negative lookbehind, you must be using Node.js >= 8.10 or else picomatch will throw an error. + +### Scan Options + +In addition to the main [picomatch options](#picomatch-options), the following options may also be used with the [.scan](#scan) method. + +| **Option** | **Type** | **Default value** | **Description** | +| --- | --- | --- | --- | +| `tokens` | `boolean` | `false` | When `true`, the returned object will include an array of tokens (objects), representing each path "segment" in the scanned glob pattern | +| `parts` | `boolean` | `false` | When `true`, the returned object will include an array of strings representing each path "segment" in the scanned glob pattern. This is automatically enabled when `options.tokens` is true | + +**Example** + +```js +const picomatch = require('picomatch'); +const result = picomatch.scan('!./foo/*.js', { tokens: true }); +console.log(result); +// { +// prefix: '!./', +// input: '!./foo/*.js', +// start: 3, +// base: 'foo', +// glob: '*.js', +// isBrace: false, +// isBracket: false, +// isGlob: true, +// isExtglob: false, +// isGlobstar: false, +// negated: true, +// maxDepth: 2, +// tokens: [ +// { value: '!./', depth: 0, isGlob: false, negated: true, isPrefix: true }, +// { value: 'foo', depth: 1, isGlob: false }, +// { value: '*.js', depth: 1, isGlob: true } +// ], +// slashes: [ 2, 6 ], +// parts: [ 'foo', '*.js' ] +// } +``` + +
    + +### Options Examples + +#### options.expandRange + +**Type**: `function` + +**Default**: `undefined` + +Custom function for expanding ranges in brace patterns. The [fill-range](https://github.com/jonschlinkert/fill-range) library is ideal for this purpose, or you can use custom code to do whatever you need. + +**Example** + +The following example shows how to create a glob that matches a folder + +```js +const fill = require('fill-range'); +const regex = pm.makeRe('foo/{01..25}/bar', { + expandRange(a, b) { + return `(${fill(a, b, { toRegex: true })})`; + } +}); + +console.log(regex); +//=> /^(?:foo\/((?:0[1-9]|1[0-9]|2[0-5]))\/bar)$/ + +console.log(regex.test('foo/00/bar')) // false +console.log(regex.test('foo/01/bar')) // true +console.log(regex.test('foo/10/bar')) // true +console.log(regex.test('foo/22/bar')) // true +console.log(regex.test('foo/25/bar')) // true +console.log(regex.test('foo/26/bar')) // false +``` + +#### options.format + +**Type**: `function` + +**Default**: `undefined` + +Custom function for formatting strings before they're matched. + +**Example** + +```js +// strip leading './' from strings +const format = str => str.replace(/^\.\//, ''); +const isMatch = picomatch('foo/*.js', { format }); +console.log(isMatch('./foo/bar.js')); //=> true +``` + +#### options.onMatch + +```js +const onMatch = ({ glob, regex, input, output }) => { + console.log({ glob, regex, input, output }); +}; + +const isMatch = picomatch('*', { onMatch }); +isMatch('foo'); +isMatch('bar'); +isMatch('baz'); +``` + +#### options.onIgnore + +```js +const onIgnore = ({ glob, regex, input, output }) => { + console.log({ glob, regex, input, output }); +}; + +const isMatch = picomatch('*', { onIgnore, ignore: 'f*' }); +isMatch('foo'); +isMatch('bar'); +isMatch('baz'); +``` + +#### options.onResult + +```js +const onResult = ({ glob, regex, input, output }) => { + console.log({ glob, regex, input, output }); +}; + +const isMatch = picomatch('*', { onResult, ignore: 'f*' }); +isMatch('foo'); +isMatch('bar'); +isMatch('baz'); +``` + +
    +
    + +## Globbing features + +* [Basic globbing](#basic-globbing) (Wildcard matching) +* [Advanced globbing](#advanced-globbing) (extglobs, posix brackets, brace matching) + +### Basic globbing + +| **Character** | **Description** | +| --- | --- | +| `*` | Matches any character zero or more times, excluding path separators. Does _not match_ path separators or hidden files or directories ("dotfiles"), unless explicitly enabled by setting the `dot` option to `true`. | +| `**` | Matches any character zero or more times, including path separators. Note that `**` will only match path separators (`/`, and `\\` on Windows) when they are the only characters in a path segment. Thus, `foo**/bar` is equivalent to `foo*/bar`, and `foo/a**b/bar` is equivalent to `foo/a*b/bar`, and _more than two_ consecutive stars in a glob path segment are regarded as _a single star_. Thus, `foo/***/bar` is equivalent to `foo/*/bar`. | +| `?` | Matches any character excluding path separators one time. Does _not match_ path separators or leading dots. | +| `[abc]` | Matches any characters inside the brackets. For example, `[abc]` would match the characters `a`, `b` or `c`, and nothing else. | + +#### Matching behavior vs. Bash + +Picomatch's matching features and expected results in unit tests are based on Bash's unit tests and the Bash 4.3 specification, with the following exceptions: + +* Bash will match `foo/bar/baz` with `*`. Picomatch only matches nested directories with `**`. +* Bash greedily matches with negated extglobs. For example, Bash 4.3 says that `!(foo)*` should match `foo` and `foobar`, since the trailing `*` bracktracks to match the preceding pattern. This is very memory-inefficient, and IMHO, also incorrect. Picomatch would return `false` for both `foo` and `foobar`. + +
    + +### Advanced globbing + +* [extglobs](#extglobs) +* [POSIX brackets](#posix-brackets) +* [Braces](#brace-expansion) + +#### Extglobs + +| **Pattern** | **Description** | +| --- | --- | +| `@(pattern)` | Match _only one_ consecutive occurrence of `pattern` | +| `*(pattern)` | Match _zero or more_ consecutive occurrences of `pattern` | +| `+(pattern)` | Match _one or more_ consecutive occurrences of `pattern` | +| `?(pattern)` | Match _zero or **one**_ consecutive occurrences of `pattern` | +| `!(pattern)` | Match _anything but_ `pattern` | + +**Examples** + +```js +const pm = require('picomatch'); + +// *(pattern) matches ZERO or more of "pattern" +console.log(pm.isMatch('a', 'a*(z)')); // true +console.log(pm.isMatch('az', 'a*(z)')); // true +console.log(pm.isMatch('azzz', 'a*(z)')); // true + +// +(pattern) matches ONE or more of "pattern" +console.log(pm.isMatch('a', 'a*(z)')); // true +console.log(pm.isMatch('az', 'a*(z)')); // true +console.log(pm.isMatch('azzz', 'a*(z)')); // true + +// supports multiple extglobs +console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false + +// supports nested extglobs +console.log(pm.isMatch('foo.bar', '!(!(foo)).!(!(bar))')); // true +``` + +#### POSIX brackets + +POSIX classes are disabled by default. Enable this feature by setting the `posix` option to true. + +**Enable POSIX bracket support** + +```js +console.log(pm.makeRe('[[:word:]]+', { posix: true })); +//=> /^(?:(?=.)[A-Za-z0-9_]+\/?)$/ +``` + +**Supported POSIX classes** + +The following named POSIX bracket expressions are supported: + +* `[:alnum:]` - Alphanumeric characters, equ `[a-zA-Z0-9]` +* `[:alpha:]` - Alphabetical characters, equivalent to `[a-zA-Z]`. +* `[:ascii:]` - ASCII characters, equivalent to `[\\x00-\\x7F]`. +* `[:blank:]` - Space and tab characters, equivalent to `[ \\t]`. +* `[:cntrl:]` - Control characters, equivalent to `[\\x00-\\x1F\\x7F]`. +* `[:digit:]` - Numerical digits, equivalent to `[0-9]`. +* `[:graph:]` - Graph characters, equivalent to `[\\x21-\\x7E]`. +* `[:lower:]` - Lowercase letters, equivalent to `[a-z]`. +* `[:print:]` - Print characters, equivalent to `[\\x20-\\x7E ]`. +* `[:punct:]` - Punctuation and symbols, equivalent to `[\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~]`. +* `[:space:]` - Extended space characters, equivalent to `[ \\t\\r\\n\\v\\f]`. +* `[:upper:]` - Uppercase letters, equivalent to `[A-Z]`. +* `[:word:]` - Word characters (letters, numbers and underscores), equivalent to `[A-Za-z0-9_]`. +* `[:xdigit:]` - Hexadecimal digits, equivalent to `[A-Fa-f0-9]`. + +See the [Bash Reference Manual](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) for more information. + +### Braces + +Picomatch does not do brace expansion. For [brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html) and advanced matching with braces, use [micromatch](https://github.com/micromatch/micromatch) instead. Picomatch has very basic support for braces. + +### Matching special characters as literals + +If you wish to match the following special characters in a filepath, and you want to use these characters in your glob pattern, they must be escaped with backslashes or quotes: + +**Special Characters** + +Some characters that are used for matching in regular expressions are also regarded as valid file path characters on some platforms. + +To match any of the following characters as literals: `$^*+?()[] + +Examples: + +```js +console.log(pm.makeRe('foo/bar \\(1\\)')); +console.log(pm.makeRe('foo/bar \\(1\\)')); +``` + +
    +
    + +## Library Comparisons + +The following table shows which features are supported by [minimatch](https://github.com/isaacs/minimatch), [micromatch](https://github.com/micromatch/micromatch), [picomatch](https://github.com/micromatch/picomatch), [nanomatch](https://github.com/micromatch/nanomatch), [extglob](https://github.com/micromatch/extglob), [braces](https://github.com/micromatch/braces), and [expand-brackets](https://github.com/micromatch/expand-brackets). + +| **Feature** | `minimatch` | `micromatch` | `picomatch` | `nanomatch` | `extglob` | `braces` | `expand-brackets` | +| --- | --- | --- | --- | --- | --- | --- | --- | +| Wildcard matching (`*?+`) | ✔ | ✔ | ✔ | ✔ | - | - | - | +| Advancing globbing | ✔ | ✔ | ✔ | - | - | - | - | +| Brace _matching_ | ✔ | ✔ | ✔ | - | - | ✔ | - | +| Brace _expansion_ | ✔ | ✔ | - | - | - | ✔ | - | +| Extglobs | partial | ✔ | ✔ | - | ✔ | - | - | +| Posix brackets | - | ✔ | ✔ | - | - | - | ✔ | +| Regular expression syntax | - | ✔ | ✔ | ✔ | ✔ | - | ✔ | +| File system operations | - | - | - | - | - | - | - | + +
    +
    + +## Benchmarks + +Performance comparison of picomatch and minimatch. + +``` +# .makeRe star + picomatch x 1,993,050 ops/sec ±0.51% (91 runs sampled) + minimatch x 627,206 ops/sec ±1.96% (87 runs sampled)) + +# .makeRe star; dot=true + picomatch x 1,436,640 ops/sec ±0.62% (91 runs sampled) + minimatch x 525,876 ops/sec ±0.60% (88 runs sampled) + +# .makeRe globstar + picomatch x 1,592,742 ops/sec ±0.42% (90 runs sampled) + minimatch x 962,043 ops/sec ±1.76% (91 runs sampled)d) + +# .makeRe globstars + picomatch x 1,615,199 ops/sec ±0.35% (94 runs sampled) + minimatch x 477,179 ops/sec ±1.33% (91 runs sampled) + +# .makeRe with leading star + picomatch x 1,220,856 ops/sec ±0.40% (92 runs sampled) + minimatch x 453,564 ops/sec ±1.43% (94 runs sampled) + +# .makeRe - basic braces + picomatch x 392,067 ops/sec ±0.70% (90 runs sampled) + minimatch x 99,532 ops/sec ±2.03% (87 runs sampled)) +``` + +
    +
    + +## Philosophies + +The goal of this library is to be blazing fast, without compromising on accuracy. + +**Accuracy** + +The number one of goal of this library is accuracy. However, it's not unusual for different glob implementations to have different rules for matching behavior, even with simple wildcard matching. It gets increasingly more complicated when combinations of different features are combined, like when extglobs are combined with globstars, braces, slashes, and so on: `!(**/{a,b,*/c})`. + +Thus, given that there is no canonical glob specification to use as a single source of truth when differences of opinion arise regarding behavior, sometimes we have to implement our best judgement and rely on feedback from users to make improvements. + +**Performance** + +Although this library performs well in benchmarks, and in most cases it's faster than other popular libraries we benchmarked against, we will always choose accuracy over performance. It's not helpful to anyone if our library is faster at returning the wrong answer. + +
    +
    + +## About + +
    +Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +Please read the [contributing guide](.github/contributing.md) for advice on opening issues, pull requests, and coding standards. + +
    + +
    +Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +npm install && npm test +``` + +
    + +
    +Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
    + +### Author + +**Jon Schlinkert** + +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +### License + +Copyright © 2017-present, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). diff --git a/libs/events/node_modules/picomatch/index.js b/libs/events/node_modules/picomatch/index.js new file mode 100644 index 000000000..d2f2bc59d --- /dev/null +++ b/libs/events/node_modules/picomatch/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./lib/picomatch'); diff --git a/libs/events/node_modules/picomatch/lib/constants.js b/libs/events/node_modules/picomatch/lib/constants.js new file mode 100644 index 000000000..a62ef3879 --- /dev/null +++ b/libs/events/node_modules/picomatch/lib/constants.js @@ -0,0 +1,179 @@ +'use strict'; + +const path = require('path'); +const WIN_SLASH = '\\\\/'; +const WIN_NO_SLASH = `[^${WIN_SLASH}]`; + +/** + * Posix glob regex + */ + +const DOT_LITERAL = '\\.'; +const PLUS_LITERAL = '\\+'; +const QMARK_LITERAL = '\\?'; +const SLASH_LITERAL = '\\/'; +const ONE_CHAR = '(?=.)'; +const QMARK = '[^/]'; +const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; +const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; +const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; +const NO_DOT = `(?!${DOT_LITERAL})`; +const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; +const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; +const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; +const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; +const STAR = `${QMARK}*?`; + +const POSIX_CHARS = { + DOT_LITERAL, + PLUS_LITERAL, + QMARK_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + QMARK, + END_ANCHOR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK_NO_DOT, + STAR, + START_ANCHOR +}; + +/** + * Windows glob regex + */ + +const WINDOWS_CHARS = { + ...POSIX_CHARS, + + SLASH_LITERAL: `[${WIN_SLASH}]`, + QMARK: WIN_NO_SLASH, + STAR: `${WIN_NO_SLASH}*?`, + DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, + NO_DOT: `(?!${DOT_LITERAL})`, + NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, + NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + QMARK_NO_DOT: `[^.${WIN_SLASH}]`, + START_ANCHOR: `(?:^|[${WIN_SLASH}])`, + END_ANCHOR: `(?:[${WIN_SLASH}]|$)` +}; + +/** + * POSIX Bracket Regex + */ + +const POSIX_REGEX_SOURCE = { + alnum: 'a-zA-Z0-9', + alpha: 'a-zA-Z', + ascii: '\\x00-\\x7F', + blank: ' \\t', + cntrl: '\\x00-\\x1F\\x7F', + digit: '0-9', + graph: '\\x21-\\x7E', + lower: 'a-z', + print: '\\x20-\\x7E ', + punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', + space: ' \\t\\r\\n\\v\\f', + upper: 'A-Z', + word: 'A-Za-z0-9_', + xdigit: 'A-Fa-f0-9' +}; + +module.exports = { + MAX_LENGTH: 1024 * 64, + POSIX_REGEX_SOURCE, + + // regular expressions + REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, + REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, + REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, + REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, + REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, + REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, + + // Replace globs with equivalent patterns to reduce parsing time. + REPLACEMENTS: { + '***': '*', + '**/**': '**', + '**/**/**': '**' + }, + + // Digits + CHAR_0: 48, /* 0 */ + CHAR_9: 57, /* 9 */ + + // Alphabet chars. + CHAR_UPPERCASE_A: 65, /* A */ + CHAR_LOWERCASE_A: 97, /* a */ + CHAR_UPPERCASE_Z: 90, /* Z */ + CHAR_LOWERCASE_Z: 122, /* z */ + + CHAR_LEFT_PARENTHESES: 40, /* ( */ + CHAR_RIGHT_PARENTHESES: 41, /* ) */ + + CHAR_ASTERISK: 42, /* * */ + + // Non-alphabetic chars. + CHAR_AMPERSAND: 38, /* & */ + CHAR_AT: 64, /* @ */ + CHAR_BACKWARD_SLASH: 92, /* \ */ + CHAR_CARRIAGE_RETURN: 13, /* \r */ + CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ + CHAR_COLON: 58, /* : */ + CHAR_COMMA: 44, /* , */ + CHAR_DOT: 46, /* . */ + CHAR_DOUBLE_QUOTE: 34, /* " */ + CHAR_EQUAL: 61, /* = */ + CHAR_EXCLAMATION_MARK: 33, /* ! */ + CHAR_FORM_FEED: 12, /* \f */ + CHAR_FORWARD_SLASH: 47, /* / */ + CHAR_GRAVE_ACCENT: 96, /* ` */ + CHAR_HASH: 35, /* # */ + CHAR_HYPHEN_MINUS: 45, /* - */ + CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ + CHAR_LEFT_CURLY_BRACE: 123, /* { */ + CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ + CHAR_LINE_FEED: 10, /* \n */ + CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ + CHAR_PERCENT: 37, /* % */ + CHAR_PLUS: 43, /* + */ + CHAR_QUESTION_MARK: 63, /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ + CHAR_RIGHT_CURLY_BRACE: 125, /* } */ + CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ + CHAR_SEMICOLON: 59, /* ; */ + CHAR_SINGLE_QUOTE: 39, /* ' */ + CHAR_SPACE: 32, /* */ + CHAR_TAB: 9, /* \t */ + CHAR_UNDERSCORE: 95, /* _ */ + CHAR_VERTICAL_LINE: 124, /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ + + SEP: path.sep, + + /** + * Create EXTGLOB_CHARS + */ + + extglobChars(chars) { + return { + '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, + '?': { type: 'qmark', open: '(?:', close: ')?' }, + '+': { type: 'plus', open: '(?:', close: ')+' }, + '*': { type: 'star', open: '(?:', close: ')*' }, + '@': { type: 'at', open: '(?:', close: ')' } + }; + }, + + /** + * Create GLOB_CHARS + */ + + globChars(win32) { + return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; + } +}; diff --git a/libs/events/node_modules/picomatch/lib/parse.js b/libs/events/node_modules/picomatch/lib/parse.js new file mode 100644 index 000000000..58269d018 --- /dev/null +++ b/libs/events/node_modules/picomatch/lib/parse.js @@ -0,0 +1,1091 @@ +'use strict'; + +const constants = require('./constants'); +const utils = require('./utils'); + +/** + * Constants + */ + +const { + MAX_LENGTH, + POSIX_REGEX_SOURCE, + REGEX_NON_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_BACKREF, + REPLACEMENTS +} = constants; + +/** + * Helpers + */ + +const expandRange = (args, options) => { + if (typeof options.expandRange === 'function') { + return options.expandRange(...args, options); + } + + args.sort(); + const value = `[${args.join('-')}]`; + + try { + /* eslint-disable-next-line no-new */ + new RegExp(value); + } catch (ex) { + return args.map(v => utils.escapeRegex(v)).join('..'); + } + + return value; +}; + +/** + * Create the message for a syntax error + */ + +const syntaxError = (type, char) => { + return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; +}; + +/** + * Parse the given input string. + * @param {String} input + * @param {Object} options + * @return {Object} + */ + +const parse = (input, options) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); + } + + input = REPLACEMENTS[input] || input; + + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + + let len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } + + const bos = { type: 'bos', value: '', output: opts.prepend || '' }; + const tokens = [bos]; + + const capture = opts.capture ? '' : '?:'; + const win32 = utils.isWindows(options); + + // create constants based on platform, for windows or posix + const PLATFORM_CHARS = constants.globChars(win32); + const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); + + const { + DOT_LITERAL, + PLUS_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK, + QMARK_NO_DOT, + STAR, + START_ANCHOR + } = PLATFORM_CHARS; + + const globstar = opts => { + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + + const nodot = opts.dot ? '' : NO_DOT; + const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; + let star = opts.bash === true ? globstar(opts) : STAR; + + if (opts.capture) { + star = `(${star})`; + } + + // minimatch options support + if (typeof opts.noext === 'boolean') { + opts.noextglob = opts.noext; + } + + const state = { + input, + index: -1, + start: 0, + dot: opts.dot === true, + consumed: '', + output: '', + prefix: '', + backtrack: false, + negated: false, + brackets: 0, + braces: 0, + parens: 0, + quotes: 0, + globstar: false, + tokens + }; + + input = utils.removePrefix(input, state); + len = input.length; + + const extglobs = []; + const braces = []; + const stack = []; + let prev = bos; + let value; + + /** + * Tokenizing helpers + */ + + const eos = () => state.index === len - 1; + const peek = state.peek = (n = 1) => input[state.index + n]; + const advance = state.advance = () => input[++state.index] || ''; + const remaining = () => input.slice(state.index + 1); + const consume = (value = '', num = 0) => { + state.consumed += value; + state.index += num; + }; + + const append = token => { + state.output += token.output != null ? token.output : token.value; + consume(token.value); + }; + + const negate = () => { + let count = 1; + + while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { + advance(); + state.start++; + count++; + } + + if (count % 2 === 0) { + return false; + } + + state.negated = true; + state.start++; + return true; + }; + + const increment = type => { + state[type]++; + stack.push(type); + }; + + const decrement = type => { + state[type]--; + stack.pop(); + }; + + /** + * Push tokens onto the tokens array. This helper speeds up + * tokenizing by 1) helping us avoid backtracking as much as possible, + * and 2) helping us avoid creating extra tokens when consecutive + * characters are plain text. This improves performance and simplifies + * lookbehinds. + */ + + const push = tok => { + if (prev.type === 'globstar') { + const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); + const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); + + if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { + state.output = state.output.slice(0, -prev.output.length); + prev.type = 'star'; + prev.value = '*'; + prev.output = star; + state.output += prev.output; + } + } + + if (extglobs.length && tok.type !== 'paren') { + extglobs[extglobs.length - 1].inner += tok.value; + } + + if (tok.value || tok.output) append(tok); + if (prev && prev.type === 'text' && tok.type === 'text') { + prev.value += tok.value; + prev.output = (prev.output || '') + tok.value; + return; + } + + tok.prev = prev; + tokens.push(tok); + prev = tok; + }; + + const extglobOpen = (type, value) => { + const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; + + token.prev = prev; + token.parens = state.parens; + token.output = state.output; + const output = (opts.capture ? '(' : '') + token.open; + + increment('parens'); + push({ type, value, output: state.output ? '' : ONE_CHAR }); + push({ type: 'paren', extglob: true, value: advance(), output }); + extglobs.push(token); + }; + + const extglobClose = token => { + let output = token.close + (opts.capture ? ')' : ''); + let rest; + + if (token.type === 'negate') { + let extglobStar = star; + + if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { + extglobStar = globstar(opts); + } + + if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { + output = token.close = `)$))${extglobStar}`; + } + + if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { + // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. + // In this case, we need to parse the string and use it in the output of the original pattern. + // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. + // + // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. + const expression = parse(rest, { ...options, fastpaths: false }).output; + + output = token.close = `)${expression})${extglobStar})`; + } + + if (token.prev.type === 'bos') { + state.negatedExtglob = true; + } + } + + push({ type: 'paren', extglob: true, value, output }); + decrement('parens'); + }; + + /** + * Fast paths + */ + + if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { + let backslashes = false; + + let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { + if (first === '\\') { + backslashes = true; + return m; + } + + if (first === '?') { + if (esc) { + return esc + first + (rest ? QMARK.repeat(rest.length) : ''); + } + if (index === 0) { + return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); + } + return QMARK.repeat(chars.length); + } + + if (first === '.') { + return DOT_LITERAL.repeat(chars.length); + } + + if (first === '*') { + if (esc) { + return esc + first + (rest ? star : ''); + } + return star; + } + return esc ? m : `\\${m}`; + }); + + if (backslashes === true) { + if (opts.unescape === true) { + output = output.replace(/\\/g, ''); + } else { + output = output.replace(/\\+/g, m => { + return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); + }); + } + } + + if (output === input && opts.contains === true) { + state.output = input; + return state; + } + + state.output = utils.wrapOutput(output, state, options); + return state; + } + + /** + * Tokenize input until we reach end-of-string + */ + + while (!eos()) { + value = advance(); + + if (value === '\u0000') { + continue; + } + + /** + * Escaped characters + */ + + if (value === '\\') { + const next = peek(); + + if (next === '/' && opts.bash !== true) { + continue; + } + + if (next === '.' || next === ';') { + continue; + } + + if (!next) { + value += '\\'; + push({ type: 'text', value }); + continue; + } + + // collapse slashes to reduce potential for exploits + const match = /^\\+/.exec(remaining()); + let slashes = 0; + + if (match && match[0].length > 2) { + slashes = match[0].length; + state.index += slashes; + if (slashes % 2 !== 0) { + value += '\\'; + } + } + + if (opts.unescape === true) { + value = advance(); + } else { + value += advance(); + } + + if (state.brackets === 0) { + push({ type: 'text', value }); + continue; + } + } + + /** + * If we're inside a regex character class, continue + * until we reach the closing bracket. + */ + + if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { + if (opts.posix !== false && value === ':') { + const inner = prev.value.slice(1); + if (inner.includes('[')) { + prev.posix = true; + + if (inner.includes(':')) { + const idx = prev.value.lastIndexOf('['); + const pre = prev.value.slice(0, idx); + const rest = prev.value.slice(idx + 2); + const posix = POSIX_REGEX_SOURCE[rest]; + if (posix) { + prev.value = pre + posix; + state.backtrack = true; + advance(); + + if (!bos.output && tokens.indexOf(prev) === 1) { + bos.output = ONE_CHAR; + } + continue; + } + } + } + } + + if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { + value = `\\${value}`; + } + + if (value === ']' && (prev.value === '[' || prev.value === '[^')) { + value = `\\${value}`; + } + + if (opts.posix === true && value === '!' && prev.value === '[') { + value = '^'; + } + + prev.value += value; + append({ value }); + continue; + } + + /** + * If we're inside a quoted string, continue + * until we reach the closing double quote. + */ + + if (state.quotes === 1 && value !== '"') { + value = utils.escapeRegex(value); + prev.value += value; + append({ value }); + continue; + } + + /** + * Double quotes + */ + + if (value === '"') { + state.quotes = state.quotes === 1 ? 0 : 1; + if (opts.keepQuotes === true) { + push({ type: 'text', value }); + } + continue; + } + + /** + * Parentheses + */ + + if (value === '(') { + increment('parens'); + push({ type: 'paren', value }); + continue; + } + + if (value === ')') { + if (state.parens === 0 && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '(')); + } + + const extglob = extglobs[extglobs.length - 1]; + if (extglob && state.parens === extglob.parens + 1) { + extglobClose(extglobs.pop()); + continue; + } + + push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); + decrement('parens'); + continue; + } + + /** + * Square brackets + */ + + if (value === '[') { + if (opts.nobracket === true || !remaining().includes(']')) { + if (opts.nobracket !== true && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('closing', ']')); + } + + value = `\\${value}`; + } else { + increment('brackets'); + } + + push({ type: 'bracket', value }); + continue; + } + + if (value === ']') { + if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { + push({ type: 'text', value, output: `\\${value}` }); + continue; + } + + if (state.brackets === 0) { + if (opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '[')); + } + + push({ type: 'text', value, output: `\\${value}` }); + continue; + } + + decrement('brackets'); + + const prevValue = prev.value.slice(1); + if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { + value = `/${value}`; + } + + prev.value += value; + append({ value }); + + // when literal brackets are explicitly disabled + // assume we should match with a regex character class + if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { + continue; + } + + const escaped = utils.escapeRegex(prev.value); + state.output = state.output.slice(0, -prev.value.length); + + // when literal brackets are explicitly enabled + // assume we should escape the brackets to match literal characters + if (opts.literalBrackets === true) { + state.output += escaped; + prev.value = escaped; + continue; + } + + // when the user specifies nothing, try to match both + prev.value = `(${capture}${escaped}|${prev.value})`; + state.output += prev.value; + continue; + } + + /** + * Braces + */ + + if (value === '{' && opts.nobrace !== true) { + increment('braces'); + + const open = { + type: 'brace', + value, + output: '(', + outputIndex: state.output.length, + tokensIndex: state.tokens.length + }; + + braces.push(open); + push(open); + continue; + } + + if (value === '}') { + const brace = braces[braces.length - 1]; + + if (opts.nobrace === true || !brace) { + push({ type: 'text', value, output: value }); + continue; + } + + let output = ')'; + + if (brace.dots === true) { + const arr = tokens.slice(); + const range = []; + + for (let i = arr.length - 1; i >= 0; i--) { + tokens.pop(); + if (arr[i].type === 'brace') { + break; + } + if (arr[i].type !== 'dots') { + range.unshift(arr[i].value); + } + } + + output = expandRange(range, opts); + state.backtrack = true; + } + + if (brace.comma !== true && brace.dots !== true) { + const out = state.output.slice(0, brace.outputIndex); + const toks = state.tokens.slice(brace.tokensIndex); + brace.value = brace.output = '\\{'; + value = output = '\\}'; + state.output = out; + for (const t of toks) { + state.output += (t.output || t.value); + } + } + + push({ type: 'brace', value, output }); + decrement('braces'); + braces.pop(); + continue; + } + + /** + * Pipes + */ + + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; + } + push({ type: 'text', value }); + continue; + } + + /** + * Commas + */ + + if (value === ',') { + let output = value; + + const brace = braces[braces.length - 1]; + if (brace && stack[stack.length - 1] === 'braces') { + brace.comma = true; + output = '|'; + } + + push({ type: 'comma', value, output }); + continue; + } + + /** + * Slashes + */ + + if (value === '/') { + // if the beginning of the glob is "./", advance the start + // to the current index, and don't add the "./" characters + // to the state. This greatly simplifies lookbehinds when + // checking for BOS characters like "!" and "." (not "./") + if (prev.type === 'dot' && state.index === state.start + 1) { + state.start = state.index + 1; + state.consumed = ''; + state.output = ''; + tokens.pop(); + prev = bos; // reset "prev" to the first token + continue; + } + + push({ type: 'slash', value, output: SLASH_LITERAL }); + continue; + } + + /** + * Dots + */ + + if (value === '.') { + if (state.braces > 0 && prev.type === 'dot') { + if (prev.value === '.') prev.output = DOT_LITERAL; + const brace = braces[braces.length - 1]; + prev.type = 'dots'; + prev.output += value; + prev.value += value; + brace.dots = true; + continue; + } + + if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { + push({ type: 'text', value, output: DOT_LITERAL }); + continue; + } + + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; + } + + /** + * Question marks + */ + + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } + + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; + + if (next === '<' && !utils.supportsLookbehinds()) { + throw new Error('Node.js v10 or higher is required for regex lookbehinds'); + } + + if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { + output = `\\${value}`; + } + + push({ type: 'text', value, output }); + continue; + } + + if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { + push({ type: 'qmark', value, output: QMARK_NO_DOT }); + continue; + } + + push({ type: 'qmark', value, output: QMARK }); + continue; + } + + /** + * Exclamation + */ + + if (value === '!') { + if (opts.noextglob !== true && peek() === '(') { + if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { + extglobOpen('negate', value); + continue; + } + } + + if (opts.nonegate !== true && state.index === 0) { + negate(); + continue; + } + } + + /** + * Plus + */ + + if (value === '+') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('plus', value); + continue; + } + + if ((prev && prev.value === '(') || opts.regex === false) { + push({ type: 'plus', value, output: PLUS_LITERAL }); + continue; + } + + if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { + push({ type: 'plus', value }); + continue; + } + + push({ type: 'plus', value: PLUS_LITERAL }); + continue; + } + + /** + * Plain text + */ + + if (value === '@') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + push({ type: 'at', extglob: true, value, output: '' }); + continue; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Plain text + */ + + if (value !== '*') { + if (value === '$' || value === '^') { + value = `\\${value}`; + } + + const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); + if (match) { + value += match[0]; + state.index += match[0].length; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Stars + */ + + if (prev && (prev.type === 'globstar' || prev.star === true)) { + prev.type = 'star'; + prev.star = true; + prev.value += value; + prev.output = star; + state.backtrack = true; + state.globstar = true; + consume(value); + continue; + } + + let rest = remaining(); + if (opts.noextglob !== true && /^\([^?]/.test(rest)) { + extglobOpen('star', value); + continue; + } + + if (prev.type === 'star') { + if (opts.noglobstar === true) { + consume(value); + continue; + } + + const prior = prev.prev; + const before = prior.prev; + const isStart = prior.type === 'slash' || prior.type === 'bos'; + const afterStar = before && (before.type === 'star' || before.type === 'globstar'); + + if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { + push({ type: 'star', value, output: '' }); + continue; + } + + const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); + const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); + if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { + push({ type: 'star', value, output: '' }); + continue; + } + + // strip consecutive `/**/` + while (rest.slice(0, 3) === '/**') { + const after = input[state.index + 4]; + if (after && after !== '/') { + break; + } + rest = rest.slice(3); + consume('/**', 3); + } + + if (prior.type === 'bos' && eos()) { + prev.type = 'globstar'; + prev.value += value; + prev.output = globstar(opts); + state.output = prev.output; + state.globstar = true; + consume(value); + continue; + } + + if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; + + prev.type = 'globstar'; + prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); + prev.value += value; + state.globstar = true; + state.output += prior.output + prev.output; + consume(value); + continue; + } + + if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { + const end = rest[1] !== void 0 ? '|$' : ''; + + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; + + prev.type = 'globstar'; + prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; + prev.value += value; + + state.output += prior.output + prev.output; + state.globstar = true; + + consume(value + advance()); + + push({ type: 'slash', value: '/', output: '' }); + continue; + } + + if (prior.type === 'bos' && rest[0] === '/') { + prev.type = 'globstar'; + prev.value += value; + prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; + state.output = prev.output; + state.globstar = true; + consume(value + advance()); + push({ type: 'slash', value: '/', output: '' }); + continue; + } + + // remove single star from output + state.output = state.output.slice(0, -prev.output.length); + + // reset previous token to globstar + prev.type = 'globstar'; + prev.output = globstar(opts); + prev.value += value; + + // reset output with globstar + state.output += prev.output; + state.globstar = true; + consume(value); + continue; + } + + const token = { type: 'star', value, output: star }; + + if (opts.bash === true) { + token.output = '.*?'; + if (prev.type === 'bos' || prev.type === 'slash') { + token.output = nodot + token.output; + } + push(token); + continue; + } + + if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { + token.output = value; + push(token); + continue; + } + + if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { + if (prev.type === 'dot') { + state.output += NO_DOT_SLASH; + prev.output += NO_DOT_SLASH; + + } else if (opts.dot === true) { + state.output += NO_DOTS_SLASH; + prev.output += NO_DOTS_SLASH; + + } else { + state.output += nodot; + prev.output += nodot; + } + + if (peek() !== '*') { + state.output += ONE_CHAR; + prev.output += ONE_CHAR; + } + } + + push(token); + } + + while (state.brackets > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); + state.output = utils.escapeLast(state.output, '['); + decrement('brackets'); + } + + while (state.parens > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); + state.output = utils.escapeLast(state.output, '('); + decrement('parens'); + } + + while (state.braces > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); + state.output = utils.escapeLast(state.output, '{'); + decrement('braces'); + } + + if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { + push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); + } + + // rebuild the output if we had to backtrack at any point + if (state.backtrack === true) { + state.output = ''; + + for (const token of state.tokens) { + state.output += token.output != null ? token.output : token.value; + + if (token.suffix) { + state.output += token.suffix; + } + } + } + + return state; +}; + +/** + * Fast paths for creating regular expressions for common glob patterns. + * This can significantly speed up processing and has very little downside + * impact when none of the fast paths match. + */ + +parse.fastpaths = (input, options) => { + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + const len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } + + input = REPLACEMENTS[input] || input; + const win32 = utils.isWindows(options); + + // create constants based on platform, for windows or posix + const { + DOT_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOTS_SLASH, + STAR, + START_ANCHOR + } = constants.globChars(win32); + + const nodot = opts.dot ? NO_DOTS : NO_DOT; + const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; + const capture = opts.capture ? '' : '?:'; + const state = { negated: false, prefix: '' }; + let star = opts.bash === true ? '.*?' : STAR; + + if (opts.capture) { + star = `(${star})`; + } + + const globstar = opts => { + if (opts.noglobstar === true) return star; + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + + const create = str => { + switch (str) { + case '*': + return `${nodot}${ONE_CHAR}${star}`; + + case '.*': + return `${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*.*': + return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*/*': + return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + + case '**': + return nodot + globstar(opts); + + case '**/*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; + + case '**/*.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '**/.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; + + default: { + const match = /^(.*?)\.(\w+)$/.exec(str); + if (!match) return; + + const source = create(match[1]); + if (!source) return; + + return source + DOT_LITERAL + match[2]; + } + } + }; + + const output = utils.removePrefix(input, state); + let source = create(output); + + if (source && opts.strictSlashes !== true) { + source += `${SLASH_LITERAL}?`; + } + + return source; +}; + +module.exports = parse; diff --git a/libs/events/node_modules/picomatch/lib/picomatch.js b/libs/events/node_modules/picomatch/lib/picomatch.js new file mode 100644 index 000000000..782d80943 --- /dev/null +++ b/libs/events/node_modules/picomatch/lib/picomatch.js @@ -0,0 +1,342 @@ +'use strict'; + +const path = require('path'); +const scan = require('./scan'); +const parse = require('./parse'); +const utils = require('./utils'); +const constants = require('./constants'); +const isObject = val => val && typeof val === 'object' && !Array.isArray(val); + +/** + * Creates a matcher function from one or more glob patterns. The + * returned function takes a string to match as its first argument, + * and returns true if the string is a match. The returned matcher + * function also takes a boolean as the second argument that, when true, + * returns an object with additional information. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch(glob[, options]); + * + * const isMatch = picomatch('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @name picomatch + * @param {String|Array} `globs` One or more glob patterns. + * @param {Object=} `options` + * @return {Function=} Returns a matcher function. + * @api public + */ + +const picomatch = (glob, options, returnState = false) => { + if (Array.isArray(glob)) { + const fns = glob.map(input => picomatch(input, options, returnState)); + const arrayMatcher = str => { + for (const isMatch of fns) { + const state = isMatch(str); + if (state) return state; + } + return false; + }; + return arrayMatcher; + } + + const isState = isObject(glob) && glob.tokens && glob.input; + + if (glob === '' || (typeof glob !== 'string' && !isState)) { + throw new TypeError('Expected pattern to be a non-empty string'); + } + + const opts = options || {}; + const posix = utils.isWindows(options); + const regex = isState + ? picomatch.compileRe(glob, options) + : picomatch.makeRe(glob, options, false, true); + + const state = regex.state; + delete regex.state; + + let isIgnored = () => false; + if (opts.ignore) { + const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; + isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); + } + + const matcher = (input, returnObject = false) => { + const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); + const result = { glob, state, regex, posix, input, output, match, isMatch }; + + if (typeof opts.onResult === 'function') { + opts.onResult(result); + } + + if (isMatch === false) { + result.isMatch = false; + return returnObject ? result : false; + } + + if (isIgnored(input)) { + if (typeof opts.onIgnore === 'function') { + opts.onIgnore(result); + } + result.isMatch = false; + return returnObject ? result : false; + } + + if (typeof opts.onMatch === 'function') { + opts.onMatch(result); + } + return returnObject ? result : true; + }; + + if (returnState) { + matcher.state = state; + } + + return matcher; +}; + +/** + * Test `input` with the given `regex`. This is used by the main + * `picomatch()` function to test the input string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.test(input, regex[, options]); + * + * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); + * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } + * ``` + * @param {String} `input` String to test. + * @param {RegExp} `regex` + * @return {Object} Returns an object with matching info. + * @api public + */ + +picomatch.test = (input, regex, options, { glob, posix } = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected input to be a string'); + } + + if (input === '') { + return { isMatch: false, output: '' }; + } + + const opts = options || {}; + const format = opts.format || (posix ? utils.toPosixSlashes : null); + let match = input === glob; + let output = (match && format) ? format(input) : input; + + if (match === false) { + output = format ? format(input) : input; + match = output === glob; + } + + if (match === false || opts.capture === true) { + if (opts.matchBase === true || opts.basename === true) { + match = picomatch.matchBase(input, regex, options, posix); + } else { + match = regex.exec(output); + } + } + + return { isMatch: Boolean(match), match, output }; +}; + +/** + * Match the basename of a filepath. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.matchBase(input, glob[, options]); + * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true + * ``` + * @param {String} `input` String to test. + * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). + * @return {Boolean} + * @api public + */ + +picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { + const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); + return regex.test(path.basename(input)); +}; + +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.isMatch(string, patterns[, options]); + * + * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String|Array} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ + +picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); + +/** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const picomatch = require('picomatch'); + * const result = picomatch.parse(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as a regex source string. + * @api public + */ + +picomatch.parse = (pattern, options) => { + if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); + return parse(pattern, { ...options, fastpaths: false }); +}; + +/** + * Scan a glob pattern to separate the pattern into segments. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.scan(input[, options]); + * + * const result = picomatch.scan('!./foo/*.js'); + * console.log(result); + * { prefix: '!./', + * input: '!./foo/*.js', + * start: 3, + * base: 'foo', + * glob: '*.js', + * isBrace: false, + * isBracket: false, + * isGlob: true, + * isExtglob: false, + * isGlobstar: false, + * negated: true } + * ``` + * @param {String} `input` Glob pattern to scan. + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public + */ + +picomatch.scan = (input, options) => scan(input, options); + +/** + * Compile a regular expression from the `state` object returned by the + * [parse()](#parse) method. + * + * @param {Object} `state` + * @param {Object} `options` + * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. + * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. + * @return {RegExp} + * @api public + */ + +picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { + if (returnOutput === true) { + return state.output; + } + + const opts = options || {}; + const prepend = opts.contains ? '' : '^'; + const append = opts.contains ? '' : '$'; + + let source = `${prepend}(?:${state.output})${append}`; + if (state && state.negated === true) { + source = `^(?!${source}).*$`; + } + + const regex = picomatch.toRegex(source, options); + if (returnState === true) { + regex.state = state; + } + + return regex; +}; + +/** + * Create a regular expression from a parsed glob pattern. + * + * ```js + * const picomatch = require('picomatch'); + * const state = picomatch.parse('*.js'); + * // picomatch.compileRe(state[, options]); + * + * console.log(picomatch.compileRe(state)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `state` The object returned from the `.parse` method. + * @param {Object} `options` + * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. + * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ + +picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { + if (!input || typeof input !== 'string') { + throw new TypeError('Expected a non-empty string'); + } + + let parsed = { negated: false, fastpaths: true }; + + if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { + parsed.output = parse.fastpaths(input, options); + } + + if (!parsed.output) { + parsed = parse(input, options); + } + + return picomatch.compileRe(parsed, options, returnOutput, returnState); +}; + +/** + * Create a regular expression from the given regex source string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.toRegex(source[, options]); + * + * const { output } = picomatch.parse('*.js'); + * console.log(picomatch.toRegex(output)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `source` Regular expression source string. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ + +picomatch.toRegex = (source, options) => { + try { + const opts = options || {}; + return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); + } catch (err) { + if (options && options.debug === true) throw err; + return /$^/; + } +}; + +/** + * Picomatch constants. + * @return {Object} + */ + +picomatch.constants = constants; + +/** + * Expose "picomatch" + */ + +module.exports = picomatch; diff --git a/libs/events/node_modules/picomatch/lib/scan.js b/libs/events/node_modules/picomatch/lib/scan.js new file mode 100644 index 000000000..e59cd7a13 --- /dev/null +++ b/libs/events/node_modules/picomatch/lib/scan.js @@ -0,0 +1,391 @@ +'use strict'; + +const utils = require('./utils'); +const { + CHAR_ASTERISK, /* * */ + CHAR_AT, /* @ */ + CHAR_BACKWARD_SLASH, /* \ */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_EXCLAMATION_MARK, /* ! */ + CHAR_FORWARD_SLASH, /* / */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_PLUS, /* + */ + CHAR_QUESTION_MARK, /* ? */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_RIGHT_SQUARE_BRACKET /* ] */ +} = require('./constants'); + +const isPathSeparator = code => { + return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; +}; + +const depth = token => { + if (token.isPrefix !== true) { + token.depth = token.isGlobstar ? Infinity : 1; + } +}; + +/** + * Quickly scans a glob pattern and returns an object with a handful of + * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), + * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not + * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). + * + * ```js + * const pm = require('picomatch'); + * console.log(pm.scan('foo/bar/*.js')); + * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {Object} Returns an object with tokens and regex source string. + * @api public + */ + +const scan = (input, options) => { + const opts = options || {}; + + const length = input.length - 1; + const scanToEnd = opts.parts === true || opts.scanToEnd === true; + const slashes = []; + const tokens = []; + const parts = []; + + let str = input; + let index = -1; + let start = 0; + let lastIndex = 0; + let isBrace = false; + let isBracket = false; + let isGlob = false; + let isExtglob = false; + let isGlobstar = false; + let braceEscaped = false; + let backslashes = false; + let negated = false; + let negatedExtglob = false; + let finished = false; + let braces = 0; + let prev; + let code; + let token = { value: '', depth: 0, isGlob: false }; + + const eos = () => index >= length; + const peek = () => str.charCodeAt(index + 1); + const advance = () => { + prev = code; + return str.charCodeAt(++index); + }; + + while (index < length) { + code = advance(); + let next; + + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + + if (code === CHAR_LEFT_CURLY_BRACE) { + braceEscaped = true; + } + continue; + } + + if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { + braces++; + + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } + + if (code === CHAR_LEFT_CURLY_BRACE) { + braces++; + continue; + } + + if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (braceEscaped !== true && code === CHAR_COMMA) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (code === CHAR_RIGHT_CURLY_BRACE) { + braces--; + + if (braces === 0) { + braceEscaped = false; + isBrace = token.isBrace = true; + finished = true; + break; + } + } + } + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (code === CHAR_FORWARD_SLASH) { + slashes.push(index); + tokens.push(token); + token = { value: '', depth: 0, isGlob: false }; + + if (finished === true) continue; + if (prev === CHAR_DOT && index === (start + 1)) { + start += 2; + continue; + } + + lastIndex = index + 1; + continue; + } + + if (opts.noext !== true) { + const isExtglobChar = code === CHAR_PLUS + || code === CHAR_AT + || code === CHAR_ASTERISK + || code === CHAR_QUESTION_MARK + || code === CHAR_EXCLAMATION_MARK; + + if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + isExtglob = token.isExtglob = true; + finished = true; + if (code === CHAR_EXCLAMATION_MARK && index === start) { + negatedExtglob = true; + } + + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } + + if (code === CHAR_RIGHT_PARENTHESES) { + isGlob = token.isGlob = true; + finished = true; + break; + } + } + continue; + } + break; + } + } + + if (code === CHAR_ASTERISK) { + if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + break; + } + + if (code === CHAR_QUESTION_MARK) { + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + break; + } + + if (code === CHAR_LEFT_SQUARE_BRACKET) { + while (eos() !== true && (next = advance())) { + if (next === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } + + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + isBracket = token.isBracket = true; + isGlob = token.isGlob = true; + finished = true; + break; + } + } + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { + negated = token.negated = true; + start++; + continue; + } + + if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_LEFT_PARENTHESES) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } + + if (code === CHAR_RIGHT_PARENTHESES) { + finished = true; + break; + } + } + continue; + } + break; + } + + if (isGlob === true) { + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + } + + if (opts.noext === true) { + isExtglob = false; + isGlob = false; + } + + let base = str; + let prefix = ''; + let glob = ''; + + if (start > 0) { + prefix = str.slice(0, start); + str = str.slice(start); + lastIndex -= start; + } + + if (base && isGlob === true && lastIndex > 0) { + base = str.slice(0, lastIndex); + glob = str.slice(lastIndex); + } else if (isGlob === true) { + base = ''; + glob = str; + } else { + base = str; + } + + if (base && base !== '' && base !== '/' && base !== str) { + if (isPathSeparator(base.charCodeAt(base.length - 1))) { + base = base.slice(0, -1); + } + } + + if (opts.unescape === true) { + if (glob) glob = utils.removeBackslashes(glob); + + if (base && backslashes === true) { + base = utils.removeBackslashes(base); + } + } + + const state = { + prefix, + input, + start, + base, + glob, + isBrace, + isBracket, + isGlob, + isExtglob, + isGlobstar, + negated, + negatedExtglob + }; + + if (opts.tokens === true) { + state.maxDepth = 0; + if (!isPathSeparator(code)) { + tokens.push(token); + } + state.tokens = tokens; + } + + if (opts.parts === true || opts.tokens === true) { + let prevIndex; + + for (let idx = 0; idx < slashes.length; idx++) { + const n = prevIndex ? prevIndex + 1 : start; + const i = slashes[idx]; + const value = input.slice(n, i); + if (opts.tokens) { + if (idx === 0 && start !== 0) { + tokens[idx].isPrefix = true; + tokens[idx].value = prefix; + } else { + tokens[idx].value = value; + } + depth(tokens[idx]); + state.maxDepth += tokens[idx].depth; + } + if (idx !== 0 || value !== '') { + parts.push(value); + } + prevIndex = i; + } + + if (prevIndex && prevIndex + 1 < input.length) { + const value = input.slice(prevIndex + 1); + parts.push(value); + + if (opts.tokens) { + tokens[tokens.length - 1].value = value; + depth(tokens[tokens.length - 1]); + state.maxDepth += tokens[tokens.length - 1].depth; + } + } + + state.slashes = slashes; + state.parts = parts; + } + + return state; +}; + +module.exports = scan; diff --git a/libs/events/node_modules/picomatch/lib/utils.js b/libs/events/node_modules/picomatch/lib/utils.js new file mode 100644 index 000000000..c3ca766a7 --- /dev/null +++ b/libs/events/node_modules/picomatch/lib/utils.js @@ -0,0 +1,64 @@ +'use strict'; + +const path = require('path'); +const win32 = process.platform === 'win32'; +const { + REGEX_BACKSLASH, + REGEX_REMOVE_BACKSLASH, + REGEX_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_GLOBAL +} = require('./constants'); + +exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); +exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); +exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); +exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); +exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); + +exports.removeBackslashes = str => { + return str.replace(REGEX_REMOVE_BACKSLASH, match => { + return match === '\\' ? '' : match; + }); +}; + +exports.supportsLookbehinds = () => { + const segs = process.version.slice(1).split('.').map(Number); + if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { + return true; + } + return false; +}; + +exports.isWindows = options => { + if (options && typeof options.windows === 'boolean') { + return options.windows; + } + return win32 === true || path.sep === '\\'; +}; + +exports.escapeLast = (input, char, lastIdx) => { + const idx = input.lastIndexOf(char, lastIdx); + if (idx === -1) return input; + if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); + return `${input.slice(0, idx)}\\${input.slice(idx)}`; +}; + +exports.removePrefix = (input, state = {}) => { + let output = input; + if (output.startsWith('./')) { + output = output.slice(2); + state.prefix = './'; + } + return output; +}; + +exports.wrapOutput = (input, state = {}, options = {}) => { + const prepend = options.contains ? '' : '^'; + const append = options.contains ? '' : '$'; + + let output = `${prepend}(?:${input})${append}`; + if (state.negated === true) { + output = `(?:^(?!${output}).*$)`; + } + return output; +}; diff --git a/libs/events/node_modules/picomatch/package.json b/libs/events/node_modules/picomatch/package.json new file mode 100644 index 000000000..3db22d408 --- /dev/null +++ b/libs/events/node_modules/picomatch/package.json @@ -0,0 +1,81 @@ +{ + "name": "picomatch", + "description": "Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.", + "version": "2.3.1", + "homepage": "https://github.com/micromatch/picomatch", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "funding": "https://github.com/sponsors/jonschlinkert", + "repository": "micromatch/picomatch", + "bugs": { + "url": "https://github.com/micromatch/picomatch/issues" + }, + "license": "MIT", + "files": [ + "index.js", + "lib" + ], + "main": "index.js", + "engines": { + "node": ">=8.6" + }, + "scripts": { + "lint": "eslint --cache --cache-location node_modules/.cache/.eslintcache --report-unused-disable-directives --ignore-path .gitignore .", + "mocha": "mocha --reporter dot", + "test": "npm run lint && npm run mocha", + "test:ci": "npm run test:cover", + "test:cover": "nyc npm run mocha" + }, + "devDependencies": { + "eslint": "^6.8.0", + "fill-range": "^7.0.1", + "gulp-format-md": "^2.0.0", + "mocha": "^6.2.2", + "nyc": "^15.0.0", + "time-require": "github:jonschlinkert/time-require" + }, + "keywords": [ + "glob", + "match", + "picomatch" + ], + "nyc": { + "reporter": [ + "html", + "lcov", + "text-summary" + ] + }, + "verb": { + "toc": { + "render": true, + "method": "preWrite", + "maxdepth": 3 + }, + "layout": "empty", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + }, + "related": { + "list": [ + "braces", + "micromatch" + ] + }, + "reflinks": [ + "braces", + "expand-brackets", + "extglob", + "fill-range", + "micromatch", + "minimatch", + "nanomatch", + "picomatch" + ] + } +} diff --git a/libs/events/node_modules/punycode/LICENSE-MIT.txt b/libs/events/node_modules/punycode/LICENSE-MIT.txt new file mode 100644 index 000000000..a41e0a7ef --- /dev/null +++ b/libs/events/node_modules/punycode/LICENSE-MIT.txt @@ -0,0 +1,20 @@ +Copyright Mathias Bynens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libs/events/node_modules/punycode/README.md b/libs/events/node_modules/punycode/README.md new file mode 100644 index 000000000..72b632cdc --- /dev/null +++ b/libs/events/node_modules/punycode/README.md @@ -0,0 +1,126 @@ +# Punycode.js [![punycode on npm](https://img.shields.io/npm/v/punycode)](https://www.npmjs.com/package/emoji-test-regex-pattern) [![](https://data.jsdelivr.com/v1/package/npm/punycode/badge)](https://www.jsdelivr.com/package/npm/punycode) + +Punycode.js is a robust Punycode converter that fully complies to [RFC 3492](https://tools.ietf.org/html/rfc3492) and [RFC 5891](https://tools.ietf.org/html/rfc5891). + +This JavaScript library is the result of comparing, optimizing and documenting different open-source implementations of the Punycode algorithm: + +* [The C example code from RFC 3492](https://tools.ietf.org/html/rfc3492#appendix-C) +* [`punycode.c` by _Markus W. Scherer_ (IBM)](http://opensource.apple.com/source/ICU/ICU-400.42/icuSources/common/punycode.c) +* [`punycode.c` by _Ben Noordhuis_](https://github.com/bnoordhuis/punycode/blob/master/punycode.c) +* [JavaScript implementation by _some_](http://stackoverflow.com/questions/183485/can-anyone-recommend-a-good-free-javascript-for-punycode-to-unicode-conversion/301287#301287) +* [`punycode.js` by _Ben Noordhuis_](https://github.com/joyent/node/blob/426298c8c1c0d5b5224ac3658c41e7c2a3fe9377/lib/punycode.js) (note: [not fully compliant](https://github.com/joyent/node/issues/2072)) + +This project was [bundled](https://github.com/joyent/node/blob/master/lib/punycode.js) with Node.js from [v0.6.2+](https://github.com/joyent/node/compare/975f1930b1...61e796decc) until [v7](https://github.com/nodejs/node/pull/7941) (soft-deprecated). + +This project provides a CommonJS module that uses ES2015+ features and JavaScript module, which work in modern Node.js versions and browsers. For the old Punycode.js version that offers the same functionality in a UMD build with support for older pre-ES2015 runtimes, including Rhino, Ringo, and Narwhal, see [v1.4.1](https://github.com/mathiasbynens/punycode.js/releases/tag/v1.4.1). + +## Installation + +Via [npm](https://www.npmjs.com/): + +```bash +npm install punycode --save +``` + +In [Node.js](https://nodejs.org/): + +> ⚠️ Note that userland modules don't hide core modules. +> For example, `require('punycode')` still imports the deprecated core module even if you executed `npm install punycode`. +> Use `require('punycode/')` to import userland modules rather than core modules. + +```js +const punycode = require('punycode/'); +``` + +## API + +### `punycode.decode(string)` + +Converts a Punycode string of ASCII symbols to a string of Unicode symbols. + +```js +// decode domain name parts +punycode.decode('maana-pta'); // 'mañana' +punycode.decode('--dqo34k'); // '☃-⌘' +``` + +### `punycode.encode(string)` + +Converts a string of Unicode symbols to a Punycode string of ASCII symbols. + +```js +// encode domain name parts +punycode.encode('mañana'); // 'maana-pta' +punycode.encode('☃-⌘'); // '--dqo34k' +``` + +### `punycode.toUnicode(input)` + +Converts a Punycode string representing a domain name or an email address to Unicode. Only the Punycoded parts of the input will be converted, i.e. it doesn’t matter if you call it on a string that has already been converted to Unicode. + +```js +// decode domain names +punycode.toUnicode('xn--maana-pta.com'); +// → 'mañana.com' +punycode.toUnicode('xn----dqo34k.com'); +// → '☃-⌘.com' + +// decode email addresses +punycode.toUnicode('джумла@xn--p-8sbkgc5ag7bhce.xn--ba-lmcq'); +// → 'джумла@джpумлатест.bрфa' +``` + +### `punycode.toASCII(input)` + +Converts a lowercased Unicode string representing a domain name or an email address to Punycode. Only the non-ASCII parts of the input will be converted, i.e. it doesn’t matter if you call it with a domain that’s already in ASCII. + +```js +// encode domain names +punycode.toASCII('mañana.com'); +// → 'xn--maana-pta.com' +punycode.toASCII('☃-⌘.com'); +// → 'xn----dqo34k.com' + +// encode email addresses +punycode.toASCII('джумла@джpумлатест.bрфa'); +// → 'джумла@xn--p-8sbkgc5ag7bhce.xn--ba-lmcq' +``` + +### `punycode.ucs2` + +#### `punycode.ucs2.decode(string)` + +Creates an array containing the numeric code point values of each Unicode symbol in the string. While [JavaScript uses UCS-2 internally](https://mathiasbynens.be/notes/javascript-encoding), this function will convert a pair of surrogate halves (each of which UCS-2 exposes as separate characters) into a single code point, matching UTF-16. + +```js +punycode.ucs2.decode('abc'); +// → [0x61, 0x62, 0x63] +// surrogate pair for U+1D306 TETRAGRAM FOR CENTRE: +punycode.ucs2.decode('\uD834\uDF06'); +// → [0x1D306] +``` + +#### `punycode.ucs2.encode(codePoints)` + +Creates a string based on an array of numeric code point values. + +```js +punycode.ucs2.encode([0x61, 0x62, 0x63]); +// → 'abc' +punycode.ucs2.encode([0x1D306]); +// → '\uD834\uDF06' +``` + +### `punycode.version` + +A string representing the current Punycode.js version number. + +## Author + +| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | +|---| +| [Mathias Bynens](https://mathiasbynens.be/) | + +## License + +Punycode.js is available under the [MIT](https://mths.be/mit) license. diff --git a/libs/events/node_modules/punycode/package.json b/libs/events/node_modules/punycode/package.json new file mode 100644 index 000000000..9d0790b2a --- /dev/null +++ b/libs/events/node_modules/punycode/package.json @@ -0,0 +1,58 @@ +{ + "name": "punycode", + "version": "2.3.0", + "description": "A robust Punycode converter that fully complies to RFC 3492 and RFC 5891, and works on nearly all JavaScript platforms.", + "homepage": "https://mths.be/punycode", + "main": "punycode.js", + "jsnext:main": "punycode.es6.js", + "module": "punycode.es6.js", + "engines": { + "node": ">=6" + }, + "keywords": [ + "punycode", + "unicode", + "idn", + "idna", + "dns", + "url", + "domain" + ], + "license": "MIT", + "author": { + "name": "Mathias Bynens", + "url": "https://mathiasbynens.be/" + }, + "contributors": [ + { + "name": "Mathias Bynens", + "url": "https://mathiasbynens.be/" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/mathiasbynens/punycode.js.git" + }, + "bugs": "https://github.com/mathiasbynens/punycode.js/issues", + "files": [ + "LICENSE-MIT.txt", + "punycode.js", + "punycode.es6.js" + ], + "scripts": { + "test": "mocha tests", + "build": "node scripts/prepublish.js" + }, + "devDependencies": { + "codecov": "^1.0.1", + "istanbul": "^0.4.1", + "mocha": "^10.2.0" + }, + "jspm": { + "map": { + "./punycode.js": { + "node": "@node/punycode" + } + } + } +} diff --git a/libs/events/node_modules/punycode/punycode.es6.js b/libs/events/node_modules/punycode/punycode.es6.js new file mode 100644 index 000000000..244e1bfbf --- /dev/null +++ b/libs/events/node_modules/punycode/punycode.es6.js @@ -0,0 +1,444 @@ +'use strict'; + +/** Highest positive signed 32-bit float value */ +const maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1 + +/** Bootstring parameters */ +const base = 36; +const tMin = 1; +const tMax = 26; +const skew = 38; +const damp = 700; +const initialBias = 72; +const initialN = 128; // 0x80 +const delimiter = '-'; // '\x2D' + +/** Regular expressions */ +const regexPunycode = /^xn--/; +const regexNonASCII = /[^\0-\x7F]/; // Note: U+007F DEL is excluded too. +const regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; // RFC 3490 separators + +/** Error messages */ +const errors = { + 'overflow': 'Overflow: input needs wider integers to process', + 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', + 'invalid-input': 'Invalid input' +}; + +/** Convenience shortcuts */ +const baseMinusTMin = base - tMin; +const floor = Math.floor; +const stringFromCharCode = String.fromCharCode; + +/*--------------------------------------------------------------------------*/ + +/** + * A generic error utility function. + * @private + * @param {String} type The error type. + * @returns {Error} Throws a `RangeError` with the applicable error message. + */ +function error(type) { + throw new RangeError(errors[type]); +} + +/** + * A generic `Array#map` utility function. + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function that gets called for every array + * item. + * @returns {Array} A new array of values returned by the callback function. + */ +function map(array, callback) { + const result = []; + let length = array.length; + while (length--) { + result[length] = callback(array[length]); + } + return result; +} + +/** + * A simple `Array#map`-like wrapper to work with domain name strings or email + * addresses. + * @private + * @param {String} domain The domain name or email address. + * @param {Function} callback The function that gets called for every + * character. + * @returns {String} A new string of characters returned by the callback + * function. + */ +function mapDomain(domain, callback) { + const parts = domain.split('@'); + let result = ''; + if (parts.length > 1) { + // In email addresses, only the domain name should be punycoded. Leave + // the local part (i.e. everything up to `@`) intact. + result = parts[0] + '@'; + domain = parts[1]; + } + // Avoid `split(regex)` for IE8 compatibility. See #17. + domain = domain.replace(regexSeparators, '\x2E'); + const labels = domain.split('.'); + const encoded = map(labels, callback).join('.'); + return result + encoded; +} + +/** + * Creates an array containing the numeric code points of each Unicode + * character in the string. While JavaScript uses UCS-2 internally, + * this function will convert a pair of surrogate halves (each of which + * UCS-2 exposes as separate characters) into a single code point, + * matching UTF-16. + * @see `punycode.ucs2.encode` + * @see + * @memberOf punycode.ucs2 + * @name decode + * @param {String} string The Unicode input string (UCS-2). + * @returns {Array} The new array of code points. + */ +function ucs2decode(string) { + const output = []; + let counter = 0; + const length = string.length; + while (counter < length) { + const value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // It's a high surrogate, and there is a next character. + const extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // Low surrogate. + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // It's an unmatched surrogate; only append this code unit, in case the + // next code unit is the high surrogate of a surrogate pair. + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; +} + +/** + * Creates a string based on an array of numeric code points. + * @see `punycode.ucs2.decode` + * @memberOf punycode.ucs2 + * @name encode + * @param {Array} codePoints The array of numeric code points. + * @returns {String} The new Unicode string (UCS-2). + */ +const ucs2encode = codePoints => String.fromCodePoint(...codePoints); + +/** + * Converts a basic code point into a digit/integer. + * @see `digitToBasic()` + * @private + * @param {Number} codePoint The basic numeric code point value. + * @returns {Number} The numeric value of a basic code point (for use in + * representing integers) in the range `0` to `base - 1`, or `base` if + * the code point does not represent a value. + */ +const basicToDigit = function(codePoint) { + if (codePoint >= 0x30 && codePoint < 0x3A) { + return 26 + (codePoint - 0x30); + } + if (codePoint >= 0x41 && codePoint < 0x5B) { + return codePoint - 0x41; + } + if (codePoint >= 0x61 && codePoint < 0x7B) { + return codePoint - 0x61; + } + return base; +}; + +/** + * Converts a digit/integer into a basic code point. + * @see `basicToDigit()` + * @private + * @param {Number} digit The numeric value of a basic code point. + * @returns {Number} The basic code point whose value (when used for + * representing integers) is `digit`, which needs to be in the range + * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is + * used; else, the lowercase form is used. The behavior is undefined + * if `flag` is non-zero and `digit` has no uppercase form. + */ +const digitToBasic = function(digit, flag) { + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); +}; + +/** + * Bias adaptation function as per section 3.4 of RFC 3492. + * https://tools.ietf.org/html/rfc3492#section-3.4 + * @private + */ +const adapt = function(delta, numPoints, firstTime) { + let k = 0; + delta = firstTime ? floor(delta / damp) : delta >> 1; + delta += floor(delta / numPoints); + for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = floor(delta / baseMinusTMin); + } + return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); +}; + +/** + * Converts a Punycode string of ASCII-only symbols to a string of Unicode + * symbols. + * @memberOf punycode + * @param {String} input The Punycode string of ASCII-only symbols. + * @returns {String} The resulting string of Unicode symbols. + */ +const decode = function(input) { + // Don't use UCS-2. + const output = []; + const inputLength = input.length; + let i = 0; + let n = initialN; + let bias = initialBias; + + // Handle the basic code points: let `basic` be the number of input code + // points before the last delimiter, or `0` if there is none, then copy + // the first basic code points to the output. + + let basic = input.lastIndexOf(delimiter); + if (basic < 0) { + basic = 0; + } + + for (let j = 0; j < basic; ++j) { + // if it's not a basic code point + if (input.charCodeAt(j) >= 0x80) { + error('not-basic'); + } + output.push(input.charCodeAt(j)); + } + + // Main decoding loop: start just after the last delimiter if any basic code + // points were copied; start at the beginning otherwise. + + for (let index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + + // `index` is the index of the next character to be consumed. + // Decode a generalized variable-length integer into `delta`, + // which gets added to `i`. The overflow checking is easier + // if we increase `i` as we go, then subtract off its starting + // value at the end to obtain `delta`. + const oldi = i; + for (let w = 1, k = base; /* no condition */; k += base) { + + if (index >= inputLength) { + error('invalid-input'); + } + + const digit = basicToDigit(input.charCodeAt(index++)); + + if (digit >= base) { + error('invalid-input'); + } + if (digit > floor((maxInt - i) / w)) { + error('overflow'); + } + + i += digit * w; + const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + + if (digit < t) { + break; + } + + const baseMinusT = base - t; + if (w > floor(maxInt / baseMinusT)) { + error('overflow'); + } + + w *= baseMinusT; + + } + + const out = output.length + 1; + bias = adapt(i - oldi, out, oldi == 0); + + // `i` was supposed to wrap around from `out` to `0`, + // incrementing `n` each time, so we'll fix that now: + if (floor(i / out) > maxInt - n) { + error('overflow'); + } + + n += floor(i / out); + i %= out; + + // Insert `n` at position `i` of the output. + output.splice(i++, 0, n); + + } + + return String.fromCodePoint(...output); +}; + +/** + * Converts a string of Unicode symbols (e.g. a domain name label) to a + * Punycode string of ASCII-only symbols. + * @memberOf punycode + * @param {String} input The string of Unicode symbols. + * @returns {String} The resulting Punycode string of ASCII-only symbols. + */ +const encode = function(input) { + const output = []; + + // Convert the input in UCS-2 to an array of Unicode code points. + input = ucs2decode(input); + + // Cache the length. + const inputLength = input.length; + + // Initialize the state. + let n = initialN; + let delta = 0; + let bias = initialBias; + + // Handle the basic code points. + for (const currentValue of input) { + if (currentValue < 0x80) { + output.push(stringFromCharCode(currentValue)); + } + } + + const basicLength = output.length; + let handledCPCount = basicLength; + + // `handledCPCount` is the number of code points that have been handled; + // `basicLength` is the number of basic code points. + + // Finish the basic string with a delimiter unless it's empty. + if (basicLength) { + output.push(delimiter); + } + + // Main encoding loop: + while (handledCPCount < inputLength) { + + // All non-basic code points < n have been handled already. Find the next + // larger one: + let m = maxInt; + for (const currentValue of input) { + if (currentValue >= n && currentValue < m) { + m = currentValue; + } + } + + // Increase `delta` enough to advance the decoder's state to , + // but guard against overflow. + const handledCPCountPlusOne = handledCPCount + 1; + if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { + error('overflow'); + } + + delta += (m - n) * handledCPCountPlusOne; + n = m; + + for (const currentValue of input) { + if (currentValue < n && ++delta > maxInt) { + error('overflow'); + } + if (currentValue === n) { + // Represent delta as a generalized variable-length integer. + let q = delta; + for (let k = base; /* no condition */; k += base) { + const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + if (q < t) { + break; + } + const qMinusT = q - t; + const baseMinusT = base - t; + output.push( + stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ); + q = floor(qMinusT / baseMinusT); + } + + output.push(stringFromCharCode(digitToBasic(q, 0))); + bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength); + delta = 0; + ++handledCPCount; + } + } + + ++delta; + ++n; + + } + return output.join(''); +}; + +/** + * Converts a Punycode string representing a domain name or an email address + * to Unicode. Only the Punycoded parts of the input will be converted, i.e. + * it doesn't matter if you call it on a string that has already been + * converted to Unicode. + * @memberOf punycode + * @param {String} input The Punycoded domain name or email address to + * convert to Unicode. + * @returns {String} The Unicode representation of the given Punycode + * string. + */ +const toUnicode = function(input) { + return mapDomain(input, function(string) { + return regexPunycode.test(string) + ? decode(string.slice(4).toLowerCase()) + : string; + }); +}; + +/** + * Converts a Unicode string representing a domain name or an email address to + * Punycode. Only the non-ASCII parts of the domain name will be converted, + * i.e. it doesn't matter if you call it with a domain that's already in + * ASCII. + * @memberOf punycode + * @param {String} input The domain name or email address to convert, as a + * Unicode string. + * @returns {String} The Punycode representation of the given domain name or + * email address. + */ +const toASCII = function(input) { + return mapDomain(input, function(string) { + return regexNonASCII.test(string) + ? 'xn--' + encode(string) + : string; + }); +}; + +/*--------------------------------------------------------------------------*/ + +/** Define the public API */ +const punycode = { + /** + * A string representing the current Punycode.js version number. + * @memberOf punycode + * @type String + */ + 'version': '2.1.0', + /** + * An object of methods to convert from JavaScript's internal character + * representation (UCS-2) to Unicode code points, and back. + * @see + * @memberOf punycode + * @type Object + */ + 'ucs2': { + 'decode': ucs2decode, + 'encode': ucs2encode + }, + 'decode': decode, + 'encode': encode, + 'toASCII': toASCII, + 'toUnicode': toUnicode +}; + +export { ucs2decode, ucs2encode, decode, encode, toASCII, toUnicode }; +export default punycode; diff --git a/libs/events/node_modules/punycode/punycode.js b/libs/events/node_modules/punycode/punycode.js new file mode 100644 index 000000000..752b98a9f --- /dev/null +++ b/libs/events/node_modules/punycode/punycode.js @@ -0,0 +1,443 @@ +'use strict'; + +/** Highest positive signed 32-bit float value */ +const maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1 + +/** Bootstring parameters */ +const base = 36; +const tMin = 1; +const tMax = 26; +const skew = 38; +const damp = 700; +const initialBias = 72; +const initialN = 128; // 0x80 +const delimiter = '-'; // '\x2D' + +/** Regular expressions */ +const regexPunycode = /^xn--/; +const regexNonASCII = /[^\0-\x7F]/; // Note: U+007F DEL is excluded too. +const regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; // RFC 3490 separators + +/** Error messages */ +const errors = { + 'overflow': 'Overflow: input needs wider integers to process', + 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', + 'invalid-input': 'Invalid input' +}; + +/** Convenience shortcuts */ +const baseMinusTMin = base - tMin; +const floor = Math.floor; +const stringFromCharCode = String.fromCharCode; + +/*--------------------------------------------------------------------------*/ + +/** + * A generic error utility function. + * @private + * @param {String} type The error type. + * @returns {Error} Throws a `RangeError` with the applicable error message. + */ +function error(type) { + throw new RangeError(errors[type]); +} + +/** + * A generic `Array#map` utility function. + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function that gets called for every array + * item. + * @returns {Array} A new array of values returned by the callback function. + */ +function map(array, callback) { + const result = []; + let length = array.length; + while (length--) { + result[length] = callback(array[length]); + } + return result; +} + +/** + * A simple `Array#map`-like wrapper to work with domain name strings or email + * addresses. + * @private + * @param {String} domain The domain name or email address. + * @param {Function} callback The function that gets called for every + * character. + * @returns {String} A new string of characters returned by the callback + * function. + */ +function mapDomain(domain, callback) { + const parts = domain.split('@'); + let result = ''; + if (parts.length > 1) { + // In email addresses, only the domain name should be punycoded. Leave + // the local part (i.e. everything up to `@`) intact. + result = parts[0] + '@'; + domain = parts[1]; + } + // Avoid `split(regex)` for IE8 compatibility. See #17. + domain = domain.replace(regexSeparators, '\x2E'); + const labels = domain.split('.'); + const encoded = map(labels, callback).join('.'); + return result + encoded; +} + +/** + * Creates an array containing the numeric code points of each Unicode + * character in the string. While JavaScript uses UCS-2 internally, + * this function will convert a pair of surrogate halves (each of which + * UCS-2 exposes as separate characters) into a single code point, + * matching UTF-16. + * @see `punycode.ucs2.encode` + * @see + * @memberOf punycode.ucs2 + * @name decode + * @param {String} string The Unicode input string (UCS-2). + * @returns {Array} The new array of code points. + */ +function ucs2decode(string) { + const output = []; + let counter = 0; + const length = string.length; + while (counter < length) { + const value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // It's a high surrogate, and there is a next character. + const extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // Low surrogate. + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // It's an unmatched surrogate; only append this code unit, in case the + // next code unit is the high surrogate of a surrogate pair. + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; +} + +/** + * Creates a string based on an array of numeric code points. + * @see `punycode.ucs2.decode` + * @memberOf punycode.ucs2 + * @name encode + * @param {Array} codePoints The array of numeric code points. + * @returns {String} The new Unicode string (UCS-2). + */ +const ucs2encode = codePoints => String.fromCodePoint(...codePoints); + +/** + * Converts a basic code point into a digit/integer. + * @see `digitToBasic()` + * @private + * @param {Number} codePoint The basic numeric code point value. + * @returns {Number} The numeric value of a basic code point (for use in + * representing integers) in the range `0` to `base - 1`, or `base` if + * the code point does not represent a value. + */ +const basicToDigit = function(codePoint) { + if (codePoint >= 0x30 && codePoint < 0x3A) { + return 26 + (codePoint - 0x30); + } + if (codePoint >= 0x41 && codePoint < 0x5B) { + return codePoint - 0x41; + } + if (codePoint >= 0x61 && codePoint < 0x7B) { + return codePoint - 0x61; + } + return base; +}; + +/** + * Converts a digit/integer into a basic code point. + * @see `basicToDigit()` + * @private + * @param {Number} digit The numeric value of a basic code point. + * @returns {Number} The basic code point whose value (when used for + * representing integers) is `digit`, which needs to be in the range + * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is + * used; else, the lowercase form is used. The behavior is undefined + * if `flag` is non-zero and `digit` has no uppercase form. + */ +const digitToBasic = function(digit, flag) { + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); +}; + +/** + * Bias adaptation function as per section 3.4 of RFC 3492. + * https://tools.ietf.org/html/rfc3492#section-3.4 + * @private + */ +const adapt = function(delta, numPoints, firstTime) { + let k = 0; + delta = firstTime ? floor(delta / damp) : delta >> 1; + delta += floor(delta / numPoints); + for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = floor(delta / baseMinusTMin); + } + return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); +}; + +/** + * Converts a Punycode string of ASCII-only symbols to a string of Unicode + * symbols. + * @memberOf punycode + * @param {String} input The Punycode string of ASCII-only symbols. + * @returns {String} The resulting string of Unicode symbols. + */ +const decode = function(input) { + // Don't use UCS-2. + const output = []; + const inputLength = input.length; + let i = 0; + let n = initialN; + let bias = initialBias; + + // Handle the basic code points: let `basic` be the number of input code + // points before the last delimiter, or `0` if there is none, then copy + // the first basic code points to the output. + + let basic = input.lastIndexOf(delimiter); + if (basic < 0) { + basic = 0; + } + + for (let j = 0; j < basic; ++j) { + // if it's not a basic code point + if (input.charCodeAt(j) >= 0x80) { + error('not-basic'); + } + output.push(input.charCodeAt(j)); + } + + // Main decoding loop: start just after the last delimiter if any basic code + // points were copied; start at the beginning otherwise. + + for (let index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + + // `index` is the index of the next character to be consumed. + // Decode a generalized variable-length integer into `delta`, + // which gets added to `i`. The overflow checking is easier + // if we increase `i` as we go, then subtract off its starting + // value at the end to obtain `delta`. + const oldi = i; + for (let w = 1, k = base; /* no condition */; k += base) { + + if (index >= inputLength) { + error('invalid-input'); + } + + const digit = basicToDigit(input.charCodeAt(index++)); + + if (digit >= base) { + error('invalid-input'); + } + if (digit > floor((maxInt - i) / w)) { + error('overflow'); + } + + i += digit * w; + const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + + if (digit < t) { + break; + } + + const baseMinusT = base - t; + if (w > floor(maxInt / baseMinusT)) { + error('overflow'); + } + + w *= baseMinusT; + + } + + const out = output.length + 1; + bias = adapt(i - oldi, out, oldi == 0); + + // `i` was supposed to wrap around from `out` to `0`, + // incrementing `n` each time, so we'll fix that now: + if (floor(i / out) > maxInt - n) { + error('overflow'); + } + + n += floor(i / out); + i %= out; + + // Insert `n` at position `i` of the output. + output.splice(i++, 0, n); + + } + + return String.fromCodePoint(...output); +}; + +/** + * Converts a string of Unicode symbols (e.g. a domain name label) to a + * Punycode string of ASCII-only symbols. + * @memberOf punycode + * @param {String} input The string of Unicode symbols. + * @returns {String} The resulting Punycode string of ASCII-only symbols. + */ +const encode = function(input) { + const output = []; + + // Convert the input in UCS-2 to an array of Unicode code points. + input = ucs2decode(input); + + // Cache the length. + const inputLength = input.length; + + // Initialize the state. + let n = initialN; + let delta = 0; + let bias = initialBias; + + // Handle the basic code points. + for (const currentValue of input) { + if (currentValue < 0x80) { + output.push(stringFromCharCode(currentValue)); + } + } + + const basicLength = output.length; + let handledCPCount = basicLength; + + // `handledCPCount` is the number of code points that have been handled; + // `basicLength` is the number of basic code points. + + // Finish the basic string with a delimiter unless it's empty. + if (basicLength) { + output.push(delimiter); + } + + // Main encoding loop: + while (handledCPCount < inputLength) { + + // All non-basic code points < n have been handled already. Find the next + // larger one: + let m = maxInt; + for (const currentValue of input) { + if (currentValue >= n && currentValue < m) { + m = currentValue; + } + } + + // Increase `delta` enough to advance the decoder's state to , + // but guard against overflow. + const handledCPCountPlusOne = handledCPCount + 1; + if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { + error('overflow'); + } + + delta += (m - n) * handledCPCountPlusOne; + n = m; + + for (const currentValue of input) { + if (currentValue < n && ++delta > maxInt) { + error('overflow'); + } + if (currentValue === n) { + // Represent delta as a generalized variable-length integer. + let q = delta; + for (let k = base; /* no condition */; k += base) { + const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + if (q < t) { + break; + } + const qMinusT = q - t; + const baseMinusT = base - t; + output.push( + stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ); + q = floor(qMinusT / baseMinusT); + } + + output.push(stringFromCharCode(digitToBasic(q, 0))); + bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength); + delta = 0; + ++handledCPCount; + } + } + + ++delta; + ++n; + + } + return output.join(''); +}; + +/** + * Converts a Punycode string representing a domain name or an email address + * to Unicode. Only the Punycoded parts of the input will be converted, i.e. + * it doesn't matter if you call it on a string that has already been + * converted to Unicode. + * @memberOf punycode + * @param {String} input The Punycoded domain name or email address to + * convert to Unicode. + * @returns {String} The Unicode representation of the given Punycode + * string. + */ +const toUnicode = function(input) { + return mapDomain(input, function(string) { + return regexPunycode.test(string) + ? decode(string.slice(4).toLowerCase()) + : string; + }); +}; + +/** + * Converts a Unicode string representing a domain name or an email address to + * Punycode. Only the non-ASCII parts of the domain name will be converted, + * i.e. it doesn't matter if you call it with a domain that's already in + * ASCII. + * @memberOf punycode + * @param {String} input The domain name or email address to convert, as a + * Unicode string. + * @returns {String} The Punycode representation of the given domain name or + * email address. + */ +const toASCII = function(input) { + return mapDomain(input, function(string) { + return regexNonASCII.test(string) + ? 'xn--' + encode(string) + : string; + }); +}; + +/*--------------------------------------------------------------------------*/ + +/** Define the public API */ +const punycode = { + /** + * A string representing the current Punycode.js version number. + * @memberOf punycode + * @type String + */ + 'version': '2.1.0', + /** + * An object of methods to convert from JavaScript's internal character + * representation (UCS-2) to Unicode code points, and back. + * @see + * @memberOf punycode + * @type Object + */ + 'ucs2': { + 'decode': ucs2decode, + 'encode': ucs2encode + }, + 'decode': decode, + 'encode': encode, + 'toASCII': toASCII, + 'toUnicode': toUnicode +}; + +module.exports = punycode; diff --git a/libs/events/node_modules/queue-microtask/LICENSE b/libs/events/node_modules/queue-microtask/LICENSE new file mode 100755 index 000000000..c7e685275 --- /dev/null +++ b/libs/events/node_modules/queue-microtask/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libs/events/node_modules/queue-microtask/README.md b/libs/events/node_modules/queue-microtask/README.md new file mode 100644 index 000000000..0be05a64f --- /dev/null +++ b/libs/events/node_modules/queue-microtask/README.md @@ -0,0 +1,90 @@ +# queue-microtask [![ci][ci-image]][ci-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] + +[ci-image]: https://img.shields.io/github/workflow/status/feross/queue-microtask/ci/master +[ci-url]: https://github.com/feross/queue-microtask/actions +[npm-image]: https://img.shields.io/npm/v/queue-microtask.svg +[npm-url]: https://npmjs.org/package/queue-microtask +[downloads-image]: https://img.shields.io/npm/dm/queue-microtask.svg +[downloads-url]: https://npmjs.org/package/queue-microtask +[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg +[standard-url]: https://standardjs.com + +### fast, tiny [`queueMicrotask`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask) shim for modern engines + +- Use [`queueMicrotask`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask) in all modern JS engines. +- No dependencies. Less than 10 lines. No shims or complicated fallbacks. +- Optimal performance in all modern environments + - Uses `queueMicrotask` in modern environments + - Fallback to `Promise.resolve().then(fn)` in Node.js 10 and earlier, and old browsers (same performance as `queueMicrotask`) + +## install + +``` +npm install queue-microtask +``` + +## usage + +```js +const queueMicrotask = require('queue-microtask') + +queueMicrotask(() => { /* this will run soon */ }) +``` + +## What is `queueMicrotask` and why would one use it? + +The `queueMicrotask` function is a WHATWG standard. It queues a microtask to be executed prior to control returning to the event loop. + +A microtask is a short function which will run after the current task has completed its work and when there is no other code waiting to be run before control of the execution context is returned to the event loop. + +The code `queueMicrotask(fn)` is equivalent to the code `Promise.resolve().then(fn)`. It is also very similar to [`process.nextTick(fn)`](https://nodejs.org/api/process.html#process_process_nexttick_callback_args) in Node. + +Using microtasks lets code run without interfering with any other, potentially higher priority, code that is pending, but before the JS engine regains control over the execution context. + +See the [spec](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#microtask-queuing) or [Node documentation](https://nodejs.org/api/globals.html#globals_queuemicrotask_callback) for more information. + +## Who is this package for? + +This package allows you to use `queueMicrotask` safely in all modern JS engines. Use it if you prioritize small JS bundle size over support for old browsers. + +If you just need to support Node 12 and later, use `queueMicrotask` directly. If you need to support all versions of Node, use this package. + +## Why not use `process.nextTick`? + +In Node, `queueMicrotask` and `process.nextTick` are [essentially equivalent](https://nodejs.org/api/globals.html#globals_queuemicrotask_callback), though there are [subtle differences](https://github.com/YuzuJS/setImmediate#macrotasks-and-microtasks) that don't matter in most situations. + +You can think of `queueMicrotask` as a standardized version of `process.nextTick` that works in the browser. No need to rely on your browser bundler to shim `process` for the browser environment. + +## Why not use `setTimeout(fn, 0)`? + +This approach is the most compatible, but it has problems. Modern browsers throttle timers severely, so `setTimeout(…, 0)` usually takes at least 4ms to run. Furthermore, the throttling gets even worse if the page is backgrounded. If you have many `setTimeout` calls, then this can severely limit the performance of your program. + +## Why not use a microtask library like [`immediate`](https://www.npmjs.com/package/immediate) or [`asap`](https://www.npmjs.com/package/asap)? + +These packages are great! However, if you prioritize small JS bundle size over optimal performance in old browsers then you may want to consider this package. + +This package (`queue-microtask`) is four times smaller than `immediate`, twice as small as `asap`, and twice as small as using `process.nextTick` and letting the browser bundler shim it automatically. + +Note: This package throws an exception in JS environments which lack `Promise` support -- which are usually very old browsers and Node.js versions. + +Since the `queueMicrotask` API is supported in Node.js, Chrome, Firefox, Safari, Opera, and Edge, **the vast majority of users will get optimal performance**. Any JS environment with `Promise`, which is almost all of them, also get optimal performance. If you need support for JS environments which lack `Promise` support, use one of the alternative packages. + +## What is a shim? + +> In computer programming, a shim is a library that transparently intercepts API calls and changes the arguments passed, handles the operation itself or redirects the operation elsewhere. – [Wikipedia](https://en.wikipedia.org/wiki/Shim_(computing)) + +This package could also be described as a "ponyfill". + +> A ponyfill is almost the same as a polyfill, but not quite. Instead of patching functionality for older browsers, a ponyfill provides that functionality as a standalone module you can use. – [PonyFoo](https://ponyfoo.com/articles/polyfills-or-ponyfills) + +## API + +### `queueMicrotask(fn)` + +The `queueMicrotask()` method queues a microtask. + +The `fn` argument is a function to be executed after all pending tasks have completed but before yielding control to the browser's event loop. + +## license + +MIT. Copyright (c) [Feross Aboukhadijeh](https://feross.org). diff --git a/libs/events/node_modules/queue-microtask/index.d.ts b/libs/events/node_modules/queue-microtask/index.d.ts new file mode 100644 index 000000000..b6a864632 --- /dev/null +++ b/libs/events/node_modules/queue-microtask/index.d.ts @@ -0,0 +1,2 @@ +declare const queueMicrotask: (cb: () => void) => void +export = queueMicrotask diff --git a/libs/events/node_modules/queue-microtask/index.js b/libs/events/node_modules/queue-microtask/index.js new file mode 100644 index 000000000..55605343a --- /dev/null +++ b/libs/events/node_modules/queue-microtask/index.js @@ -0,0 +1,9 @@ +/*! queue-microtask. MIT License. Feross Aboukhadijeh */ +let promise + +module.exports = typeof queueMicrotask === 'function' + ? queueMicrotask.bind(typeof window !== 'undefined' ? window : global) + // reuse resolved promise, and allocate it lazily + : cb => (promise || (promise = Promise.resolve())) + .then(cb) + .catch(err => setTimeout(() => { throw err }, 0)) diff --git a/libs/events/node_modules/queue-microtask/package.json b/libs/events/node_modules/queue-microtask/package.json new file mode 100644 index 000000000..d29a401f5 --- /dev/null +++ b/libs/events/node_modules/queue-microtask/package.json @@ -0,0 +1,55 @@ +{ + "name": "queue-microtask", + "description": "fast, tiny `queueMicrotask` shim for modern engines", + "version": "1.2.3", + "author": { + "name": "Feross Aboukhadijeh", + "email": "feross@feross.org", + "url": "https://feross.org" + }, + "bugs": { + "url": "https://github.com/feross/queue-microtask/issues" + }, + "devDependencies": { + "standard": "*", + "tape": "^5.2.2" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "homepage": "https://github.com/feross/queue-microtask", + "keywords": [ + "asap", + "immediate", + "micro task", + "microtask", + "nextTick", + "process.nextTick", + "queue micro task", + "queue microtask", + "queue-microtask", + "queueMicrotask", + "setImmediate", + "task" + ], + "license": "MIT", + "main": "index.js", + "repository": { + "type": "git", + "url": "git://github.com/feross/queue-microtask.git" + }, + "scripts": { + "test": "standard && tape test/*.js" + } +} diff --git a/libs/events/node_modules/require-from-string/index.js b/libs/events/node_modules/require-from-string/index.js new file mode 100644 index 000000000..cb5595fde --- /dev/null +++ b/libs/events/node_modules/require-from-string/index.js @@ -0,0 +1,34 @@ +'use strict'; + +var Module = require('module'); +var path = require('path'); + +module.exports = function requireFromString(code, filename, opts) { + if (typeof filename === 'object') { + opts = filename; + filename = undefined; + } + + opts = opts || {}; + filename = filename || ''; + + opts.appendPaths = opts.appendPaths || []; + opts.prependPaths = opts.prependPaths || []; + + if (typeof code !== 'string') { + throw new Error('code must be a string, not ' + typeof code); + } + + var paths = Module._nodeModulePaths(path.dirname(filename)); + + var parent = module.parent; + var m = new Module(filename, parent); + m.filename = filename; + m.paths = [].concat(opts.prependPaths).concat(paths).concat(opts.appendPaths); + m._compile(code, filename); + + var exports = m.exports; + parent && parent.children && parent.children.splice(parent.children.indexOf(m), 1); + + return exports; +}; diff --git a/libs/events/node_modules/require-from-string/license b/libs/events/node_modules/require-from-string/license new file mode 100644 index 000000000..1aeb74fd2 --- /dev/null +++ b/libs/events/node_modules/require-from-string/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Vsevolod Strukchinsky (github.com/floatdrop) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/require-from-string/package.json b/libs/events/node_modules/require-from-string/package.json new file mode 100644 index 000000000..800d46efc --- /dev/null +++ b/libs/events/node_modules/require-from-string/package.json @@ -0,0 +1,28 @@ +{ + "name": "require-from-string", + "version": "2.0.2", + "description": "Require module from string", + "license": "MIT", + "repository": "floatdrop/require-from-string", + "author": { + "name": "Vsevolod Strukchinsky", + "email": "floatdrop@gmail.com", + "url": "github.com/floatdrop" + }, + "engines": { + "node": ">=0.10.0" + }, + "scripts": { + "test": "mocha" + }, + "files": [ + "index.js" + ], + "keywords": [ + "" + ], + "dependencies": {}, + "devDependencies": { + "mocha": "*" + } +} diff --git a/libs/events/node_modules/require-from-string/readme.md b/libs/events/node_modules/require-from-string/readme.md new file mode 100644 index 000000000..88b3236f8 --- /dev/null +++ b/libs/events/node_modules/require-from-string/readme.md @@ -0,0 +1,56 @@ +# require-from-string [![Build Status](https://travis-ci.org/floatdrop/require-from-string.svg?branch=master)](https://travis-ci.org/floatdrop/require-from-string) + +Load module from string in Node. + +## Install + +``` +$ npm install --save require-from-string +``` + + +## Usage + +```js +var requireFromString = require('require-from-string'); + +requireFromString('module.exports = 1'); +//=> 1 +``` + + +## API + +### requireFromString(code, [filename], [options]) + +#### code + +*Required* +Type: `string` + +Module code. + +#### filename +Type: `string` +Default: `''` + +Optional filename. + + +#### options +Type: `object` + +##### appendPaths +Type: `Array` + +List of `paths`, that will be appended to module `paths`. Useful, when you want +to be able require modules from these paths. + +##### prependPaths +Type: `Array` + +Same as `appendPaths`, but paths will be prepended. + +## License + +MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop) diff --git a/libs/events/node_modules/reusify/.coveralls.yml b/libs/events/node_modules/reusify/.coveralls.yml new file mode 100644 index 000000000..359f68349 --- /dev/null +++ b/libs/events/node_modules/reusify/.coveralls.yml @@ -0,0 +1 @@ +repo_token: yIxhFqtaaz5iGVYfie9mODehFYogm8S8L diff --git a/libs/events/node_modules/reusify/.travis.yml b/libs/events/node_modules/reusify/.travis.yml new file mode 100644 index 000000000..197047681 --- /dev/null +++ b/libs/events/node_modules/reusify/.travis.yml @@ -0,0 +1,28 @@ +language: node_js +sudo: false + +node_js: + - 9 + - 8 + - 7 + - 6 + - 5 + - 4 + - 4.0 + - iojs-v3 + - iojs-v2 + - iojs-v1 + - 0.12 + - 0.10 + +cache: + directories: + - node_modules + +after_script: +- npm run coverage + +notifications: + email: + on_success: never + on_failure: always diff --git a/libs/events/node_modules/reusify/LICENSE b/libs/events/node_modules/reusify/LICENSE new file mode 100644 index 000000000..fbf3a01d8 --- /dev/null +++ b/libs/events/node_modules/reusify/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Matteo Collina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/libs/events/node_modules/reusify/README.md b/libs/events/node_modules/reusify/README.md new file mode 100644 index 000000000..badcb7ccf --- /dev/null +++ b/libs/events/node_modules/reusify/README.md @@ -0,0 +1,145 @@ +# reusify + +[![npm version][npm-badge]][npm-url] +[![Build Status][travis-badge]][travis-url] +[![Coverage Status][coveralls-badge]][coveralls-url] + +Reuse your objects and functions for maximum speed. This technique will +make any function run ~10% faster. You call your functions a +lot, and it adds up quickly in hot code paths. + +``` +$ node benchmarks/createNoCodeFunction.js +Total time 53133 +Total iterations 100000000 +Iteration/s 1882069.5236482036 + +$ node benchmarks/reuseNoCodeFunction.js +Total time 50617 +Total iterations 100000000 +Iteration/s 1975620.838848608 +``` + +The above benchmark uses fibonacci to simulate a real high-cpu load. +The actual numbers might differ for your use case, but the difference +should not. + +The benchmark was taken using Node v6.10.0. + +This library was extracted from +[fastparallel](http://npm.im/fastparallel). + +## Example + +```js +var reusify = require('reusify') +var fib = require('reusify/benchmarks/fib') +var instance = reusify(MyObject) + +// get an object from the cache, +// or creates a new one when cache is empty +var obj = instance.get() + +// set the state +obj.num = 100 +obj.func() + +// reset the state. +// if the state contains any external object +// do not use delete operator (it is slow) +// prefer set them to null +obj.num = 0 + +// store an object in the cache +instance.release(obj) + +function MyObject () { + // you need to define this property + // so V8 can compile MyObject into an + // hidden class + this.next = null + this.num = 0 + + var that = this + + // this function is never reallocated, + // so it can be optimized by V8 + this.func = function () { + if (null) { + // do nothing + } else { + // calculates fibonacci + fib(that.num) + } + } +} +``` + +The above example was intended for synchronous code, let's see async: +```js +var reusify = require('reusify') +var instance = reusify(MyObject) + +for (var i = 0; i < 100; i++) { + getData(i, console.log) +} + +function getData (value, cb) { + var obj = instance.get() + + obj.value = value + obj.cb = cb + obj.run() +} + +function MyObject () { + this.next = null + this.value = null + + var that = this + + this.run = function () { + asyncOperation(that.value, that.handle) + } + + this.handle = function (err, result) { + that.cb(err, result) + that.value = null + that.cb = null + instance.release(that) + } +} +``` + +Also note how in the above examples, the code, that consumes an istance of `MyObject`, +reset the state to initial condition, just before storing it in the cache. +That's needed so that every subsequent request for an instance from the cache, +could get a clean instance. + +## Why + +It is faster because V8 doesn't have to collect all the functions you +create. On a short-lived benchmark, it is as fast as creating the +nested function, but on a longer time frame it creates less +pressure on the garbage collector. + +## Other examples +If you want to see some complex example, checkout [middie](https://github.com/fastify/middie) and [steed](https://github.com/mcollina/steed). + +## Acknowledgements + +Thanks to [Trevor Norris](https://github.com/trevnorris) for +getting me down the rabbit hole of performance, and thanks to [Mathias +Buss](http://github.com/mafintosh) for suggesting me to share this +trick. + +## License + +MIT + +[npm-badge]: https://badge.fury.io/js/reusify.svg +[npm-url]: https://badge.fury.io/js/reusify +[travis-badge]: https://api.travis-ci.org/mcollina/reusify.svg +[travis-url]: https://travis-ci.org/mcollina/reusify +[coveralls-badge]: https://coveralls.io/repos/mcollina/reusify/badge.svg?branch=master&service=github +[coveralls-url]: https://coveralls.io/github/mcollina/reusify?branch=master diff --git a/libs/events/node_modules/reusify/benchmarks/createNoCodeFunction.js b/libs/events/node_modules/reusify/benchmarks/createNoCodeFunction.js new file mode 100644 index 000000000..ce1aac7b7 --- /dev/null +++ b/libs/events/node_modules/reusify/benchmarks/createNoCodeFunction.js @@ -0,0 +1,30 @@ +'use strict' + +var fib = require('./fib') +var max = 100000000 +var start = Date.now() + +// create a funcion with the typical error +// pattern, that delegates the heavy load +// to something else +function createNoCodeFunction () { + /* eslint no-constant-condition: "off" */ + var num = 100 + + ;(function () { + if (null) { + // do nothing + } else { + fib(num) + } + })() +} + +for (var i = 0; i < max; i++) { + createNoCodeFunction() +} + +var time = Date.now() - start +console.log('Total time', time) +console.log('Total iterations', max) +console.log('Iteration/s', max / time * 1000) diff --git a/libs/events/node_modules/reusify/benchmarks/fib.js b/libs/events/node_modules/reusify/benchmarks/fib.js new file mode 100644 index 000000000..e22cc48de --- /dev/null +++ b/libs/events/node_modules/reusify/benchmarks/fib.js @@ -0,0 +1,13 @@ +'use strict' + +function fib (num) { + var fib = [] + + fib[0] = 0 + fib[1] = 1 + for (var i = 2; i <= num; i++) { + fib[i] = fib[i - 2] + fib[i - 1] + } +} + +module.exports = fib diff --git a/libs/events/node_modules/reusify/benchmarks/reuseNoCodeFunction.js b/libs/events/node_modules/reusify/benchmarks/reuseNoCodeFunction.js new file mode 100644 index 000000000..3358d6e50 --- /dev/null +++ b/libs/events/node_modules/reusify/benchmarks/reuseNoCodeFunction.js @@ -0,0 +1,38 @@ +'use strict' + +var reusify = require('../') +var fib = require('./fib') +var instance = reusify(MyObject) +var max = 100000000 +var start = Date.now() + +function reuseNoCodeFunction () { + var obj = instance.get() + obj.num = 100 + obj.func() + obj.num = 0 + instance.release(obj) +} + +function MyObject () { + this.next = null + var that = this + this.num = 0 + this.func = function () { + /* eslint no-constant-condition: "off" */ + if (null) { + // do nothing + } else { + fib(that.num) + } + } +} + +for (var i = 0; i < max; i++) { + reuseNoCodeFunction() +} + +var time = Date.now() - start +console.log('Total time', time) +console.log('Total iterations', max) +console.log('Iteration/s', max / time * 1000) diff --git a/libs/events/node_modules/reusify/package.json b/libs/events/node_modules/reusify/package.json new file mode 100644 index 000000000..ee66aeecb --- /dev/null +++ b/libs/events/node_modules/reusify/package.json @@ -0,0 +1,45 @@ +{ + "name": "reusify", + "version": "1.0.4", + "description": "Reuse objects and functions with style", + "main": "reusify.js", + "scripts": { + "lint": "standard", + "test": "tape test.js | faucet", + "istanbul": "istanbul cover tape test.js", + "coverage": "npm run istanbul; cat coverage/lcov.info | coveralls" + }, + "pre-commit": [ + "lint", + "test" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/mcollina/reusify.git" + }, + "keywords": [ + "reuse", + "object", + "performance", + "function", + "fast" + ], + "author": "Matteo Collina ", + "license": "MIT", + "bugs": { + "url": "https://github.com/mcollina/reusify/issues" + }, + "homepage": "https://github.com/mcollina/reusify#readme", + "engines": { + "node": ">=0.10.0", + "iojs": ">=1.0.0" + }, + "devDependencies": { + "coveralls": "^2.13.3", + "faucet": "0.0.1", + "istanbul": "^0.4.5", + "pre-commit": "^1.2.2", + "standard": "^10.0.3", + "tape": "^4.8.0" + } +} diff --git a/libs/events/node_modules/reusify/reusify.js b/libs/events/node_modules/reusify/reusify.js new file mode 100644 index 000000000..e6f36f3a8 --- /dev/null +++ b/libs/events/node_modules/reusify/reusify.js @@ -0,0 +1,33 @@ +'use strict' + +function reusify (Constructor) { + var head = new Constructor() + var tail = head + + function get () { + var current = head + + if (current.next) { + head = current.next + } else { + head = new Constructor() + tail = head + } + + current.next = null + + return current + } + + function release (obj) { + tail.next = obj + tail = obj + } + + return { + get: get, + release: release + } +} + +module.exports = reusify diff --git a/libs/events/node_modules/reusify/test.js b/libs/events/node_modules/reusify/test.js new file mode 100644 index 000000000..929cfd719 --- /dev/null +++ b/libs/events/node_modules/reusify/test.js @@ -0,0 +1,66 @@ +'use strict' + +var test = require('tape') +var reusify = require('./') + +test('reuse objects', function (t) { + t.plan(6) + + function MyObject () { + t.pass('constructor called') + this.next = null + } + + var instance = reusify(MyObject) + var obj = instance.get() + + t.notEqual(obj, instance.get(), 'two instance created') + t.notOk(obj.next, 'next must be null') + + instance.release(obj) + + // the internals keeps a hot copy ready for reuse + // putting this one back in the queue + instance.release(instance.get()) + + // comparing the old one with the one we got + // never do this in real code, after release you + // should never reuse that instance + t.equal(obj, instance.get(), 'instance must be reused') +}) + +test('reuse more than 2 objects', function (t) { + function MyObject () { + t.pass('constructor called') + this.next = null + } + + var instance = reusify(MyObject) + var obj = instance.get() + var obj2 = instance.get() + var obj3 = instance.get() + + t.notOk(obj.next, 'next must be null') + t.notOk(obj2.next, 'next must be null') + t.notOk(obj3.next, 'next must be null') + + t.notEqual(obj, obj2) + t.notEqual(obj, obj3) + t.notEqual(obj3, obj2) + + instance.release(obj) + instance.release(obj2) + instance.release(obj3) + + // skip one + instance.get() + + var obj4 = instance.get() + var obj5 = instance.get() + var obj6 = instance.get() + + t.equal(obj4, obj) + t.equal(obj5, obj2) + t.equal(obj6, obj3) + t.end() +}) diff --git a/libs/events/node_modules/rimraf/LICENSE b/libs/events/node_modules/rimraf/LICENSE new file mode 100644 index 000000000..1493534e6 --- /dev/null +++ b/libs/events/node_modules/rimraf/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2011-2023 Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/libs/events/node_modules/rimraf/README.md b/libs/events/node_modules/rimraf/README.md new file mode 100644 index 000000000..0f57b0533 --- /dev/null +++ b/libs/events/node_modules/rimraf/README.md @@ -0,0 +1,214 @@ +The [UNIX command]() `rm -rf` for node. + +Install with `npm install rimraf`. + +## Major Changes from v3 to v4 + +- The function returns a `Promise` instead of taking a callback. +- Globbing requires the `--glob` option to be set. (Removed in + 4.0 and 4.1, opt-in support added in 4.2.) +- Functions take arrays of paths, as well as a single path. +- Native implementation used by default when available, except on + Windows, where this implementation is faster and more reliable. +- New implementation on Windows, falling back to "move then + remove" strategy when exponential backoff for `EBUSY` fails to + resolve the situation. +- Simplified implementation on Posix, since the Windows + affordances are not necessary there. +- As of 4.3, return/resolve value is boolean instead of undefined + +## API + +Hybrid module, load either with `import` or `require()`. + +```js +// default export is the main rimraf function, or use named imports +import rimraf from 'rimraf' +// or +const rimraf = require('rimraf') + +// other strategies exported as well +import { rimraf, rimrafSync, native, nativeSync } from 'rimraf' +// or +const { rimraf, rimrafSync, native, nativeSync } = require('rimraf') +``` + +All removal functions return a boolean indicating that all +entries were successfully removed. + +The only case in which this will not return `true` is if +something was omitted from the removal via a `filter` option. + +### `rimraf(f, [opts]) -> Promise` + +This first parameter is a path or array of paths. The second +argument is an options object. + +Options: + +- `preserveRoot`: If set to boolean `false`, then allow the + recursive removal of the root directory. Otherwise, this is + not allowed. +- `tmp`: Windows only. Temp folder to use to place files and + folders for the "move then remove" fallback. Must be on the + same physical device as the path being deleted. Defaults to + `os.tmpdir()` when that is on the same drive letter as the path + being deleted, or `${drive}:\temp` if present, or `${drive}:\` + if not. +- `maxRetries`: Windows and Native only. Maximum number of + retry attempts in case of `EBUSY`, `EMFILE`, and `ENFILE` + errors. Default `10` for Windows implementation, `0` for Native + implementation. +- `backoff`: Windows only. Rate of exponential backoff for async + removal in case of `EBUSY`, `EMFILE`, and `ENFILE` errors. + Should be a number greater than 1. Default `1.2` +- `maxBackoff`: Windows only. Maximum total backoff time in ms to + attempt asynchronous retries in case of `EBUSY`, `EMFILE`, and + `ENFILE` errors. Default `200`. With the default `1.2` backoff + rate, this results in 14 retries, with the final retry being + delayed 33ms. +- `retryDelay`: Native only. Time to wait between retries, using + linear backoff. Default `100`. +- `signal` Pass in an AbortSignal to cancel the directory + removal. This is useful when removing large folder structures, + if you'd like to limit the amount of time spent. + + Using a `signal` option prevents the use of Node's built-in + `fs.rm` because that implementation does not support abort + signals. + +- `filter` Method that returns a boolean indicating whether that + path should be deleted. With async rimraf methods, this may + return a Promise that resolves to a boolean. (Since Promises + are truthy, returning a Promise from a sync filter is the same + as just not filtering anything.) + + The first argument to the filter is the path string. The + second argument is either a `Dirent` or `Stats` object for that + path. (The first path explored will be a `Stats`, the rest + will be `Dirent`.) + + If a filter method is provided, it will _only_ remove entries + if the filter returns (or resolves to) a truthy value. Omitting + a directory will still allow its children to be removed, unless + they are also filtered out, but any parents of a filtered entry + will not be removed, since the directory would not be empty in + that case. + + Using a filter method prevents the use of Node's built-in + `fs.rm` because that implementation does not support filtering. + +Any other options are provided to the native Node.js `fs.rm` implementation +when that is used. + +This will attempt to choose the best implementation, based on Node.js +version and `process.platform`. To force a specific implementation, use +one of the other functions provided. + +### `rimraf.sync(f, [opts])` `rimraf.rimrafSync(f, [opts])` + +Synchronous form of `rimraf()` + +Note that, unlike many file system operations, the synchronous form will +typically be significantly _slower_ than the async form, because recursive +deletion is extremely parallelizable. + +### `rimraf.native(f, [opts])` + +Uses the built-in `fs.rm` implementation that Node.js provides. This is +used by default on Node.js versions greater than or equal to `14.14.0`. + +### `rimraf.nativeSync(f, [opts])` `rimraf.native.sync(f, [opts])` + +Synchronous form of `rimraf.native` + +### `rimraf.manual(f, [opts])` + +Use the JavaScript implementation appropriate for your operating system. + +### `rimraf.manualSync(f, [opts])` `rimraf.manualSync(f, opts)` + +Synchronous form of `rimraf.manual()` + +### `rimraf.windows(f, [opts])` + +JavaScript implementation of file removal appropriate for Windows +platforms. Works around `unlink` and `rmdir` not being atomic +operations, and `EPERM` when deleting files with certain +permission modes. + +First deletes all non-directory files within the tree, and then +removes all directories, which should ideally be empty by that +time. When an `ENOTEMPTY` is raised in the second pass, falls +back to the `rimraf.moveRemove` strategy as needed. + +### `rimraf.windows.sync(path, [opts])` `rimraf.windowsSync(path, [opts])` + +Synchronous form of `rimraf.windows()` + +### `rimraf.moveRemove(path, [opts])` + +Moves all files and folders to the parent directory of `path` +with a temporary filename prior to attempting to remove them. + +Note that, in cases where the operation fails, this _may_ leave +files lying around in the parent directory with names like +`.file-basename.txt.0.123412341`. Until the Windows kernel +provides a way to perform atomic `unlink` and `rmdir` operations, +this is unfortunately unavoidable. + +To move files to a different temporary directory other than the +parent, provide `opts.tmp`. Note that this _must_ be on the same +physical device as the folder being deleted, or else the +operation will fail. + +This is the slowest strategy, but most reliable on Windows +platforms. Used as a last-ditch fallback by `rimraf.windows()`. + +### `rimraf.moveRemove.sync(path, [opts])` `rimraf.moveRemoveSync(path, [opts])` + +Synchronous form of `rimraf.moveRemove()` + +### Command Line Interface + +``` +rimraf version 4.3.0 + +Usage: rimraf [ ...] +Deletes all files and folders at "path", recursively. + +Options: + -- Treat all subsequent arguments as paths + -h --help Display this usage info + --preserve-root Do not remove '/' recursively (default) + --no-preserve-root Do not treat '/' specially + -G --no-glob Treat arguments as literal paths, not globs (default) + -g --glob Treat arguments as glob patterns + -v --verbose Be verbose when deleting files, showing them as + they are removed. Not compatible with --impl=native + -V --no-verbose Be silent when deleting files, showing nothing as + they are removed (default) + -i --interactive Ask for confirmation before deleting anything + Not compatible with --impl=native + -I --no-interactive Do not ask for confirmation before deleting + + --impl= Specify the implementation to use: + rimraf: choose the best option (default) + native: the built-in implementation in Node.js + manual: the platform-specific JS implementation + posix: the Posix JS implementation + windows: the Windows JS implementation (falls back to + move-remove on ENOTEMPTY) + move-remove: a slow reliable Windows fallback + +Implementation-specific options: + --tmp= Temp file folder for 'move-remove' implementation + --max-retries= maxRetries for 'native' and 'windows' implementations + --retry-delay= retryDelay for 'native' implementation, default 100 + --backoff= Exponential backoff factor for retries (default: 1.2) +``` + +## mkdirp + +If you need to _create_ a directory recursively, check out +[mkdirp](https://github.com/isaacs/node-mkdirp). diff --git a/libs/events/node_modules/rimraf/package.json b/libs/events/node_modules/rimraf/package.json new file mode 100644 index 000000000..573563eab --- /dev/null +++ b/libs/events/node_modules/rimraf/package.json @@ -0,0 +1,84 @@ +{ + "name": "rimraf", + "version": "4.4.1", + "main": "./dist/cjs/src/index-cjs.js", + "module": "./dist/mjs/index.js", + "types": "./dist/mjs/index.d.ts", + "bin": "./dist/cjs/src/bin.js", + "exports": { + ".": { + "import": { + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" + }, + "require": { + "types": "./dist/cjs/src/index.d.ts", + "default": "./dist/cjs/src/index-cjs.js" + } + } + }, + "files": [ + "dist" + ], + "description": "A deep deletion module for node (like `rm -rf`)", + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "ISC", + "repository": "git://github.com/isaacs/rimraf.git", + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "preprepare": "rm -rf dist", + "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json", + "postprepare": "bash fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn", + "benchmark": "node benchmark/index.js", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" + }, + "prettier": { + "semi": false, + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "devDependencies": { + "@types/node": "^18.11.9", + "@types/tap": "^15.0.7", + "c8": "^7.12.0", + "eslint-config-prettier": "^8.6.0", + "mkdirp": "1", + "prettier": "^2.8.2", + "tap": "^16.3.4", + "ts-node": "^10.9.1", + "typedoc": "^0.23.21", + "typescript": "^4.9.3" + }, + "tap": { + "coverage": false, + "libtap-settings": "libtap-settings.js", + "node-arg": [ + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "engines": { + "node": ">=14" + }, + "dependencies": { + "glob": "^9.2.0" + } +} diff --git a/libs/events/node_modules/run-parallel/LICENSE b/libs/events/node_modules/run-parallel/LICENSE new file mode 100644 index 000000000..c7e685275 --- /dev/null +++ b/libs/events/node_modules/run-parallel/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libs/events/node_modules/run-parallel/README.md b/libs/events/node_modules/run-parallel/README.md new file mode 100644 index 000000000..edc3da452 --- /dev/null +++ b/libs/events/node_modules/run-parallel/README.md @@ -0,0 +1,85 @@ +# run-parallel [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] + +[travis-image]: https://img.shields.io/travis/feross/run-parallel/master.svg +[travis-url]: https://travis-ci.org/feross/run-parallel +[npm-image]: https://img.shields.io/npm/v/run-parallel.svg +[npm-url]: https://npmjs.org/package/run-parallel +[downloads-image]: https://img.shields.io/npm/dm/run-parallel.svg +[downloads-url]: https://npmjs.org/package/run-parallel +[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg +[standard-url]: https://standardjs.com + +### Run an array of functions in parallel + +![parallel](https://raw.githubusercontent.com/feross/run-parallel/master/img.png) [![Sauce Test Status](https://saucelabs.com/browser-matrix/run-parallel.svg)](https://saucelabs.com/u/run-parallel) + +### install + +``` +npm install run-parallel +``` + +### usage + +#### parallel(tasks, [callback]) + +Run the `tasks` array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its callback, the main +`callback` is immediately called with the value of the error. Once the `tasks` have +completed, the results are passed to the final `callback` as an array. + +It is also possible to use an object instead of an array. Each property will be run as a +function and the results will be passed to the final `callback` as an object instead of +an array. This can be a more readable way of handling the results. + +##### arguments + +- `tasks` - An array or object containing functions to run. Each function is passed a +`callback(err, result)` which it must call on completion with an error `err` (which can +be `null`) and an optional `result` value. +- `callback(err, results)` - An optional callback to run once all the functions have +completed. This function gets a results array (or object) containing all the result +arguments passed to the task callbacks. + +##### example + +```js +var parallel = require('run-parallel') + +parallel([ + function (callback) { + setTimeout(function () { + callback(null, 'one') + }, 200) + }, + function (callback) { + setTimeout(function () { + callback(null, 'two') + }, 100) + } +], +// optional callback +function (err, results) { + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. +}) +``` + +This module is basically equavalent to +[`async.parallel`](https://github.com/caolan/async#paralleltasks-callback), but it's +handy to just have the one function you need instead of the kitchen sink. Modularity! +Especially handy if you're serving to the browser and need to reduce your javascript +bundle size. + +Works great in the browser with [browserify](http://browserify.org/)! + +### see also + +- [run-auto](https://github.com/feross/run-auto) +- [run-parallel-limit](https://github.com/feross/run-parallel-limit) +- [run-series](https://github.com/feross/run-series) +- [run-waterfall](https://github.com/feross/run-waterfall) + +### license + +MIT. Copyright (c) [Feross Aboukhadijeh](http://feross.org). diff --git a/libs/events/node_modules/run-parallel/index.js b/libs/events/node_modules/run-parallel/index.js new file mode 100644 index 000000000..6307141d6 --- /dev/null +++ b/libs/events/node_modules/run-parallel/index.js @@ -0,0 +1,51 @@ +/*! run-parallel. MIT License. Feross Aboukhadijeh */ +module.exports = runParallel + +const queueMicrotask = require('queue-microtask') + +function runParallel (tasks, cb) { + let results, pending, keys + let isSync = true + + if (Array.isArray(tasks)) { + results = [] + pending = tasks.length + } else { + keys = Object.keys(tasks) + results = {} + pending = keys.length + } + + function done (err) { + function end () { + if (cb) cb(err, results) + cb = null + } + if (isSync) queueMicrotask(end) + else end() + } + + function each (i, err, result) { + results[i] = result + if (--pending === 0 || err) { + done(err) + } + } + + if (!pending) { + // empty + done(null) + } else if (keys) { + // object + keys.forEach(function (key) { + tasks[key](function (err, result) { each(key, err, result) }) + }) + } else { + // array + tasks.forEach(function (task, i) { + task(function (err, result) { each(i, err, result) }) + }) + } + + isSync = false +} diff --git a/libs/events/node_modules/run-parallel/package.json b/libs/events/node_modules/run-parallel/package.json new file mode 100644 index 000000000..1f1475788 --- /dev/null +++ b/libs/events/node_modules/run-parallel/package.json @@ -0,0 +1,58 @@ +{ + "name": "run-parallel", + "description": "Run an array of functions in parallel", + "version": "1.2.0", + "author": { + "name": "Feross Aboukhadijeh", + "email": "feross@feross.org", + "url": "https://feross.org" + }, + "bugs": { + "url": "https://github.com/feross/run-parallel/issues" + }, + "dependencies": { + "queue-microtask": "^1.2.2" + }, + "devDependencies": { + "airtap": "^3.0.0", + "standard": "*", + "tape": "^5.0.1" + }, + "homepage": "https://github.com/feross/run-parallel", + "keywords": [ + "parallel", + "async", + "function", + "callback", + "asynchronous", + "run", + "array", + "run parallel" + ], + "license": "MIT", + "main": "index.js", + "repository": { + "type": "git", + "url": "git://github.com/feross/run-parallel.git" + }, + "scripts": { + "test": "standard && npm run test-node && npm run test-browser", + "test-browser": "airtap -- test/*.js", + "test-browser-local": "airtap --local -- test/*.js", + "test-node": "tape test/*.js" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] +} diff --git a/libs/events/node_modules/semver/LICENSE b/libs/events/node_modules/semver/LICENSE new file mode 100644 index 000000000..19129e315 --- /dev/null +++ b/libs/events/node_modules/semver/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/libs/events/node_modules/semver/README.md b/libs/events/node_modules/semver/README.md new file mode 100644 index 000000000..2293a14fd --- /dev/null +++ b/libs/events/node_modules/semver/README.md @@ -0,0 +1,443 @@ +semver(1) -- The semantic versioner for npm +=========================================== + +## Install + +```bash +npm install semver +```` + +## Usage + +As a node module: + +```js +const semver = require('semver') + +semver.valid('1.2.3') // '1.2.3' +semver.valid('a.b.c') // null +semver.clean(' =v1.2.3 ') // '1.2.3' +semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true +semver.gt('1.2.3', '9.8.7') // false +semver.lt('1.2.3', '9.8.7') // true +semver.minVersion('>=1.0.0') // '1.0.0' +semver.valid(semver.coerce('v2')) // '2.0.0' +semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7' +``` + +As a command-line utility: + +``` +$ semver -h + +A JavaScript implementation of the https://semver.org/ specification +Copyright Isaac Z. Schlueter + +Usage: semver [options] [ [...]] +Prints valid versions sorted by SemVer precedence + +Options: +-r --range + Print versions that match the specified range. + +-i --increment [] + Increment a version by the specified level. Level can + be one of: major, minor, patch, premajor, preminor, + prepatch, or prerelease. Default level is 'patch'. + Only one version may be specified. + +--preid + Identifier to be used to prefix premajor, preminor, + prepatch or prerelease version increments. + +-l --loose + Interpret versions and ranges loosely + +-p --include-prerelease + Always include prerelease versions in range matching + +-c --coerce + Coerce a string into SemVer if possible + (does not imply --loose) + +--rtl + Coerce version strings right to left + +--ltr + Coerce version strings left to right (default) + +Program exits successfully if any valid version satisfies +all supplied ranges, and prints all satisfying versions. + +If no satisfying versions are found, then exits failure. + +Versions are printed in ascending order, so supplying +multiple versions to the utility will just sort them. +``` + +## Versions + +A "version" is described by the `v2.0.0` specification found at +. + +A leading `"="` or `"v"` character is stripped off and ignored. + +## Ranges + +A `version range` is a set of `comparators` which specify versions +that satisfy the range. + +A `comparator` is composed of an `operator` and a `version`. The set +of primitive `operators` is: + +* `<` Less than +* `<=` Less than or equal to +* `>` Greater than +* `>=` Greater than or equal to +* `=` Equal. If no operator is specified, then equality is assumed, + so this operator is optional, but MAY be included. + +For example, the comparator `>=1.2.7` would match the versions +`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6` +or `1.1.0`. + +Comparators can be joined by whitespace to form a `comparator set`, +which is satisfied by the **intersection** of all of the comparators +it includes. + +A range is composed of one or more comparator sets, joined by `||`. A +version matches a range if and only if every comparator in at least +one of the `||`-separated comparator sets is satisfied by the version. + +For example, the range `>=1.2.7 <1.3.0` would match the versions +`1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`, +or `1.1.0`. + +The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`, +`1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`. + +### Prerelease Tags + +If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then +it will only be allowed to satisfy comparator sets if at least one +comparator with the same `[major, minor, patch]` tuple also has a +prerelease tag. + +For example, the range `>1.2.3-alpha.3` would be allowed to match the +version `1.2.3-alpha.7`, but it would *not* be satisfied by +`3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater +than" `1.2.3-alpha.3` according to the SemVer sort rules. The version +range only accepts prerelease tags on the `1.2.3` version. The +version `3.4.5` *would* satisfy the range, because it does not have a +prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`. + +The purpose for this behavior is twofold. First, prerelease versions +frequently are updated very quickly, and contain many breaking changes +that are (by the author's design) not yet fit for public consumption. +Therefore, by default, they are excluded from range matching +semantics. + +Second, a user who has opted into using a prerelease version has +clearly indicated the intent to use *that specific* set of +alpha/beta/rc versions. By including a prerelease tag in the range, +the user is indicating that they are aware of the risk. However, it +is still not appropriate to assume that they have opted into taking a +similar risk on the *next* set of prerelease versions. + +Note that this behavior can be suppressed (treating all prerelease +versions as if they were normal versions, for the purpose of range +matching) by setting the `includePrerelease` flag on the options +object to any +[functions](https://github.com/npm/node-semver#functions) that do +range matching. + +#### Prerelease Identifiers + +The method `.inc` takes an additional `identifier` string argument that +will append the value of the string as a prerelease identifier: + +```javascript +semver.inc('1.2.3', 'prerelease', 'beta') +// '1.2.4-beta.0' +``` + +command-line example: + +```bash +$ semver 1.2.3 -i prerelease --preid beta +1.2.4-beta.0 +``` + +Which then can be used to increment further: + +```bash +$ semver 1.2.4-beta.0 -i prerelease +1.2.4-beta.1 +``` + +### Advanced Range Syntax + +Advanced range syntax desugars to primitive comparators in +deterministic ways. + +Advanced ranges may be combined in the same way as primitive +comparators using white space or `||`. + +#### Hyphen Ranges `X.Y.Z - A.B.C` + +Specifies an inclusive set. + +* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4` + +If a partial version is provided as the first version in the inclusive +range, then the missing pieces are replaced with zeroes. + +* `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4` + +If a partial version is provided as the second version in the +inclusive range, then all versions that start with the supplied parts +of the tuple are accepted, but nothing that would be greater than the +provided tuple parts. + +* `1.2.3 - 2.3` := `>=1.2.3 <2.4.0` +* `1.2.3 - 2` := `>=1.2.3 <3.0.0` + +#### X-Ranges `1.2.x` `1.X` `1.2.*` `*` + +Any of `X`, `x`, or `*` may be used to "stand in" for one of the +numeric values in the `[major, minor, patch]` tuple. + +* `*` := `>=0.0.0` (Any version satisfies) +* `1.x` := `>=1.0.0 <2.0.0` (Matching major version) +* `1.2.x` := `>=1.2.0 <1.3.0` (Matching major and minor versions) + +A partial version range is treated as an X-Range, so the special +character is in fact optional. + +* `""` (empty string) := `*` := `>=0.0.0` +* `1` := `1.x.x` := `>=1.0.0 <2.0.0` +* `1.2` := `1.2.x` := `>=1.2.0 <1.3.0` + +#### Tilde Ranges `~1.2.3` `~1.2` `~1` + +Allows patch-level changes if a minor version is specified on the +comparator. Allows minor-level changes if not. + +* `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0` +* `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0` (Same as `1.2.x`) +* `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0` (Same as `1.x`) +* `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0` +* `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0` (Same as `0.2.x`) +* `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0` (Same as `0.x`) +* `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. + +#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4` + +Allows changes that do not modify the left-most non-zero element in the +`[major, minor, patch]` tuple. In other words, this allows patch and +minor updates for versions `1.0.0` and above, patch updates for +versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`. + +Many authors treat a `0.x` version as if the `x` were the major +"breaking-change" indicator. + +Caret ranges are ideal when an author may make breaking changes +between `0.2.4` and `0.3.0` releases, which is a common practice. +However, it presumes that there will *not* be breaking changes between +`0.2.4` and `0.2.5`. It allows for changes that are presumed to be +additive (but non-breaking), according to commonly observed practices. + +* `^1.2.3` := `>=1.2.3 <2.0.0` +* `^0.2.3` := `>=0.2.3 <0.3.0` +* `^0.0.3` := `>=0.0.3 <0.0.4` +* `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. +* `^0.0.3-beta` := `>=0.0.3-beta <0.0.4` Note that prereleases in the + `0.0.3` version *only* will be allowed, if they are greater than or + equal to `beta`. So, `0.0.3-pr.2` would be allowed. + +When parsing caret ranges, a missing `patch` value desugars to the +number `0`, but will allow flexibility within that value, even if the +major and minor versions are both `0`. + +* `^1.2.x` := `>=1.2.0 <2.0.0` +* `^0.0.x` := `>=0.0.0 <0.1.0` +* `^0.0` := `>=0.0.0 <0.1.0` + +A missing `minor` and `patch` values will desugar to zero, but also +allow flexibility within those values, even if the major version is +zero. + +* `^1.x` := `>=1.0.0 <2.0.0` +* `^0.x` := `>=0.0.0 <1.0.0` + +### Range Grammar + +Putting all this together, here is a Backus-Naur grammar for ranges, +for the benefit of parser authors: + +```bnf +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) * +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ +``` + +## Functions + +All methods and classes take a final `options` object argument. All +options in this object are `false` by default. The options supported +are: + +- `loose` Be more forgiving about not-quite-valid semver strings. + (Any resulting output will always be 100% strict compliant, of + course.) For backwards compatibility reasons, if the `options` + argument is a boolean value instead of an object, it is interpreted + to be the `loose` param. +- `includePrerelease` Set to suppress the [default + behavior](https://github.com/npm/node-semver#prerelease-tags) of + excluding prerelease tagged versions from ranges unless they are + explicitly opted into. + +Strict-mode Comparators and Ranges will be strict about the SemVer +strings that they parse. + +* `valid(v)`: Return the parsed version, or null if it's not valid. +* `inc(v, release)`: Return the version incremented by the release + type (`major`, `premajor`, `minor`, `preminor`, `patch`, + `prepatch`, or `prerelease`), or null if it's not valid + * `premajor` in one call will bump the version up to the next major + version and down to a prerelease of that major version. + `preminor`, and `prepatch` work the same way. + * If called from a non-prerelease version, the `prerelease` will work the + same as `prepatch`. It increments the patch version, then makes a + prerelease. If the input version is already a prerelease it simply + increments it. +* `prerelease(v)`: Returns an array of prerelease components, or null + if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]` +* `major(v)`: Return the major version number. +* `minor(v)`: Return the minor version number. +* `patch(v)`: Return the patch version number. +* `intersects(r1, r2, loose)`: Return true if the two supplied ranges + or comparators intersect. +* `parse(v)`: Attempt to parse a string as a semantic version, returning either + a `SemVer` object or `null`. + +### Comparison + +* `gt(v1, v2)`: `v1 > v2` +* `gte(v1, v2)`: `v1 >= v2` +* `lt(v1, v2)`: `v1 < v2` +* `lte(v1, v2)`: `v1 <= v2` +* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent, + even if they're not the exact same string. You already know how to + compare strings. +* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`. +* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call + the corresponding function above. `"==="` and `"!=="` do simple + string comparison, but are included for completeness. Throws if an + invalid comparison string is provided. +* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if + `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. +* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions + in descending order when passed to `Array.sort()`. +* `compareBuild(v1, v2)`: The same as `compare` but considers `build` when two versions + are equal. Sorts in ascending order if passed to `Array.sort()`. + `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. +* `diff(v1, v2)`: Returns difference between two versions by the release type + (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`), + or null if the versions are the same. + +### Comparators + +* `intersects(comparator)`: Return true if the comparators intersect + +### Ranges + +* `validRange(range)`: Return the valid range or null if it's not valid +* `satisfies(version, range)`: Return true if the version satisfies the + range. +* `maxSatisfying(versions, range)`: Return the highest version in the list + that satisfies the range, or `null` if none of them do. +* `minSatisfying(versions, range)`: Return the lowest version in the list + that satisfies the range, or `null` if none of them do. +* `minVersion(range)`: Return the lowest version that can possibly match + the given range. +* `gtr(version, range)`: Return `true` if version is greater than all the + versions possible in the range. +* `ltr(version, range)`: Return `true` if version is less than all the + versions possible in the range. +* `outside(version, range, hilo)`: Return true if the version is outside + the bounds of the range in either the high or low direction. The + `hilo` argument must be either the string `'>'` or `'<'`. (This is + the function called by `gtr` and `ltr`.) +* `intersects(range)`: Return true if any of the ranges comparators intersect + +Note that, since ranges may be non-contiguous, a version might not be +greater than a range, less than a range, *or* satisfy a range! For +example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9` +until `2.0.0`, so the version `1.2.10` would not be greater than the +range (because `2.0.1` satisfies, which is higher), nor less than the +range (since `1.2.8` satisfies, which is lower), and it also does not +satisfy the range. + +If you want to know if a version satisfies or does not satisfy a +range, use the `satisfies(version, range)` function. + +### Coercion + +* `coerce(version, options)`: Coerces a string to semver if possible + +This aims to provide a very forgiving translation of a non-semver string to +semver. It looks for the first digit in a string, and consumes all +remaining characters which satisfy at least a partial semver (e.g., `1`, +`1.2`, `1.2.3`) up to the max permitted length (256 characters). Longer +versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`). All +surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes +`3.4.0`). Only text which lacks digits will fail coercion (`version one` +is not valid). The maximum length for any semver component considered for +coercion is 16 characters; longer components will be ignored +(`10000000000000000.4.7.4` becomes `4.7.4`). The maximum value for any +semver component is `Integer.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value +components are invalid (`9999999999999999.4.7.4` is likely invalid). + +If the `options.rtl` flag is set, then `coerce` will return the right-most +coercible tuple that does not share an ending index with a longer coercible +tuple. For example, `1.2.3.4` will return `2.3.4` in rtl mode, not +`4.0.0`. `1.2.3/4` will return `4.0.0`, because the `4` is not a part of +any other overlapping SemVer tuple. + +### Clean + +* `clean(version)`: Clean a string to be a valid semver if possible + +This will return a cleaned and trimmed semver version. If the provided version is not valid a null will be returned. This does not work for ranges. + +ex. +* `s.clean(' = v 2.1.5foo')`: `null` +* `s.clean(' = v 2.1.5foo', { loose: true })`: `'2.1.5-foo'` +* `s.clean(' = v 2.1.5-foo')`: `null` +* `s.clean(' = v 2.1.5-foo', { loose: true })`: `'2.1.5-foo'` +* `s.clean('=v2.1.5')`: `'2.1.5'` +* `s.clean(' =v2.1.5')`: `2.1.5` +* `s.clean(' 2.1.5 ')`: `'2.1.5'` +* `s.clean('~1.0.0')`: `null` diff --git a/libs/events/node_modules/semver/bin/semver.js b/libs/events/node_modules/semver/bin/semver.js new file mode 100755 index 000000000..666034a75 --- /dev/null +++ b/libs/events/node_modules/semver/bin/semver.js @@ -0,0 +1,174 @@ +#!/usr/bin/env node +// Standalone semver comparison program. +// Exits successfully and prints matching version(s) if +// any supplied version is valid and passes all tests. + +var argv = process.argv.slice(2) + +var versions = [] + +var range = [] + +var inc = null + +var version = require('../package.json').version + +var loose = false + +var includePrerelease = false + +var coerce = false + +var rtl = false + +var identifier + +var semver = require('../semver') + +var reverse = false + +var options = {} + +main() + +function main () { + if (!argv.length) return help() + while (argv.length) { + var a = argv.shift() + var indexOfEqualSign = a.indexOf('=') + if (indexOfEqualSign !== -1) { + a = a.slice(0, indexOfEqualSign) + argv.unshift(a.slice(indexOfEqualSign + 1)) + } + switch (a) { + case '-rv': case '-rev': case '--rev': case '--reverse': + reverse = true + break + case '-l': case '--loose': + loose = true + break + case '-p': case '--include-prerelease': + includePrerelease = true + break + case '-v': case '--version': + versions.push(argv.shift()) + break + case '-i': case '--inc': case '--increment': + switch (argv[0]) { + case 'major': case 'minor': case 'patch': case 'prerelease': + case 'premajor': case 'preminor': case 'prepatch': + inc = argv.shift() + break + default: + inc = 'patch' + break + } + break + case '--preid': + identifier = argv.shift() + break + case '-r': case '--range': + range.push(argv.shift()) + break + case '-c': case '--coerce': + coerce = true + break + case '--rtl': + rtl = true + break + case '--ltr': + rtl = false + break + case '-h': case '--help': case '-?': + return help() + default: + versions.push(a) + break + } + } + + var options = { loose: loose, includePrerelease: includePrerelease, rtl: rtl } + + versions = versions.map(function (v) { + return coerce ? (semver.coerce(v, options) || { version: v }).version : v + }).filter(function (v) { + return semver.valid(v) + }) + if (!versions.length) return fail() + if (inc && (versions.length !== 1 || range.length)) { return failInc() } + + for (var i = 0, l = range.length; i < l; i++) { + versions = versions.filter(function (v) { + return semver.satisfies(v, range[i], options) + }) + if (!versions.length) return fail() + } + return success(versions) +} + +function failInc () { + console.error('--inc can only be used on a single version with no range') + fail() +} + +function fail () { process.exit(1) } + +function success () { + var compare = reverse ? 'rcompare' : 'compare' + versions.sort(function (a, b) { + return semver[compare](a, b, options) + }).map(function (v) { + return semver.clean(v, options) + }).map(function (v) { + return inc ? semver.inc(v, inc, options, identifier) : v + }).forEach(function (v, i, _) { console.log(v) }) +} + +function help () { + console.log(['SemVer ' + version, + '', + 'A JavaScript implementation of the https://semver.org/ specification', + 'Copyright Isaac Z. Schlueter', + '', + 'Usage: semver [options] [ [...]]', + 'Prints valid versions sorted by SemVer precedence', + '', + 'Options:', + '-r --range ', + ' Print versions that match the specified range.', + '', + '-i --increment []', + ' Increment a version by the specified level. Level can', + ' be one of: major, minor, patch, premajor, preminor,', + " prepatch, or prerelease. Default level is 'patch'.", + ' Only one version may be specified.', + '', + '--preid ', + ' Identifier to be used to prefix premajor, preminor,', + ' prepatch or prerelease version increments.', + '', + '-l --loose', + ' Interpret versions and ranges loosely', + '', + '-p --include-prerelease', + ' Always include prerelease versions in range matching', + '', + '-c --coerce', + ' Coerce a string into SemVer if possible', + ' (does not imply --loose)', + '', + '--rtl', + ' Coerce version strings right to left', + '', + '--ltr', + ' Coerce version strings left to right (default)', + '', + 'Program exits successfully if any valid version satisfies', + 'all supplied ranges, and prints all satisfying versions.', + '', + 'If no satisfying versions are found, then exits failure.', + '', + 'Versions are printed in ascending order, so supplying', + 'multiple versions to the utility will just sort them.' + ].join('\n')) +} diff --git a/libs/events/node_modules/semver/package.json b/libs/events/node_modules/semver/package.json new file mode 100644 index 000000000..6b970a629 --- /dev/null +++ b/libs/events/node_modules/semver/package.json @@ -0,0 +1,38 @@ +{ + "name": "semver", + "version": "6.3.1", + "description": "The semantic version parser used by npm.", + "main": "semver.js", + "scripts": { + "test": "tap test/ --100 --timeout=30", + "lint": "echo linting disabled", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run lint -- --fix", + "snap": "tap test/ --100 --timeout=30", + "posttest": "npm run lint" + }, + "devDependencies": { + "@npmcli/template-oss": "4.17.0", + "tap": "^12.7.0" + }, + "license": "ISC", + "repository": { + "type": "git", + "url": "https://github.com/npm/node-semver.git" + }, + "bin": { + "semver": "./bin/semver.js" + }, + "files": [ + "bin", + "range.bnf", + "semver.js" + ], + "author": "GitHub Inc.", + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "content": "./scripts/template-oss", + "version": "4.17.0" + } +} diff --git a/libs/events/node_modules/semver/range.bnf b/libs/events/node_modules/semver/range.bnf new file mode 100644 index 000000000..d4c6ae0d7 --- /dev/null +++ b/libs/events/node_modules/semver/range.bnf @@ -0,0 +1,16 @@ +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | [1-9] ( [0-9] ) * +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ diff --git a/libs/events/node_modules/semver/semver.js b/libs/events/node_modules/semver/semver.js new file mode 100644 index 000000000..39319c13c --- /dev/null +++ b/libs/events/node_modules/semver/semver.js @@ -0,0 +1,1643 @@ +exports = module.exports = SemVer + +var debug +/* istanbul ignore next */ +if (typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG)) { + debug = function () { + var args = Array.prototype.slice.call(arguments, 0) + args.unshift('SEMVER') + console.log.apply(console, args) + } +} else { + debug = function () {} +} + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0' + +var MAX_LENGTH = 256 +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || + /* istanbul ignore next */ 9007199254740991 + +// Max safe segment length for coercion. +var MAX_SAFE_COMPONENT_LENGTH = 16 + +var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + +// The actual regexps go on exports.re +var re = exports.re = [] +var safeRe = exports.safeRe = [] +var src = exports.src = [] +var t = exports.tokens = {} +var R = 0 + +function tok (n) { + t[n] = R++ +} + +var LETTERDASHNUMBER = '[a-zA-Z0-9-]' + +// Replace some greedy regex tokens to prevent regex dos issues. These regex are +// used internally via the safeRe object since all inputs in this library get +// normalized first to trim and collapse all extra whitespace. The original +// regexes are exported for userland consumption and lower level usage. A +// future breaking change could export the safer regex only with a note that +// all input should have extra whitespace removed. +var safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], +] + +function makeSafeRe (value) { + for (var i = 0; i < safeRegexReplacements.length; i++) { + var token = safeRegexReplacements[i][0] + var max = safeRegexReplacements[i][1] + value = value + .split(token + '*').join(token + '{0,' + max + '}') + .split(token + '+').join(token + '{1,' + max + '}') + } + return value +} + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +tok('NUMERICIDENTIFIER') +src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*' +tok('NUMERICIDENTIFIERLOOSE') +src[t.NUMERICIDENTIFIERLOOSE] = '\\d+' + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +tok('NONNUMERICIDENTIFIER') +src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-]' + LETTERDASHNUMBER + '*' + +// ## Main Version +// Three dot-separated numeric identifiers. + +tok('MAINVERSION') +src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIER] + ')' + +tok('MAINVERSIONLOOSE') +src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')' + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +tok('PRERELEASEIDENTIFIER') +src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] + + '|' + src[t.NONNUMERICIDENTIFIER] + ')' + +tok('PRERELEASEIDENTIFIERLOOSE') +src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] + + '|' + src[t.NONNUMERICIDENTIFIER] + ')' + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +tok('PRERELEASE') +src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] + + '(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))' + +tok('PRERELEASELOOSE') +src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))' + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +tok('BUILDIDENTIFIER') +src[t.BUILDIDENTIFIER] = LETTERDASHNUMBER + '+' + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +tok('BUILD') +src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] + + '(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))' + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +tok('FULL') +tok('FULLPLAIN') +src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] + + src[t.PRERELEASE] + '?' + + src[t.BUILD] + '?' + +src[t.FULL] = '^' + src[t.FULLPLAIN] + '$' + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +tok('LOOSEPLAIN') +src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] + + src[t.PRERELEASELOOSE] + '?' + + src[t.BUILD] + '?' + +tok('LOOSE') +src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$' + +tok('GTLT') +src[t.GTLT] = '((?:<|>)?=?)' + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +tok('XRANGEIDENTIFIERLOOSE') +src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' +tok('XRANGEIDENTIFIER') +src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*' + +tok('XRANGEPLAIN') +src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + + '(?:' + src[t.PRERELEASE] + ')?' + + src[t.BUILD] + '?' + + ')?)?' + +tok('XRANGEPLAINLOOSE') +src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[t.PRERELEASELOOSE] + ')?' + + src[t.BUILD] + '?' + + ')?)?' + +tok('XRANGE') +src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$' +tok('XRANGELOOSE') +src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$' + +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +tok('COERCE') +src[t.COERCE] = '(^|[^\\d])' + + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:$|[^\\d])' +tok('COERCERTL') +re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g') +safeRe[t.COERCERTL] = new RegExp(makeSafeRe(src[t.COERCE]), 'g') + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +tok('LONETILDE') +src[t.LONETILDE] = '(?:~>?)' + +tok('TILDETRIM') +src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+' +re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g') +safeRe[t.TILDETRIM] = new RegExp(makeSafeRe(src[t.TILDETRIM]), 'g') +var tildeTrimReplace = '$1~' + +tok('TILDE') +src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$' +tok('TILDELOOSE') +src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$' + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +tok('LONECARET') +src[t.LONECARET] = '(?:\\^)' + +tok('CARETTRIM') +src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+' +re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g') +safeRe[t.CARETTRIM] = new RegExp(makeSafeRe(src[t.CARETTRIM]), 'g') +var caretTrimReplace = '$1^' + +tok('CARET') +src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$' +tok('CARETLOOSE') +src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$' + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +tok('COMPARATORLOOSE') +src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$' +tok('COMPARATOR') +src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$' + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +tok('COMPARATORTRIM') +src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] + + '\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')' + +// this one has to use the /g flag +re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g') +safeRe[t.COMPARATORTRIM] = new RegExp(makeSafeRe(src[t.COMPARATORTRIM]), 'g') +var comparatorTrimReplace = '$1$2$3' + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +tok('HYPHENRANGE') +src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[t.XRANGEPLAIN] + ')' + + '\\s*$' + +tok('HYPHENRANGELOOSE') +src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[t.XRANGEPLAINLOOSE] + ')' + + '\\s*$' + +// Star ranges basically just allow anything at all. +tok('STAR') +src[t.STAR] = '(<|>)?=?\\s*\\*' + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]) + if (!re[i]) { + re[i] = new RegExp(src[i]) + + // Replace all greedy whitespace to prevent regex dos issues. These regex are + // used internally via the safeRe object since all inputs in this library get + // normalized first to trim and collapse all extra whitespace. The original + // regexes are exported for userland consumption and lower level usage. A + // future breaking change could export the safer regex only with a note that + // all input should have extra whitespace removed. + safeRe[i] = new RegExp(makeSafeRe(src[i])) + } +} + +exports.parse = parse +function parse (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (version instanceof SemVer) { + return version + } + + if (typeof version !== 'string') { + return null + } + + if (version.length > MAX_LENGTH) { + return null + } + + var r = options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL] + if (!r.test(version)) { + return null + } + + try { + return new SemVer(version, options) + } catch (er) { + return null + } +} + +exports.valid = valid +function valid (version, options) { + var v = parse(version, options) + return v ? v.version : null +} + +exports.clean = clean +function clean (version, options) { + var s = parse(version.trim().replace(/^[=v]+/, ''), options) + return s ? s.version : null +} + +exports.SemVer = SemVer + +function SemVer (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + if (version instanceof SemVer) { + if (version.loose === options.loose) { + return version + } else { + version = version.version + } + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version) + } + + if (version.length > MAX_LENGTH) { + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + } + + if (!(this instanceof SemVer)) { + return new SemVer(version, options) + } + + debug('SemVer', version, options) + this.options = options + this.loose = !!options.loose + + var m = version.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]) + + if (!m) { + throw new TypeError('Invalid Version: ' + version) + } + + this.raw = version + + // these are actually numbers + this.major = +m[1] + this.minor = +m[2] + this.patch = +m[3] + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') + } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') + } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') + } + + // numberify any prerelease numeric ids + if (!m[4]) { + this.prerelease = [] + } else { + this.prerelease = m[4].split('.').map(function (id) { + if (/^[0-9]+$/.test(id)) { + var num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num + } + } + return id + }) + } + + this.build = m[5] ? m[5].split('.') : [] + this.format() +} + +SemVer.prototype.format = function () { + this.version = this.major + '.' + this.minor + '.' + this.patch + if (this.prerelease.length) { + this.version += '-' + this.prerelease.join('.') + } + return this.version +} + +SemVer.prototype.toString = function () { + return this.version +} + +SemVer.prototype.compare = function (other) { + debug('SemVer.compare', this.version, this.options, other) + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return this.compareMain(other) || this.comparePre(other) +} + +SemVer.prototype.compareMain = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch) +} + +SemVer.prototype.comparePre = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } + + var i = 0 + do { + var a = this.prerelease[i] + var b = other.prerelease[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) +} + +SemVer.prototype.compareBuild = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + var i = 0 + do { + var a = this.build[i] + var b = other.build[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) +} + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function (release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0 + this.patch = 0 + this.minor = 0 + this.major++ + this.inc('pre', identifier) + break + case 'preminor': + this.prerelease.length = 0 + this.patch = 0 + this.minor++ + this.inc('pre', identifier) + break + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0 + this.inc('patch', identifier) + this.inc('pre', identifier) + break + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier) + } + this.inc('pre', identifier) + break + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0) { + this.major++ + } + this.minor = 0 + this.patch = 0 + this.prerelease = [] + break + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++ + } + this.patch = 0 + this.prerelease = [] + break + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) { + this.patch++ + } + this.prerelease = [] + break + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) { + this.prerelease = [0] + } else { + var i = this.prerelease.length + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++ + i = -2 + } + } + if (i === -1) { + // didn't increment anything + this.prerelease.push(0) + } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) { + this.prerelease = [identifier, 0] + } + } else { + this.prerelease = [identifier, 0] + } + } + break + + default: + throw new Error('invalid increment argument: ' + release) + } + this.format() + this.raw = this.version + return this +} + +exports.inc = inc +function inc (version, release, loose, identifier) { + if (typeof (loose) === 'string') { + identifier = loose + loose = undefined + } + + try { + return new SemVer(version, loose).inc(release, identifier).version + } catch (er) { + return null + } +} + +exports.diff = diff +function diff (version1, version2) { + if (eq(version1, version2)) { + return null + } else { + var v1 = parse(version1) + var v2 = parse(version2) + var prefix = '' + if (v1.prerelease.length || v2.prerelease.length) { + prefix = 'pre' + var defaultResult = 'prerelease' + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return prefix + key + } + } + } + return defaultResult // may be undefined + } +} + +exports.compareIdentifiers = compareIdentifiers + +var numeric = /^[0-9]+$/ +function compareIdentifiers (a, b) { + var anum = numeric.test(a) + var bnum = numeric.test(b) + + if (anum && bnum) { + a = +a + b = +b + } + + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 +} + +exports.rcompareIdentifiers = rcompareIdentifiers +function rcompareIdentifiers (a, b) { + return compareIdentifiers(b, a) +} + +exports.major = major +function major (a, loose) { + return new SemVer(a, loose).major +} + +exports.minor = minor +function minor (a, loose) { + return new SemVer(a, loose).minor +} + +exports.patch = patch +function patch (a, loose) { + return new SemVer(a, loose).patch +} + +exports.compare = compare +function compare (a, b, loose) { + return new SemVer(a, loose).compare(new SemVer(b, loose)) +} + +exports.compareLoose = compareLoose +function compareLoose (a, b) { + return compare(a, b, true) +} + +exports.compareBuild = compareBuild +function compareBuild (a, b, loose) { + var versionA = new SemVer(a, loose) + var versionB = new SemVer(b, loose) + return versionA.compare(versionB) || versionA.compareBuild(versionB) +} + +exports.rcompare = rcompare +function rcompare (a, b, loose) { + return compare(b, a, loose) +} + +exports.sort = sort +function sort (list, loose) { + return list.sort(function (a, b) { + return exports.compareBuild(a, b, loose) + }) +} + +exports.rsort = rsort +function rsort (list, loose) { + return list.sort(function (a, b) { + return exports.compareBuild(b, a, loose) + }) +} + +exports.gt = gt +function gt (a, b, loose) { + return compare(a, b, loose) > 0 +} + +exports.lt = lt +function lt (a, b, loose) { + return compare(a, b, loose) < 0 +} + +exports.eq = eq +function eq (a, b, loose) { + return compare(a, b, loose) === 0 +} + +exports.neq = neq +function neq (a, b, loose) { + return compare(a, b, loose) !== 0 +} + +exports.gte = gte +function gte (a, b, loose) { + return compare(a, b, loose) >= 0 +} + +exports.lte = lte +function lte (a, b, loose) { + return compare(a, b, loose) <= 0 +} + +exports.cmp = cmp +function cmp (a, op, b, loose) { + switch (op) { + case '===': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a === b + + case '!==': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a !== b + + case '': + case '=': + case '==': + return eq(a, b, loose) + + case '!=': + return neq(a, b, loose) + + case '>': + return gt(a, b, loose) + + case '>=': + return gte(a, b, loose) + + case '<': + return lt(a, b, loose) + + case '<=': + return lte(a, b, loose) + + default: + throw new TypeError('Invalid operator: ' + op) + } +} + +exports.Comparator = Comparator +function Comparator (comp, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value + } + } + + if (!(this instanceof Comparator)) { + return new Comparator(comp, options) + } + + comp = comp.trim().split(/\s+/).join(' ') + debug('comparator', comp, options) + this.options = options + this.loose = !!options.loose + this.parse(comp) + + if (this.semver === ANY) { + this.value = '' + } else { + this.value = this.operator + this.semver.version + } + + debug('comp', this) +} + +var ANY = {} +Comparator.prototype.parse = function (comp) { + var r = this.options.loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR] + var m = comp.match(r) + + if (!m) { + throw new TypeError('Invalid comparator: ' + comp) + } + + this.operator = m[1] !== undefined ? m[1] : '' + if (this.operator === '=') { + this.operator = '' + } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) { + this.semver = ANY + } else { + this.semver = new SemVer(m[2], this.options.loose) + } +} + +Comparator.prototype.toString = function () { + return this.value +} + +Comparator.prototype.test = function (version) { + debug('Comparator.test', version, this.options.loose) + + if (this.semver === ANY || version === ANY) { + return true + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + return cmp(version, this.operator, this.semver, this.options) +} + +Comparator.prototype.intersects = function (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + var rangeTmp + + if (this.operator === '') { + if (this.value === '') { + return true + } + rangeTmp = new Range(comp.value, options) + return satisfies(this.value, rangeTmp, options) + } else if (comp.operator === '') { + if (comp.value === '') { + return true + } + rangeTmp = new Range(this.value, options) + return satisfies(comp.semver, rangeTmp, options) + } + + var sameDirectionIncreasing = + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '>=' || comp.operator === '>') + var sameDirectionDecreasing = + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '<=' || comp.operator === '<') + var sameSemVer = this.semver.version === comp.semver.version + var differentDirectionsInclusive = + (this.operator === '>=' || this.operator === '<=') && + (comp.operator === '>=' || comp.operator === '<=') + var oppositeDirectionsLessThan = + cmp(this.semver, '<', comp.semver, options) && + ((this.operator === '>=' || this.operator === '>') && + (comp.operator === '<=' || comp.operator === '<')) + var oppositeDirectionsGreaterThan = + cmp(this.semver, '>', comp.semver, options) && + ((this.operator === '<=' || this.operator === '<') && + (comp.operator === '>=' || comp.operator === '>')) + + return sameDirectionIncreasing || sameDirectionDecreasing || + (sameSemVer && differentDirectionsInclusive) || + oppositeDirectionsLessThan || oppositeDirectionsGreaterThan +} + +exports.Range = Range +function Range (range, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (range instanceof Range) { + if (range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease) { + return range + } else { + return new Range(range.raw, options) + } + } + + if (range instanceof Comparator) { + return new Range(range.value, options) + } + + if (!(this instanceof Range)) { + return new Range(range, options) + } + + this.options = options + this.loose = !!options.loose + this.includePrerelease = !!options.includePrerelease + + // First reduce all whitespace as much as possible so we do not have to rely + // on potentially slow regexes like \s*. This is then stored and used for + // future error messages as well. + this.raw = range + .trim() + .split(/\s+/) + .join(' ') + + // First, split based on boolean or || + this.set = this.raw.split('||').map(function (range) { + return this.parseRange(range.trim()) + }, this).filter(function (c) { + // throw out any that are not relevant for whatever reason + return c.length + }) + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + this.raw) + } + + this.format() +} + +Range.prototype.format = function () { + this.range = this.set.map(function (comps) { + return comps.join(' ').trim() + }).join('||').trim() + return this.range +} + +Range.prototype.toString = function () { + return this.range +} + +Range.prototype.parseRange = function (range) { + var loose = this.options.loose + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE] + range = range.replace(hr, hyphenReplace) + debug('hyphen replace', range) + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range, safeRe[t.COMPARATORTRIM]) + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace) + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace) + + // normalize spaces + range = range.split(/\s+/).join(' ') + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR] + var set = range.split(' ').map(function (comp) { + return parseComparator(comp, this.options) + }, this).join(' ').split(/\s+/) + if (this.options.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function (comp) { + return !!comp.match(compRe) + }) + } + set = set.map(function (comp) { + return new Comparator(comp, this.options) + }, this) + + return set +} + +Range.prototype.intersects = function (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') + } + + return this.set.some(function (thisComparators) { + return ( + isSatisfiable(thisComparators, options) && + range.set.some(function (rangeComparators) { + return ( + isSatisfiable(rangeComparators, options) && + thisComparators.every(function (thisComparator) { + return rangeComparators.every(function (rangeComparator) { + return thisComparator.intersects(rangeComparator, options) + }) + }) + ) + }) + ) + }) +} + +// take a set of comparators and determine whether there +// exists a version which can satisfy it +function isSatisfiable (comparators, options) { + var result = true + var remainingComparators = comparators.slice() + var testComparator = remainingComparators.pop() + + while (result && remainingComparators.length) { + result = remainingComparators.every(function (otherComparator) { + return testComparator.intersects(otherComparator, options) + }) + + testComparator = remainingComparators.pop() + } + + return result +} + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators +function toComparators (range, options) { + return new Range(range, options).set.map(function (comp) { + return comp.map(function (c) { + return c.value + }).join(' ').trim().split(' ') + }) +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator (comp, options) { + debug('comp', comp, options) + comp = replaceCarets(comp, options) + debug('caret', comp) + comp = replaceTildes(comp, options) + debug('tildes', comp) + comp = replaceXRanges(comp, options) + debug('xrange', comp) + comp = replaceStars(comp, options) + debug('stars', comp) + return comp +} + +function isX (id) { + return !id || id.toLowerCase() === 'x' || id === '*' +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceTilde(comp, options) + }).join(' ') +} + +function replaceTilde (comp, options) { + var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE] + return comp.replace(r, function (_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else if (pr) { + debug('replaceTilde pr', pr) + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } else { + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + + debug('tilde return', ret) + return ret + }) +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceCaret(comp, options) + }).join(' ') +} + +function replaceCaret (comp, options) { + debug('caret', comp, options) + var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET] + return comp.replace(r, function (_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + if (M === '0') { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else { + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + (+M + 1) + '.0.0' + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0' + } + } + + debug('caret return', ret) + return ret + }) +} + +function replaceXRanges (comp, options) { + debug('replaceXRanges', comp, options) + return comp.split(/\s+/).map(function (comp) { + return replaceXRange(comp, options) + }).join(' ') +} + +function replaceXRange (comp, options) { + comp = comp.trim() + var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE] + return comp.replace(r, function (ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + var xM = isX(M) + var xm = xM || isX(m) + var xp = xm || isX(p) + var anyX = xp + + if (gtlt === '=' && anyX) { + gtlt = '' + } + + // if we're including prereleases in the match, then we need + // to fix this to -0, the lowest possible prerelease value + pr = options.includePrerelease ? '-0' : '' + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0-0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } + + ret = gtlt + M + '.' + m + '.' + p + pr + } else if (xm) { + ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr + } else if (xp) { + ret = '>=' + M + '.' + m + '.0' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + pr + } + + debug('xRange return', ret) + + return ret + }) +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars (comp, options) { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(safeRe[t.STAR], '') +} + +// This function is passed to string.replace(re[t.HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = '>=' + fM + '.0.0' + } else if (isX(fp)) { + from = '>=' + fM + '.' + fm + '.0' + } else { + from = '>=' + from + } + + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = '<' + (+tM + 1) + '.0.0' + } else if (isX(tp)) { + to = '<' + tM + '.' + (+tm + 1) + '.0' + } else if (tpr) { + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr + } else { + to = '<=' + to + } + + return (from + ' ' + to).trim() +} + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function (version) { + if (!version) { + return false + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } + } + return false +} + +function testSet (set, version, options) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } + } + + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === ANY) { + continue + } + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false + } + + return true +} + +exports.satisfies = satisfies +function satisfies (version, range, options) { + try { + range = new Range(range, options) + } catch (er) { + return false + } + return range.test(version) +} + +exports.maxSatisfying = maxSatisfying +function maxSatisfying (versions, range, options) { + var max = null + var maxSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max +} + +exports.minSatisfying = minSatisfying +function minSatisfying (versions, range, options) { + var min = null + var minSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } + }) + return min +} + +exports.minVersion = minVersion +function minVersion (range, loose) { + range = new Range(range, loose) + + var minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } + + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } + + minver = null + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + comparators.forEach(function (comparator) { + // Clone to avoid manipulating the comparator's semver object. + var compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!minver || gt(minver, compver)) { + minver = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error('Unexpected operation: ' + comparator.operator) + } + }) + } + + if (minver && range.test(minver)) { + return minver + } + + return null +} + +exports.validRange = validRange +function validRange (range, options) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr +function ltr (version, range, options) { + return outside(version, range, '<', options) +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr +function gtr (version, range, options) { + return outside(version, range, '>', options) +} + +exports.outside = outside +function outside (version, range, hilo, options) { + version = new SemVer(version, options) + range = new Range(range, options) + + var gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, options)) { + return false + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + var high = null + var low = null + + comparators.forEach(function (comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true +} + +exports.prerelease = prerelease +function prerelease (version, options) { + var parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +} + +exports.intersects = intersects +function intersects (r1, r2, options) { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2) +} + +exports.coerce = coerce +function coerce (version, options) { + if (version instanceof SemVer) { + return version + } + + if (typeof version === 'number') { + version = String(version) + } + + if (typeof version !== 'string') { + return null + } + + options = options || {} + + var match = null + if (!options.rtl) { + match = version.match(safeRe[t.COERCE]) + } else { + // Find the right-most coercible string that does not share + // a terminus with a more left-ward coercible string. + // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' + // + // Walk through the string checking with a /g regexp + // Manually set the index so as to pick up overlapping matches. + // Stop when we get a match that ends at the string end, since no + // coercible string can be more right-ward without the same terminus. + var next + while ((next = safeRe[t.COERCERTL].exec(version)) && + (!match || match.index + match[0].length !== version.length) + ) { + if (!match || + next.index + next[0].length !== match.index + match[0].length) { + match = next + } + safeRe[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length + } + // leave it in a clean state + safeRe[t.COERCERTL].lastIndex = -1 + } + + if (match === null) { + return null + } + + return parse(match[2] + + '.' + (match[3] || '0') + + '.' + (match[4] || '0'), options) +} diff --git a/libs/events/node_modules/source-map/CHANGELOG.md b/libs/events/node_modules/source-map/CHANGELOG.md new file mode 100644 index 000000000..3a8c066c6 --- /dev/null +++ b/libs/events/node_modules/source-map/CHANGELOG.md @@ -0,0 +1,301 @@ +# Change Log + +## 0.5.6 + +* Fix for regression when people were using numbers as names in source maps. See + #236. + +## 0.5.5 + +* Fix "regression" of unsupported, implementation behavior that half the world + happens to have come to depend on. See #235. + +* Fix regression involving function hoisting in SpiderMonkey. See #233. + +## 0.5.4 + +* Large performance improvements to source-map serialization. See #228 and #229. + +## 0.5.3 + +* Do not include unnecessary distribution files. See + commit ef7006f8d1647e0a83fdc60f04f5a7ca54886f86. + +## 0.5.2 + +* Include browser distributions of the library in package.json's `files`. See + issue #212. + +## 0.5.1 + +* Fix latent bugs in IndexedSourceMapConsumer.prototype._parseMappings. See + ff05274becc9e6e1295ed60f3ea090d31d843379. + +## 0.5.0 + +* Node 0.8 is no longer supported. + +* Use webpack instead of dryice for bundling. + +* Big speedups serializing source maps. See pull request #203. + +* Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that + explicitly start with the source root. See issue #199. + +## 0.4.4 + +* Fix an issue where using a `SourceMapGenerator` after having created a + `SourceMapConsumer` from it via `SourceMapConsumer.fromSourceMap` failed. See + issue #191. + +* Fix an issue with where `SourceMapGenerator` would mistakenly consider + different mappings as duplicates of each other and avoid generating them. See + issue #192. + +## 0.4.3 + +* A very large number of performance improvements, particularly when parsing + source maps. Collectively about 75% of time shaved off of the source map + parsing benchmark! + +* Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy + searching in the presence of a column option. See issue #177. + +* Fix a bug with joining a source and its source root when the source is above + the root. See issue #182. + +* Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to + determine when all sources' contents are inlined into the source map. See + issue #190. + +## 0.4.2 + +* Add an `.npmignore` file so that the benchmarks aren't pulled down by + dependent projects. Issue #169. + +* Add an optional `column` argument to + `SourceMapConsumer.prototype.allGeneratedPositionsFor` and better handle lines + with no mappings. Issues #172 and #173. + +## 0.4.1 + +* Fix accidentally defining a global variable. #170. + +## 0.4.0 + +* The default direction for fuzzy searching was changed back to its original + direction. See #164. + +* There is now a `bias` option you can supply to `SourceMapConsumer` to control + the fuzzy searching direction. See #167. + +* About an 8% speed up in parsing source maps. See #159. + +* Added a benchmark for parsing and generating source maps. + +## 0.3.0 + +* Change the default direction that searching for positions fuzzes when there is + not an exact match. See #154. + +* Support for environments using json2.js for JSON serialization. See #156. + +## 0.2.0 + +* Support for consuming "indexed" source maps which do not have any remote + sections. See pull request #127. This introduces a minor backwards + incompatibility if you are monkey patching `SourceMapConsumer.prototype` + methods. + +## 0.1.43 + +* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue + #148 for some discussion and issues #150, #151, and #152 for implementations. + +## 0.1.42 + +* Fix an issue where `SourceNode`s from different versions of the source-map + library couldn't be used in conjunction with each other. See issue #142. + +## 0.1.41 + +* Fix a bug with getting the source content of relative sources with a "./" + prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768). + +* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the + column span of each mapping. + +* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find + all generated positions associated with a given original source and line. + +## 0.1.40 + +* Performance improvements for parsing source maps in SourceMapConsumer. + +## 0.1.39 + +* Fix a bug where setting a source's contents to null before any source content + had been set before threw a TypeError. See issue #131. + +## 0.1.38 + +* Fix a bug where finding relative paths from an empty path were creating + absolute paths. See issue #129. + +## 0.1.37 + +* Fix a bug where if the source root was an empty string, relative source paths + would turn into absolute source paths. Issue #124. + +## 0.1.36 + +* Allow the `names` mapping property to be an empty string. Issue #121. + +## 0.1.35 + +* A third optional parameter was added to `SourceNode.fromStringWithSourceMap` + to specify a path that relative sources in the second parameter should be + relative to. Issue #105. + +* If no file property is given to a `SourceMapGenerator`, then the resulting + source map will no longer have a `null` file property. The property will + simply not exist. Issue #104. + +* Fixed a bug where consecutive newlines were ignored in `SourceNode`s. + Issue #116. + +## 0.1.34 + +* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103. + +* Fix bug involving source contents and the + `SourceMapGenerator.prototype.applySourceMap`. Issue #100. + +## 0.1.33 + +* Fix some edge cases surrounding path joining and URL resolution. + +* Add a third parameter for relative path to + `SourceMapGenerator.prototype.applySourceMap`. + +* Fix issues with mappings and EOLs. + +## 0.1.32 + +* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns + (issue 92). + +* Fixed test runner to actually report number of failed tests as its process + exit code. + +* Fixed a typo when reporting bad mappings (issue 87). + +## 0.1.31 + +* Delay parsing the mappings in SourceMapConsumer until queried for a source + location. + +* Support Sass source maps (which at the time of writing deviate from the spec + in small ways) in SourceMapConsumer. + +## 0.1.30 + +* Do not join source root with a source, when the source is a data URI. + +* Extend the test runner to allow running single specific test files at a time. + +* Performance improvements in `SourceNode.prototype.walk` and + `SourceMapConsumer.prototype.eachMapping`. + +* Source map browser builds will now work inside Workers. + +* Better error messages when attempting to add an invalid mapping to a + `SourceMapGenerator`. + +## 0.1.29 + +* Allow duplicate entries in the `names` and `sources` arrays of source maps + (usually from TypeScript) we are parsing. Fixes github issue 72. + +## 0.1.28 + +* Skip duplicate mappings when creating source maps from SourceNode; github + issue 75. + +## 0.1.27 + +* Don't throw an error when the `file` property is missing in SourceMapConsumer, + we don't use it anyway. + +## 0.1.26 + +* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70. + +## 0.1.25 + +* Make compatible with browserify + +## 0.1.24 + +* Fix issue with absolute paths and `file://` URIs. See + https://bugzilla.mozilla.org/show_bug.cgi?id=885597 + +## 0.1.23 + +* Fix issue with absolute paths and sourcesContent, github issue 64. + +## 0.1.22 + +* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21. + +## 0.1.21 + +* Fixed handling of sources that start with a slash so that they are relative to + the source root's host. + +## 0.1.20 + +* Fixed github issue #43: absolute URLs aren't joined with the source root + anymore. + +## 0.1.19 + +* Using Travis CI to run tests. + +## 0.1.18 + +* Fixed a bug in the handling of sourceRoot. + +## 0.1.17 + +* Added SourceNode.fromStringWithSourceMap. + +## 0.1.16 + +* Added missing documentation. + +* Fixed the generating of empty mappings in SourceNode. + +## 0.1.15 + +* Added SourceMapGenerator.applySourceMap. + +## 0.1.14 + +* The sourceRoot is now handled consistently. + +## 0.1.13 + +* Added SourceMapGenerator.fromSourceMap. + +## 0.1.12 + +* SourceNode now generates empty mappings too. + +## 0.1.11 + +* Added name support to SourceNode. + +## 0.1.10 + +* Added sourcesContent support to the customer and generator. diff --git a/libs/events/node_modules/source-map/LICENSE b/libs/events/node_modules/source-map/LICENSE new file mode 100644 index 000000000..ed1b7cf27 --- /dev/null +++ b/libs/events/node_modules/source-map/LICENSE @@ -0,0 +1,28 @@ + +Copyright (c) 2009-2011, Mozilla Foundation and contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the names of the Mozilla Foundation nor the names of project + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libs/events/node_modules/source-map/README.md b/libs/events/node_modules/source-map/README.md new file mode 100644 index 000000000..fea4beb19 --- /dev/null +++ b/libs/events/node_modules/source-map/README.md @@ -0,0 +1,742 @@ +# Source Map + +[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map) + +[![NPM](https://nodei.co/npm/source-map.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/source-map) + +This is a library to generate and consume the source map format +[described here][format]. + +[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit + +## Use with Node + + $ npm install source-map + +## Use on the Web + + + +-------------------------------------------------------------------------------- + + + + + +## Table of Contents + +- [Examples](#examples) + - [Consuming a source map](#consuming-a-source-map) + - [Generating a source map](#generating-a-source-map) + - [With SourceNode (high level API)](#with-sourcenode-high-level-api) + - [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api) +- [API](#api) + - [SourceMapConsumer](#sourcemapconsumer) + - [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap) + - [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans) + - [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition) + - [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition) + - [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition) + - [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources) + - [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing) + - [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order) + - [SourceMapGenerator](#sourcemapgenerator) + - [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap) + - [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer) + - [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping) + - [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent) + - [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath) + - [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring) + - [SourceNode](#sourcenode) + - [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name) + - [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath) + - [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk) + - [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk) + - [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent) + - [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn) + - [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn) + - [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep) + - [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement) + - [SourceNode.prototype.toString()](#sourcenodeprototypetostring) + - [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap) + + + +## Examples + +### Consuming a source map + +```js +var rawSourceMap = { + version: 3, + file: 'min.js', + names: ['bar', 'baz', 'n'], + sources: ['one.js', 'two.js'], + sourceRoot: 'http://example.com/www/js/', + mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA' +}; + +var smc = new SourceMapConsumer(rawSourceMap); + +console.log(smc.sources); +// [ 'http://example.com/www/js/one.js', +// 'http://example.com/www/js/two.js' ] + +console.log(smc.originalPositionFor({ + line: 2, + column: 28 +})); +// { source: 'http://example.com/www/js/two.js', +// line: 2, +// column: 10, +// name: 'n' } + +console.log(smc.generatedPositionFor({ + source: 'http://example.com/www/js/two.js', + line: 2, + column: 10 +})); +// { line: 2, column: 28 } + +smc.eachMapping(function (m) { + // ... +}); +``` + +### Generating a source map + +In depth guide: +[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/) + +#### With SourceNode (high level API) + +```js +function compile(ast) { + switch (ast.type) { + case 'BinaryExpression': + return new SourceNode( + ast.location.line, + ast.location.column, + ast.location.source, + [compile(ast.left), " + ", compile(ast.right)] + ); + case 'Literal': + return new SourceNode( + ast.location.line, + ast.location.column, + ast.location.source, + String(ast.value) + ); + // ... + default: + throw new Error("Bad AST"); + } +} + +var ast = parse("40 + 2", "add.js"); +console.log(compile(ast).toStringWithSourceMap({ + file: 'add.js' +})); +// { code: '40 + 2', +// map: [object SourceMapGenerator] } +``` + +#### With SourceMapGenerator (low level API) + +```js +var map = new SourceMapGenerator({ + file: "source-mapped.js" +}); + +map.addMapping({ + generated: { + line: 10, + column: 35 + }, + source: "foo.js", + original: { + line: 33, + column: 2 + }, + name: "christopher" +}); + +console.log(map.toString()); +// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}' +``` + +## API + +Get a reference to the module: + +```js +// Node.js +var sourceMap = require('source-map'); + +// Browser builds +var sourceMap = window.sourceMap; + +// Inside Firefox +const sourceMap = require("devtools/toolkit/sourcemap/source-map.js"); +``` + +### SourceMapConsumer + +A SourceMapConsumer instance represents a parsed source map which we can query +for information about the original file positions by giving it a file position +in the generated source. + +#### new SourceMapConsumer(rawSourceMap) + +The only parameter is the raw source map (either as a string which can be +`JSON.parse`'d, or an object). According to the spec, source maps have the +following attributes: + +* `version`: Which version of the source map spec this map is following. + +* `sources`: An array of URLs to the original source files. + +* `names`: An array of identifiers which can be referenced by individual + mappings. + +* `sourceRoot`: Optional. The URL root from which all sources are relative. + +* `sourcesContent`: Optional. An array of contents of the original source files. + +* `mappings`: A string of base64 VLQs which contain the actual mappings. + +* `file`: Optional. The generated filename this source map is associated with. + +```js +var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData); +``` + +#### SourceMapConsumer.prototype.computeColumnSpans() + +Compute the last column for each generated mapping. The last column is +inclusive. + +```js +// Before: +consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) +// [ { line: 2, +// column: 1 }, +// { line: 2, +// column: 10 }, +// { line: 2, +// column: 20 } ] + +consumer.computeColumnSpans(); + +// After: +consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) +// [ { line: 2, +// column: 1, +// lastColumn: 9 }, +// { line: 2, +// column: 10, +// lastColumn: 19 }, +// { line: 2, +// column: 20, +// lastColumn: Infinity } ] + +``` + +#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition) + +Returns the original source, line, and column information for the generated +source's line and column positions provided. The only argument is an object with +the following properties: + +* `line`: The line number in the generated source. Line numbers in + this library are 1-based (note that the underlying source map + specification uses 0-based line numbers -- this library handles the + translation). + +* `column`: The column number in the generated source. Column numbers + in this library are 0-based. + +* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or + `SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest + element that is smaller than or greater than the one we are searching for, + respectively, if the exact element cannot be found. Defaults to + `SourceMapConsumer.GREATEST_LOWER_BOUND`. + +and an object is returned with the following properties: + +* `source`: The original source file, or null if this information is not + available. + +* `line`: The line number in the original source, or null if this information is + not available. The line number is 1-based. + +* `column`: The column number in the original source, or null if this + information is not available. The column number is 0-based. + +* `name`: The original identifier, or null if this information is not available. + +```js +consumer.originalPositionFor({ line: 2, column: 10 }) +// { source: 'foo.coffee', +// line: 2, +// column: 2, +// name: null } + +consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 }) +// { source: null, +// line: null, +// column: null, +// name: null } +``` + +#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition) + +Returns the generated line and column information for the original source, +line, and column positions provided. The only argument is an object with +the following properties: + +* `source`: The filename of the original source. + +* `line`: The line number in the original source. The line number is + 1-based. + +* `column`: The column number in the original source. The column + number is 0-based. + +and an object is returned with the following properties: + +* `line`: The line number in the generated source, or null. The line + number is 1-based. + +* `column`: The column number in the generated source, or null. The + column number is 0-based. + +```js +consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 }) +// { line: 1, +// column: 56 } +``` + +#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition) + +Returns all generated line and column information for the original source, line, +and column provided. If no column is provided, returns all mappings +corresponding to a either the line we are searching for or the next closest line +that has any mappings. Otherwise, returns all mappings corresponding to the +given line and either the column we are searching for or the next closest column +that has any offsets. + +The only argument is an object with the following properties: + +* `source`: The filename of the original source. + +* `line`: The line number in the original source. The line number is + 1-based. + +* `column`: Optional. The column number in the original source. The + column number is 0-based. + +and an array of objects is returned, each with the following properties: + +* `line`: The line number in the generated source, or null. The line + number is 1-based. + +* `column`: The column number in the generated source, or null. The + column number is 0-based. + +```js +consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" }) +// [ { line: 2, +// column: 1 }, +// { line: 2, +// column: 10 }, +// { line: 2, +// column: 20 } ] +``` + +#### SourceMapConsumer.prototype.hasContentsOfAllSources() + +Return true if we have the embedded source content for every source listed in +the source map, false otherwise. + +In other words, if this method returns `true`, then +`consumer.sourceContentFor(s)` will succeed for every source `s` in +`consumer.sources`. + +```js +// ... +if (consumer.hasContentsOfAllSources()) { + consumerReadyCallback(consumer); +} else { + fetchSources(consumer, consumerReadyCallback); +} +// ... +``` + +#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing]) + +Returns the original source content for the source provided. The only +argument is the URL of the original source file. + +If the source content for the given source is not found, then an error is +thrown. Optionally, pass `true` as the second param to have `null` returned +instead. + +```js +consumer.sources +// [ "my-cool-lib.clj" ] + +consumer.sourceContentFor("my-cool-lib.clj") +// "..." + +consumer.sourceContentFor("this is not in the source map"); +// Error: "this is not in the source map" is not in the source map + +consumer.sourceContentFor("this is not in the source map", true); +// null +``` + +#### SourceMapConsumer.prototype.eachMapping(callback, context, order) + +Iterate over each mapping between an original source/line/column and a +generated line/column in this source map. + +* `callback`: The function that is called with each mapping. Mappings have the + form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, + name }` + +* `context`: Optional. If specified, this object will be the value of `this` + every time that `callback` is called. + +* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or + `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over + the mappings sorted by the generated file's line/column order or the + original's source/line/column order, respectively. Defaults to + `SourceMapConsumer.GENERATED_ORDER`. + +```js +consumer.eachMapping(function (m) { console.log(m); }) +// ... +// { source: 'illmatic.js', +// generatedLine: 1, +// generatedColumn: 0, +// originalLine: 1, +// originalColumn: 0, +// name: null } +// { source: 'illmatic.js', +// generatedLine: 2, +// generatedColumn: 0, +// originalLine: 2, +// originalColumn: 0, +// name: null } +// ... +``` +### SourceMapGenerator + +An instance of the SourceMapGenerator represents a source map which is being +built incrementally. + +#### new SourceMapGenerator([startOfSourceMap]) + +You may pass an object with the following properties: + +* `file`: The filename of the generated source that this source map is + associated with. + +* `sourceRoot`: A root for all relative URLs in this source map. + +* `skipValidation`: Optional. When `true`, disables validation of mappings as + they are added. This can improve performance but should be used with + discretion, as a last resort. Even then, one should avoid using this flag when + running tests, if possible. + +```js +var generator = new sourceMap.SourceMapGenerator({ + file: "my-generated-javascript-file.js", + sourceRoot: "http://example.com/app/js/" +}); +``` + +#### SourceMapGenerator.fromSourceMap(sourceMapConsumer) + +Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance. + +* `sourceMapConsumer` The SourceMap. + +```js +var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer); +``` + +#### SourceMapGenerator.prototype.addMapping(mapping) + +Add a single mapping from original source line and column to the generated +source's line and column for this source map being created. The mapping object +should have the following properties: + +* `generated`: An object with the generated line and column positions. + +* `original`: An object with the original line and column positions. + +* `source`: The original source file (relative to the sourceRoot). + +* `name`: An optional original token name for this mapping. + +```js +generator.addMapping({ + source: "module-one.scm", + original: { line: 128, column: 0 }, + generated: { line: 3, column: 456 } +}) +``` + +#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent) + +Set the source content for an original source file. + +* `sourceFile` the URL of the original source file. + +* `sourceContent` the content of the source file. + +```js +generator.setSourceContent("module-one.scm", + fs.readFileSync("path/to/module-one.scm")) +``` + +#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]]) + +Applies a SourceMap for a source file to the SourceMap. +Each mapping to the supplied source file is rewritten using the +supplied SourceMap. Note: The resolution for the resulting mappings +is the minimum of this map and the supplied map. + +* `sourceMapConsumer`: The SourceMap to be applied. + +* `sourceFile`: Optional. The filename of the source file. + If omitted, sourceMapConsumer.file will be used, if it exists. + Otherwise an error will be thrown. + +* `sourceMapPath`: Optional. The dirname of the path to the SourceMap + to be applied. If relative, it is relative to the SourceMap. + + This parameter is needed when the two SourceMaps aren't in the same + directory, and the SourceMap to be applied contains relative source + paths. If so, those relative source paths need to be rewritten + relative to the SourceMap. + + If omitted, it is assumed that both SourceMaps are in the same directory, + thus not needing any rewriting. (Supplying `'.'` has the same effect.) + +#### SourceMapGenerator.prototype.toString() + +Renders the source map being generated to a string. + +```js +generator.toString() +// '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}' +``` + +### SourceNode + +SourceNodes provide a way to abstract over interpolating and/or concatenating +snippets of generated JavaScript source code, while maintaining the line and +column information associated between those snippets and the original source +code. This is useful as the final intermediate representation a compiler might +use before outputting the generated JS and source map. + +#### new SourceNode([line, column, source[, chunk[, name]]]) + +* `line`: The original line number associated with this source node, or null if + it isn't associated with an original line. The line number is 1-based. + +* `column`: The original column number associated with this source node, or null + if it isn't associated with an original column. The column number + is 0-based. + +* `source`: The original source's filename; null if no filename is provided. + +* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see + below. + +* `name`: Optional. The original identifier. + +```js +var node = new SourceNode(1, 2, "a.cpp", [ + new SourceNode(3, 4, "b.cpp", "extern int status;\n"), + new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"), + new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"), +]); +``` + +#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath]) + +Creates a SourceNode from generated code and a SourceMapConsumer. + +* `code`: The generated code + +* `sourceMapConsumer` The SourceMap for the generated code + +* `relativePath` The optional path that relative sources in `sourceMapConsumer` + should be relative to. + +```js +var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8")); +var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"), + consumer); +``` + +#### SourceNode.prototype.add(chunk) + +Add a chunk of generated JS to this source node. + +* `chunk`: A string snippet of generated JS code, another instance of + `SourceNode`, or an array where each member is one of those things. + +```js +node.add(" + "); +node.add(otherNode); +node.add([leftHandOperandNode, " + ", rightHandOperandNode]); +``` + +#### SourceNode.prototype.prepend(chunk) + +Prepend a chunk of generated JS to this source node. + +* `chunk`: A string snippet of generated JS code, another instance of + `SourceNode`, or an array where each member is one of those things. + +```js +node.prepend("/** Build Id: f783haef86324gf **/\n\n"); +``` + +#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent) + +Set the source content for a source file. This will be added to the +`SourceMap` in the `sourcesContent` field. + +* `sourceFile`: The filename of the source file + +* `sourceContent`: The content of the source file + +```js +node.setSourceContent("module-one.scm", + fs.readFileSync("path/to/module-one.scm")) +``` + +#### SourceNode.prototype.walk(fn) + +Walk over the tree of JS snippets in this node and its children. The walking +function is called once for each snippet of JS and is passed that snippet and +the its original associated source's line/column location. + +* `fn`: The traversal function. + +```js +var node = new SourceNode(1, 2, "a.js", [ + new SourceNode(3, 4, "b.js", "uno"), + "dos", + [ + "tres", + new SourceNode(5, 6, "c.js", "quatro") + ] +]); + +node.walk(function (code, loc) { console.log("WALK:", code, loc); }) +// WALK: uno { source: 'b.js', line: 3, column: 4, name: null } +// WALK: dos { source: 'a.js', line: 1, column: 2, name: null } +// WALK: tres { source: 'a.js', line: 1, column: 2, name: null } +// WALK: quatro { source: 'c.js', line: 5, column: 6, name: null } +``` + +#### SourceNode.prototype.walkSourceContents(fn) + +Walk over the tree of SourceNodes. The walking function is called for each +source file content and is passed the filename and source content. + +* `fn`: The traversal function. + +```js +var a = new SourceNode(1, 2, "a.js", "generated from a"); +a.setSourceContent("a.js", "original a"); +var b = new SourceNode(1, 2, "b.js", "generated from b"); +b.setSourceContent("b.js", "original b"); +var c = new SourceNode(1, 2, "c.js", "generated from c"); +c.setSourceContent("c.js", "original c"); + +var node = new SourceNode(null, null, null, [a, b, c]); +node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); }) +// WALK: a.js : original a +// WALK: b.js : original b +// WALK: c.js : original c +``` + +#### SourceNode.prototype.join(sep) + +Like `Array.prototype.join` except for SourceNodes. Inserts the separator +between each of this source node's children. + +* `sep`: The separator. + +```js +var lhs = new SourceNode(1, 2, "a.rs", "my_copy"); +var operand = new SourceNode(3, 4, "a.rs", "="); +var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()"); + +var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]); +var joinedNode = node.join(" "); +``` + +#### SourceNode.prototype.replaceRight(pattern, replacement) + +Call `String.prototype.replace` on the very right-most source snippet. Useful +for trimming white space from the end of a source node, etc. + +* `pattern`: The pattern to replace. + +* `replacement`: The thing to replace the pattern with. + +```js +// Trim trailing white space. +node.replaceRight(/\s*$/, ""); +``` + +#### SourceNode.prototype.toString() + +Return the string representation of this source node. Walks over the tree and +concatenates all the various snippets together to one string. + +```js +var node = new SourceNode(1, 2, "a.js", [ + new SourceNode(3, 4, "b.js", "uno"), + "dos", + [ + "tres", + new SourceNode(5, 6, "c.js", "quatro") + ] +]); + +node.toString() +// 'unodostresquatro' +``` + +#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap]) + +Returns the string representation of this tree of source nodes, plus a +SourceMapGenerator which contains all the mappings between the generated and +original sources. + +The arguments are the same as those to `new SourceMapGenerator`. + +```js +var node = new SourceNode(1, 2, "a.js", [ + new SourceNode(3, 4, "b.js", "uno"), + "dos", + [ + "tres", + new SourceNode(5, 6, "c.js", "quatro") + ] +]); + +node.toStringWithSourceMap({ file: "my-output-file.js" }) +// { code: 'unodostresquatro', +// map: [object SourceMapGenerator] } +``` diff --git a/libs/events/node_modules/source-map/lib/array-set.js b/libs/events/node_modules/source-map/lib/array-set.js new file mode 100644 index 000000000..fbd5c81ca --- /dev/null +++ b/libs/events/node_modules/source-map/lib/array-set.js @@ -0,0 +1,121 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var util = require('./util'); +var has = Object.prototype.hasOwnProperty; +var hasNativeMap = typeof Map !== "undefined"; + +/** + * A data structure which is a combination of an array and a set. Adding a new + * member is O(1), testing for membership is O(1), and finding the index of an + * element is O(1). Removing elements from the set is not supported. Only + * strings are supported for membership. + */ +function ArraySet() { + this._array = []; + this._set = hasNativeMap ? new Map() : Object.create(null); +} + +/** + * Static method for creating ArraySet instances from an existing array. + */ +ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { + var set = new ArraySet(); + for (var i = 0, len = aArray.length; i < len; i++) { + set.add(aArray[i], aAllowDuplicates); + } + return set; +}; + +/** + * Return how many unique items are in this ArraySet. If duplicates have been + * added, than those do not count towards the size. + * + * @returns Number + */ +ArraySet.prototype.size = function ArraySet_size() { + return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; +}; + +/** + * Add the given string to this set. + * + * @param String aStr + */ +ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { + var sStr = hasNativeMap ? aStr : util.toSetString(aStr); + var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr); + var idx = this._array.length; + if (!isDuplicate || aAllowDuplicates) { + this._array.push(aStr); + } + if (!isDuplicate) { + if (hasNativeMap) { + this._set.set(aStr, idx); + } else { + this._set[sStr] = idx; + } + } +}; + +/** + * Is the given string a member of this set? + * + * @param String aStr + */ +ArraySet.prototype.has = function ArraySet_has(aStr) { + if (hasNativeMap) { + return this._set.has(aStr); + } else { + var sStr = util.toSetString(aStr); + return has.call(this._set, sStr); + } +}; + +/** + * What is the index of the given string in the array? + * + * @param String aStr + */ +ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { + if (hasNativeMap) { + var idx = this._set.get(aStr); + if (idx >= 0) { + return idx; + } + } else { + var sStr = util.toSetString(aStr); + if (has.call(this._set, sStr)) { + return this._set[sStr]; + } + } + + throw new Error('"' + aStr + '" is not in the set.'); +}; + +/** + * What is the element at the given index? + * + * @param Number aIdx + */ +ArraySet.prototype.at = function ArraySet_at(aIdx) { + if (aIdx >= 0 && aIdx < this._array.length) { + return this._array[aIdx]; + } + throw new Error('No element indexed by ' + aIdx); +}; + +/** + * Returns the array representation of this set (which has the proper indices + * indicated by indexOf). Note that this is a copy of the internal array used + * for storing the members so that no one can mess with internal state. + */ +ArraySet.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); +}; + +exports.ArraySet = ArraySet; diff --git a/libs/events/node_modules/source-map/lib/base64-vlq.js b/libs/events/node_modules/source-map/lib/base64-vlq.js new file mode 100644 index 000000000..612b40401 --- /dev/null +++ b/libs/events/node_modules/source-map/lib/base64-vlq.js @@ -0,0 +1,140 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + * + * Based on the Base 64 VLQ implementation in Closure Compiler: + * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java + * + * Copyright 2011 The Closure Compiler Authors. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var base64 = require('./base64'); + +// A single base 64 digit can contain 6 bits of data. For the base 64 variable +// length quantities we use in the source map spec, the first bit is the sign, +// the next four bits are the actual value, and the 6th bit is the +// continuation bit. The continuation bit tells us whether there are more +// digits in this value following this digit. +// +// Continuation +// | Sign +// | | +// V V +// 101011 + +var VLQ_BASE_SHIFT = 5; + +// binary: 100000 +var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + +// binary: 011111 +var VLQ_BASE_MASK = VLQ_BASE - 1; + +// binary: 100000 +var VLQ_CONTINUATION_BIT = VLQ_BASE; + +/** + * Converts from a two-complement value to a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) + */ +function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; +} + +/** + * Converts to a two-complement value from a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ +function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; +} + +/** + * Returns the base 64 VLQ encoded value. + */ +exports.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; + + var vlq = toVLQSigned(aValue); + + do { + digit = vlq & VLQ_BASE_MASK; + vlq >>>= VLQ_BASE_SHIFT; + if (vlq > 0) { + // There are still more digits in this value, so we must make sure the + // continuation bit is marked. + digit |= VLQ_CONTINUATION_BIT; + } + encoded += base64.encode(digit); + } while (vlq > 0); + + return encoded; +}; + +/** + * Decodes the next base 64 VLQ value from the given string and returns the + * value and the rest of the string via the out parameter. + */ +exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { + var strLen = aStr.length; + var result = 0; + var shift = 0; + var continuation, digit; + + do { + if (aIndex >= strLen) { + throw new Error("Expected more digits in base 64 VLQ value."); + } + + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } + + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); + + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; +}; diff --git a/libs/events/node_modules/source-map/lib/base64.js b/libs/events/node_modules/source-map/lib/base64.js new file mode 100644 index 000000000..8aa86b302 --- /dev/null +++ b/libs/events/node_modules/source-map/lib/base64.js @@ -0,0 +1,67 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + +/** + * Encode an integer in the range of 0 to 63 to a single base 64 digit. + */ +exports.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; + } + throw new TypeError("Must be between 0 and 63: " + number); +}; + +/** + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. + */ +exports.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + + var littleA = 97; // 'a' + var littleZ = 122; // 'z' + + var zero = 48; // '0' + var nine = 57; // '9' + + var plus = 43; // '+' + var slash = 47; // '/' + + var littleOffset = 26; + var numberOffset = 52; + + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); + } + + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } + + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); + } + + // 62: + + if (charCode == plus) { + return 62; + } + + // 63: / + if (charCode == slash) { + return 63; + } + + // Invalid base64 digit. + return -1; +}; diff --git a/libs/events/node_modules/source-map/lib/binary-search.js b/libs/events/node_modules/source-map/lib/binary-search.js new file mode 100644 index 000000000..010ac941e --- /dev/null +++ b/libs/events/node_modules/source-map/lib/binary-search.js @@ -0,0 +1,111 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +exports.GREATEST_LOWER_BOUND = 1; +exports.LEAST_UPPER_BOUND = 2; + +/** + * Recursive implementation of binary search. + * + * @param aLow Indices here and lower do not contain the needle. + * @param aHigh Indices here and higher do not contain the needle. + * @param aNeedle The element being searched for. + * @param aHaystack The non-empty array being searched. + * @param aCompare Function which takes two elements and returns -1, 0, or 1. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + */ +function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { + // This function terminates when one of the following is true: + // + // 1. We find the exact element we are looking for. + // + // 2. We did not find the exact element, but we can return the index of + // the next-closest element. + // + // 3. We did not find the exact element, and there is no next-closest + // element than the one we are searching for, so we return -1. + var mid = Math.floor((aHigh - aLow) / 2) + aLow; + var cmp = aCompare(aNeedle, aHaystack[mid], true); + if (cmp === 0) { + // Found the element we are looking for. + return mid; + } + else if (cmp > 0) { + // Our needle is greater than aHaystack[mid]. + if (aHigh - mid > 1) { + // The element is in the upper half. + return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); + } + + // The exact needle element was not found in this haystack. Determine if + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return aHigh < aHaystack.length ? aHigh : -1; + } else { + return mid; + } + } + else { + // Our needle is less than aHaystack[mid]. + if (mid - aLow > 1) { + // The element is in the lower half. + return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); + } + + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return mid; + } else { + return aLow < 0 ? -1 : aLow; + } + } +} + +/** + * This is an implementation of binary search which will always try and return + * the index of the closest element if there is no exact hit. This is because + * mappings between original and generated line/col pairs are single points, + * and there is an implicit region between each of them, so a miss just means + * that you aren't on the very start of a region. + * + * @param aNeedle The element you are looking for. + * @param aHaystack The array that is being searched. + * @param aCompare A function which takes the needle and an element in the + * array and returns -1, 0, or 1 depending on whether the needle is less + * than, equal to, or greater than the element, respectively. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + */ +exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { + if (aHaystack.length === 0) { + return -1; + } + + var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, + aCompare, aBias || exports.GREATEST_LOWER_BOUND); + if (index < 0) { + return -1; + } + + // We have found either the exact element, or the next-closest element than + // the one we are searching for. However, there may be more than one such + // element. Make sure we always return the smallest of these. + while (index - 1 >= 0) { + if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { + break; + } + --index; + } + + return index; +}; diff --git a/libs/events/node_modules/source-map/lib/mapping-list.js b/libs/events/node_modules/source-map/lib/mapping-list.js new file mode 100644 index 000000000..06d1274a0 --- /dev/null +++ b/libs/events/node_modules/source-map/lib/mapping-list.js @@ -0,0 +1,79 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2014 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var util = require('./util'); + +/** + * Determine whether mappingB is after mappingA with respect to generated + * position. + */ +function generatedPositionAfter(mappingA, mappingB) { + // Optimized for most common case + var lineA = mappingA.generatedLine; + var lineB = mappingB.generatedLine; + var columnA = mappingA.generatedColumn; + var columnB = mappingB.generatedColumn; + return lineB > lineA || lineB == lineA && columnB >= columnA || + util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; +} + +/** + * A data structure to provide a sorted view of accumulated mappings in a + * performance conscious manner. It trades a neglibable overhead in general + * case for a large speedup in case of mappings being added in order. + */ +function MappingList() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; +} + +/** + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. + * + * NOTE: The order of the mappings is NOT guaranteed. + */ +MappingList.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); + }; + +/** + * Add the given source mapping. + * + * @param Object aMapping + */ +MappingList.prototype.add = function MappingList_add(aMapping) { + if (generatedPositionAfter(this._last, aMapping)) { + this._last = aMapping; + this._array.push(aMapping); + } else { + this._sorted = false; + this._array.push(aMapping); + } +}; + +/** + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. + * + * WARNING: This method returns internal data without copying, for + * performance. The return value must NOT be mutated, and should be treated as + * an immutable borrow. If you want to take ownership, you must make your own + * copy. + */ +MappingList.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; +}; + +exports.MappingList = MappingList; diff --git a/libs/events/node_modules/source-map/lib/quick-sort.js b/libs/events/node_modules/source-map/lib/quick-sort.js new file mode 100644 index 000000000..6a7caadbb --- /dev/null +++ b/libs/events/node_modules/source-map/lib/quick-sort.js @@ -0,0 +1,114 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +// It turns out that some (most?) JavaScript engines don't self-host +// `Array.prototype.sort`. This makes sense because C++ will likely remain +// faster than JS when doing raw CPU-intensive sorting. However, when using a +// custom comparator function, calling back and forth between the VM's C++ and +// JIT'd JS is rather slow *and* loses JIT type information, resulting in +// worse generated code for the comparator function than would be optimal. In +// fact, when sorting with a comparator, these costs outweigh the benefits of +// sorting in C++. By using our own JS-implemented Quick Sort (below), we get +// a ~3500ms mean speed-up in `bench/bench.html`. + +/** + * Swap the elements indexed by `x` and `y` in the array `ary`. + * + * @param {Array} ary + * The array. + * @param {Number} x + * The index of the first item. + * @param {Number} y + * The index of the second item. + */ +function swap(ary, x, y) { + var temp = ary[x]; + ary[x] = ary[y]; + ary[y] = temp; +} + +/** + * Returns a random integer within the range `low .. high` inclusive. + * + * @param {Number} low + * The lower bound on the range. + * @param {Number} high + * The upper bound on the range. + */ +function randomIntInRange(low, high) { + return Math.round(low + (Math.random() * (high - low))); +} + +/** + * The Quick Sort algorithm. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + * @param {Number} p + * Start index of the array + * @param {Number} r + * End index of the array + */ +function doQuickSort(ary, comparator, p, r) { + // If our lower bound is less than our upper bound, we (1) partition the + // array into two pieces and (2) recurse on each half. If it is not, this is + // the empty array and our base case. + + if (p < r) { + // (1) Partitioning. + // + // The partitioning chooses a pivot between `p` and `r` and moves all + // elements that are less than or equal to the pivot to the before it, and + // all the elements that are greater than it after it. The effect is that + // once partition is done, the pivot is in the exact place it will be when + // the array is put in sorted order, and it will not need to be moved + // again. This runs in O(n) time. + + // Always choose a random pivot so that an input array which is reverse + // sorted does not cause O(n^2) running time. + var pivotIndex = randomIntInRange(p, r); + var i = p - 1; + + swap(ary, pivotIndex, r); + var pivot = ary[r]; + + // Immediately after `j` is incremented in this loop, the following hold + // true: + // + // * Every element in `ary[p .. i]` is less than or equal to the pivot. + // + // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. + for (var j = p; j < r; j++) { + if (comparator(ary[j], pivot) <= 0) { + i += 1; + swap(ary, i, j); + } + } + + swap(ary, i + 1, j); + var q = i + 1; + + // (2) Recurse on each half. + + doQuickSort(ary, comparator, p, q - 1); + doQuickSort(ary, comparator, q + 1, r); + } +} + +/** + * Sort the given array in-place with the given comparator function. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + */ +exports.quickSort = function (ary, comparator) { + doQuickSort(ary, comparator, 0, ary.length - 1); +}; diff --git a/libs/events/node_modules/source-map/lib/source-map-consumer.js b/libs/events/node_modules/source-map/lib/source-map-consumer.js new file mode 100644 index 000000000..7b99d1da7 --- /dev/null +++ b/libs/events/node_modules/source-map/lib/source-map-consumer.js @@ -0,0 +1,1145 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var util = require('./util'); +var binarySearch = require('./binary-search'); +var ArraySet = require('./array-set').ArraySet; +var base64VLQ = require('./base64-vlq'); +var quickSort = require('./quick-sort').quickSort; + +function SourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL) + : new BasicSourceMapConsumer(sourceMap, aSourceMapURL); +} + +SourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL); +} + +/** + * The version of the source mapping spec that we are consuming. + */ +SourceMapConsumer.prototype._version = 3; + +// `__generatedMappings` and `__originalMappings` are arrays that hold the +// parsed mapping coordinates from the source map's "mappings" attribute. They +// are lazily instantiated, accessed via the `_generatedMappings` and +// `_originalMappings` getters respectively, and we only parse the mappings +// and create these arrays once queried for a source location. We jump through +// these hoops because there can be many thousands of mappings, and parsing +// them is expensive, so we only want to do it if we must. +// +// Each object in the arrays is of the form: +// +// { +// generatedLine: The line number in the generated code, +// generatedColumn: The column number in the generated code, +// source: The path to the original source file that generated this +// chunk of code, +// originalLine: The line number in the original source that +// corresponds to this chunk of generated code, +// originalColumn: The column number in the original source that +// corresponds to this chunk of generated code, +// name: The name of the original symbol which generated this chunk of +// code. +// } +// +// All properties except for `generatedLine` and `generatedColumn` can be +// `null`. +// +// `_generatedMappings` is ordered by the generated positions. +// +// `_originalMappings` is ordered by the original positions. + +SourceMapConsumer.prototype.__generatedMappings = null; +Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { + configurable: true, + enumerable: true, + get: function () { + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__generatedMappings; + } +}); + +SourceMapConsumer.prototype.__originalMappings = null; +Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + configurable: true, + enumerable: true, + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__originalMappings; + } +}); + +SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; + }; + +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +SourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + throw new Error("Subclasses must implement _parseMappings"); + }; + +SourceMapConsumer.GENERATED_ORDER = 1; +SourceMapConsumer.ORIGINAL_ORDER = 2; + +SourceMapConsumer.GREATEST_LOWER_BOUND = 1; +SourceMapConsumer.LEAST_UPPER_BOUND = 2; + +/** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @param Function aCallback + * The function that is called with each mapping. + * @param Object aContext + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param aOrder + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. + */ +SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; + + var mappings; + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + mappings = this._generatedMappings; + break; + case SourceMapConsumer.ORIGINAL_ORDER: + mappings = this._originalMappings; + break; + default: + throw new Error("Unknown order of iteration."); + } + + var sourceRoot = this.sourceRoot; + mappings.map(function (mapping) { + var source = mapping.source === null ? null : this._sources.at(mapping.source); + source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL); + return { + source: source, + generatedLine: mapping.generatedLine, + generatedColumn: mapping.generatedColumn, + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: mapping.name === null ? null : this._names.at(mapping.name) + }; + }, this).forEach(aCallback, context); + }; + +/** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number is 1-based. + * - column: Optional. the column number in the original source. + * The column number is 0-based. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ +SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util.getArg(aArgs, 'line'); + + // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping + // returns the index of the closest mapping less than the needle. By + // setting needle.originalColumn to 0, we thus find the last mapping for + // the given line, provided such a mapping exists. + var needle = { + source: util.getArg(aArgs, 'source'), + originalLine: line, + originalColumn: util.getArg(aArgs, 'column', 0) + }; + + needle.source = this._findSourceIndex(needle.source); + if (needle.source < 0) { + return []; + } + + var mappings = []; + + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we found. Since + // mappings are sorted, this is guaranteed to find all mappings for + // the line we found. + while (mapping && mapping.originalLine === originalLine) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } else { + var originalColumn = mapping.originalColumn; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we were searching for. + // Since mappings are sorted, this is guaranteed to find all mappings for + // the line we are searching for. + while (mapping && + mapping.originalLine === line && + mapping.originalColumn == originalColumn) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } + } + + return mappings; + }; + +exports.SourceMapConsumer = SourceMapConsumer; + +/** + * A BasicSourceMapConsumer instance represents a parsed source map which we can + * query for information about the original file positions by giving it a file + * position in the generated source. + * + * The first parameter is the raw source map (either as a JSON string, or + * already parsed to an object). According to the spec, source maps have the + * following attributes: + * + * - version: Which version of the source map spec this map is following. + * - sources: An array of URLs to the original source files. + * - names: An array of identifiers which can be referrenced by individual mappings. + * - sourceRoot: Optional. The URL root from which all sources are relative. + * - sourcesContent: Optional. An array of contents of the original source files. + * - mappings: A string of base64 VLQs which contain the actual mappings. + * - file: Optional. The generated file this source map is associated with. + * + * Here is an example source map, taken from the source map spec[0]: + * + * { + * version : 3, + * file: "out.js", + * sourceRoot : "", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AA,AB;;ABCDE;" + * } + * + * The second parameter, if given, is a string whose value is the URL + * at which the source map was found. This URL is used to compute the + * sources array. + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + */ +function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + var version = util.getArg(sourceMap, 'version'); + var sources = util.getArg(sourceMap, 'sources'); + // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which + // requires the array) to play nice here. + var names = util.getArg(sourceMap, 'names', []); + var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); + var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); + var mappings = util.getArg(sourceMap, 'mappings'); + var file = util.getArg(sourceMap, 'file', null); + + // Once again, Sass deviates from the spec and supplies the version as a + // string rather than a number, so we use loose equality checking here. + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + if (sourceRoot) { + sourceRoot = util.normalize(sourceRoot); + } + + sources = sources + .map(String) + // Some source maps produce relative source paths like "./foo.js" instead of + // "foo.js". Normalize these first so that future comparisons will succeed. + // See bugzil.la/1090768. + .map(util.normalize) + // Always ensure that absolute sources are internally stored relative to + // the source root, if the source root is absolute. Not doing this would + // be particularly problematic when the source root is a prefix of the + // source (valid, but why??). See github issue #199 and bugzil.la/1188982. + .map(function (source) { + return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) + ? util.relative(sourceRoot, source) + : source; + }); + + // Pass `true` below to allow duplicate names and sources. While source maps + // are intended to be compressed and deduplicated, the TypeScript compiler + // sometimes generates source maps with duplicates in them. See Github issue + // #72 and bugzil.la/889492. + this._names = ArraySet.fromArray(names.map(String), true); + this._sources = ArraySet.fromArray(sources, true); + + this._absoluteSources = this._sources.toArray().map(function (s) { + return util.computeSourceURL(sourceRoot, s, aSourceMapURL); + }); + + this.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this._sourceMapURL = aSourceMapURL; + this.file = file; +} + +BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; + +/** + * Utility function to find the index of a source. Returns -1 if not + * found. + */ +BasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) { + var relativeSource = aSource; + if (this.sourceRoot != null) { + relativeSource = util.relative(this.sourceRoot, relativeSource); + } + + if (this._sources.has(relativeSource)) { + return this._sources.indexOf(relativeSource); + } + + // Maybe aSource is an absolute URL as returned by |sources|. In + // this case we can't simply undo the transform. + var i; + for (i = 0; i < this._absoluteSources.length; ++i) { + if (this._absoluteSources[i] == aSource) { + return i; + } + } + + return -1; +}; + +/** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @param String aSourceMapURL + * The URL at which the source map can be found (optional) + * @returns BasicSourceMapConsumer + */ +BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) { + var smc = Object.create(BasicSourceMapConsumer.prototype); + + var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); + var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); + smc.sourceRoot = aSourceMap._sourceRoot; + smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), + smc.sourceRoot); + smc.file = aSourceMap._file; + smc._sourceMapURL = aSourceMapURL; + smc._absoluteSources = smc._sources.toArray().map(function (s) { + return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL); + }); + + // Because we are modifying the entries (by converting string sources and + // names to indices into the sources and names ArraySets), we have to make + // a copy of the entry or else bad things happen. Shared mutable state + // strikes again! See github issue #191. + + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; + + for (var i = 0, length = generatedMappings.length; i < length; i++) { + var srcMapping = generatedMappings[i]; + var destMapping = new Mapping; + destMapping.generatedLine = srcMapping.generatedLine; + destMapping.generatedColumn = srcMapping.generatedColumn; + + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; + + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); + } + + destGeneratedMappings.push(destMapping); + } + + quickSort(smc.__originalMappings, util.compareByOriginalPositions); + + return smc; + }; + +/** + * The version of the source mapping spec that we are consuming. + */ +BasicSourceMapConsumer.prototype._version = 3; + +/** + * The list of original sources. + */ +Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { + get: function () { + return this._absoluteSources.slice(); + } +}); + +/** + * Provide the JIT with a nice shape / hidden class. + */ +function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; +} + +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +BasicSourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + var generatedLine = 1; + var previousGeneratedColumn = 0; + var previousOriginalLine = 0; + var previousOriginalColumn = 0; + var previousSource = 0; + var previousName = 0; + var length = aStr.length; + var index = 0; + var cachedSegments = {}; + var temp = {}; + var originalMappings = []; + var generatedMappings = []; + var mapping, str, segment, end, value; + + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; + } + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; + + // Because each offset is encoded relative to the previous one, + // many segments often have the same encoding. We can exploit this + // fact by caching the parsed variable length fields of each segment, + // allowing us to avoid a second parse if we encounter the same + // segment again. + for (end = index; end < length; end++) { + if (this._charIsMappingSeparator(aStr, end)) { + break; + } + } + str = aStr.slice(index, end); + + segment = cachedSegments[str]; + if (segment) { + index += str.length; + } else { + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } + + if (segment.length === 2) { + throw new Error('Found a source, but no line and column'); + } + + if (segment.length === 3) { + throw new Error('Found a source and line, but no column'); + } + + cachedSegments[str] = segment; + } + + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; + + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; + + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; + + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; + + if (segment.length > 4) { + // Original name. + mapping.name = previousName + segment[4]; + previousName += segment[4]; + } + } + + generatedMappings.push(mapping); + if (typeof mapping.originalLine === 'number') { + originalMappings.push(mapping); + } + } + } + + quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; + + quickSort(originalMappings, util.compareByOriginalPositions); + this.__originalMappings = originalMappings; + }; + +/** + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. + */ +BasicSourceMapConsumer.prototype._findMapping = + function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, + aColumnName, aComparator, aBias) { + // To return the position we are searching for, we must first find the + // mapping for the given position and then return the opposite position it + // points to. Because the mappings are sorted, we can use binary search to + // find the best mapping. + + if (aNeedle[aLineName] <= 0) { + throw new TypeError('Line must be greater than or equal to 1, got ' + + aNeedle[aLineName]); + } + if (aNeedle[aColumnName] < 0) { + throw new TypeError('Column must be greater than or equal to 0, got ' + + aNeedle[aColumnName]); + } + + return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + }; + +/** + * Compute the last column for each generated mapping. The last column is + * inclusive. + */ +BasicSourceMapConsumer.prototype.computeColumnSpans = + function SourceMapConsumer_computeColumnSpans() { + for (var index = 0; index < this._generatedMappings.length; ++index) { + var mapping = this._generatedMappings[index]; + + // Mappings do not contain a field for the last generated columnt. We + // can come up with an optimistic estimate, however, by assuming that + // mappings are contiguous (i.e. given two consecutive mappings, the + // first mapping ends where the second one starts). + if (index + 1 < this._generatedMappings.length) { + var nextMapping = this._generatedMappings[index + 1]; + + if (mapping.generatedLine === nextMapping.generatedLine) { + mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; + continue; + } + } + + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; + } + }; + +/** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. The line number + * is 1-based. + * - column: The column number in the generated source. The column + * number is 0-based. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. The + * line number is 1-based. + * - column: The column number in the original source, or null. The + * column number is 0-based. + * - name: The original identifier, or null. + */ +BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util.compareByGeneratedPositionsDeflated, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._generatedMappings[index]; + + if (mapping.generatedLine === needle.generatedLine) { + var source = util.getArg(mapping, 'source', null); + if (source !== null) { + source = this._sources.at(source); + source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL); + } + var name = util.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); + } + return { + source: source, + line: util.getArg(mapping, 'originalLine', null), + column: util.getArg(mapping, 'originalColumn', null), + name: name + }; + } + } + + return { + source: null, + line: null, + column: null, + name: null + }; + }; + +/** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ +BasicSourceMapConsumer.prototype.hasContentsOfAllSources = + function BasicSourceMapConsumer_hasContentsOfAllSources() { + if (!this.sourcesContent) { + return false; + } + return this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { return sc == null; }); + }; + +/** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ +BasicSourceMapConsumer.prototype.sourceContentFor = + function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + if (!this.sourcesContent) { + return null; + } + + var index = this._findSourceIndex(aSource); + if (index >= 0) { + return this.sourcesContent[index]; + } + + var relativeSource = aSource; + if (this.sourceRoot != null) { + relativeSource = util.relative(this.sourceRoot, relativeSource); + } + + var url; + if (this.sourceRoot != null + && (url = util.urlParse(this.sourceRoot))) { + // XXX: file:// URIs and absolute paths lead to unexpected behavior for + // many users. We can help them out when they expect file:// URIs to + // behave like it would if they were running a local HTTP server. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. + var fileUriAbsPath = relativeSource.replace(/^file:\/\//, ""); + if (url.scheme == "file" + && this._sources.has(fileUriAbsPath)) { + return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] + } + + if ((!url.path || url.path == "/") + && this._sources.has("/" + relativeSource)) { + return this.sourcesContent[this._sources.indexOf("/" + relativeSource)]; + } + } + + // This function is used recursively from + // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we + // don't want to throw if we can't find the source - we just want to + // return null, so we provide a flag to exit gracefully. + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + relativeSource + '" is not in the SourceMap.'); + } + }; + +/** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number + * is 1-based. + * - column: The column number in the original source. The column + * number is 0-based. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ +BasicSourceMapConsumer.prototype.generatedPositionFor = + function SourceMapConsumer_generatedPositionFor(aArgs) { + var source = util.getArg(aArgs, 'source'); + source = this._findSourceIndex(source); + if (source < 0) { + return { + line: null, + column: null, + lastColumn: null + }; + } + + var needle = { + source: source, + originalLine: util.getArg(aArgs, 'line'), + originalColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (mapping.source === needle.source) { + return { + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }; + } + } + + return { + line: null, + column: null, + lastColumn: null + }; + }; + +exports.BasicSourceMapConsumer = BasicSourceMapConsumer; + +/** + * An IndexedSourceMapConsumer instance represents a parsed source map which + * we can query for information. It differs from BasicSourceMapConsumer in + * that it takes "indexed" source maps (i.e. ones with a "sections" field) as + * input. + * + * The first parameter is a raw source map (either as a JSON string, or already + * parsed to an object). According to the spec for indexed source maps, they + * have the following attributes: + * + * - version: Which version of the source map spec this map is following. + * - file: Optional. The generated file this source map is associated with. + * - sections: A list of section definitions. + * + * Each value under the "sections" field has two fields: + * - offset: The offset into the original specified at which this section + * begins to apply, defined as an object with a "line" and "column" + * field. + * - map: A source map definition. This source map could also be indexed, + * but doesn't have to be. + * + * Instead of the "map" field, it's also possible to have a "url" field + * specifying a URL to retrieve a source map from, but that's currently + * unsupported. + * + * Here's an example source map, taken from the source map spec[0], but + * modified to omit a section which uses the "url" field. + * + * { + * version : 3, + * file: "app.js", + * sections: [{ + * offset: {line:100, column:10}, + * map: { + * version : 3, + * file: "section.js", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AAAA,E;;ABCDE;" + * } + * }], + * } + * + * The second parameter, if given, is a string whose value is the URL + * at which the source map was found. This URL is used to compute the + * sources array. + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + */ +function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + var version = util.getArg(sourceMap, 'version'); + var sections = util.getArg(sourceMap, 'sections'); + + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + this._sources = new ArraySet(); + this._names = new ArraySet(); + + var lastOffset = { + line: -1, + column: 0 + }; + this._sections = sections.map(function (s) { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error('Support for url field in sections not implemented.'); + } + var offset = util.getArg(s, 'offset'); + var offsetLine = util.getArg(offset, 'line'); + var offsetColumn = util.getArg(offset, 'column'); + + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); + } + lastOffset = offset; + + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1 + }, + consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL) + } + }); +} + +IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; + +/** + * The version of the source mapping spec that we are consuming. + */ +IndexedSourceMapConsumer.prototype._version = 3; + +/** + * The list of original sources. + */ +Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { + get: function () { + var sources = []; + for (var i = 0; i < this._sections.length; i++) { + for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { + sources.push(this._sections[i].consumer.sources[j]); + } + } + return sources; + } +}); + +/** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. The line number + * is 1-based. + * - column: The column number in the generated source. The column + * number is 0-based. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. The + * line number is 1-based. + * - column: The column number in the original source, or null. The + * column number is 0-based. + * - name: The original identifier, or null. + */ +IndexedSourceMapConsumer.prototype.originalPositionFor = + function IndexedSourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + // Find the section containing the generated position we're trying to map + // to an original position. + var sectionIndex = binarySearch.search(needle, this._sections, + function(needle, section) { + var cmp = needle.generatedLine - section.generatedOffset.generatedLine; + if (cmp) { + return cmp; + } + + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; + } + + return section.consumer.originalPositionFor({ + line: needle.generatedLine - + (section.generatedOffset.generatedLine - 1), + column: needle.generatedColumn - + (section.generatedOffset.generatedLine === needle.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias + }); + }; + +/** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ +IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = + function IndexedSourceMapConsumer_hasContentsOfAllSources() { + return this._sections.every(function (s) { + return s.consumer.hasContentsOfAllSources(); + }); + }; + +/** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ +IndexedSourceMapConsumer.prototype.sourceContentFor = + function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; + } + } + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + +/** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number + * is 1-based. + * - column: The column number in the original source. The column + * number is 0-based. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ +IndexedSourceMapConsumer.prototype.generatedPositionFor = + function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + // Only consider this section if the requested source is in the list of + // sources of the consumer. + if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) { + continue; + } + var generatedPosition = section.consumer.generatedPositionFor(aArgs); + if (generatedPosition) { + var ret = { + line: generatedPosition.line + + (section.generatedOffset.generatedLine - 1), + column: generatedPosition.column + + (section.generatedOffset.generatedLine === generatedPosition.line + ? section.generatedOffset.generatedColumn - 1 + : 0) + }; + return ret; + } + } + + return { + line: null, + column: null + }; + }; + +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +IndexedSourceMapConsumer.prototype._parseMappings = + function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { + this.__generatedMappings = []; + this.__originalMappings = []; + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + var sectionMappings = section.consumer._generatedMappings; + for (var j = 0; j < sectionMappings.length; j++) { + var mapping = sectionMappings[j]; + + var source = section.consumer._sources.at(mapping.source); + source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL); + this._sources.add(source); + source = this._sources.indexOf(source); + + var name = null; + if (mapping.name) { + name = section.consumer._names.at(mapping.name); + this._names.add(name); + name = this._names.indexOf(name); + } + + // The mappings coming from the consumer for the section have + // generated positions relative to the start of the section, so we + // need to offset them to be relative to the start of the concatenated + // generated file. + var adjustedMapping = { + source: source, + generatedLine: mapping.generatedLine + + (section.generatedOffset.generatedLine - 1), + generatedColumn: mapping.generatedColumn + + (section.generatedOffset.generatedLine === mapping.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: name + }; + + this.__generatedMappings.push(adjustedMapping); + if (typeof adjustedMapping.originalLine === 'number') { + this.__originalMappings.push(adjustedMapping); + } + } + } + + quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); + quickSort(this.__originalMappings, util.compareByOriginalPositions); + }; + +exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; diff --git a/libs/events/node_modules/source-map/lib/source-map-generator.js b/libs/events/node_modules/source-map/lib/source-map-generator.js new file mode 100644 index 000000000..508bcfbbc --- /dev/null +++ b/libs/events/node_modules/source-map/lib/source-map-generator.js @@ -0,0 +1,425 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var base64VLQ = require('./base64-vlq'); +var util = require('./util'); +var ArraySet = require('./array-set').ArraySet; +var MappingList = require('./mapping-list').MappingList; + +/** + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: + * + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. + */ +function SourceMapGenerator(aArgs) { + if (!aArgs) { + aArgs = {}; + } + this._file = util.getArg(aArgs, 'file', null); + this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); + this._skipValidation = util.getArg(aArgs, 'skipValidation', false); + this._sources = new ArraySet(); + this._names = new ArraySet(); + this._mappings = new MappingList(); + this._sourcesContents = null; +} + +SourceMapGenerator.prototype._version = 3; + +/** + * Creates a new SourceMapGenerator based on a SourceMapConsumer + * + * @param aSourceMapConsumer The SourceMap. + */ +SourceMapGenerator.fromSourceMap = + function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { + var sourceRoot = aSourceMapConsumer.sourceRoot; + var generator = new SourceMapGenerator({ + file: aSourceMapConsumer.file, + sourceRoot: sourceRoot + }); + aSourceMapConsumer.eachMapping(function (mapping) { + var newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn + } + }; + + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util.relative(sourceRoot, newMapping.source); + } + + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; + + if (mapping.name != null) { + newMapping.name = mapping.name; + } + } + + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var sourceRelative = sourceFile; + if (sourceRoot !== null) { + sourceRelative = util.relative(sourceRoot, sourceFile); + } + + if (!generator._sources.has(sourceRelative)) { + generator._sources.add(sourceRelative); + } + + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; + }; + +/** + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: + * + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. + */ +SourceMapGenerator.prototype.addMapping = + function SourceMapGenerator_addMapping(aArgs) { + var generated = util.getArg(aArgs, 'generated'); + var original = util.getArg(aArgs, 'original', null); + var source = util.getArg(aArgs, 'source', null); + var name = util.getArg(aArgs, 'name', null); + + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); + } + + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } + } + + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } + + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; + +/** + * Set the source content for a source file. + */ +SourceMapGenerator.prototype.setSourceContent = + function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { + var source = aSourceFile; + if (this._sourceRoot != null) { + source = util.relative(this._sourceRoot, source); + } + + if (aSourceContent != null) { + // Add the source content to the _sourcesContents map. + // Create a new _sourcesContents map if the property is null. + if (!this._sourcesContents) { + this._sourcesContents = Object.create(null); + } + this._sourcesContents[util.toSetString(source)] = aSourceContent; + } else if (this._sourcesContents) { + // Remove the source file from the _sourcesContents map. + // If the _sourcesContents map is empty, set the property to null. + delete this._sourcesContents[util.toSetString(source)]; + if (Object.keys(this._sourcesContents).length === 0) { + this._sourcesContents = null; + } + } + }; + +/** + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. + * + * @param aSourceMapConsumer The source map to be applied. + * @param aSourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param aSourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. + */ +SourceMapGenerator.prototype.applySourceMap = + function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { + var sourceFile = aSourceFile; + // If aSourceFile is omitted, we will use the file property of the SourceMap + if (aSourceFile == null) { + if (aSourceMapConsumer.file == null) { + throw new Error( + 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + + 'or the source map\'s "file" property. Both were omitted.' + ); + } + sourceFile = aSourceMapConsumer.file; + } + var sourceRoot = this._sourceRoot; + // Make "sourceFile" relative if an absolute Url is passed. + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + // Applying the SourceMap can add and remove items from the sources and + // the names array. + var newSources = new ArraySet(); + var newNames = new ArraySet(); + + // Find mappings for the "sourceFile" + this._mappings.unsortedForEach(function (mapping) { + if (mapping.source === sourceFile && mapping.originalLine != null) { + // Check if it can be mapped by the source map, then update the mapping. + var original = aSourceMapConsumer.originalPositionFor({ + line: mapping.originalLine, + column: mapping.originalColumn + }); + if (original.source != null) { + // Copy mapping + mapping.source = original.source; + if (aSourceMapPath != null) { + mapping.source = util.join(aSourceMapPath, mapping.source) + } + if (sourceRoot != null) { + mapping.source = util.relative(sourceRoot, mapping.source); + } + mapping.originalLine = original.line; + mapping.originalColumn = original.column; + if (original.name != null) { + mapping.name = original.name; + } + } + } + + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } + + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } + + }, this); + this._sources = newSources; + this._names = newNames; + + // Copy sourcesContents of applied map. + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aSourceMapPath != null) { + sourceFile = util.join(aSourceMapPath, sourceFile); + } + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + this.setSourceContent(sourceFile, content); + } + }, this); + }; + +/** + * A mapping can have one of the three levels of data: + * + * 1. Just the generated position. + * 2. The Generated position, original position, and original source. + * 3. Generated and original position, original source, as well as a name + * token. + * + * To maintain consistency, we validate that any new mapping being added falls + * in to one of these categories. + */ +SourceMapGenerator.prototype._validateMapping = + function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, + aName) { + // When aOriginal is truthy but has empty values for .line and .column, + // it is most likely a programmer error. In this case we throw a very + // specific error message to try to guide them the right way. + // For example: https://github.com/Polymer/polymer-bundler/pull/519 + if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { + throw new Error( + 'original.line and original.column are not numbers -- you probably meant to omit ' + + 'the original mapping entirely and only map the generated position. If so, pass ' + + 'null for the original mapping instead of an object with empty or null values.' + ); + } + + if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aGenerated.line > 0 && aGenerated.column >= 0 + && !aOriginal && !aSource && !aName) { + // Case 1. + return; + } + else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aOriginal && 'line' in aOriginal && 'column' in aOriginal + && aGenerated.line > 0 && aGenerated.column >= 0 + && aOriginal.line > 0 && aOriginal.column >= 0 + && aSource) { + // Cases 2 and 3. + return; + } + else { + throw new Error('Invalid mapping: ' + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName + })); + } + }; + +/** + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. + */ +SourceMapGenerator.prototype._serializeMappings = + function SourceMapGenerator_serializeMappings() { + var previousGeneratedColumn = 0; + var previousGeneratedLine = 1; + var previousOriginalColumn = 0; + var previousOriginalLine = 0; + var previousName = 0; + var previousSource = 0; + var result = ''; + var next; + var mapping; + var nameIdx; + var sourceIdx; + + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = '' + + if (mapping.generatedLine !== previousGeneratedLine) { + previousGeneratedColumn = 0; + while (mapping.generatedLine !== previousGeneratedLine) { + next += ';'; + previousGeneratedLine++; + } + } + else { + if (i > 0) { + if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + continue; + } + next += ','; + } + } + + next += base64VLQ.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; + + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ.encode(sourceIdx - previousSource); + previousSource = sourceIdx; + + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; + + next += base64VLQ.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; + + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ.encode(nameIdx - previousName); + previousName = nameIdx; + } + } + + result += next; + } + + return result; + }; + +SourceMapGenerator.prototype._generateSourcesContent = + function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { + return aSources.map(function (source) { + if (!this._sourcesContents) { + return null; + } + if (aSourceRoot != null) { + source = util.relative(aSourceRoot, source); + } + var key = util.toSetString(source); + return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) + ? this._sourcesContents[key] + : null; + }, this); + }; + +/** + * Externalize the source map. + */ +SourceMapGenerator.prototype.toJSON = + function SourceMapGenerator_toJSON() { + var map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: this._serializeMappings() + }; + if (this._file != null) { + map.file = this._file; + } + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + } + + return map; + }; + +/** + * Render the source map being generated to a string. + */ +SourceMapGenerator.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; + +exports.SourceMapGenerator = SourceMapGenerator; diff --git a/libs/events/node_modules/source-map/lib/source-node.js b/libs/events/node_modules/source-map/lib/source-node.js new file mode 100644 index 000000000..8bcdbe385 --- /dev/null +++ b/libs/events/node_modules/source-map/lib/source-node.js @@ -0,0 +1,413 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator; +var util = require('./util'); + +// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other +// operating systems these days (capturing the result). +var REGEX_NEWLINE = /(\r?\n)/; + +// Newline character code for charCodeAt() comparisons +var NEWLINE_CODE = 10; + +// Private symbol for identifying `SourceNode`s when multiple versions of +// the source-map library are loaded. This MUST NOT CHANGE across +// versions! +var isSourceNode = "$$$isSourceNode$$$"; + +/** + * SourceNodes provide a way to abstract over interpolating/concatenating + * snippets of generated JavaScript source code while maintaining the line and + * column information associated with the original source code. + * + * @param aLine The original line number. + * @param aColumn The original column number. + * @param aSource The original source's filename. + * @param aChunks Optional. An array of strings which are snippets of + * generated JS, or other SourceNodes. + * @param aName The original identifier. + */ +function SourceNode(aLine, aColumn, aSource, aChunks, aName) { + this.children = []; + this.sourceContents = {}; + this.line = aLine == null ? null : aLine; + this.column = aColumn == null ? null : aColumn; + this.source = aSource == null ? null : aSource; + this.name = aName == null ? null : aName; + this[isSourceNode] = true; + if (aChunks != null) this.add(aChunks); +} + +/** + * Creates a SourceNode from generated code and a SourceMapConsumer. + * + * @param aGeneratedCode The generated code + * @param aSourceMapConsumer The SourceMap for the generated code + * @param aRelativePath Optional. The path that relative sources in the + * SourceMapConsumer should be relative to. + */ +SourceNode.fromStringWithSourceMap = + function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + // The SourceNode we want to fill with the generated code + // and the SourceMap + var node = new SourceNode(); + + // All even indices of this array are one line of the generated code, + // while all odd indices are the newlines between two adjacent lines + // (since `REGEX_NEWLINE` captures its match). + // Processed fragments are accessed by calling `shiftNextLine`. + var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); + var remainingLinesIndex = 0; + var shiftNextLine = function() { + var lineContents = getNextLine(); + // The last line of a file might not have a newline. + var newLine = getNextLine() || ""; + return lineContents + newLine; + + function getNextLine() { + return remainingLinesIndex < remainingLines.length ? + remainingLines[remainingLinesIndex++] : undefined; + } + }; + + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; + + // The generate SourceNodes we need a code range. + // To extract it current and last mapping is used. + // Here we store the last mapping. + var lastMapping = null; + + aSourceMapConsumer.eachMapping(function (mapping) { + if (lastMapping !== null) { + // We add the code from "lastMapping" to "mapping": + // First check if there is a new line in between. + if (lastGeneratedLine < mapping.generatedLine) { + // Associate first line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + lastGeneratedLine++; + lastGeneratedColumn = 0; + // The remaining code is added without mapping + } else { + // There is no new line in between. + // Associate the code between "lastGeneratedColumn" and + // "mapping.generatedColumn" with "lastMapping" + var nextLine = remainingLines[remainingLinesIndex] || ''; + var code = nextLine.substr(0, mapping.generatedColumn - + lastGeneratedColumn); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - + lastGeneratedColumn); + lastGeneratedColumn = mapping.generatedColumn; + addMappingWithCode(lastMapping, code); + // No more remaining code, continue + lastMapping = mapping; + return; + } + } + // We add the generated code until the first mapping + // to the SourceNode without any mapping. + // Each line is added as separate string. + while (lastGeneratedLine < mapping.generatedLine) { + node.add(shiftNextLine()); + lastGeneratedLine++; + } + if (lastGeneratedColumn < mapping.generatedColumn) { + var nextLine = remainingLines[remainingLinesIndex] || ''; + node.add(nextLine.substr(0, mapping.generatedColumn)); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); + lastGeneratedColumn = mapping.generatedColumn; + } + lastMapping = mapping; + }, this); + // We have processed all mappings. + if (remainingLinesIndex < remainingLines.length) { + if (lastMapping) { + // Associate the remaining code in the current line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + } + // and add the remaining lines without any mapping + node.add(remainingLines.splice(remainingLinesIndex).join("")); + } + + // Copy sourcesContent into SourceNode + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aRelativePath != null) { + sourceFile = util.join(aRelativePath, sourceFile); + } + node.setSourceContent(sourceFile, content); + } + }); + + return node; + + function addMappingWithCode(mapping, code) { + if (mapping === null || mapping.source === undefined) { + node.add(code); + } else { + var source = aRelativePath + ? util.join(aRelativePath, mapping.source) + : mapping.source; + node.add(new SourceNode(mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name)); + } + } + }; + +/** + * Add a chunk of generated JS to this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ +SourceNode.prototype.add = function SourceNode_add(aChunk) { + if (Array.isArray(aChunk)) { + aChunk.forEach(function (chunk) { + this.add(chunk); + }, this); + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + if (aChunk) { + this.children.push(aChunk); + } + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; +}; + +/** + * Add a chunk of generated JS to the beginning of this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ +SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { + if (Array.isArray(aChunk)) { + for (var i = aChunk.length-1; i >= 0; i--) { + this.prepend(aChunk[i]); + } + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + this.children.unshift(aChunk); + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; +}; + +/** + * Walk over the tree of JS snippets in this node and its children. The + * walking function is called once for each snippet of JS and is passed that + * snippet and the its original associated source's line/column location. + * + * @param aFn The traversal function. + */ +SourceNode.prototype.walk = function SourceNode_walk(aFn) { + var chunk; + for (var i = 0, len = this.children.length; i < len; i++) { + chunk = this.children[i]; + if (chunk[isSourceNode]) { + chunk.walk(aFn); + } + else { + if (chunk !== '') { + aFn(chunk, { source: this.source, + line: this.line, + column: this.column, + name: this.name }); + } + } + } +}; + +/** + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. + * + * @param aSep The separator. + */ +SourceNode.prototype.join = function SourceNode_join(aSep) { + var newChildren; + var i; + var len = this.children.length; + if (len > 0) { + newChildren = []; + for (i = 0; i < len-1; i++) { + newChildren.push(this.children[i]); + newChildren.push(aSep); + } + newChildren.push(this.children[i]); + this.children = newChildren; + } + return this; +}; + +/** + * Call String.prototype.replace on the very right-most source snippet. Useful + * for trimming whitespace from the end of a source node, etc. + * + * @param aPattern The pattern to replace. + * @param aReplacement The thing to replace the pattern with. + */ +SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { + var lastChild = this.children[this.children.length - 1]; + if (lastChild[isSourceNode]) { + lastChild.replaceRight(aPattern, aReplacement); + } + else if (typeof lastChild === 'string') { + this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + } + else { + this.children.push(''.replace(aPattern, aReplacement)); + } + return this; +}; + +/** + * Set the source content for a source file. This will be added to the SourceMapGenerator + * in the sourcesContent field. + * + * @param aSourceFile The filename of the source file + * @param aSourceContent The content of the source file + */ +SourceNode.prototype.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; + +/** + * Walk over the tree of SourceNodes. The walking function is called for each + * source file content and is passed the filename and source content. + * + * @param aFn The traversal function. + */ +SourceNode.prototype.walkSourceContents = + function SourceNode_walkSourceContents(aFn) { + for (var i = 0, len = this.children.length; i < len; i++) { + if (this.children[i][isSourceNode]) { + this.children[i].walkSourceContents(aFn); + } + } + + var sources = Object.keys(this.sourceContents); + for (var i = 0, len = sources.length; i < len; i++) { + aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + } + }; + +/** + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. + */ +SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; +}; + +/** + * Returns the string representation of this source node along with a source + * map. + */ +SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { + var generated = { + code: "", + line: 1, + column: 0 + }; + var map = new SourceMapGenerator(aArgs); + var sourceMappingActive = false; + var lastOriginalSource = null; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastOriginalName = null; + this.walk(function (chunk, original) { + generated.code += chunk; + if (original.source !== null + && original.line !== null + && original.column !== null) { + if(lastOriginalSource !== original.source + || lastOriginalLine !== original.line + || lastOriginalColumn !== original.column + || lastOriginalName !== original.name) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + lastOriginalSource = original.source; + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + lastOriginalName = original.name; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping({ + generated: { + line: generated.line, + column: generated.column + } + }); + lastOriginalSource = null; + sourceMappingActive = false; + } + for (var idx = 0, length = chunk.length; idx < length; idx++) { + if (chunk.charCodeAt(idx) === NEWLINE_CODE) { + generated.line++; + generated.column = 0; + // Mappings end at eol + if (idx + 1 === length) { + lastOriginalSource = null; + sourceMappingActive = false; + } else if (sourceMappingActive) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + } else { + generated.column++; + } + } + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); + + return { code: generated.code, map: map }; +}; + +exports.SourceNode = SourceNode; diff --git a/libs/events/node_modules/source-map/lib/util.js b/libs/events/node_modules/source-map/lib/util.js new file mode 100644 index 000000000..3ca92e56f --- /dev/null +++ b/libs/events/node_modules/source-map/lib/util.js @@ -0,0 +1,488 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +/** + * This is a helper function for getting values from parameter/options + * objects. + * + * @param args The object we are extracting values from + * @param name The name of the property we are getting. + * @param defaultValue An optional value to return if the property is missing + * from the object. If this is not specified and the property is missing, an + * error will be thrown. + */ +function getArg(aArgs, aName, aDefaultValue) { + if (aName in aArgs) { + return aArgs[aName]; + } else if (arguments.length === 3) { + return aDefaultValue; + } else { + throw new Error('"' + aName + '" is a required argument.'); + } +} +exports.getArg = getArg; + +var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/; +var dataUrlRegexp = /^data:.+\,.+$/; + +function urlParse(aUrl) { + var match = aUrl.match(urlRegexp); + if (!match) { + return null; + } + return { + scheme: match[1], + auth: match[2], + host: match[3], + port: match[4], + path: match[5] + }; +} +exports.urlParse = urlParse; + +function urlGenerate(aParsedUrl) { + var url = ''; + if (aParsedUrl.scheme) { + url += aParsedUrl.scheme + ':'; + } + url += '//'; + if (aParsedUrl.auth) { + url += aParsedUrl.auth + '@'; + } + if (aParsedUrl.host) { + url += aParsedUrl.host; + } + if (aParsedUrl.port) { + url += ":" + aParsedUrl.port + } + if (aParsedUrl.path) { + url += aParsedUrl.path; + } + return url; +} +exports.urlGenerate = urlGenerate; + +/** + * Normalizes a path, or the path portion of a URL: + * + * - Replaces consecutive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. + * + * Based on code in the Node.js 'path' core module. + * + * @param aPath The path or url to normalize. + */ +function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; + } + path = url.path; + } + var isAbsolute = exports.isAbsolute(path); + + var parts = path.split(/\/+/); + for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { + part = parts[i]; + if (part === '.') { + parts.splice(i, 1); + } else if (part === '..') { + up++; + } else if (up > 0) { + if (part === '') { + // The first part is blank if the path is absolute. Trying to go + // above the root is a no-op. Therefore we can remove all '..' parts + // directly after the root. + parts.splice(i + 1, up); + up = 0; + } else { + parts.splice(i, 2); + up--; + } + } + } + path = parts.join('/'); + + if (path === '') { + path = isAbsolute ? '/' : '.'; + } + + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; +} +exports.normalize = normalize; + +/** + * Joins two paths/URLs. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. + * + * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a + * scheme-relative URL: Then the scheme of aRoot, if any, is prepended + * first. + * - Otherwise aPath is a path. If aRoot is a URL, then its path portion + * is updated with the result and aRoot is returned. Otherwise the result + * is returned. + * - If aPath is absolute, the result is aPath. + * - Otherwise the two paths are joined with a slash. + * - Joining for example 'http://' and 'www.example.com' is also supported. + */ +function join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; + } + + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); + } + + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } + + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } + + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); + + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; +} +exports.join = join; + +exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || urlRegexp.test(aPath); +}; + +/** + * Make a path relative to a URL or another path. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. + */ +function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + + aRoot = aRoot.replace(/\/$/, ''); + + // It is possible for the path to be above the root. In this case, simply + // checking whether the root is a prefix of the path won't work. Instead, we + // need to remove components from the root one by one, until either we find + // a prefix that fits, or we run out of components to remove. + var level = 0; + while (aPath.indexOf(aRoot + '/') !== 0) { + var index = aRoot.lastIndexOf("/"); + if (index < 0) { + return aPath; + } + + // If the only part of the root that is left is the scheme (i.e. http://, + // file:///, etc.), one or more slashes (/), or simply nothing at all, we + // have exhausted all components, so the path is not relative to the root. + aRoot = aRoot.slice(0, index); + if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { + return aPath; + } + + ++level; + } + + // Make sure we add a "../" for each component we removed from the root. + return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); +} +exports.relative = relative; + +var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); +}()); + +function identity (s) { + return s; +} + +/** + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. + * + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 + * + * @param String aStr + */ +function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } + + return aStr; +} +exports.toSetString = supportsNullProto ? identity : toSetString; + +function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } + + return aStr; +} +exports.fromSetString = supportsNullProto ? identity : fromSetString; + +function isProtoString(s) { + if (!s) { + return false; + } + + var length = s.length; + + if (length < 9 /* "__proto__".length */) { + return false; + } + + if (s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */) { + return false; + } + + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; + } + } + + return true; +} + +/** + * Comparator between two mappings where the original positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same original source/line/column, but different generated + * line and column the same. Useful when searching for a mapping with a + * stubbed out mapping. + */ +function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); +} +exports.compareByOriginalPositions = compareByOriginalPositions; + +/** + * Comparator between two mappings with deflated source and name indices where + * the generated positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same generated line and column, but different + * source/name/original line and column the same. Useful when searching for a + * mapping with a stubbed out mapping. + */ +function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); +} +exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + +function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; + } + + if (aStr1 === null) { + return 1; // aStr2 !== null + } + + if (aStr2 === null) { + return -1; // aStr1 !== null + } + + if (aStr1 > aStr2) { + return 1; + } + + return -1; +} + +/** + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. + */ +function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); +} +exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; + +/** + * Strip any JSON XSSI avoidance prefix from the string (as documented + * in the source maps specification), and then parse the string as + * JSON. + */ +function parseSourceMapInput(str) { + return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, '')); +} +exports.parseSourceMapInput = parseSourceMapInput; + +/** + * Compute the URL of a source given the the source root, the source's + * URL, and the source map's URL. + */ +function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) { + sourceURL = sourceURL || ''; + + if (sourceRoot) { + // This follows what Chrome does. + if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') { + sourceRoot += '/'; + } + // The spec says: + // Line 4: An optional source root, useful for relocating source + // files on a server or removing repeated values in the + // “sources” entry. This value is prepended to the individual + // entries in the “source” field. + sourceURL = sourceRoot + sourceURL; + } + + // Historically, SourceMapConsumer did not take the sourceMapURL as + // a parameter. This mode is still somewhat supported, which is why + // this code block is conditional. However, it's preferable to pass + // the source map URL to SourceMapConsumer, so that this function + // can implement the source URL resolution algorithm as outlined in + // the spec. This block is basically the equivalent of: + // new URL(sourceURL, sourceMapURL).toString() + // ... except it avoids using URL, which wasn't available in the + // older releases of node still supported by this library. + // + // The spec says: + // If the sources are not absolute URLs after prepending of the + // “sourceRoot”, the sources are resolved relative to the + // SourceMap (like resolving script src in a html document). + if (sourceMapURL) { + var parsed = urlParse(sourceMapURL); + if (!parsed) { + throw new Error("sourceMapURL could not be parsed"); + } + if (parsed.path) { + // Strip the last path component, but keep the "/". + var index = parsed.path.lastIndexOf('/'); + if (index >= 0) { + parsed.path = parsed.path.substring(0, index + 1); + } + } + sourceURL = join(urlGenerate(parsed), sourceURL); + } + + return normalize(sourceURL); +} +exports.computeSourceURL = computeSourceURL; diff --git a/libs/events/node_modules/source-map/package.json b/libs/events/node_modules/source-map/package.json new file mode 100644 index 000000000..24663417e --- /dev/null +++ b/libs/events/node_modules/source-map/package.json @@ -0,0 +1,73 @@ +{ + "name": "source-map", + "description": "Generates and consumes source maps", + "version": "0.6.1", + "homepage": "https://github.com/mozilla/source-map", + "author": "Nick Fitzgerald ", + "contributors": [ + "Tobias Koppers ", + "Duncan Beevers ", + "Stephen Crane ", + "Ryan Seddon ", + "Miles Elam ", + "Mihai Bazon ", + "Michael Ficarra ", + "Todd Wolfson ", + "Alexander Solovyov ", + "Felix Gnass ", + "Conrad Irwin ", + "usrbincc ", + "David Glasser ", + "Chase Douglas ", + "Evan Wallace ", + "Heather Arthur ", + "Hugh Kennedy ", + "David Glasser ", + "Simon Lydell ", + "Jmeas Smith ", + "Michael Z Goddard ", + "azu ", + "John Gozde ", + "Adam Kirkton ", + "Chris Montgomery ", + "J. Ryan Stinnett ", + "Jack Herrington ", + "Chris Truter ", + "Daniel Espeset ", + "Jamie Wong ", + "Eddy Bruël ", + "Hawken Rives ", + "Gilad Peleg ", + "djchie ", + "Gary Ye ", + "Nicolas Lalevée " + ], + "repository": { + "type": "git", + "url": "http://github.com/mozilla/source-map.git" + }, + "main": "./source-map.js", + "files": [ + "source-map.js", + "source-map.d.ts", + "lib/", + "dist/source-map.debug.js", + "dist/source-map.js", + "dist/source-map.min.js", + "dist/source-map.min.js.map" + ], + "engines": { + "node": ">=0.10.0" + }, + "license": "BSD-3-Clause", + "scripts": { + "test": "npm run build && node test/run-tests.js", + "build": "webpack --color", + "toc": "doctoc --title '## Table of Contents' README.md && doctoc --title '## Table of Contents' CONTRIBUTING.md" + }, + "devDependencies": { + "doctoc": "^0.15.0", + "webpack": "^1.12.0" + }, + "typings": "source-map" +} diff --git a/libs/events/node_modules/source-map/source-map.d.ts b/libs/events/node_modules/source-map/source-map.d.ts new file mode 100644 index 000000000..8f972b0cf --- /dev/null +++ b/libs/events/node_modules/source-map/source-map.d.ts @@ -0,0 +1,98 @@ +export interface StartOfSourceMap { + file?: string; + sourceRoot?: string; +} + +export interface RawSourceMap extends StartOfSourceMap { + version: string; + sources: string[]; + names: string[]; + sourcesContent?: string[]; + mappings: string; +} + +export interface Position { + line: number; + column: number; +} + +export interface LineRange extends Position { + lastColumn: number; +} + +export interface FindPosition extends Position { + // SourceMapConsumer.GREATEST_LOWER_BOUND or SourceMapConsumer.LEAST_UPPER_BOUND + bias?: number; +} + +export interface SourceFindPosition extends FindPosition { + source: string; +} + +export interface MappedPosition extends Position { + source: string; + name?: string; +} + +export interface MappingItem { + source: string; + generatedLine: number; + generatedColumn: number; + originalLine: number; + originalColumn: number; + name: string; +} + +export class SourceMapConsumer { + static GENERATED_ORDER: number; + static ORIGINAL_ORDER: number; + + static GREATEST_LOWER_BOUND: number; + static LEAST_UPPER_BOUND: number; + + constructor(rawSourceMap: RawSourceMap); + computeColumnSpans(): void; + originalPositionFor(generatedPosition: FindPosition): MappedPosition; + generatedPositionFor(originalPosition: SourceFindPosition): LineRange; + allGeneratedPositionsFor(originalPosition: MappedPosition): Position[]; + hasContentsOfAllSources(): boolean; + sourceContentFor(source: string, returnNullOnMissing?: boolean): string; + eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void; +} + +export interface Mapping { + generated: Position; + original: Position; + source: string; + name?: string; +} + +export class SourceMapGenerator { + constructor(startOfSourceMap?: StartOfSourceMap); + static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator; + addMapping(mapping: Mapping): void; + setSourceContent(sourceFile: string, sourceContent: string): void; + applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void; + toString(): string; +} + +export interface CodeWithSourceMap { + code: string; + map: SourceMapGenerator; +} + +export class SourceNode { + constructor(); + constructor(line: number, column: number, source: string); + constructor(line: number, column: number, source: string, chunk?: string, name?: string); + static fromStringWithSourceMap(code: string, sourceMapConsumer: SourceMapConsumer, relativePath?: string): SourceNode; + add(chunk: string): void; + prepend(chunk: string): void; + setSourceContent(sourceFile: string, sourceContent: string): void; + walk(fn: (chunk: string, mapping: MappedPosition) => void): void; + walkSourceContents(fn: (file: string, content: string) => void): void; + join(sep: string): SourceNode; + replaceRight(pattern: string, replacement: string): SourceNode; + toString(): string; + toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap; +} diff --git a/libs/events/node_modules/source-map/source-map.js b/libs/events/node_modules/source-map/source-map.js new file mode 100644 index 000000000..bc88fe820 --- /dev/null +++ b/libs/events/node_modules/source-map/source-map.js @@ -0,0 +1,8 @@ +/* + * Copyright 2009-2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE.txt or: + * http://opensource.org/licenses/BSD-3-Clause + */ +exports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator; +exports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer; +exports.SourceNode = require('./lib/source-node').SourceNode; diff --git a/libs/events/node_modules/to-regex-range/LICENSE b/libs/events/node_modules/to-regex-range/LICENSE new file mode 100644 index 000000000..7cccaf9e3 --- /dev/null +++ b/libs/events/node_modules/to-regex-range/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libs/events/node_modules/to-regex-range/README.md b/libs/events/node_modules/to-regex-range/README.md new file mode 100644 index 000000000..38887dafa --- /dev/null +++ b/libs/events/node_modules/to-regex-range/README.md @@ -0,0 +1,305 @@ +# to-regex-range [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/to-regex-range.svg?style=flat)](https://www.npmjs.com/package/to-regex-range) [![NPM monthly downloads](https://img.shields.io/npm/dm/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![NPM total downloads](https://img.shields.io/npm/dt/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![Linux Build Status](https://img.shields.io/travis/micromatch/to-regex-range.svg?style=flat&label=Travis)](https://travis-ci.org/micromatch/to-regex-range) + +> Pass two numbers, get a regex-compatible source string for matching ranges. Validated against more than 2.78 million test assertions. + +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save to-regex-range +``` + +
    +What does this do? + +
    + +This libary generates the `source` string to be passed to `new RegExp()` for matching a range of numbers. + +**Example** + +```js +const toRegexRange = require('to-regex-range'); +const regex = new RegExp(toRegexRange('15', '95')); +``` + +A string is returned so that you can do whatever you need with it before passing it to `new RegExp()` (like adding `^` or `$` boundaries, defining flags, or combining it another string). + +
    + +
    + +
    +Why use this library? + +
    + +### Convenience + +Creating regular expressions for matching numbers gets deceptively complicated pretty fast. + +For example, let's say you need a validation regex for matching part of a user-id, postal code, social security number, tax id, etc: + +* regex for matching `1` => `/1/` (easy enough) +* regex for matching `1` through `5` => `/[1-5]/` (not bad...) +* regex for matching `1` or `5` => `/(1|5)/` (still easy...) +* regex for matching `1` through `50` => `/([1-9]|[1-4][0-9]|50)/` (uh-oh...) +* regex for matching `1` through `55` => `/([1-9]|[1-4][0-9]|5[0-5])/` (no prob, I can do this...) +* regex for matching `1` through `555` => `/([1-9]|[1-9][0-9]|[1-4][0-9]{2}|5[0-4][0-9]|55[0-5])/` (maybe not...) +* regex for matching `0001` through `5555` => `/(0{3}[1-9]|0{2}[1-9][0-9]|0[1-9][0-9]{2}|[1-4][0-9]{3}|5[0-4][0-9]{2}|55[0-4][0-9]|555[0-5])/` (okay, I get the point!) + +The numbers are contrived, but they're also really basic. In the real world you might need to generate a regex on-the-fly for validation. + +**Learn more** + +If you're interested in learning more about [character classes](http://www.regular-expressions.info/charclass.html) and other regex features, I personally have always found [regular-expressions.info](http://www.regular-expressions.info/charclass.html) to be pretty useful. + +### Heavily tested + +As of April 07, 2019, this library runs [>1m test assertions](./test/test.js) against generated regex-ranges to provide brute-force verification that results are correct. + +Tests run in ~280ms on my MacBook Pro, 2.5 GHz Intel Core i7. + +### Optimized + +Generated regular expressions are optimized: + +* duplicate sequences and character classes are reduced using quantifiers +* smart enough to use `?` conditionals when number(s) or range(s) can be positive or negative +* uses fragment caching to avoid processing the same exact string more than once + +
    + +
    + +## Usage + +Add this library to your javascript application with the following line of code + +```js +const toRegexRange = require('to-regex-range'); +``` + +The main export is a function that takes two integers: the `min` value and `max` value (formatted as strings or numbers). + +```js +const source = toRegexRange('15', '95'); +//=> 1[5-9]|[2-8][0-9]|9[0-5] + +const regex = new RegExp(`^${source}$`); +console.log(regex.test('14')); //=> false +console.log(regex.test('50')); //=> true +console.log(regex.test('94')); //=> true +console.log(regex.test('96')); //=> false +``` + +## Options + +### options.capture + +**Type**: `boolean` + +**Deafault**: `undefined` + +Wrap the returned value in parentheses when there is more than one regex condition. Useful when you're dynamically generating ranges. + +```js +console.log(toRegexRange('-10', '10')); +//=> -[1-9]|-?10|[0-9] + +console.log(toRegexRange('-10', '10', { capture: true })); +//=> (-[1-9]|-?10|[0-9]) +``` + +### options.shorthand + +**Type**: `boolean` + +**Deafault**: `undefined` + +Use the regex shorthand for `[0-9]`: + +```js +console.log(toRegexRange('0', '999999')); +//=> [0-9]|[1-9][0-9]{1,5} + +console.log(toRegexRange('0', '999999', { shorthand: true })); +//=> \d|[1-9]\d{1,5} +``` + +### options.relaxZeros + +**Type**: `boolean` + +**Default**: `true` + +This option relaxes matching for leading zeros when when ranges are zero-padded. + +```js +const source = toRegexRange('-0010', '0010'); +const regex = new RegExp(`^${source}$`); +console.log(regex.test('-10')); //=> true +console.log(regex.test('-010')); //=> true +console.log(regex.test('-0010')); //=> true +console.log(regex.test('10')); //=> true +console.log(regex.test('010')); //=> true +console.log(regex.test('0010')); //=> true +``` + +When `relaxZeros` is false, matching is strict: + +```js +const source = toRegexRange('-0010', '0010', { relaxZeros: false }); +const regex = new RegExp(`^${source}$`); +console.log(regex.test('-10')); //=> false +console.log(regex.test('-010')); //=> false +console.log(regex.test('-0010')); //=> true +console.log(regex.test('10')); //=> false +console.log(regex.test('010')); //=> false +console.log(regex.test('0010')); //=> true +``` + +## Examples + +| **Range** | **Result** | **Compile time** | +| --- | --- | --- | +| `toRegexRange(-10, 10)` | `-[1-9]\|-?10\|[0-9]` | _132μs_ | +| `toRegexRange(-100, -10)` | `-1[0-9]\|-[2-9][0-9]\|-100` | _50μs_ | +| `toRegexRange(-100, 100)` | `-[1-9]\|-?[1-9][0-9]\|-?100\|[0-9]` | _42μs_ | +| `toRegexRange(001, 100)` | `0{0,2}[1-9]\|0?[1-9][0-9]\|100` | _109μs_ | +| `toRegexRange(001, 555)` | `0{0,2}[1-9]\|0?[1-9][0-9]\|[1-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _51μs_ | +| `toRegexRange(0010, 1000)` | `0{0,2}1[0-9]\|0{0,2}[2-9][0-9]\|0?[1-9][0-9]{2}\|1000` | _31μs_ | +| `toRegexRange(1, 50)` | `[1-9]\|[1-4][0-9]\|50` | _24μs_ | +| `toRegexRange(1, 55)` | `[1-9]\|[1-4][0-9]\|5[0-5]` | _23μs_ | +| `toRegexRange(1, 555)` | `[1-9]\|[1-9][0-9]\|[1-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _30μs_ | +| `toRegexRange(1, 5555)` | `[1-9]\|[1-9][0-9]{1,2}\|[1-4][0-9]{3}\|5[0-4][0-9]{2}\|55[0-4][0-9]\|555[0-5]` | _43μs_ | +| `toRegexRange(111, 555)` | `11[1-9]\|1[2-9][0-9]\|[2-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _38μs_ | +| `toRegexRange(29, 51)` | `29\|[34][0-9]\|5[01]` | _24μs_ | +| `toRegexRange(31, 877)` | `3[1-9]\|[4-9][0-9]\|[1-7][0-9]{2}\|8[0-6][0-9]\|87[0-7]` | _32μs_ | +| `toRegexRange(5, 5)` | `5` | _8μs_ | +| `toRegexRange(5, 6)` | `5\|6` | _11μs_ | +| `toRegexRange(1, 2)` | `1\|2` | _6μs_ | +| `toRegexRange(1, 5)` | `[1-5]` | _15μs_ | +| `toRegexRange(1, 10)` | `[1-9]\|10` | _22μs_ | +| `toRegexRange(1, 100)` | `[1-9]\|[1-9][0-9]\|100` | _25μs_ | +| `toRegexRange(1, 1000)` | `[1-9]\|[1-9][0-9]{1,2}\|1000` | _31μs_ | +| `toRegexRange(1, 10000)` | `[1-9]\|[1-9][0-9]{1,3}\|10000` | _34μs_ | +| `toRegexRange(1, 100000)` | `[1-9]\|[1-9][0-9]{1,4}\|100000` | _36μs_ | +| `toRegexRange(1, 1000000)` | `[1-9]\|[1-9][0-9]{1,5}\|1000000` | _42μs_ | +| `toRegexRange(1, 10000000)` | `[1-9]\|[1-9][0-9]{1,6}\|10000000` | _42μs_ | + +## Heads up! + +**Order of arguments** + +When the `min` is larger than the `max`, values will be flipped to create a valid range: + +```js +toRegexRange('51', '29'); +``` + +Is effectively flipped to: + +```js +toRegexRange('29', '51'); +//=> 29|[3-4][0-9]|5[0-1] +``` + +**Steps / increments** + +This library does not support steps (increments). A pr to add support would be welcome. + +## History + +### v2.0.0 - 2017-04-21 + +**New features** + +Adds support for zero-padding! + +### v1.0.0 + +**Optimizations** + +Repeating ranges are now grouped using quantifiers. rocessing time is roughly the same, but the generated regex is much smaller, which should result in faster matching. + +## Attribution + +Inspired by the python library [range-regex](https://github.com/dimka665/range-regex). + +## About + +
    +Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +
    + +
    +Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` + +
    + +
    +Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +$ npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
    + +### Related projects + +You might also be interested in these projects: + +* [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. Used… [more](https://github.com/jonschlinkert/expand-range) | [homepage](https://github.com/jonschlinkert/expand-range "Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. Used by micromatch.") +* [fill-range](https://www.npmjs.com/package/fill-range): Fill in a range of numbers or letters, optionally passing an increment or `step` to… [more](https://github.com/jonschlinkert/fill-range) | [homepage](https://github.com/jonschlinkert/fill-range "Fill in a range of numbers or letters, optionally passing an increment or `step` to use, or create a regex-compatible range with `options.toRegex`") +* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/micromatch/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.") +* [repeat-element](https://www.npmjs.com/package/repeat-element): Create an array by repeating the given value n times. | [homepage](https://github.com/jonschlinkert/repeat-element "Create an array by repeating the given value n times.") +* [repeat-string](https://www.npmjs.com/package/repeat-string): Repeat the given string n times. Fastest implementation for repeating a string. | [homepage](https://github.com/jonschlinkert/repeat-string "Repeat the given string n times. Fastest implementation for repeating a string.") + +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 63 | [jonschlinkert](https://github.com/jonschlinkert) | +| 3 | [doowb](https://github.com/doowb) | +| 2 | [realityking](https://github.com/realityking) | + +### Author + +**Jon Schlinkert** + +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +Please consider supporting me on Patreon, or [start your own Patreon page](https://patreon.com/invite/bxpbvm)! + + + + + +### License + +Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 07, 2019._ \ No newline at end of file diff --git a/libs/events/node_modules/to-regex-range/index.js b/libs/events/node_modules/to-regex-range/index.js new file mode 100644 index 000000000..77fbaced1 --- /dev/null +++ b/libs/events/node_modules/to-regex-range/index.js @@ -0,0 +1,288 @@ +/*! + * to-regex-range + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +const isNumber = require('is-number'); + +const toRegexRange = (min, max, options) => { + if (isNumber(min) === false) { + throw new TypeError('toRegexRange: expected the first argument to be a number'); + } + + if (max === void 0 || min === max) { + return String(min); + } + + if (isNumber(max) === false) { + throw new TypeError('toRegexRange: expected the second argument to be a number.'); + } + + let opts = { relaxZeros: true, ...options }; + if (typeof opts.strictZeros === 'boolean') { + opts.relaxZeros = opts.strictZeros === false; + } + + let relax = String(opts.relaxZeros); + let shorthand = String(opts.shorthand); + let capture = String(opts.capture); + let wrap = String(opts.wrap); + let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; + + if (toRegexRange.cache.hasOwnProperty(cacheKey)) { + return toRegexRange.cache[cacheKey].result; + } + + let a = Math.min(min, max); + let b = Math.max(min, max); + + if (Math.abs(a - b) === 1) { + let result = min + '|' + max; + if (opts.capture) { + return `(${result})`; + } + if (opts.wrap === false) { + return result; + } + return `(?:${result})`; + } + + let isPadded = hasPadding(min) || hasPadding(max); + let state = { min, max, a, b }; + let positives = []; + let negatives = []; + + if (isPadded) { + state.isPadded = isPadded; + state.maxLen = String(state.max).length; + } + + if (a < 0) { + let newMin = b < 0 ? Math.abs(b) : 1; + negatives = splitToPatterns(newMin, Math.abs(a), state, opts); + a = state.a = 0; + } + + if (b >= 0) { + positives = splitToPatterns(a, b, state, opts); + } + + state.negatives = negatives; + state.positives = positives; + state.result = collatePatterns(negatives, positives, opts); + + if (opts.capture === true) { + state.result = `(${state.result})`; + } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { + state.result = `(?:${state.result})`; + } + + toRegexRange.cache[cacheKey] = state; + return state.result; +}; + +function collatePatterns(neg, pos, options) { + let onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; + let onlyPositive = filterPatterns(pos, neg, '', false, options) || []; + let intersected = filterPatterns(neg, pos, '-?', true, options) || []; + let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); + return subpatterns.join('|'); +} + +function splitToRanges(min, max) { + let nines = 1; + let zeros = 1; + + let stop = countNines(min, nines); + let stops = new Set([max]); + + while (min <= stop && stop <= max) { + stops.add(stop); + nines += 1; + stop = countNines(min, nines); + } + + stop = countZeros(max + 1, zeros) - 1; + + while (min < stop && stop <= max) { + stops.add(stop); + zeros += 1; + stop = countZeros(max + 1, zeros) - 1; + } + + stops = [...stops]; + stops.sort(compare); + return stops; +} + +/** + * Convert a range to a regex pattern + * @param {Number} `start` + * @param {Number} `stop` + * @return {String} + */ + +function rangeToPattern(start, stop, options) { + if (start === stop) { + return { pattern: start, count: [], digits: 0 }; + } + + let zipped = zip(start, stop); + let digits = zipped.length; + let pattern = ''; + let count = 0; + + for (let i = 0; i < digits; i++) { + let [startDigit, stopDigit] = zipped[i]; + + if (startDigit === stopDigit) { + pattern += startDigit; + + } else if (startDigit !== '0' || stopDigit !== '9') { + pattern += toCharacterClass(startDigit, stopDigit, options); + + } else { + count++; + } + } + + if (count) { + pattern += options.shorthand === true ? '\\d' : '[0-9]'; + } + + return { pattern, count: [count], digits }; +} + +function splitToPatterns(min, max, tok, options) { + let ranges = splitToRanges(min, max); + let tokens = []; + let start = min; + let prev; + + for (let i = 0; i < ranges.length; i++) { + let max = ranges[i]; + let obj = rangeToPattern(String(start), String(max), options); + let zeros = ''; + + if (!tok.isPadded && prev && prev.pattern === obj.pattern) { + if (prev.count.length > 1) { + prev.count.pop(); + } + + prev.count.push(obj.count[0]); + prev.string = prev.pattern + toQuantifier(prev.count); + start = max + 1; + continue; + } + + if (tok.isPadded) { + zeros = padZeros(max, tok, options); + } + + obj.string = zeros + obj.pattern + toQuantifier(obj.count); + tokens.push(obj); + start = max + 1; + prev = obj; + } + + return tokens; +} + +function filterPatterns(arr, comparison, prefix, intersection, options) { + let result = []; + + for (let ele of arr) { + let { string } = ele; + + // only push if _both_ are negative... + if (!intersection && !contains(comparison, 'string', string)) { + result.push(prefix + string); + } + + // or _both_ are positive + if (intersection && contains(comparison, 'string', string)) { + result.push(prefix + string); + } + } + return result; +} + +/** + * Zip strings + */ + +function zip(a, b) { + let arr = []; + for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); + return arr; +} + +function compare(a, b) { + return a > b ? 1 : b > a ? -1 : 0; +} + +function contains(arr, key, val) { + return arr.some(ele => ele[key] === val); +} + +function countNines(min, len) { + return Number(String(min).slice(0, -len) + '9'.repeat(len)); +} + +function countZeros(integer, zeros) { + return integer - (integer % Math.pow(10, zeros)); +} + +function toQuantifier(digits) { + let [start = 0, stop = ''] = digits; + if (stop || start > 1) { + return `{${start + (stop ? ',' + stop : '')}}`; + } + return ''; +} + +function toCharacterClass(a, b, options) { + return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; +} + +function hasPadding(str) { + return /^-?(0+)\d/.test(str); +} + +function padZeros(value, tok, options) { + if (!tok.isPadded) { + return value; + } + + let diff = Math.abs(tok.maxLen - String(value).length); + let relax = options.relaxZeros !== false; + + switch (diff) { + case 0: + return ''; + case 1: + return relax ? '0?' : '0'; + case 2: + return relax ? '0{0,2}' : '00'; + default: { + return relax ? `0{0,${diff}}` : `0{${diff}}`; + } + } +} + +/** + * Cache + */ + +toRegexRange.cache = {}; +toRegexRange.clearCache = () => (toRegexRange.cache = {}); + +/** + * Expose `toRegexRange` + */ + +module.exports = toRegexRange; diff --git a/libs/events/node_modules/to-regex-range/package.json b/libs/events/node_modules/to-regex-range/package.json new file mode 100644 index 000000000..4ef194f35 --- /dev/null +++ b/libs/events/node_modules/to-regex-range/package.json @@ -0,0 +1,88 @@ +{ + "name": "to-regex-range", + "description": "Pass two numbers, get a regex-compatible source string for matching ranges. Validated against more than 2.78 million test assertions.", + "version": "5.0.1", + "homepage": "https://github.com/micromatch/to-regex-range", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "contributors": [ + "Jon Schlinkert (http://twitter.com/jonschlinkert)", + "Rouven Weßling (www.rouvenwessling.de)" + ], + "repository": "micromatch/to-regex-range", + "bugs": { + "url": "https://github.com/micromatch/to-regex-range/issues" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "main": "index.js", + "engines": { + "node": ">=8.0" + }, + "scripts": { + "test": "mocha" + }, + "dependencies": { + "is-number": "^7.0.0" + }, + "devDependencies": { + "fill-range": "^6.0.0", + "gulp-format-md": "^2.0.0", + "mocha": "^6.0.2", + "text-table": "^0.2.0", + "time-diff": "^0.3.1" + }, + "keywords": [ + "bash", + "date", + "expand", + "expansion", + "expression", + "glob", + "match", + "match date", + "match number", + "match numbers", + "match year", + "matches", + "matching", + "number", + "numbers", + "numerical", + "range", + "ranges", + "regex", + "regexp", + "regular", + "regular expression", + "sequence" + ], + "verb": { + "layout": "default", + "toc": false, + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + }, + "helpers": { + "examples": { + "displayName": "examples" + } + }, + "related": { + "list": [ + "expand-range", + "fill-range", + "micromatch", + "repeat-element", + "repeat-string" + ] + } + } +} diff --git a/libs/events/node_modules/uglify-js/LICENSE b/libs/events/node_modules/uglify-js/LICENSE new file mode 100644 index 000000000..122e8fb97 --- /dev/null +++ b/libs/events/node_modules/uglify-js/LICENSE @@ -0,0 +1,29 @@ +UglifyJS is released under the BSD license: + +Copyright 2012-2019 (c) Mihai Bazon + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/libs/events/node_modules/uglify-js/README.md b/libs/events/node_modules/uglify-js/README.md new file mode 100644 index 000000000..ba5f2a297 --- /dev/null +++ b/libs/events/node_modules/uglify-js/README.md @@ -0,0 +1,1478 @@ +UglifyJS 3 +========== + +UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit. + +#### Note: +- `uglify-js` supports JavaScript and most language features in ECMAScript. +- For more exotic parts of ECMAScript, process your source file with transpilers + like [Babel](https://babeljs.io/) before passing onto `uglify-js`. +- `uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage) + that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS/tree/v2.x). + +Install +------- + +First make sure you have installed the latest version of [node.js](http://nodejs.org/) +(You may need to restart your computer after this step). + +From NPM for use as a command line app: + + npm install uglify-js -g + +From NPM for programmatic use: + + npm install uglify-js + +# Command line usage + + uglifyjs [input files] [options] + +UglifyJS can take multiple input files. It's recommended that you pass the +input files first, then pass the options. UglifyJS will parse input files +in sequence and apply any compression options. The files are parsed in the +same global scope, that is, a reference from a file to some +variable/function declared in another file will be matched properly. + +If no input file is specified, UglifyJS will read from STDIN. + +If you wish to pass your options before the input files, separate the two with +a double dash to prevent input files being used as option arguments: + + uglifyjs --compress --mangle -- input.js + +### Command line options + +``` + -h, --help Print usage information. + `--help options` for details on available options. + -V, --version Print version number. + -p, --parse Specify parser options: + `acorn` Use Acorn for parsing. + `bare_returns` Allow return outside of functions. + Useful when minifying CommonJS + modules and Userscripts that may + be anonymous function wrapped (IIFE) + by the .user.js engine `caller`. + `spidermonkey` Assume input files are SpiderMonkey + AST format (as JSON). + -c, --compress [options] Enable compressor/specify compressor options: + `pure_funcs` List of functions that can be safely + removed when their return values are + not used. + -m, --mangle [options] Mangle names/specify mangler options: + `reserved` List of names that should not be mangled. + --mangle-props [options] Mangle properties/specify mangler options: + `builtins` Mangle property names that overlaps + with standard JavaScript globals. + `debug` Add debug prefix and suffix. + `domprops` Mangle property names that overlaps + with DOM properties. + `keep_quoted` Only mangle unquoted properties. + `regex` Only mangle matched property names. + `reserved` List of names that should not be mangled. + -b, --beautify [options] Beautify output/specify output options: + `beautify` Enabled with `--beautify` by default. + `preamble` Preamble to prepend to the output. You + can use this to insert a comment, for + example for licensing information. + This will not be parsed, but the source + map will adjust for its presence. + `quote_style` Quote style: + 0 - auto + 1 - single + 2 - double + 3 - original + `wrap_iife` Wrap IIFEs in parentheses. Note: you may + want to disable `negate_iife` under + compressor options. + -O, --output-opts [options] Specify output options (`beautify` disabled by default). + -o, --output Output file path (default STDOUT). Specify `ast` or + `spidermonkey` to write UglifyJS or SpiderMonkey AST + as JSON to STDOUT respectively. + --annotations Process and preserve comment annotations. + (`/*@__PURE__*/` or `/*#__PURE__*/`) + --no-annotations Ignore and discard comment annotations. + --comments [filter] Preserve copyright comments in the output. By + default this works like Google Closure, keeping + JSDoc-style comments that contain "@license" or + "@preserve". You can optionally pass one of the + following arguments to this flag: + - "all" to keep all comments + - a valid JS RegExp like `/foo/` or `/^!/` to + keep only matching comments. + Note that currently not *all* comments can be + kept when compression is on, because of dead + code removal or cascading statements into + sequences. + --config-file Read `minify()` options from JSON file. + -d, --define [=value] Global definitions. + -e, --enclose [arg[:value]] Embed everything in a big function, with configurable + argument(s) & value(s). + --expression Parse a single expression, rather than a program + (for parsing JSON). + --ie Support non-standard Internet Explorer. + Equivalent to setting `ie: true` in `minify()` + for `compress`, `mangle` and `output` options. + By default UglifyJS will not try to be IE-proof. + --keep-fargs Do not mangle/drop function arguments. + --keep-fnames Do not mangle/drop function names. Useful for + code relying on Function.prototype.name. + --module Process input as ES module (implies --toplevel) + --name-cache File to hold mangled name mappings. + --self Build UglifyJS as a library (implies --wrap UglifyJS) + --source-map [options] Enable source map/specify source map options: + `base` Path to compute relative paths from input files. + `content` Input source map, useful if you're compressing + JS that was generated from some other original + code. Specify "inline" if the source map is + included within the sources. + `filename` Filename and/or location of the output source + (sets `file` attribute in source map). + `includeSources` Pass this flag if you want to include + the content of source files in the + source map as sourcesContent property. + `names` Include symbol names in the source map. + `root` Path to the original source to be included in + the source map. + `url` If specified, path to the source map to append in + `//# sourceMappingURL`. + --timings Display operations run time on STDERR. + --toplevel Compress and/or mangle variables in top level scope. + --v8 Support non-standard Chrome & Node.js + Equivalent to setting `v8: true` in `minify()` + for `mangle` and `output` options. + By default UglifyJS will not try to be v8-proof. + --verbose Print diagnostic messages. + --warn Print warning messages. + --webkit Support non-standard Safari/Webkit. + Equivalent to setting `webkit: true` in `minify()` + for `compress`, `mangle` and `output` options. + By default UglifyJS will not try to be Safari-proof. + --wrap Embed everything in a big function, making the + “exports” and “global” variables available. You + need to pass an argument to this option to + specify the name that your module will take + when included in, say, a browser. +``` + +Specify `--output` (`-o`) to declare the output file. Otherwise the output +goes to STDOUT. + +## CLI source map options + +UglifyJS can generate a source map file, which is highly useful for +debugging your compressed JavaScript. To get a source map, pass +`--source-map --output output.js` (source map will be written out to +`output.js.map`). + +Additional options: + +- `--source-map "filename=''"` to specify the name of the source map. The value of + `filename` is only used to set `file` attribute (see [the spec][sm-spec]) + in source map file. + +- `--source-map "root=''"` to pass the URL where the original files can be found. + +- `--source-map "names=false"` to omit symbol names if you want to reduce size + of the source map file. + +- `--source-map "url=''"` to specify the URL where the source map can be found. + Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the + `//# sourceMappingURL=` directive. + +For example: + + uglifyjs js/file1.js js/file2.js \ + -o foo.min.js -c -m \ + --source-map "root='http://foo.com/src',url='foo.min.js.map'" + +The above will compress and mangle `file1.js` and `file2.js`, will drop the +output in `foo.min.js` and the source map in `foo.min.js.map`. The source +mapping will refer to `http://foo.com/src/js/file1.js` and +`http://foo.com/src/js/file2.js` (in fact it will list `http://foo.com/src` +as the source map root, and the original files as `js/file1.js` and +`js/file2.js`). + +### Composed source map + +When you're compressing JS code that was output by a compiler such as +CoffeeScript, mapping to the JS code won't be too helpful. Instead, you'd +like to map back to the original code (i.e. CoffeeScript). UglifyJS has an +option to take an input source map. Assuming you have a mapping from +CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript → +compressed JS by mapping every token in the compiled JS to its original +location. + +To use this feature pass `--source-map "content='/path/to/input/source.map'"` +or `--source-map "content=inline"` if the source map is included inline with +the sources. + +## CLI compress options + +You need to pass `--compress` (`-c`) to enable the compressor. Optionally +you can pass a comma-separated list of [compress options](#compress-options). + +Options are in the form `foo=bar`, or just `foo` (the latter implies +a boolean option that you want to set `true`; it's effectively a +shortcut for `foo=true`). + +Example: + + uglifyjs file.js -c toplevel,sequences=false + +## CLI mangle options + +To enable the mangler you need to pass `--mangle` (`-m`). The following +(comma-separated) options are supported: + +- `eval` (default: `false`) — mangle names visible in scopes where `eval` or + `with` are used. + +- `reserved` (default: `[]`) — when mangling is enabled but you want to + prevent certain names from being mangled, you can declare those names with + `--mangle reserved` — pass a comma-separated list of names. For example: + + uglifyjs ... -m reserved=['$','require','exports'] + + to prevent the `require`, `exports` and `$` names from being changed. + +### CLI mangling property names (`--mangle-props`) + +**Note:** THIS WILL PROBABLY BREAK YOUR CODE. Mangling property names +is a separate step, different from variable name mangling. Pass +`--mangle-props` to enable it. It will mangle all properties in the +input code with the exception of built in DOM properties and properties +in core JavaScript classes. For example: + +```javascript +// example.js +var x = { + baz_: 0, + foo_: 1, + calc: function() { + return this.foo_ + this.baz_; + } +}; +x.bar_ = 2; +x["baz_"] = 3; +console.log(x.calc()); +``` +Mangle all properties (except for JavaScript `builtins`): +```bash +$ uglifyjs example.js -c -m --mangle-props +``` +```javascript +var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l()); +``` +Mangle all properties except for `reserved` properties: +```bash +$ uglifyjs example.js -c -m --mangle-props reserved=[foo_,bar_] +``` +```javascript +var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._()); +``` +Mangle all properties matching a `regex`: +```bash +$ uglifyjs example.js -c -m --mangle-props regex=/_$/ +``` +```javascript +var x={o:0,_:1,calc:function(){return this._+this.o}};x.l=2,x.o=3,console.log(x.calc()); +``` + +Combining mangle properties options: +```bash +$ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_] +``` +```javascript +var x={o:0,_:1,calc:function(){return this._+this.o}};x.bar_=2,x.o=3,console.log(x.calc()); +``` + +In order for this to be of any use, we avoid mangling standard JS names by +default (`--mangle-props builtins` to override). + +A default exclusion file is provided in `tools/domprops.json` which should +cover most standard JS and DOM properties defined in various browsers. Pass +`--mangle-props domprops` to disable this feature. + +A regular expression can be used to define which property names should be +mangled. For example, `--mangle-props regex=/^_/` will only mangle property +names that start with an underscore. + +When you compress multiple files using this option, in order for them to +work together in the end we need to ensure somehow that one property gets +mangled to the same name in all of them. For this, pass `--name-cache filename.json` +and UglifyJS will maintain these mappings in a file which can then be reused. +It should be initially empty. Example: + +```bash +$ rm -f /tmp/cache.json # start fresh +$ uglifyjs file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js +$ uglifyjs file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js +``` + +Now, `part1.js` and `part2.js` will be consistent with each other in terms +of mangled property names. + +Using the name cache is not necessary if you compress all your files in a +single call to UglifyJS. + +### Mangling unquoted names (`--mangle-props keep_quoted`) + +Using quoted property name (`o["foo"]`) reserves the property name (`foo`) +so that it is not mangled throughout the entire script even when used in an +unquoted style (`o.foo`). Example: + +```javascript +// stuff.js +var o = { + "foo": 1, + bar: 3, +}; +o.foo += o.bar; +console.log(o.foo); +``` +```bash +$ uglifyjs stuff.js --mangle-props keep_quoted -c -m +``` +```javascript +var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo); +``` + +If the minified output will be processed again by UglifyJS, consider specifying +`keep_quoted_props` so the same property names are preserved: + +```bash +$ uglifyjs stuff.js --mangle-props keep_quoted -c -m -O keep_quoted_props +``` +```javascript +var o={"foo":1,o:3};o.foo+=o.o,console.log(o.foo); +``` + +### Debugging property name mangling + +You can also pass `--mangle-props debug` in order to mangle property names +without completely obscuring them. For example the property `o.foo` +would mangle to `o._$foo$_` with this option. This allows property mangling +of a large codebase while still being able to debug the code and identify +where mangling is breaking things. + +```bash +$ uglifyjs stuff.js --mangle-props debug -c -m +``` +```javascript +var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_); +``` + +You can also pass a custom suffix using `--mangle-props debug=XYZ`. This would then +mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a +script to identify how a property got mangled. One technique is to pass a +random number on every compile to simulate mangling changing with different +inputs (e.g. as you update the input script with new properties), and to help +identify mistakes like writing mangled keys to storage. + + +# API Reference + +Assuming installation via NPM, you can load UglifyJS in your application +like this: +```javascript +var UglifyJS = require("uglify-js"); +``` + +There is a single high level function, **`minify(code, options)`**, +which will perform all minification [phases](#minify-options) in a configurable +manner. By default `minify()` will enable the options [`compress`](#compress-options) +and [`mangle`](#mangle-options). Example: +```javascript +var code = "function add(first, second) { return first + second; }"; +var result = UglifyJS.minify(code); +console.log(result.error); // runtime error, or `undefined` if no error +console.log(result.code); // minified output: function add(n,d){return n+d} +``` + +You can `minify` more than one JavaScript file at a time by using an object +for the first argument where the keys are file names and the values are source +code: +```javascript +var code = { + "file1.js": "function add(first, second) { return first + second; }", + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}; +var result = UglifyJS.minify(code); +console.log(result.code); +// function add(d,n){return d+n}console.log(add(3,7)); +``` + +The `toplevel` option: +```javascript +var code = { + "file1.js": "function add(first, second) { return first + second; }", + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}; +var options = { toplevel: true }; +var result = UglifyJS.minify(code, options); +console.log(result.code); +// console.log(3+7); +``` + +The `nameCache` option: +```javascript +var options = { + mangle: { + toplevel: true, + }, + nameCache: {} +}; +var result1 = UglifyJS.minify({ + "file1.js": "function add(first, second) { return first + second; }" +}, options); +var result2 = UglifyJS.minify({ + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}, options); +console.log(result1.code); +// function n(n,r){return n+r} +console.log(result2.code); +// console.log(n(3,7)); +``` + +You may persist the name cache to the file system in the following way: +```javascript +var cacheFileName = "/tmp/cache.json"; +var options = { + mangle: { + properties: true, + }, + nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8")) +}; +fs.writeFileSync("part1.js", UglifyJS.minify({ + "file1.js": fs.readFileSync("file1.js", "utf8"), + "file2.js": fs.readFileSync("file2.js", "utf8") +}, options).code, "utf8"); +fs.writeFileSync("part2.js", UglifyJS.minify({ + "file3.js": fs.readFileSync("file3.js", "utf8"), + "file4.js": fs.readFileSync("file4.js", "utf8") +}, options).code, "utf8"); +fs.writeFileSync(cacheFileName, JSON.stringify(options.nameCache), "utf8"); +``` + +An example of a combination of `minify()` options: +```javascript +var code = { + "file1.js": "function add(first, second) { return first + second; }", + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}; +var options = { + toplevel: true, + compress: { + global_defs: { + "@console.log": "alert" + }, + passes: 2 + }, + output: { + beautify: false, + preamble: "/* uglified */" + } +}; +var result = UglifyJS.minify(code, options); +console.log(result.code); +// /* uglified */ +// alert(10);" +``` + +To produce warnings: +```javascript +var code = "function f(){ var u; return 2 + 3; }"; +var options = { warnings: true }; +var result = UglifyJS.minify(code, options); +console.log(result.error); // runtime error, `undefined` in this case +console.log(result.warnings); // [ 'Dropping unused variable u [0:1,18]' ] +console.log(result.code); // function f(){return 5} +``` + +An error example: +```javascript +var result = UglifyJS.minify({"foo.js" : "if (0) else console.log(1);"}); +console.log(JSON.stringify(result.error)); +// {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7} +``` +Note: unlike `uglify-js@2.x`, the `3.x` API does not throw errors. To +achieve a similar effect one could do the following: +```javascript +var result = UglifyJS.minify(code, options); +if (result.error) throw result.error; +``` + +## Minify options + +- `annotations` — pass `false` to ignore all comment annotations and elide them + from output. Useful when, for instance, external tools incorrectly applied + `/*@__PURE__*/` or `/*#__PURE__*/`. Pass `true` to both compress and retain + comment annotations in output to allow for further processing downstream. + +- `compress` (default: `{}`) — pass `false` to skip compressing entirely. + Pass an object to specify custom [compress options](#compress-options). + +- `expression` (default: `false`) — parse as a single expression, e.g. JSON. + +- `ie` (default: `false`) — enable workarounds for Internet Explorer bugs. + +- `keep_fargs` (default: `false`) — pass `true` to prevent discarding or mangling + of function arguments. + +- `keep_fnames` (default: `false`) — pass `true` to prevent discarding or mangling + of function names. Useful for code relying on `Function.prototype.name`. + +- `mangle` (default: `true`) — pass `false` to skip mangling names, or pass + an object to specify [mangle options](#mangle-options) (see below). + + - `mangle.properties` (default: `false`) — a subcategory of the mangle option. + Pass an object to specify custom [mangle property options](#mangle-properties-options). + +- `module` (default: `false`) — set to `true` if you wish to process input as + ES module, i.e. implicit `"use strict";` and support for top-level `await`, + alongside with `toplevel` enabled. + +- `nameCache` (default: `null`) — pass an empty object `{}` or a previously + used `nameCache` object if you wish to cache mangled variable and + property names across multiple invocations of `minify()`. Note: this is + a read/write property. `minify()` will read the name cache state of this + object and update it during minification so that it may be + reused or externally persisted by the user. + +- `output` (default: `null`) — pass an object if you wish to specify + additional [output options](#output-options). The defaults are optimized + for best compression. + +- `parse` (default: `{}`) — pass an object if you wish to specify some + additional [parse options](#parse-options). + +- `sourceMap` (default: `false`) — pass an object if you wish to specify + [source map options](#source-map-options). + +- `toplevel` (default: `false`) — set to `true` if you wish to enable top level + variable and function name mangling and to drop unused variables and functions. + +- `v8` (default: `false`) — enable workarounds for Chrome & Node.js bugs. + +- `warnings` (default: `false`) — pass `true` to return compressor warnings + in `result.warnings`. Use the value `"verbose"` for more detailed warnings. + +- `webkit` (default: `false`) — enable workarounds for Safari/WebKit bugs. + PhantomJS users should set this option to `true`. + +## Minify options structure + +```javascript +{ + parse: { + // parse options + }, + compress: { + // compress options + }, + mangle: { + // mangle options + + properties: { + // mangle property options + } + }, + output: { + // output options + }, + sourceMap: { + // source map options + }, + nameCache: null, // or specify a name cache object + toplevel: false, + warnings: false, +} +``` + +### Source map options + +To generate a source map: +```javascript +var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, { + sourceMap: { + filename: "out.js", + url: "out.js.map" + } +}); +console.log(result.code); // minified output +console.log(result.map); // source map +``` + +Note that the source map is not saved in a file, it's just returned in +`result.map`. The value passed for `sourceMap.url` is only used to set +`//# sourceMappingURL=out.js.map` in `result.code`. The value of +`filename` is only used to set `file` attribute (see [the spec][sm-spec]) +in source map file. + +You can set option `sourceMap.url` to be `"inline"` and source map will +be appended to code. + +You can also specify sourceRoot property to be included in source map: +```javascript +var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, { + sourceMap: { + root: "http://example.com/src", + url: "out.js.map" + } +}); +``` + +If you're compressing compiled JavaScript and have a source map for it, you +can use `sourceMap.content`: +```javascript +var result = UglifyJS.minify({"compiled.js": "compiled code"}, { + sourceMap: { + content: "content from compiled.js.map", + url: "minified.js.map" + } +}); +// same as before, it returns `code` and `map` +``` + +If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.url`. + +If you wish to reduce file size of the source map, set option `sourceMap.names` +to be `false` and all symbol names will be omitted. + +## Parse options + +- `bare_returns` (default: `false`) — support top level `return` statements + +- `html5_comments` (default: `true`) — process HTML comment as workaround for + browsers which do not recognize `` in strings + +- `keep_quoted_props` (default: `false`) — when turned on, prevents stripping + quotes from property names in object literals. + +- `max_line_len` (default: `false`) — maximum line length (for uglified code) + +- `preamble` (default: `null`) — when passed it must be a string and + it will be prepended to the output literally. The source map will + adjust for this text. Can be used to insert a comment containing + licensing information, for example. + +- `preserve_line` (default: `false`) — pass `true` to retain line numbering on + a best effort basis. + +- `quote_keys` (default: `false`) — pass `true` to quote all keys in literal + objects + +- `quote_style` (default: `0`) — preferred quote style for strings (affects + quoted property names and directives as well): + - `0` — prefers double quotes, switches to single quotes when there are + more double quotes in the string itself. `0` is best for gzip size. + - `1` — always use single quotes + - `2` — always use double quotes + - `3` — always use the original quotes + +- `semicolons` (default: `true`) — separate statements with semicolons. If + you pass `false` then whenever possible we will use a newline instead of a + semicolon, leading to more readable output of uglified code (size before + gzip could be smaller; size after gzip insignificantly larger). + +- `shebang` (default: `true`) — preserve shebang `#!` in preamble (bash scripts) + +- `width` (default: `80`) — only takes effect when beautification is on, this + specifies an (orientative) line width that the beautifier will try to + obey. It refers to the width of the line text (excluding indentation). + It doesn't work very well currently, but it does make the code generated + by UglifyJS more readable. + +- `wrap_iife` (default: `false`) — pass `true` to wrap immediately invoked + function expressions. See + [#640](https://github.com/mishoo/UglifyJS/issues/640) for more details. + +# Miscellaneous + +### Keeping copyright notices or other comments + +You can pass `--comments` to retain certain comments in the output. By +default it will keep JSDoc-style comments that contain "@preserve", +"@license" or "@cc_on" (conditional compilation for IE). You can pass +`--comments all` to keep all the comments, or a valid JavaScript regexp to +keep only comments that match this regexp. For example `--comments /^!/` +will keep comments like `/*! Copyright Notice */`. + +Note, however, that there might be situations where comments are lost. For +example: +```javascript +function f() { + /** @preserve Foo Bar */ + function g() { + // this function is never called + } + return something(); +} +``` + +Even though it has "@preserve", the comment will be lost because the inner +function `g` (which is the AST node to which the comment is attached to) is +discarded by the compressor as not referenced. + +The safest comments where to place copyright information (or other info that +needs to be kept in the output) are comments attached to toplevel nodes. + +### The `unsafe` `compress` option + +It enables some transformations that *might* break code logic in certain +contrived cases, but should be fine for most code. You might want to try it +on your own code, it should reduce the minified size. Here's what happens +when this flag is on: + +- `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[ 1, 2, 3 ]` +- `new Object()` → `{}` +- `String(exp)` or `exp.toString()` → `"" + exp` +- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new` + +### Conditional compilation + +You can use the `--define` (`-d`) switch in order to declare global +variables that UglifyJS will assume to be constants (unless defined in +scope). For example if you pass `--define DEBUG=false` then, coupled with +dead code removal UglifyJS will discard the following from the output: +```javascript +if (DEBUG) { + console.log("debug stuff"); +} +``` + +You can specify nested constants in the form of `--define env.DEBUG=false`. + +UglifyJS will warn about the condition being always false and about dropping +unreachable code; for now there is no option to turn off only this specific +warning, you can pass `warnings=false` to turn off *all* warnings. + +Another way of doing that is to declare your globals as constants in a +separate file and include it into the build. For example you can have a +`build/defines.js` file with the following: +```javascript +var DEBUG = false; +var PRODUCTION = true; +// etc. +``` + +and build your code like this: + + uglifyjs build/defines.js js/foo.js js/bar.js... -c + +UglifyJS will notice the constants and, since they cannot be altered, it +will evaluate references to them to the value itself and drop unreachable +code as usual. The build will contain the `const` declarations if you use +them. If you are targeting < ES6 environments which does not support `const`, +using `var` with `reduce_vars` (enabled by default) should suffice. + +### Conditional compilation API + +You can also use conditional compilation via the programmatic API. With the difference that the +property name is `global_defs` and is a compressor property: + +```javascript +var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), { + compress: { + dead_code: true, + global_defs: { + DEBUG: false + } + } +}); +``` + +To replace an identifier with an arbitrary non-constant expression it is +necessary to prefix the `global_defs` key with `"@"` to instruct UglifyJS +to parse the value as an expression: +```javascript +UglifyJS.minify("alert('hello');", { + compress: { + global_defs: { + "@alert": "console.log" + } + } +}).code; +// returns: 'console.log("hello");' +``` + +Otherwise it would be replaced as string literal: +```javascript +UglifyJS.minify("alert('hello');", { + compress: { + global_defs: { + "alert": "console.log" + } + } +}).code; +// returns: '"console.log"("hello");' +``` + +### Using native Uglify AST with `minify()` +```javascript +// example: parse only, produce native Uglify AST + +var result = UglifyJS.minify(code, { + parse: {}, + compress: false, + mangle: false, + output: { + ast: true, + code: false // optional - faster if false + } +}); + +// result.ast contains native Uglify AST +``` +```javascript +// example: accept native Uglify AST input and then compress and mangle +// to produce both code and native AST. + +var result = UglifyJS.minify(ast, { + compress: {}, + mangle: {}, + output: { + ast: true, + code: true // optional - faster if false + } +}); + +// result.ast contains native Uglify AST +// result.code contains the minified code in string form. +``` + +### Working with Uglify AST + +Transversal and transformation of the native AST can be performed through +[`TreeWalker`](https://github.com/mishoo/UglifyJS/blob/master/lib/ast.js) and +[`TreeTransformer`](https://github.com/mishoo/UglifyJS/blob/master/lib/transform.js) +respectively. + +### ESTree / SpiderMonkey AST + +UglifyJS has its own abstract syntax tree format; for +[practical reasons](http://lisperator.net/blog/uglifyjs-why-not-switching-to-spidermonkey-ast/) +we can't easily change to using the SpiderMonkey AST internally. However, +UglifyJS now has a converter which can import a SpiderMonkey AST. + +For example [Acorn][acorn] is a super-fast parser that produces a +SpiderMonkey AST. It has a small CLI utility that parses one file and dumps +the AST in JSON on the standard output. To use UglifyJS to mangle and +compress that: + + acorn file.js | uglifyjs -p spidermonkey -m -c + +The `-p spidermonkey` option tells UglifyJS that all input files are not +JavaScript, but JS code described in SpiderMonkey AST in JSON. Therefore we +don't use our own parser in this case, but just transform that AST into our +internal AST. + +### Use Acorn for parsing + +More for fun, I added the `-p acorn` option which will use Acorn to do all +the parsing. If you pass this option, UglifyJS will `require("acorn")`. + +Acorn is really fast (e.g. 250ms instead of 380ms on some 650K code), but +converting the SpiderMonkey tree that Acorn produces takes another 150ms so +in total it's a bit more than just using UglifyJS's own parser. + +[acorn]: https://github.com/ternjs/acorn +[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k + +### Uglify Fast Minify Mode + +It's not well known, but whitespace removal and symbol mangling accounts +for 95% of the size reduction in minified code for most JavaScript - not +elaborate code transforms. One can simply disable `compress` to speed up +Uglify builds by 3 to 5 times. + +| d3.js | minify size | gzip size | minify time (seconds) | +| --- | ---: | ---: | ---: | +| original | 511,371 | 119,932 | - | +| uglify-js@3.13.0 mangle=false, compress=false | 363,988 | 95,695 | 0.56 | +| uglify-js@3.13.0 mangle=true, compress=false | 253,305 | 81,281 | 0.99 | +| uglify-js@3.13.0 mangle=true, compress=true | 244,436 | 79,854 | 5.30 | + +To enable fast minify mode from the CLI use: +``` +uglifyjs file.js -m +``` +To enable fast minify mode with the API use: +```javascript +UglifyJS.minify(code, { compress: false, mangle: true }); +``` + +### Source maps and debugging + +Various `compress` transforms that simplify, rearrange, inline and remove code +are known to have an adverse effect on debugging with source maps. This is +expected as code is optimized and mappings are often simply not possible as +some code no longer exists. For highest fidelity in source map debugging +disable the Uglify `compress` option and just use `mangle`. + +### Compiler assumptions + +To allow for better optimizations, the compiler makes various assumptions: + +- The code does not rely on preserving its runtime performance characteristics. + Typically uglified code will run faster due to less instructions and easier + inlining, but may be slower on rare occasions for a specific platform, e.g. + see [`reduce_funcs`](#compress-options). +- `.toString()` and `.valueOf()` don't have side effects, and for built-in + objects they have not been overridden. +- `undefined`, `NaN` and `Infinity` have not been externally redefined. +- `arguments.callee`, `arguments.caller` and `Function.prototype.caller` are not used. +- The code doesn't expect the contents of `Function.prototype.toString()` or + `Error.prototype.stack` to be anything in particular. +- Getting and setting properties on a plain object does not cause other side effects + (using `.watch()` or `Proxy`). +- Object properties can be added, removed and modified (not prevented with + `Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`, + `Object.preventExtensions()` or `Object.seal()`). +- If array destructuring is present, index-like properties in `Array.prototype` + have not been overridden: + ```javascript + Object.prototype[0] = 42; + var [ a ] = []; + var { 0: b } = {}; + // 42 undefined + console.log([][0], a); + // 42 42 + console.log({}[0], b); + ``` +- Earlier versions of JavaScript will throw `SyntaxError` with the following: + ```javascript + ({ + p: 42, + get p() {}, + }); + // SyntaxError: Object literal may not have data and accessor property with + // the same name + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Iteration order of keys over an object which contains spread syntax in later + versions of Chrome and Node.js may be altered. +- When `toplevel` is enabled, UglifyJS effectively assumes input code is wrapped + within `function(){ ... }`, thus forbids aliasing of declared global variables: + ```javascript + A = "FAIL"; + var B = "FAIL"; + // can be `global`, `self`, `window` etc. + var top = function() { + return this; + }(); + // "PASS" + top.A = "PASS"; + console.log(A); + // "FAIL" after compress and/or mangle + top.B = "PASS"; + console.log(B); + ``` +- Use of `arguments` alongside destructuring as function parameters, e.g. + `function({}, arguments) {}` will result in `SyntaxError` in earlier versions + of Chrome and Node.js - UglifyJS may modify the input which in turn may + suppress those errors. +- Earlier versions of Chrome and Node.js will throw `ReferenceError` with the + following: + ```javascript + var a; + try { + throw 42; + } catch ({ + [a]: b, + // ReferenceError: a is not defined + }) { + let a; + } + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Later versions of JavaScript will throw `SyntaxError` with the following: + ```javascript + a => { + let a; + }; + // SyntaxError: Identifier 'a' has already been declared + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Later versions of JavaScript will throw `SyntaxError` with the following: + ```javascript + try { + // ... + } catch ({ message: a }) { + var a; + } + // SyntaxError: Identifier 'a' has already been declared + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Some versions of Chrome and Node.js will throw `ReferenceError` with the + following: + ```javascript + console.log(((a, b = function() { + return a; + // ReferenceError: a is not defined + }()) => b)()); + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Some arithmetic operations with `BigInt` may throw `TypeError`: + ```javascript + 1n + 1; + // TypeError: can't convert BigInt to number + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Some versions of JavaScript will throw `SyntaxError` with the + following: + ```javascript + console.log(String.raw`\uFo`); + // SyntaxError: Invalid Unicode escape sequence + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Some versions of JavaScript will throw `SyntaxError` with the + following: + ```javascript + try {} catch (e) { + for (var e of []); + } + // SyntaxError: Identifier 'e' has already been declared + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Some versions of Chrome and Node.js will give incorrect results with the + following: + ```javascript + console.log({ + ...{ + set 42(v) {}, + 42: "PASS", + }, + }); + // Expected: { '42': 'PASS' } + // Actual: { '42': undefined } + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Later versions of JavaScript will throw `SyntaxError` with the following: + ```javascript + var await; + class A { + static p = await; + } + // SyntaxError: Unexpected reserved word + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Later versions of JavaScript will throw `SyntaxError` with the following: + ```javascript + var async; + for (async of []); + // SyntaxError: The left-hand side of a for-of loop may not be 'async'. + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Some versions of Chrome and Node.js will give incorrect results with the + following: + ```javascript + console.log({ + ...console, + get 42() { + return "FAIL"; + }, + [42]: "PASS", + }[42], { + ...console, + get 42() { + return "FAIL"; + }, + 42: "PASS", + }[42]); + // Expected: "PASS PASS" + // Actual: "PASS FAIL" + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Earlier versions of JavaScript will throw `TypeError` with the following: + ```javascript + (function() { + { + const a = "foo"; + } + { + const a = "bar"; + } + })(); + // TypeError: const 'a' has already been declared + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Later versions of Chrome and Node.js will give incorrect results with the + following: + ```javascript + try { + class A { + static 42; + static get 42() {} + } + console.log("PASS"); + } catch (e) { + console.log("FAIL"); + } + // Expected: "PASS" + // Actual: "FAIL" + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Some versions of Chrome and Node.js will give incorrect results with the + following: + ```javascript + (async function(a) { + (function() { + var b = await => console.log("PASS"); + b(); + })(); + })().catch(console.error); + // Expected: "PASS" + // Actual: SyntaxError: Unexpected reserved word + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Later versions of Chrome and Node.js will give incorrect results with the + following: + ```javascript + try { + f(); + function f() { + throw 42; + } + } catch (e) { + console.log(typeof f, e); + } + // Expected: "function 42" + // Actual: "undefined 42" + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Later versions of JavaScript will throw `SyntaxError` with the following: + ```javascript + "use strict"; + console.log(function f() { + return f = "PASS"; + }()); + // Expected: "PASS" + // Actual: TypeError: invalid assignment to const 'f' + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Adobe ExtendScript will give incorrect results with the following: + ```javascript + alert(true ? "PASS" : false ? "FAIL" : null); + // Expected: "PASS" + // Actual: "FAIL" + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Adobe ExtendScript will give incorrect results with the following: + ```javascript + alert(42 ? null ? "FAIL" : "PASS" : "FAIL"); + // Expected: "PASS" + // Actual: SyntaxError: Expected: : + ``` + UglifyJS may modify the input which in turn may suppress those errors. diff --git a/libs/events/node_modules/uglify-js/bin/uglifyjs b/libs/events/node_modules/uglify-js/bin/uglifyjs new file mode 100755 index 000000000..49e5185ea --- /dev/null +++ b/libs/events/node_modules/uglify-js/bin/uglifyjs @@ -0,0 +1,605 @@ +#! /usr/bin/env node +// -*- js -*- + +"use strict"; + +require("../tools/tty"); + +var fs = require("fs"); +var info = require("../package.json"); +var path = require("path"); +var UglifyJS = require("../tools/node"); + +var skip_keys = [ "cname", "fixed", "in_arg", "inlined", "length_read", "parent_scope", "redef", "scope", "unused" ]; +var truthy_keys = [ "optional", "pure", "terminal", "uses_arguments", "uses_eval", "uses_with" ]; + +var files = {}; +var options = {}; +var short_forms = { + b: "beautify", + c: "compress", + d: "define", + e: "enclose", + h: "help", + m: "mangle", + o: "output", + O: "output-opts", + p: "parse", + v: "version", + V: "version", +}; +var args = process.argv.slice(2); +var paths = []; +var output, nameCache; +var specified = {}; +while (args.length) { + var arg = args.shift(); + if (arg[0] != "-") { + paths.push(arg); + } else if (arg == "--") { + paths = paths.concat(args); + break; + } else if (arg[1] == "-") { + process_option(arg.slice(2)); + } else [].forEach.call(arg.slice(1), function(letter, index, arg) { + if (!(letter in short_forms)) fatal("invalid option -" + letter); + process_option(short_forms[letter], index + 1 < arg.length); + }); +} + +function process_option(name, no_value) { + specified[name] = true; + switch (name) { + case "help": + switch (read_value()) { + case "ast": + print(UglifyJS.describe_ast()); + break; + case "options": + var text = []; + var toplevels = []; + var padding = ""; + var defaults = UglifyJS.default_options(); + for (var name in defaults) { + var option = defaults[name]; + if (option && typeof option == "object") { + text.push("--" + ({ + output: "beautify", + sourceMap: "source-map", + }[name] || name) + " options:"); + text.push(format_object(option)); + text.push(""); + } else { + if (padding.length < name.length) padding = Array(name.length + 1).join(" "); + toplevels.push([ { + keep_fargs: "keep-fargs", + keep_fnames: "keep-fnames", + nameCache: "name-cache", + }[name] || name, option ]); + } + } + toplevels.forEach(function(tokens) { + text.push("--" + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]); + }); + print(text.join("\n")); + break; + default: + print([ + "Usage: uglifyjs [files...] [options]", + "", + "Options:", + " -h, --help Print usage information.", + " `--help options` for details on available options.", + " -v, -V, --version Print version number.", + " -p, --parse Specify parser options.", + " -c, --compress [options] Enable compressor/specify compressor options.", + " -m, --mangle [options] Mangle names/specify mangler options.", + " --mangle-props [options] Mangle properties/specify mangler options.", + " -b, --beautify [options] Beautify output/specify output options.", + " -O, --output-opts Output options (beautify disabled).", + " -o, --output Output file (default STDOUT).", + " --annotations Process and preserve comment annotations.", + " --no-annotations Ignore and discard comment annotations.", + " --comments [filter] Preserve copyright comments in the output.", + " --config-file Read minify() options from JSON file.", + " -d, --define [=value] Global definitions.", + " -e, --enclose [arg[,...][:value[,...]]] Embed everything in a big function, with configurable argument(s) & value(s).", + " --expression Parse a single expression, rather than a program.", + " --ie Support non-standard Internet Explorer.", + " --keep-fargs Do not mangle/drop function arguments.", + " --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.", + " --module Process input as ES module (implies --toplevel)", + " --name-cache File to hold mangled name mappings.", + " --rename Force symbol expansion.", + " --no-rename Disable symbol expansion.", + " --self Build UglifyJS as a library (implies --wrap UglifyJS)", + " --source-map [options] Enable source map/specify source map options.", + " --timings Display operations run time on STDERR.", + " --toplevel Compress and/or mangle variables in toplevel scope.", + " --v8 Support non-standard Chrome & Node.js.", + " --validate Perform validation during AST manipulations.", + " --verbose Print diagnostic messages.", + " --warn Print warning messages.", + " --webkit Support non-standard Safari/Webkit.", + " --wrap Embed everything as a function with “exports” corresponding to “name” globally.", + "", + "(internal debug use only)", + " --in-situ Warning: replaces original source files with minified output.", + " --reduce-test Reduce a standalone test case (assumes cloned repository).", + ].join("\n")); + } + process.exit(); + case "version": + print(info.name + " " + info.version); + process.exit(); + case "config-file": + var config = JSON.parse(read_file(read_value(true))); + if (config.mangle && config.mangle.properties && config.mangle.properties.regex) { + config.mangle.properties.regex = UglifyJS.parse(config.mangle.properties.regex, { + expression: true, + }).value; + } + for (var key in config) if (!(key in options)) options[key] = config[key]; + break; + case "compress": + case "mangle": + options[name] = parse_js(read_value(), options[name]); + break; + case "source-map": + options.sourceMap = parse_js(read_value(), options.sourceMap); + break; + case "enclose": + options[name] = read_value(); + break; + case "annotations": + case "expression": + case "ie": + case "ie8": + case "module": + case "timings": + case "toplevel": + case "v8": + case "validate": + case "webkit": + options[name] = true; + break; + case "no-annotations": + options.annotations = false; + break; + case "keep-fargs": + options.keep_fargs = true; + break; + case "keep-fnames": + options.keep_fnames = true; + break; + case "wrap": + options[name] = read_value(true); + break; + case "verbose": + options.warnings = "verbose"; + break; + case "warn": + if (!options.warnings) options.warnings = true; + break; + case "beautify": + options.output = parse_js(read_value(), options.output); + if (!("beautify" in options.output)) options.output.beautify = true; + break; + case "output-opts": + options.output = parse_js(read_value(true), options.output); + break; + case "comments": + if (typeof options.output != "object") options.output = {}; + options.output.comments = read_value(); + if (options.output.comments === true) options.output.comments = "some"; + break; + case "define": + if (typeof options.compress != "object") options.compress = {}; + options.compress.global_defs = parse_js(read_value(true), options.compress.global_defs, "define"); + break; + case "mangle-props": + if (typeof options.mangle != "object") options.mangle = {}; + options.mangle.properties = parse_js(read_value(), options.mangle.properties); + break; + case "name-cache": + nameCache = read_value(true); + options.nameCache = JSON.parse(read_file(nameCache, "{}")); + break; + case "output": + output = read_value(true); + break; + case "parse": + options.parse = parse_js(read_value(true), options.parse); + break; + case "rename": + options.rename = true; + break; + case "no-rename": + options.rename = false; + break; + case "in-situ": + case "reduce-test": + case "self": + break; + default: + fatal("invalid option --" + name); + } + + function read_value(required) { + if (no_value || !args.length || args[0][0] == "-") { + if (required) fatal("missing option argument for --" + name); + return true; + } + return args.shift(); + } +} +if (!output && options.sourceMap && options.sourceMap.url != "inline") fatal("cannot write source map to STDOUT"); +if (specified["beautify"] && specified["output-opts"]) fatal("--beautify cannot be used with --output-opts"); +[ "compress", "mangle" ].forEach(function(name) { + if (!(name in options)) options[name] = false; +}); +if (/^ast|spidermonkey$/.test(output)) { + if (typeof options.output != "object") options.output = {}; + options.output.ast = true; + options.output.code = false; +} +if (options.parse && (options.parse.acorn || options.parse.spidermonkey) + && options.sourceMap && options.sourceMap.content == "inline") { + fatal("inline source map only works with built-in parser"); +} +if (options.warnings) { + UglifyJS.AST_Node.log_function(print_error, options.warnings == "verbose"); + delete options.warnings; +} +var convert_path = function(name) { + return name; +}; +if (typeof options.sourceMap == "object" && "base" in options.sourceMap) { + convert_path = function() { + var base = options.sourceMap.base; + delete options.sourceMap.base; + return function(name) { + return path.relative(base, name); + }; + }(); +} +if (specified["self"]) { + if (paths.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed"); + if (!options.wrap) options.wrap = "UglifyJS"; + paths = UglifyJS.FILES; +} else if (paths.length) { + paths = simple_glob(paths); +} +if (specified["in-situ"]) { + if (output && output != "spidermonkey" || specified["reduce-test"] || specified["self"]) { + fatal("incompatible options specified"); + } + paths.forEach(function(name) { + print(name); + if (/^ast|spidermonkey$/.test(name)) fatal("invalid file name specified"); + files = {}; + files[convert_path(name)] = read_file(name); + output = name; + run(); + }); +} else if (paths.length) { + paths.forEach(function(name) { + files[convert_path(name)] = read_file(name); + }); + run(); +} else { + var timerId = process.stdin.isTTY && process.argv.length < 3 && setTimeout(function() { + print_error("Waiting for input... (use `--help` to print usage information)"); + }, 1500); + var chunks = []; + process.stdin.setEncoding("utf8"); + process.stdin.once("data", function() { + clearTimeout(timerId); + }).on("data", function(chunk) { + chunks.push(chunk); + }).on("end", function() { + files = { STDIN: chunks.join("") }; + run(); + }); + process.stdin.resume(); +} + +function convert_ast(fn) { + return UglifyJS.AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null)); +} + +function run() { + var content = options.sourceMap && options.sourceMap.content; + if (content && content != "inline") { + UglifyJS.AST_Node.info("Using input source map: {content}", { + content : content, + }); + options.sourceMap.content = read_file(content, content); + } + try { + if (options.parse) { + if (options.parse.acorn) { + var annotations = Object.create(null); + files = convert_ast(function(toplevel, name) { + var content = files[name]; + var list = annotations[name] = []; + var prev = -1; + return require("acorn").parse(content, { + allowHashBang: true, + ecmaVersion: "latest", + locations: true, + onComment: function(block, text, start, end) { + var match = /[@#]__PURE__/.exec(text); + if (!match) { + if (start != prev) return; + match = [ list[prev] ]; + } + while (/\s/.test(content[end])) end++; + list[end] = match[0]; + prev = end; + }, + preserveParens: true, + program: toplevel, + sourceFile: name, + sourceType: "module", + }); + }); + files.walk(new UglifyJS.TreeWalker(function(node) { + if (!(node instanceof UglifyJS.AST_Call)) return; + var list = annotations[node.start.file]; + var pure = list[node.start.pos]; + if (!pure) { + var tokens = node.start.parens; + if (tokens) for (var i = 0; !pure && i < tokens.length; i++) { + pure = list[tokens[i].pos]; + } + } + if (pure) node.pure = pure; + })); + } else if (options.parse.spidermonkey) { + files = convert_ast(function(toplevel, name) { + var obj = JSON.parse(files[name]); + if (!toplevel) return obj; + toplevel.body = toplevel.body.concat(obj.body); + return toplevel; + }); + } + } + } catch (ex) { + fatal(ex); + } + var result; + if (specified["reduce-test"]) { + // load on demand - assumes cloned repository + var reduce_test = require("../test/reduce"); + if (Object.keys(files).length != 1) fatal("can only test on a single file"); + result = reduce_test(files[Object.keys(files)[0]], options, { + log: print_error, + verbose: true, + }); + } else { + result = UglifyJS.minify(files, options); + } + if (result.error) { + var ex = result.error; + if (ex.name == "SyntaxError") { + print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col); + var file = files[ex.filename]; + if (file) { + var col = ex.col; + var lines = file.split(/\r?\n/); + var line = lines[ex.line - 1]; + if (!line && !col) { + line = lines[ex.line - 2]; + col = line.length; + } + if (line) { + var limit = 70; + if (col > limit) { + line = line.slice(col - limit); + col = limit; + } + print_error(line.slice(0, 80)); + print_error(line.slice(0, col).replace(/\S/g, " ") + "^"); + } + } + } else if (ex.defs) { + print_error("Supported options:"); + print_error(format_object(ex.defs)); + } + fatal(ex); + } else if (output == "ast") { + if (!options.compress && !options.mangle) { + var toplevel = result.ast; + if (!(toplevel instanceof UglifyJS.AST_Toplevel)) { + if (!(toplevel instanceof UglifyJS.AST_Statement)) toplevel = new UglifyJS.AST_SimpleStatement({ + body: toplevel, + }); + toplevel = new UglifyJS.AST_Toplevel({ + body: [ toplevel ], + }); + } + toplevel.figure_out_scope({}); + } + print(JSON.stringify(result.ast, function(key, value) { + if (value) switch (key) { + case "enclosed": + return value.length ? value.map(symdef) : undefined; + case "functions": + case "globals": + case "variables": + return value.size() ? value.map(symdef) : undefined; + case "thedef": + return symdef(value); + } + if (skip_property(key, value)) return; + if (value instanceof UglifyJS.AST_Token) return; + if (value instanceof UglifyJS.Dictionary) return; + if (value instanceof UglifyJS.AST_Node) { + var result = { + _class: "AST_" + value.TYPE + }; + value.CTOR.PROPS.forEach(function(prop) { + result[prop] = value[prop]; + }); + return result; + } + return value; + }, 2)); + } else if (output == "spidermonkey") { + print(JSON.stringify(result.ast.to_mozilla_ast(), null, 2)); + } else if (output) { + var code; + if (result.ast) { + var opts = {}; + for (var name in options.output) { + if (!/^ast|code$/.test(name)) opts[name] = options.output[name]; + } + code = UglifyJS.AST_Node.from_mozilla_ast(result.ast.to_mozilla_ast()).print_to_string(opts); + } else { + code = result.code; + } + fs.writeFileSync(output, code); + if (result.map) fs.writeFileSync(output + ".map", result.map); + } else { + print(result.code); + } + if (nameCache) fs.writeFileSync(nameCache, JSON.stringify(options.nameCache)); + if (result.timings) for (var phase in result.timings) { + print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s"); + } +} + +function fatal(message) { + if (message instanceof Error) { + message = message.stack.replace(/^\S*?Error:/, "ERROR:") + } else { + message = "ERROR: " + message; + } + print_error(message); + process.exit(1); +} + +// A file glob function that only supports "*" and "?" wildcards in the basename. +// Example: "foo/bar/*baz??.*.js" +// Argument `paths` must be an array of strings. +// Returns an array of strings. Garbage in, garbage out. +function simple_glob(paths) { + return paths.reduce(function(paths, glob) { + if (/\*|\?/.test(glob)) { + var dir = path.dirname(glob); + try { + var entries = fs.readdirSync(dir).filter(function(name) { + try { + return fs.statSync(path.join(dir, name)).isFile(); + } catch (ex) { + return false; + } + }); + } catch (ex) {} + if (entries) { + var pattern = "^" + path.basename(glob) + .replace(/[.+^$[\]\\(){}]/g, "\\$&") + .replace(/\*/g, "[^/\\\\]*") + .replace(/\?/g, "[^/\\\\]") + "$"; + var mod = process.platform === "win32" ? "i" : ""; + var rx = new RegExp(pattern, mod); + var results = entries.filter(function(name) { + return rx.test(name); + }).sort().map(function(name) { + return path.join(dir, name); + }); + if (results.length) { + [].push.apply(paths, results); + return paths; + } + } + } + paths.push(glob); + return paths; + }, []); +} + +function read_file(path, default_value) { + try { + return fs.readFileSync(path, "utf8"); + } catch (ex) { + if (ex.code == "ENOENT" && default_value != null) return default_value; + fatal(ex); + } +} + +function parse_js(value, options, flag) { + if (!options || typeof options != "object") options = Object.create(null); + if (typeof value == "string") try { + UglifyJS.parse(value, { + expression: true + }).walk(new UglifyJS.TreeWalker(function(node) { + if (node instanceof UglifyJS.AST_Assign) { + var name = node.left.print_to_string(); + var value = node.right; + if (flag) { + options[name] = value; + } else if (value instanceof UglifyJS.AST_Array) { + options[name] = value.elements.map(to_string); + } else { + options[name] = to_string(value); + } + return true; + } + if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) { + var name = node.print_to_string(); + options[name] = true; + return true; + } + if (!(node instanceof UglifyJS.AST_Sequence)) throw node; + + function to_string(value) { + return value instanceof UglifyJS.AST_Constant ? value.value : value.print_to_string({ + quote_keys: true + }); + } + })); + } catch (ex) { + if (flag) { + fatal("cannot parse arguments for '" + flag + "': " + value); + } else { + options[value] = null; + } + } + return options; +} + +function skip_property(key, value) { + return skip_keys.indexOf(key) >= 0 + // only skip truthy_keys if their value is falsy + || truthy_keys.indexOf(key) >= 0 && !value; +} + +function symdef(def) { + var ret = (1e6 + def.id) + " " + def.name; + if (def.mangled_name) ret += " " + def.mangled_name; + return ret; +} + +function format_object(obj) { + var lines = []; + var padding = ""; + Object.keys(obj).map(function(name) { + if (padding.length < name.length) padding = Array(name.length + 1).join(" "); + return [ name, JSON.stringify(obj[name]) ]; + }).forEach(function(tokens) { + lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]); + }); + return lines.join("\n"); +} + +function print_error(msg) { + process.stderr.write(msg); + process.stderr.write("\n"); +} + +function print(txt) { + process.stdout.write(txt); + process.stdout.write("\n"); +} diff --git a/libs/events/node_modules/uglify-js/lib/ast.js b/libs/events/node_modules/uglify-js/lib/ast.js new file mode 100644 index 000000000..16ea9c805 --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/ast.js @@ -0,0 +1,2356 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function DEFNODE(type, props, methods, base) { + if (typeof base === "undefined") base = AST_Node; + props = props ? props.split(/\s+/) : []; + var self_props = props; + if (base && base.PROPS) props = props.concat(base.PROPS); + var code = [ + "return function AST_", type, "(props){", + // not essential, but speeds up compress by a few percent + "this._bits=0;", + "if(props){", + ]; + props.forEach(function(prop) { + code.push("this.", prop, "=props.", prop, ";"); + }); + code.push("}"); + var proto = Object.create(base && base.prototype); + if (methods.initialize || proto.initialize) code.push("this.initialize();"); + code.push("};"); + var ctor = new Function(code.join(""))(); + ctor.prototype = proto; + ctor.prototype.CTOR = ctor; + ctor.prototype.TYPE = ctor.TYPE = type; + if (base) { + ctor.BASE = base; + base.SUBCLASSES.push(ctor); + } + ctor.DEFMETHOD = function(name, method) { + this.prototype[name] = method; + }; + ctor.PROPS = props; + ctor.SELF_PROPS = self_props; + ctor.SUBCLASSES = []; + for (var name in methods) if (HOP(methods, name)) { + if (/^\$/.test(name)) { + ctor[name.substr(1)] = methods[name]; + } else { + ctor.DEFMETHOD(name, methods[name]); + } + } + if (typeof exports !== "undefined") exports["AST_" + type] = ctor; + return ctor; +} + +var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before comments_after file raw", { +}, null); + +var AST_Node = DEFNODE("Node", "start end", { + _clone: function(deep) { + if (deep) { + var self = this.clone(); + return self.transform(new TreeTransformer(function(node) { + if (node !== self) { + return node.clone(true); + } + })); + } + return new this.CTOR(this); + }, + clone: function(deep) { + return this._clone(deep); + }, + $documentation: "Base class of all AST nodes", + $propdoc: { + start: "[AST_Token] The first token of this node", + end: "[AST_Token] The last token of this node" + }, + equals: function(node) { + return this.TYPE == node.TYPE && this._equals(node); + }, + walk: function(visitor) { + visitor.visit(this); + }, + _validate: function() { + if (this.TYPE == "Node") throw new Error("should not instantiate AST_Node"); + }, + validate: function() { + var ctor = this.CTOR; + do { + ctor.prototype._validate.call(this); + } while (ctor = ctor.BASE); + }, + validate_ast: function() { + var marker = {}; + this.walk(new TreeWalker(function(node) { + if (node.validate_visited === marker) { + throw new Error(string_template("cannot reuse AST_{TYPE} from [{start}]", node)); + } + node.validate_visited = marker; + })); + }, +}, null); + +DEF_BITPROPS(AST_Node, [ + // AST_Node + "_optimized", + "_squeezed", + // AST_Call + "call_only", + // AST_Lambda + "collapse_scanning", + // AST_SymbolRef + "defined", + "evaluating", + "falsy", + // AST_SymbolRef + "in_arg", + // AST_Return + "in_bool", + // AST_SymbolRef + "is_undefined", + // AST_LambdaExpression + // AST_LambdaDefinition + "inlined", + // AST_Lambda + "length_read", + // AST_Yield + "nested", + // AST_Lambda + "new", + // AST_Call + // AST_PropAccess + "optional", + // AST_ClassProperty + "private", + // AST_Call + "pure", + // AST_Assign + "redundant", + // AST_Node + "single_use", + // AST_ClassProperty + "static", + // AST_Call + // AST_PropAccess + "terminal", + "truthy", + // AST_Scope + "uses_eval", + // AST_Scope + "uses_with", +]); + +(AST_Node.log_function = function(fn, verbose) { + if (typeof fn != "function") { + AST_Node.info = AST_Node.warn = noop; + return; + } + var printed = Object.create(null); + AST_Node.info = verbose ? function(text, props) { + log("INFO: " + string_template(text, props)); + } : noop; + AST_Node.warn = function(text, props) { + log("WARN: " + string_template(text, props)); + }; + + function log(msg) { + if (printed[msg]) return; + printed[msg] = true; + fn(msg); + } +})(); + +var restore_transforms = []; +AST_Node.enable_validation = function() { + AST_Node.disable_validation(); + (function validate_transform(ctor) { + ctor.SUBCLASSES.forEach(validate_transform); + if (!HOP(ctor.prototype, "transform")) return; + var transform = ctor.prototype.transform; + ctor.prototype.transform = function(tw, in_list) { + var node = transform.call(this, tw, in_list); + if (node instanceof AST_Node) { + node.validate(); + } else if (!(node === null || in_list && List.is_op(node))) { + throw new Error("invalid transformed value: " + node); + } + return node; + }; + restore_transforms.push(function() { + ctor.prototype.transform = transform; + }); + })(this); +}; + +AST_Node.disable_validation = function() { + var restore; + while (restore = restore_transforms.pop()) restore(); +}; + +function all_equals(k, l) { + return k.length == l.length && all(k, function(m, i) { + return m.equals(l[i]); + }); +} + +function list_equals(s, t) { + return s.length == t.length && all(s, function(u, i) { + return u == t[i]; + }); +} + +function prop_equals(u, v) { + if (u === v) return true; + if (u == null) return v == null; + return u instanceof AST_Node && v instanceof AST_Node && u.equals(v); +} + +/* -----[ statements ]----- */ + +var AST_Statement = DEFNODE("Statement", null, { + $documentation: "Base class of all statements", + _validate: function() { + if (this.TYPE == "Statement") throw new Error("should not instantiate AST_Statement"); + }, +}); + +var AST_Debugger = DEFNODE("Debugger", null, { + $documentation: "Represents a debugger statement", + _equals: return_true, +}, AST_Statement); + +var AST_Directive = DEFNODE("Directive", "quote value", { + $documentation: "Represents a directive, like \"use strict\";", + $propdoc: { + quote: "[string?] the original quote character", + value: "[string] The value of this directive as a plain string (it's not an AST_String!)", + }, + _equals: function(node) { + return this.value == node.value; + }, + _validate: function() { + if (this.quote != null) { + if (typeof this.quote != "string") throw new Error("quote must be string"); + if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote); + } + if (typeof this.value != "string") throw new Error("value must be string"); + }, +}, AST_Statement); + +var AST_EmptyStatement = DEFNODE("EmptyStatement", null, { + $documentation: "The empty statement (empty block or simply a semicolon)", + _equals: return_true, +}, AST_Statement); + +function is_statement(node) { + return node instanceof AST_Statement + && !(node instanceof AST_ClassExpression) + && !(node instanceof AST_LambdaExpression); +} + +function validate_expression(value, prop, multiple, allow_spread, allow_hole) { + multiple = multiple ? "contain" : "be"; + if (!(value instanceof AST_Node)) throw new Error(prop + " must " + multiple + " AST_Node"); + if (value instanceof AST_DefaultValue) throw new Error(prop + " cannot " + multiple + " AST_DefaultValue"); + if (value instanceof AST_Destructured) throw new Error(prop + " cannot " + multiple + " AST_Destructured"); + if (value instanceof AST_Hole && !allow_hole) throw new Error(prop + " cannot " + multiple + " AST_Hole"); + if (value instanceof AST_Spread && !allow_spread) throw new Error(prop + " cannot " + multiple + " AST_Spread"); + if (is_statement(value)) throw new Error(prop + " cannot " + multiple + " AST_Statement"); + if (value instanceof AST_SymbolDeclaration) { + throw new Error(prop + " cannot " + multiple + " AST_SymbolDeclaration"); + } +} + +function must_be_expression(node, prop) { + validate_expression(node[prop], prop); +} + +var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", { + $documentation: "A statement consisting of an expression, i.e. a = 1 + 2", + $propdoc: { + body: "[AST_Node] an expression node (should not be instanceof AST_Statement)", + }, + _equals: function(node) { + return this.body.equals(node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.body.walk(visitor); + }); + }, + _validate: function() { + must_be_expression(this, "body"); + }, +}, AST_Statement); + +var AST_BlockScope = DEFNODE("BlockScope", "_var_names enclosed functions make_def parent_scope variables", { + $documentation: "Base class for all statements introducing a lexical scope", + $propdoc: { + enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any inner scopes", + functions: "[Dictionary/S] like `variables`, but only lists function declarations", + parent_scope: "[AST_Scope?/S] link to the parent scope", + variables: "[Dictionary/S] a map of name ---> SymbolDef for all variables/functions defined in this scope", + }, + clone: function(deep) { + var node = this._clone(deep); + if (this.enclosed) node.enclosed = this.enclosed.slice(); + if (this.functions) node.functions = this.functions.clone(); + if (this.variables) node.variables = this.variables.clone(); + return node; + }, + pinned: function() { + return this.resolve().pinned(); + }, + resolve: function() { + return this.parent_scope.resolve(); + }, + _validate: function() { + if (this.TYPE == "BlockScope") throw new Error("should not instantiate AST_BlockScope"); + if (this.parent_scope == null) return; + if (!(this.parent_scope instanceof AST_BlockScope)) throw new Error("parent_scope must be AST_BlockScope"); + if (!(this.resolve() instanceof AST_Scope)) throw new Error("must be contained within AST_Scope"); + }, +}, AST_Statement); + +function walk_body(node, visitor) { + node.body.forEach(function(node) { + node.walk(visitor); + }); +} + +var AST_Block = DEFNODE("Block", "body", { + $documentation: "A body of statements (usually braced)", + $propdoc: { + body: "[AST_Statement*] an array of statements" + }, + _equals: function(node) { + return all_equals(this.body, node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + walk_body(node, visitor); + }); + }, + _validate: function() { + if (this.TYPE == "Block") throw new Error("should not instantiate AST_Block"); + this.body.forEach(function(node) { + if (!is_statement(node)) throw new Error("body must contain AST_Statement"); + }); + }, +}, AST_BlockScope); + +var AST_BlockStatement = DEFNODE("BlockStatement", null, { + $documentation: "A block statement", +}, AST_Block); + +var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", { + $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`", + $propdoc: { + body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement" + }, + _validate: function() { + if (this.TYPE == "StatementWithBody") throw new Error("should not instantiate AST_StatementWithBody"); + if (!is_statement(this.body)) throw new Error("body must be AST_Statement"); + }, +}, AST_BlockScope); + +var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", { + $documentation: "Statement with a label", + $propdoc: { + label: "[AST_Label] a label definition" + }, + _equals: function(node) { + return this.label.equals(node.label) + && this.body.equals(node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.label.walk(visitor); + node.body.walk(visitor); + }); + }, + clone: function(deep) { + var node = this._clone(deep); + if (deep) { + var label = node.label; + var def = this.label; + node.walk(new TreeWalker(function(node) { + if (node instanceof AST_LoopControl) { + if (!node.label || node.label.thedef !== def) return; + node.label.thedef = label; + label.references.push(node); + return true; + } + if (node instanceof AST_Scope) return true; + })); + } + return node; + }, + _validate: function() { + if (!(this.label instanceof AST_Label)) throw new Error("label must be AST_Label"); + }, +}, AST_StatementWithBody); + +var AST_IterationStatement = DEFNODE("IterationStatement", null, { + $documentation: "Internal class. All loops inherit from it.", + _validate: function() { + if (this.TYPE == "IterationStatement") throw new Error("should not instantiate AST_IterationStatement"); + }, +}, AST_StatementWithBody); + +var AST_DWLoop = DEFNODE("DWLoop", "condition", { + $documentation: "Base class for do/while statements", + $propdoc: { + condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement" + }, + _equals: function(node) { + return this.body.equals(node.body) + && this.condition.equals(node.condition); + }, + _validate: function() { + if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop"); + must_be_expression(this, "condition"); + }, +}, AST_IterationStatement); + +var AST_Do = DEFNODE("Do", null, { + $documentation: "A `do` statement", + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.body.walk(visitor); + node.condition.walk(visitor); + }); + }, +}, AST_DWLoop); + +var AST_While = DEFNODE("While", null, { + $documentation: "A `while` statement", + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.condition.walk(visitor); + node.body.walk(visitor); + }); + }, +}, AST_DWLoop); + +var AST_For = DEFNODE("For", "init condition step", { + $documentation: "A `for` statement", + $propdoc: { + init: "[AST_Node?] the `for` initialization code, or null if empty", + condition: "[AST_Node?] the `for` termination clause, or null if empty", + step: "[AST_Node?] the `for` update clause, or null if empty" + }, + _equals: function(node) { + return prop_equals(this.init, node.init) + && prop_equals(this.condition, node.condition) + && prop_equals(this.step, node.step) + && this.body.equals(node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.init) node.init.walk(visitor); + if (node.condition) node.condition.walk(visitor); + if (node.step) node.step.walk(visitor); + node.body.walk(visitor); + }); + }, + _validate: function() { + if (this.init != null) { + if (!(this.init instanceof AST_Node)) throw new Error("init must be AST_Node"); + if (is_statement(this.init) && !(this.init instanceof AST_Definitions)) { + throw new Error("init cannot be AST_Statement"); + } + } + if (this.condition != null) must_be_expression(this, "condition"); + if (this.step != null) must_be_expression(this, "step"); + }, +}, AST_IterationStatement); + +var AST_ForEnumeration = DEFNODE("ForEnumeration", "init object", { + $documentation: "Base class for enumeration loops, i.e. `for ... in`, `for ... of` & `for await ... of`", + $propdoc: { + init: "[AST_Node] the assignment target during iteration", + object: "[AST_Node] the object to iterate over" + }, + _equals: function(node) { + return this.init.equals(node.init) + && this.object.equals(node.object) + && this.body.equals(node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.init.walk(visitor); + node.object.walk(visitor); + node.body.walk(visitor); + }); + }, + _validate: function() { + if (this.TYPE == "ForEnumeration") throw new Error("should not instantiate AST_ForEnumeration"); + if (this.init instanceof AST_Definitions) { + if (this.init.definitions.length != 1) throw new Error("init must have single declaration"); + } else { + validate_destructured(this.init, function(node) { + if (!(node instanceof AST_PropAccess || node instanceof AST_SymbolRef)) { + throw new Error("init must be assignable: " + node.TYPE); + } + }); + } + must_be_expression(this, "object"); + }, +}, AST_IterationStatement); + +var AST_ForIn = DEFNODE("ForIn", null, { + $documentation: "A `for ... in` statement", +}, AST_ForEnumeration); + +var AST_ForOf = DEFNODE("ForOf", null, { + $documentation: "A `for ... of` statement", +}, AST_ForEnumeration); + +var AST_ForAwaitOf = DEFNODE("ForAwaitOf", null, { + $documentation: "A `for await ... of` statement", +}, AST_ForOf); + +var AST_With = DEFNODE("With", "expression", { + $documentation: "A `with` statement", + $propdoc: { + expression: "[AST_Node] the `with` expression" + }, + _equals: function(node) { + return this.expression.equals(node.expression) + && this.body.equals(node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + node.body.walk(visitor); + }); + }, + _validate: function() { + must_be_expression(this, "expression"); + }, +}, AST_StatementWithBody); + +/* -----[ scope and functions ]----- */ + +var AST_Scope = DEFNODE("Scope", "fn_defs may_call_this uses_eval uses_with", { + $documentation: "Base class for all statements introducing a lambda scope", + $propdoc: { + uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`", + uses_with: "[boolean/S] tells whether this scope uses the `with` statement", + }, + pinned: function() { + return this.uses_eval || this.uses_with; + }, + resolve: return_this, + _validate: function() { + if (this.TYPE == "Scope") throw new Error("should not instantiate AST_Scope"); + }, +}, AST_Block); + +var AST_Toplevel = DEFNODE("Toplevel", "globals", { + $documentation: "The toplevel scope", + $propdoc: { + globals: "[Dictionary/S] a map of name ---> SymbolDef for all undeclared names", + }, + wrap: function(name) { + var body = this.body; + return parse([ + "(function(exports){'$ORIG';})(typeof ", + name, + "=='undefined'?(", + name, + "={}):", + name, + ");" + ].join(""), { + filename: "wrap=" + JSON.stringify(name) + }).transform(new TreeTransformer(function(node) { + if (node instanceof AST_Directive && node.value == "$ORIG") { + return List.splice(body); + } + })); + }, + enclose: function(args_values) { + if (typeof args_values != "string") args_values = ""; + var index = args_values.indexOf(":"); + if (index < 0) index = args_values.length; + var body = this.body; + return parse([ + "(function(", + args_values.slice(0, index), + '){"$ORIG"})(', + args_values.slice(index + 1), + ")" + ].join(""), { + filename: "enclose=" + JSON.stringify(args_values) + }).transform(new TreeTransformer(function(node) { + if (node instanceof AST_Directive && node.value == "$ORIG") { + return List.splice(body); + } + })); + } +}, AST_Scope); + +var AST_ClassInitBlock = DEFNODE("ClassInitBlock", null, { + $documentation: "Value for `class` static initialization blocks", +}, AST_Scope); + +var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_arguments", { + $documentation: "Base class for functions", + $propdoc: { + argnames: "[(AST_DefaultValue|AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals", + length_read: "[boolean/S] whether length property of this function is accessed", + rest: "[(AST_Destructured|AST_SymbolFunarg)?] rest parameter, or null if absent", + uses_arguments: "[boolean|number/S] whether this function accesses the arguments array", + }, + each_argname: function(visit) { + var tw = new TreeWalker(function(node) { + if (node instanceof AST_DefaultValue) { + node.name.walk(tw); + return true; + } + if (node instanceof AST_DestructuredKeyVal) { + node.value.walk(tw); + return true; + } + if (node instanceof AST_SymbolFunarg) visit(node); + }); + this.argnames.forEach(function(argname) { + argname.walk(tw); + }); + if (this.rest) this.rest.walk(tw); + }, + _equals: function(node) { + return prop_equals(this.rest, node.rest) + && prop_equals(this.name, node.name) + && prop_equals(this.value, node.value) + && all_equals(this.argnames, node.argnames) + && all_equals(this.body, node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.name) node.name.walk(visitor); + node.argnames.forEach(function(argname) { + argname.walk(visitor); + }); + if (node.rest) node.rest.walk(visitor); + walk_body(node, visitor); + }); + }, + _validate: function() { + if (this.TYPE == "Lambda") throw new Error("should not instantiate AST_Lambda"); + this.argnames.forEach(function(node) { + validate_destructured(node, function(node) { + if (!(node instanceof AST_SymbolFunarg)) throw new Error("argnames must be AST_SymbolFunarg[]"); + }, true); + }); + if (this.rest != null) validate_destructured(this.rest, function(node) { + if (!(node instanceof AST_SymbolFunarg)) throw new Error("rest must be AST_SymbolFunarg"); + }); + }, +}, AST_Scope); + +var AST_Accessor = DEFNODE("Accessor", null, { + $documentation: "A getter/setter function", + _validate: function() { + if (this.name != null) throw new Error("name must be null"); + }, +}, AST_Lambda); + +var AST_LambdaExpression = DEFNODE("LambdaExpression", "inlined", { + $documentation: "Base class for function expressions", + $propdoc: { + inlined: "[boolean/S] whether this function has been inlined", + }, + _validate: function() { + if (this.TYPE == "LambdaExpression") throw new Error("should not instantiate AST_LambdaExpression"); + }, +}, AST_Lambda); + +function is_arrow(node) { + return node instanceof AST_Arrow || node instanceof AST_AsyncArrow; +} + +function is_async(node) { + return node instanceof AST_AsyncArrow + || node instanceof AST_AsyncDefun + || node instanceof AST_AsyncFunction + || node instanceof AST_AsyncGeneratorDefun + || node instanceof AST_AsyncGeneratorFunction; +} + +function is_generator(node) { + return node instanceof AST_AsyncGeneratorDefun + || node instanceof AST_AsyncGeneratorFunction + || node instanceof AST_GeneratorDefun + || node instanceof AST_GeneratorFunction; +} + +function walk_lambda(node, tw) { + if (is_arrow(node) && node.value) { + node.value.walk(tw); + } else { + walk_body(node, tw); + } +} + +var AST_Arrow = DEFNODE("Arrow", "value", { + $documentation: "An arrow function expression", + $propdoc: { + value: "[AST_Node?] simple return expression, or null if using function body.", + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.argnames.forEach(function(argname) { + argname.walk(visitor); + }); + if (node.rest) node.rest.walk(visitor); + if (node.value) { + node.value.walk(visitor); + } else { + walk_body(node, visitor); + } + }); + }, + _validate: function() { + if (this.name != null) throw new Error("name must be null"); + if (this.uses_arguments) throw new Error("uses_arguments must be false"); + if (this.value != null) { + must_be_expression(this, "value"); + if (this.body.length) throw new Error("body must be empty if value exists"); + } + }, +}, AST_LambdaExpression); + +var AST_AsyncArrow = DEFNODE("AsyncArrow", "value", { + $documentation: "An asynchronous arrow function expression", + $propdoc: { + value: "[AST_Node?] simple return expression, or null if using function body.", + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.argnames.forEach(function(argname) { + argname.walk(visitor); + }); + if (node.rest) node.rest.walk(visitor); + if (node.value) { + node.value.walk(visitor); + } else { + walk_body(node, visitor); + } + }); + }, + _validate: function() { + if (this.name != null) throw new Error("name must be null"); + if (this.uses_arguments) throw new Error("uses_arguments must be false"); + if (this.value != null) { + must_be_expression(this, "value"); + if (this.body.length) throw new Error("body must be empty if value exists"); + } + }, +}, AST_LambdaExpression); + +var AST_AsyncFunction = DEFNODE("AsyncFunction", "name", { + $documentation: "An asynchronous function expression", + $propdoc: { + name: "[AST_SymbolLambda?] the name of this function, or null if not specified", + }, + _validate: function() { + if (this.name != null) { + if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda"); + } + }, +}, AST_LambdaExpression); + +var AST_AsyncGeneratorFunction = DEFNODE("AsyncGeneratorFunction", "name", { + $documentation: "An asynchronous generator function expression", + $propdoc: { + name: "[AST_SymbolLambda?] the name of this function, or null if not specified", + }, + _validate: function() { + if (this.name != null) { + if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda"); + } + }, +}, AST_LambdaExpression); + +var AST_Function = DEFNODE("Function", "name", { + $documentation: "A function expression", + $propdoc: { + name: "[AST_SymbolLambda?] the name of this function, or null if not specified", + }, + _validate: function() { + if (this.name != null) { + if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda"); + } + }, +}, AST_LambdaExpression); + +var AST_GeneratorFunction = DEFNODE("GeneratorFunction", "name", { + $documentation: "A generator function expression", + $propdoc: { + name: "[AST_SymbolLambda?] the name of this function, or null if not specified", + }, + _validate: function() { + if (this.name != null) { + if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda"); + } + }, +}, AST_LambdaExpression); + +var AST_LambdaDefinition = DEFNODE("LambdaDefinition", "inlined name", { + $documentation: "Base class for function definitions", + $propdoc: { + inlined: "[boolean/S] whether this function has been inlined", + name: "[AST_SymbolDefun] the name of this function", + }, + _validate: function() { + if (this.TYPE == "LambdaDefinition") throw new Error("should not instantiate AST_LambdaDefinition"); + if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun"); + }, +}, AST_Lambda); + +var AST_AsyncDefun = DEFNODE("AsyncDefun", null, { + $documentation: "An asynchronous function definition", +}, AST_LambdaDefinition); + +var AST_AsyncGeneratorDefun = DEFNODE("AsyncGeneratorDefun", null, { + $documentation: "An asynchronous generator function definition", +}, AST_LambdaDefinition); + +var AST_Defun = DEFNODE("Defun", null, { + $documentation: "A function definition", +}, AST_LambdaDefinition); + +var AST_GeneratorDefun = DEFNODE("GeneratorDefun", null, { + $documentation: "A generator function definition", +}, AST_LambdaDefinition); + +/* -----[ classes ]----- */ + +var AST_Class = DEFNODE("Class", "extends name properties", { + $documentation: "Base class for class literals", + $propdoc: { + extends: "[AST_Node?] the super class, or null if not specified", + properties: "[AST_ClassProperty*] array of class properties", + }, + _equals: function(node) { + return prop_equals(this.name, node.name) + && prop_equals(this.extends, node.extends) + && all_equals(this.properties, node.properties); + }, + resolve: function(def_class) { + return def_class ? this : this.parent_scope.resolve(); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.name) node.name.walk(visitor); + if (node.extends) node.extends.walk(visitor); + node.properties.forEach(function(prop) { + prop.walk(visitor); + }); + }); + }, + _validate: function() { + if (this.TYPE == "Class") throw new Error("should not instantiate AST_Class"); + if (this.extends != null) must_be_expression(this, "extends"); + this.properties.forEach(function(node) { + if (!(node instanceof AST_ClassProperty)) throw new Error("properties must contain AST_ClassProperty"); + }); + }, +}, AST_BlockScope); + +var AST_DefClass = DEFNODE("DefClass", null, { + $documentation: "A class definition", + $propdoc: { + name: "[AST_SymbolDefClass] the name of this class", + }, + _validate: function() { + if (!(this.name instanceof AST_SymbolDefClass)) throw new Error("name must be AST_SymbolDefClass"); + }, +}, AST_Class); + +var AST_ClassExpression = DEFNODE("ClassExpression", null, { + $documentation: "A class expression", + $propdoc: { + name: "[AST_SymbolClass?] the name of this class, or null if not specified", + }, + _validate: function() { + if (this.name != null) { + if (!(this.name instanceof AST_SymbolClass)) throw new Error("name must be AST_SymbolClass"); + } + }, +}, AST_Class); + +var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", { + $documentation: "Base class for `class` properties", + $propdoc: { + key: "[string|AST_Node?] property name (AST_Node for computed property, null for initialization block)", + private: "[boolean] whether this is a private property", + static: "[boolean] whether this is a static property", + value: "[AST_Node?] property value (AST_Accessor for getters/setters, AST_LambdaExpression for methods, null if not specified for fields)", + }, + _equals: function(node) { + return !this.private == !node.private + && !this.static == !node.static + && prop_equals(this.key, node.key) + && prop_equals(this.value, node.value); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.key instanceof AST_Node) node.key.walk(visitor); + if (node.value) node.value.walk(visitor); + }); + }, + _validate: function() { + if (this.TYPE == "ClassProperty") throw new Error("should not instantiate AST_ClassProperty"); + if (this instanceof AST_ClassInit) { + if (this.key != null) throw new Error("key must be null"); + } else if (typeof this.key != "string") { + if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node"); + must_be_expression(this, "key"); + } + if(this.value != null) { + if (!(this.value instanceof AST_Node)) throw new Error("value must be AST_Node"); + } + }, +}); + +var AST_ClassField = DEFNODE("ClassField", null, { + $documentation: "A `class` field", + _validate: function() { + if(this.value != null) must_be_expression(this, "value"); + }, +}, AST_ClassProperty); + +var AST_ClassGetter = DEFNODE("ClassGetter", null, { + $documentation: "A `class` getter", + _validate: function() { + if (!(this.value instanceof AST_Accessor)) throw new Error("value must be AST_Accessor"); + }, +}, AST_ClassProperty); + +var AST_ClassSetter = DEFNODE("ClassSetter", null, { + $documentation: "A `class` setter", + _validate: function() { + if (!(this.value instanceof AST_Accessor)) throw new Error("value must be AST_Accessor"); + }, +}, AST_ClassProperty); + +var AST_ClassMethod = DEFNODE("ClassMethod", null, { + $documentation: "A `class` method", + _validate: function() { + if (!(this.value instanceof AST_LambdaExpression)) throw new Error("value must be AST_LambdaExpression"); + if (is_arrow(this.value)) throw new Error("value cannot be AST_Arrow or AST_AsyncArrow"); + if (this.value.name != null) throw new Error("name of class method's lambda must be null"); + }, +}, AST_ClassProperty); + +var AST_ClassInit = DEFNODE("ClassInit", null, { + $documentation: "A `class` static initialization block", + _validate: function() { + if (!this.static) throw new Error("static must be true"); + if (!(this.value instanceof AST_ClassInitBlock)) throw new Error("value must be AST_ClassInitBlock"); + }, + initialize: function() { + this.static = true; + }, +}, AST_ClassProperty); + +/* -----[ JUMPS ]----- */ + +var AST_Jump = DEFNODE("Jump", null, { + $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)", + _validate: function() { + if (this.TYPE == "Jump") throw new Error("should not instantiate AST_Jump"); + }, +}, AST_Statement); + +var AST_Exit = DEFNODE("Exit", "value", { + $documentation: "Base class for “exits” (`return` and `throw`)", + $propdoc: { + value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return" + }, + _equals: function(node) { + return prop_equals(this.value, node.value); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.value) node.value.walk(visitor); + }); + }, + _validate: function() { + if (this.TYPE == "Exit") throw new Error("should not instantiate AST_Exit"); + }, +}, AST_Jump); + +var AST_Return = DEFNODE("Return", null, { + $documentation: "A `return` statement", + _validate: function() { + if (this.value != null) must_be_expression(this, "value"); + }, +}, AST_Exit); + +var AST_Throw = DEFNODE("Throw", null, { + $documentation: "A `throw` statement", + _validate: function() { + must_be_expression(this, "value"); + }, +}, AST_Exit); + +var AST_LoopControl = DEFNODE("LoopControl", "label", { + $documentation: "Base class for loop control statements (`break` and `continue`)", + $propdoc: { + label: "[AST_LabelRef?] the label, or null if none", + }, + _equals: function(node) { + return prop_equals(this.label, node.label); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.label) node.label.walk(visitor); + }); + }, + _validate: function() { + if (this.TYPE == "LoopControl") throw new Error("should not instantiate AST_LoopControl"); + if (this.label != null) { + if (!(this.label instanceof AST_LabelRef)) throw new Error("label must be AST_LabelRef"); + } + }, +}, AST_Jump); + +var AST_Break = DEFNODE("Break", null, { + $documentation: "A `break` statement" +}, AST_LoopControl); + +var AST_Continue = DEFNODE("Continue", null, { + $documentation: "A `continue` statement" +}, AST_LoopControl); + +/* -----[ IF ]----- */ + +var AST_If = DEFNODE("If", "condition alternative", { + $documentation: "A `if` statement", + $propdoc: { + condition: "[AST_Node] the `if` condition", + alternative: "[AST_Statement?] the `else` part, or null if not present" + }, + _equals: function(node) { + return this.body.equals(node.body) + && this.condition.equals(node.condition) + && prop_equals(this.alternative, node.alternative); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.condition.walk(visitor); + node.body.walk(visitor); + if (node.alternative) node.alternative.walk(visitor); + }); + }, + _validate: function() { + must_be_expression(this, "condition"); + if (this.alternative != null) { + if (!is_statement(this.alternative)) throw new Error("alternative must be AST_Statement"); + } + }, +}, AST_StatementWithBody); + +/* -----[ SWITCH ]----- */ + +var AST_Switch = DEFNODE("Switch", "expression", { + $documentation: "A `switch` statement", + $propdoc: { + expression: "[AST_Node] the `switch` “discriminant”" + }, + _equals: function(node) { + return this.expression.equals(node.expression) + && all_equals(this.body, node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + walk_body(node, visitor); + }); + }, + _validate: function() { + must_be_expression(this, "expression"); + this.body.forEach(function(node) { + if (!(node instanceof AST_SwitchBranch)) throw new Error("body must be AST_SwitchBranch[]"); + }); + }, +}, AST_Block); + +var AST_SwitchBranch = DEFNODE("SwitchBranch", null, { + $documentation: "Base class for `switch` branches", + _validate: function() { + if (this.TYPE == "SwitchBranch") throw new Error("should not instantiate AST_SwitchBranch"); + }, +}, AST_Block); + +var AST_Default = DEFNODE("Default", null, { + $documentation: "A `default` switch branch", +}, AST_SwitchBranch); + +var AST_Case = DEFNODE("Case", "expression", { + $documentation: "A `case` switch branch", + $propdoc: { + expression: "[AST_Node] the `case` expression" + }, + _equals: function(node) { + return this.expression.equals(node.expression) + && all_equals(this.body, node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + walk_body(node, visitor); + }); + }, + _validate: function() { + must_be_expression(this, "expression"); + }, +}, AST_SwitchBranch); + +/* -----[ EXCEPTIONS ]----- */ + +var AST_Try = DEFNODE("Try", "bcatch bfinally", { + $documentation: "A `try` statement", + $propdoc: { + bcatch: "[AST_Catch?] the catch block, or null if not present", + bfinally: "[AST_Finally?] the finally block, or null if not present" + }, + _equals: function(node) { + return all_equals(this.body, node.body) + && prop_equals(this.bcatch, node.bcatch) + && prop_equals(this.bfinally, node.bfinally); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + walk_body(node, visitor); + if (node.bcatch) node.bcatch.walk(visitor); + if (node.bfinally) node.bfinally.walk(visitor); + }); + }, + _validate: function() { + if (this.bcatch != null) { + if (!(this.bcatch instanceof AST_Catch)) throw new Error("bcatch must be AST_Catch"); + } + if (this.bfinally != null) { + if (!(this.bfinally instanceof AST_Finally)) throw new Error("bfinally must be AST_Finally"); + } + }, +}, AST_Block); + +var AST_Catch = DEFNODE("Catch", "argname", { + $documentation: "A `catch` node; only makes sense as part of a `try` statement", + $propdoc: { + argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present", + }, + _equals: function(node) { + return prop_equals(this.argname, node.argname) + && all_equals(this.body, node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.argname) node.argname.walk(visitor); + walk_body(node, visitor); + }); + }, + _validate: function() { + if (this.argname != null) validate_destructured(this.argname, function(node) { + if (!(node instanceof AST_SymbolCatch)) throw new Error("argname must be AST_SymbolCatch"); + }); + }, +}, AST_Block); + +var AST_Finally = DEFNODE("Finally", null, { + $documentation: "A `finally` node; only makes sense as part of a `try` statement" +}, AST_Block); + +/* -----[ VAR ]----- */ + +var AST_Definitions = DEFNODE("Definitions", "definitions", { + $documentation: "Base class for `var` nodes (variable declarations/initializations)", + $propdoc: { + definitions: "[AST_VarDef*] array of variable definitions" + }, + _equals: function(node) { + return all_equals(this.definitions, node.definitions); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.definitions.forEach(function(defn) { + defn.walk(visitor); + }); + }); + }, + _validate: function() { + if (this.TYPE == "Definitions") throw new Error("should not instantiate AST_Definitions"); + if (this.definitions.length < 1) throw new Error("must have at least one definition"); + }, +}, AST_Statement); + +var AST_Const = DEFNODE("Const", null, { + $documentation: "A `const` statement", + _validate: function() { + this.definitions.forEach(function(node) { + if (!(node instanceof AST_VarDef)) throw new Error("definitions must be AST_VarDef[]"); + validate_destructured(node.name, function(node) { + if (!(node instanceof AST_SymbolConst)) throw new Error("name must be AST_SymbolConst"); + }); + }); + }, +}, AST_Definitions); + +var AST_Let = DEFNODE("Let", null, { + $documentation: "A `let` statement", + _validate: function() { + this.definitions.forEach(function(node) { + if (!(node instanceof AST_VarDef)) throw new Error("definitions must be AST_VarDef[]"); + validate_destructured(node.name, function(node) { + if (!(node instanceof AST_SymbolLet)) throw new Error("name must be AST_SymbolLet"); + }); + }); + }, +}, AST_Definitions); + +var AST_Var = DEFNODE("Var", null, { + $documentation: "A `var` statement", + _validate: function() { + this.definitions.forEach(function(node) { + if (!(node instanceof AST_VarDef)) throw new Error("definitions must be AST_VarDef[]"); + validate_destructured(node.name, function(node) { + if (!(node instanceof AST_SymbolVar)) throw new Error("name must be AST_SymbolVar"); + }); + }); + }, +}, AST_Definitions); + +var AST_VarDef = DEFNODE("VarDef", "name value", { + $documentation: "A variable declaration; only appears in a AST_Definitions node", + $propdoc: { + name: "[AST_Destructured|AST_SymbolVar] name of the variable", + value: "[AST_Node?] initializer, or null of there's no initializer", + }, + _equals: function(node) { + return this.name.equals(node.name) + && prop_equals(this.value, node.value); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.name.walk(visitor); + if (node.value) node.value.walk(visitor); + }); + }, + _validate: function() { + if (this.value != null) must_be_expression(this, "value"); + }, +}); + +/* -----[ OTHER ]----- */ + +var AST_ExportDeclaration = DEFNODE("ExportDeclaration", "body", { + $documentation: "An `export` statement", + $propdoc: { + body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export", + }, + _equals: function(node) { + return this.body.equals(node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.body.walk(visitor); + }); + }, + _validate: function() { + if (!(this.body instanceof AST_DefClass + || this.body instanceof AST_Definitions + || this.body instanceof AST_LambdaDefinition)) { + throw new Error("body must be AST_DefClass, AST_Definitions or AST_LambdaDefinition"); + } + }, +}, AST_Statement); + +var AST_ExportDefault = DEFNODE("ExportDefault", "body", { + $documentation: "An `export default` statement", + $propdoc: { + body: "[AST_Node] the default export", + }, + _equals: function(node) { + return this.body.equals(node.body); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.body.walk(visitor); + }); + }, + _validate: function() { + if (!(this.body instanceof AST_DefClass || this.body instanceof AST_LambdaDefinition)) { + must_be_expression(this, "body"); + } + }, +}, AST_Statement); + +var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path", { + $documentation: "An `export ... from '...'` statement", + $propdoc: { + aliases: "[AST_String*] array of aliases to export", + keys: "[AST_String*] array of keys to import", + path: "[AST_String] the path to import module", + }, + _equals: function(node) { + return this.path.equals(node.path) + && all_equals(this.aliases, node.aliases) + && all_equals(this.keys, node.keys); + }, + _validate: function() { + if (this.aliases.length != this.keys.length) { + throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length); + } + this.aliases.forEach(function(name) { + if (!(name instanceof AST_String)) throw new Error("aliases must contain AST_String"); + }); + this.keys.forEach(function(name) { + if (!(name instanceof AST_String)) throw new Error("keys must contain AST_String"); + }); + if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String"); + }, +}, AST_Statement); + +var AST_ExportReferences = DEFNODE("ExportReferences", "properties", { + $documentation: "An `export { ... }` statement", + $propdoc: { + properties: "[AST_SymbolExport*] array of aliases to export", + }, + _equals: function(node) { + return all_equals(this.properties, node.properties); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.properties.forEach(function(prop) { + prop.walk(visitor); + }); + }); + }, + _validate: function() { + this.properties.forEach(function(prop) { + if (!(prop instanceof AST_SymbolExport)) throw new Error("properties must contain AST_SymbolExport"); + }); + }, +}, AST_Statement); + +var AST_Import = DEFNODE("Import", "all default path properties", { + $documentation: "An `import` statement", + $propdoc: { + all: "[AST_SymbolImport?] the imported namespace, or null if not specified", + default: "[AST_SymbolImport?] the alias for default `export`, or null if not specified", + path: "[AST_String] the path to import module", + properties: "[(AST_SymbolImport*)?] array of aliases, or null if not specified", + }, + _equals: function(node) { + return this.path.equals(node.path) + && prop_equals(this.all, node.all) + && prop_equals(this.default, node.default) + && !this.properties == !node.properties + && (!this.properties || all_equals(this.properties, node.properties)); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.all) node.all.walk(visitor); + if (node.default) node.default.walk(visitor); + if (node.properties) node.properties.forEach(function(prop) { + prop.walk(visitor); + }); + }); + }, + _validate: function() { + if (this.all != null) { + if (!(this.all instanceof AST_SymbolImport)) throw new Error("all must be AST_SymbolImport"); + if (this.properties != null) throw new Error("cannot import both * and {} in the same statement"); + } + if (this.default != null) { + if (!(this.default instanceof AST_SymbolImport)) throw new Error("default must be AST_SymbolImport"); + if (this.default.key.value !== "") throw new Error("invalid default key: " + this.default.key.value); + } + if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String"); + if (this.properties != null) this.properties.forEach(function(node) { + if (!(node instanceof AST_SymbolImport)) throw new Error("properties must contain AST_SymbolImport"); + }); + }, +}, AST_Statement); + +var AST_DefaultValue = DEFNODE("DefaultValue", "name value", { + $documentation: "A default value declaration", + $propdoc: { + name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable", + value: "[AST_Node] value to assign if variable is `undefined`", + }, + _equals: function(node) { + return this.name.equals(node.name) + && this.value.equals(node.value); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.name.walk(visitor); + node.value.walk(visitor); + }); + }, + _validate: function() { + must_be_expression(this, "value"); + }, +}); + +function must_be_expressions(node, prop, allow_spread, allow_hole) { + node[prop].forEach(function(node) { + validate_expression(node, prop, true, allow_spread, allow_hole); + }); +} + +var AST_Call = DEFNODE("Call", "args expression optional pure terminal", { + $documentation: "A function call expression", + $propdoc: { + args: "[AST_Node*] array of arguments", + expression: "[AST_Node] expression to invoke as function", + optional: "[boolean] whether the expression is optional chaining", + pure: "[boolean/S] marker for side-effect-free call expression", + terminal: "[boolean] whether the chain has ended", + }, + _equals: function(node) { + return !this.optional == !node.optional + && this.expression.equals(node.expression) + && all_equals(this.args, node.args); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + node.args.forEach(function(arg) { + arg.walk(visitor); + }); + }); + }, + _validate: function() { + must_be_expression(this, "expression"); + must_be_expressions(this, "args", true); + }, +}); + +var AST_New = DEFNODE("New", null, { + $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties", + _validate: function() { + if (this.optional) throw new Error("optional must be false"); + if (this.terminal) throw new Error("terminal must be false"); + }, +}, AST_Call); + +var AST_Sequence = DEFNODE("Sequence", "expressions", { + $documentation: "A sequence expression (comma-separated expressions)", + $propdoc: { + expressions: "[AST_Node*] array of expressions (at least two)", + }, + _equals: function(node) { + return all_equals(this.expressions, node.expressions); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expressions.forEach(function(expr) { + expr.walk(visitor); + }); + }); + }, + _validate: function() { + if (this.expressions.length < 2) throw new Error("expressions must contain multiple elements"); + must_be_expressions(this, "expressions"); + }, +}); + +function root_expr(prop) { + while (prop instanceof AST_PropAccess) prop = prop.expression; + return prop; +} + +var AST_PropAccess = DEFNODE("PropAccess", "expression optional property terminal", { + $documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`", + $propdoc: { + expression: "[AST_Node] the “container” expression", + optional: "[boolean] whether the expression is optional chaining", + property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node", + terminal: "[boolean] whether the chain has ended", + }, + _equals: function(node) { + return !this.optional == !node.optional + && prop_equals(this.property, node.property) + && this.expression.equals(node.expression); + }, + get_property: function() { + var p = this.property; + if (p instanceof AST_Constant) return p.value; + if (p instanceof AST_UnaryPrefix && p.operator == "void" && p.expression instanceof AST_Constant) return; + return p; + }, + _validate: function() { + if (this.TYPE == "PropAccess") throw new Error("should not instantiate AST_PropAccess"); + must_be_expression(this, "expression"); + }, +}); + +var AST_Dot = DEFNODE("Dot", "quoted", { + $documentation: "A dotted property access expression", + $propdoc: { + quoted: "[boolean] whether property is transformed from a quoted string", + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + }); + }, + _validate: function() { + if (typeof this.property != "string") throw new Error("property must be string"); + }, +}, AST_PropAccess); + +var AST_Sub = DEFNODE("Sub", null, { + $documentation: "Index-style property access, i.e. `a[\"foo\"]`", + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + node.property.walk(visitor); + }); + }, + _validate: function() { + must_be_expression(this, "property"); + }, +}, AST_PropAccess); + +var AST_Spread = DEFNODE("Spread", "expression", { + $documentation: "Spread expression in array/object literals or function calls", + $propdoc: { + expression: "[AST_Node] expression to be expanded", + }, + _equals: function(node) { + return this.expression.equals(node.expression); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + }); + }, + _validate: function() { + must_be_expression(this, "expression"); + }, +}); + +var AST_Unary = DEFNODE("Unary", "operator expression", { + $documentation: "Base class for unary expressions", + $propdoc: { + operator: "[string] the operator", + expression: "[AST_Node] expression that this unary operator applies to", + }, + _equals: function(node) { + return this.operator == node.operator + && this.expression.equals(node.expression); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + }); + }, + _validate: function() { + if (this.TYPE == "Unary") throw new Error("should not instantiate AST_Unary"); + if (typeof this.operator != "string") throw new Error("operator must be string"); + must_be_expression(this, "expression"); + }, +}); + +var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, { + $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`" +}, AST_Unary); + +var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, { + $documentation: "Unary postfix expression, i.e. `i++`" +}, AST_Unary); + +var AST_Binary = DEFNODE("Binary", "operator left right", { + $documentation: "Binary expression, i.e. `a + b`", + $propdoc: { + left: "[AST_Node] left-hand side expression", + operator: "[string] the operator", + right: "[AST_Node] right-hand side expression" + }, + _equals: function(node) { + return this.operator == node.operator + && this.left.equals(node.left) + && this.right.equals(node.right); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.left.walk(visitor); + node.right.walk(visitor); + }); + }, + _validate: function() { + if (!(this instanceof AST_Assign)) must_be_expression(this, "left"); + if (typeof this.operator != "string") throw new Error("operator must be string"); + must_be_expression(this, "right"); + }, +}); + +var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative", { + $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`", + $propdoc: { + condition: "[AST_Node]", + consequent: "[AST_Node]", + alternative: "[AST_Node]" + }, + _equals: function(node) { + return this.condition.equals(node.condition) + && this.consequent.equals(node.consequent) + && this.alternative.equals(node.alternative); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.condition.walk(visitor); + node.consequent.walk(visitor); + node.alternative.walk(visitor); + }); + }, + _validate: function() { + must_be_expression(this, "condition"); + must_be_expression(this, "consequent"); + must_be_expression(this, "alternative"); + }, +}); + +var AST_Assign = DEFNODE("Assign", null, { + $documentation: "An assignment expression — `a = b + 5`", + _validate: function() { + if (this.operator.indexOf("=") < 0) throw new Error('operator must contain "="'); + if (this.left instanceof AST_Destructured) { + if (this.operator != "=") throw new Error("invalid destructuring operator: " + this.operator); + validate_destructured(this.left, function(node) { + if (!(node instanceof AST_PropAccess || node instanceof AST_SymbolRef)) { + throw new Error("left must be assignable: " + node.TYPE); + } + }); + } else if (!(this.left instanceof AST_Infinity + || this.left instanceof AST_NaN + || this.left instanceof AST_PropAccess && !this.left.optional + || this.left instanceof AST_SymbolRef + || this.left instanceof AST_Undefined)) { + throw new Error("left must be assignable"); + } + }, +}, AST_Binary); + +var AST_Await = DEFNODE("Await", "expression", { + $documentation: "An await expression", + $propdoc: { + expression: "[AST_Node] expression with Promise to resolve on", + }, + _equals: function(node) { + return this.expression.equals(node.expression); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + }); + }, + _validate: function() { + must_be_expression(this, "expression"); + }, +}); + +var AST_Yield = DEFNODE("Yield", "expression nested", { + $documentation: "A yield expression", + $propdoc: { + expression: "[AST_Node?] return value for iterator, or null if undefined", + nested: "[boolean] whether to iterate over expression as generator", + }, + _equals: function(node) { + return !this.nested == !node.nested + && prop_equals(this.expression, node.expression); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.expression) node.expression.walk(visitor); + }); + }, + _validate: function() { + if (this.expression != null) { + must_be_expression(this, "expression"); + } else if (this.nested) { + throw new Error("yield* must contain expression"); + } + }, +}); + +/* -----[ LITERALS ]----- */ + +var AST_Array = DEFNODE("Array", "elements", { + $documentation: "An array literal", + $propdoc: { + elements: "[AST_Node*] array of elements" + }, + _equals: function(node) { + return all_equals(this.elements, node.elements); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.elements.forEach(function(element) { + element.walk(visitor); + }); + }); + }, + _validate: function() { + must_be_expressions(this, "elements", true, true); + }, +}); + +var AST_Destructured = DEFNODE("Destructured", "rest", { + $documentation: "Base class for destructured literal", + $propdoc: { + rest: "[(AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)?] rest parameter, or null if absent", + }, + _validate: function() { + if (this.TYPE == "Destructured") throw new Error("should not instantiate AST_Destructured"); + }, +}); + +function validate_destructured(node, check, allow_default) { + if (node instanceof AST_DefaultValue && allow_default) return validate_destructured(node.name, check); + if (node instanceof AST_Destructured) { + if (node.rest != null) validate_destructured(node.rest, check); + if (node instanceof AST_DestructuredArray) return node.elements.forEach(function(node) { + if (!(node instanceof AST_Hole)) validate_destructured(node, check, true); + }); + if (node instanceof AST_DestructuredObject) return node.properties.forEach(function(prop) { + validate_destructured(prop.value, check, true); + }); + } + check(node); +} + +var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", { + $documentation: "A destructured array literal", + $propdoc: { + elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements", + }, + _equals: function(node) { + return prop_equals(this.rest, node.rest) + && all_equals(this.elements, node.elements); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.elements.forEach(function(element) { + element.walk(visitor); + }); + if (node.rest) node.rest.walk(visitor); + }); + }, +}, AST_Destructured); + +var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", { + $documentation: "A key: value destructured property", + $propdoc: { + key: "[string|AST_Node] property name. For computed property this is an AST_Node.", + value: "[AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef] property value", + }, + _equals: function(node) { + return prop_equals(this.key, node.key) + && this.value.equals(node.value); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.key instanceof AST_Node) node.key.walk(visitor); + node.value.walk(visitor); + }); + }, + _validate: function() { + if (typeof this.key != "string") { + if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node"); + must_be_expression(this, "key"); + } + if (!(this.value instanceof AST_Node)) throw new Error("value must be AST_Node"); + }, +}); + +var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", { + $documentation: "A destructured object literal", + $propdoc: { + properties: "[AST_DestructuredKeyVal*] array of properties", + }, + _equals: function(node) { + return prop_equals(this.rest, node.rest) + && all_equals(this.properties, node.properties); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.properties.forEach(function(prop) { + prop.walk(visitor); + }); + if (node.rest) node.rest.walk(visitor); + }); + }, + _validate: function() { + this.properties.forEach(function(node) { + if (!(node instanceof AST_DestructuredKeyVal)) throw new Error("properties must be AST_DestructuredKeyVal[]"); + }); + }, +}, AST_Destructured); + +var AST_Object = DEFNODE("Object", "properties", { + $documentation: "An object literal", + $propdoc: { + properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties" + }, + _equals: function(node) { + return all_equals(this.properties, node.properties); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.properties.forEach(function(prop) { + prop.walk(visitor); + }); + }); + }, + _validate: function() { + this.properties.forEach(function(node) { + if (!(node instanceof AST_ObjectProperty || node instanceof AST_Spread)) { + throw new Error("properties must contain AST_ObjectProperty and/or AST_Spread only"); + } + }); + }, +}); + +var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", { + $documentation: "Base class for literal object properties", + $propdoc: { + key: "[string|AST_Node] property name. For computed property this is an AST_Node.", + value: "[AST_Node] property value. For getters and setters this is an AST_Accessor.", + }, + _equals: function(node) { + return prop_equals(this.key, node.key) + && this.value.equals(node.value); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.key instanceof AST_Node) node.key.walk(visitor); + node.value.walk(visitor); + }); + }, + _validate: function() { + if (this.TYPE == "ObjectProperty") throw new Error("should not instantiate AST_ObjectProperty"); + if (typeof this.key != "string") { + if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node"); + must_be_expression(this, "key"); + } + if (!(this.value instanceof AST_Node)) throw new Error("value must be AST_Node"); + }, +}); + +var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", null, { + $documentation: "A key: value object property", + _validate: function() { + must_be_expression(this, "value"); + }, +}, AST_ObjectProperty); + +var AST_ObjectMethod = DEFNODE("ObjectMethod", null, { + $documentation: "A key(){} object property", + _validate: function() { + if (!(this.value instanceof AST_LambdaExpression)) throw new Error("value must be AST_LambdaExpression"); + if (is_arrow(this.value)) throw new Error("value cannot be AST_Arrow or AST_AsyncArrow"); + if (this.value.name != null) throw new Error("name of object method's lambda must be null"); + }, +}, AST_ObjectKeyVal); + +var AST_ObjectSetter = DEFNODE("ObjectSetter", null, { + $documentation: "An object setter property", + _validate: function() { + if (!(this.value instanceof AST_Accessor)) throw new Error("value must be AST_Accessor"); + }, +}, AST_ObjectProperty); + +var AST_ObjectGetter = DEFNODE("ObjectGetter", null, { + $documentation: "An object getter property", + _validate: function() { + if (!(this.value instanceof AST_Accessor)) throw new Error("value must be AST_Accessor"); + }, +}, AST_ObjectProperty); + +var AST_Symbol = DEFNODE("Symbol", "scope name thedef", { + $documentation: "Base class for all symbols", + $propdoc: { + name: "[string] name of this symbol", + scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)", + thedef: "[SymbolDef/S] the definition of this symbol" + }, + _equals: function(node) { + return this.thedef ? this.thedef === node.thedef : this.name == node.name; + }, + _validate: function() { + if (this.TYPE == "Symbol") throw new Error("should not instantiate AST_Symbol"); + if (typeof this.name != "string") throw new Error("name must be string"); + }, +}); + +var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", { + $documentation: "A declaration symbol (symbol in var, function name or argument, symbol in catch)", +}, AST_Symbol); + +var AST_SymbolConst = DEFNODE("SymbolConst", null, { + $documentation: "Symbol defining a constant", +}, AST_SymbolDeclaration); + +var AST_SymbolImport = DEFNODE("SymbolImport", "key", { + $documentation: "Symbol defined by an `import` statement", + $propdoc: { + key: "[AST_String] the original `export` name", + }, + _equals: function(node) { + return this.name == node.name + && this.key.equals(node.key); + }, + _validate: function() { + if (!(this.key instanceof AST_String)) throw new Error("key must be AST_String"); + }, +}, AST_SymbolConst); + +var AST_SymbolLet = DEFNODE("SymbolLet", null, { + $documentation: "Symbol defining a lexical-scoped variable", +}, AST_SymbolDeclaration); + +var AST_SymbolVar = DEFNODE("SymbolVar", null, { + $documentation: "Symbol defining a variable", +}, AST_SymbolDeclaration); + +var AST_SymbolFunarg = DEFNODE("SymbolFunarg", "unused", { + $documentation: "Symbol naming a function argument", +}, AST_SymbolVar); + +var AST_SymbolDefun = DEFNODE("SymbolDefun", null, { + $documentation: "Symbol defining a function", +}, AST_SymbolDeclaration); + +var AST_SymbolLambda = DEFNODE("SymbolLambda", null, { + $documentation: "Symbol naming a function expression", +}, AST_SymbolDeclaration); + +var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, { + $documentation: "Symbol defining a class", +}, AST_SymbolConst); + +var AST_SymbolClass = DEFNODE("SymbolClass", null, { + $documentation: "Symbol naming a class expression", +}, AST_SymbolConst); + +var AST_SymbolCatch = DEFNODE("SymbolCatch", null, { + $documentation: "Symbol naming the exception in catch", +}, AST_SymbolDeclaration); + +var AST_Label = DEFNODE("Label", "references", { + $documentation: "Symbol naming a label (declaration)", + $propdoc: { + references: "[AST_LoopControl*] a list of nodes referring to this label" + }, + initialize: function() { + this.references = []; + this.thedef = this; + }, +}, AST_Symbol); + +var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", { + $documentation: "Reference to some symbol (not definition/declaration)", +}, AST_Symbol); + +var AST_SymbolExport = DEFNODE("SymbolExport", "alias", { + $documentation: "Reference in an `export` statement", + $propdoc: { + alias: "[AST_String] the `export` alias", + }, + _equals: function(node) { + return this.name == node.name + && this.alias.equals(node.alias); + }, + _validate: function() { + if (!(this.alias instanceof AST_String)) throw new Error("alias must be AST_String"); + }, +}, AST_SymbolRef); + +var AST_LabelRef = DEFNODE("LabelRef", null, { + $documentation: "Reference to a label symbol", +}, AST_Symbol); + +var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, { + $documentation: "Base class for `super` & `this`", + _equals: return_true, + _validate: function() { + if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity"); + }, +}, AST_Symbol); + +var AST_Super = DEFNODE("Super", null, { + $documentation: "The `super` symbol", + _validate: function() { + if (this.name !== "super") throw new Error('name must be "super"'); + }, +}, AST_ObjectIdentity); + +var AST_This = DEFNODE("This", null, { + $documentation: "The `this` symbol", + _validate: function() { + if (this.TYPE == "This" && this.name !== "this") throw new Error('name must be "this"'); + }, +}, AST_ObjectIdentity); + +var AST_NewTarget = DEFNODE("NewTarget", null, { + $documentation: "The `new.target` symbol", + initialize: function() { + this.name = "new.target"; + }, + _validate: function() { + if (this.name !== "new.target") throw new Error('name must be "new.target": ' + this.name); + }, +}, AST_This); + +var AST_Template = DEFNODE("Template", "expressions strings tag", { + $documentation: "A template literal, i.e. tag`str1${expr1}...strN${exprN}strN+1`", + $propdoc: { + expressions: "[AST_Node*] the placeholder expressions", + strings: "[string*] the raw text segments", + tag: "[AST_Node?] tag function, or null if absent", + }, + _equals: function(node) { + return prop_equals(this.tag, node.tag) + && list_equals(this.strings, node.strings) + && all_equals(this.expressions, node.expressions); + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + if (node.tag) node.tag.walk(visitor); + node.expressions.forEach(function(expr) { + expr.walk(visitor); + }); + }); + }, + _validate: function() { + if (this.expressions.length + 1 != this.strings.length) { + throw new Error("malformed template with " + this.expressions.length + " placeholder(s) but " + this.strings.length + " text segment(s)"); + } + must_be_expressions(this, "expressions"); + this.strings.forEach(function(string) { + if (typeof string != "string") throw new Error("strings must contain string"); + }); + if (this.tag != null) must_be_expression(this, "tag"); + }, +}); + +var AST_Constant = DEFNODE("Constant", null, { + $documentation: "Base class for all constants", + _equals: function(node) { + return this.value === node.value; + }, + _validate: function() { + if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant"); + }, +}); + +var AST_String = DEFNODE("String", "quote value", { + $documentation: "A string literal", + $propdoc: { + quote: "[string?] the original quote character", + value: "[string] the contents of this string", + }, + _validate: function() { + if (this.quote != null) { + if (typeof this.quote != "string") throw new Error("quote must be string"); + if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote); + } + if (typeof this.value != "string") throw new Error("value must be string"); + }, +}, AST_Constant); + +var AST_Number = DEFNODE("Number", "value", { + $documentation: "A number literal", + $propdoc: { + value: "[number] the numeric value", + }, + _validate: function() { + if (typeof this.value != "number") throw new Error("value must be number"); + if (!isFinite(this.value)) throw new Error("value must be finite"); + if (this.value < 0) throw new Error("value cannot be negative"); + }, +}, AST_Constant); + +var AST_BigInt = DEFNODE("BigInt", "value", { + $documentation: "A BigInt literal", + $propdoc: { + value: "[string] the numeric representation", + }, + _validate: function() { + if (typeof this.value != "string") throw new Error("value must be string"); + if (this.value[0] == "-") throw new Error("value cannot be negative"); + }, +}, AST_Constant); + +var AST_RegExp = DEFNODE("RegExp", "value", { + $documentation: "A regexp literal", + $propdoc: { + value: "[RegExp] the actual regexp" + }, + _equals: function(node) { + return "" + this.value == "" + node.value; + }, + _validate: function() { + if (!(this.value instanceof RegExp)) throw new Error("value must be RegExp"); + }, +}, AST_Constant); + +var AST_Atom = DEFNODE("Atom", null, { + $documentation: "Base class for atoms", + _equals: return_true, + _validate: function() { + if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom"); + }, +}, AST_Constant); + +var AST_Null = DEFNODE("Null", null, { + $documentation: "The `null` atom", + value: null, +}, AST_Atom); + +var AST_NaN = DEFNODE("NaN", null, { + $documentation: "The impossible value", + value: 0/0, +}, AST_Atom); + +var AST_Undefined = DEFNODE("Undefined", null, { + $documentation: "The `undefined` value", + value: function(){}(), +}, AST_Atom); + +var AST_Hole = DEFNODE("Hole", null, { + $documentation: "A hole in an array", + value: function(){}(), +}, AST_Atom); + +var AST_Infinity = DEFNODE("Infinity", null, { + $documentation: "The `Infinity` value", + value: 1/0, +}, AST_Atom); + +var AST_Boolean = DEFNODE("Boolean", null, { + $documentation: "Base class for booleans", + _validate: function() { + if (this.TYPE == "Boolean") throw new Error("should not instantiate AST_Boolean"); + }, +}, AST_Atom); + +var AST_False = DEFNODE("False", null, { + $documentation: "The `false` atom", + value: false, +}, AST_Boolean); + +var AST_True = DEFNODE("True", null, { + $documentation: "The `true` atom", + value: true, +}, AST_Boolean); + +/* -----[ TreeWalker ]----- */ + +function TreeWalker(callback) { + this.callback = callback; + this.directives = Object.create(null); + this.stack = []; +} +TreeWalker.prototype = { + visit: function(node, descend) { + this.push(node); + var done = this.callback(node, descend || noop); + if (!done && descend) descend(); + this.pop(); + }, + parent: function(n) { + return this.stack[this.stack.length - 2 - (n || 0)]; + }, + push: function(node) { + var value; + if (node instanceof AST_Class) { + this.directives = Object.create(this.directives); + value = "use strict"; + } else if (node instanceof AST_Directive) { + value = node.value; + } else if (node instanceof AST_Lambda) { + this.directives = Object.create(this.directives); + } + if (value && !this.directives[value]) this.directives[value] = node; + this.stack.push(node); + }, + pop: function() { + var node = this.stack.pop(); + if (node instanceof AST_Class || node instanceof AST_Lambda) { + this.directives = Object.getPrototypeOf(this.directives); + } + }, + self: function() { + return this.stack[this.stack.length - 1]; + }, + find_parent: function(type) { + var stack = this.stack; + for (var i = stack.length - 1; --i >= 0;) { + var x = stack[i]; + if (x instanceof type) return x; + } + }, + has_directive: function(type) { + var dir = this.directives[type]; + if (dir) return dir; + var node = this.stack[this.stack.length - 1]; + if (node instanceof AST_Scope) { + for (var i = 0; i < node.body.length; ++i) { + var st = node.body[i]; + if (!(st instanceof AST_Directive)) break; + if (st.value == type) return st; + } + } + }, + loopcontrol_target: function(node) { + var stack = this.stack; + if (node.label) for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof AST_LabeledStatement && x.label.name == node.label.name) + return x.body; + } else for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof AST_IterationStatement + || node instanceof AST_Break && x instanceof AST_Switch) + return x; + } + }, + in_boolean_context: function() { + for (var drop = true, level = 0, parent, self = this.self(); parent = this.parent(level++); self = parent) { + if (parent instanceof AST_Binary) switch (parent.operator) { + case "&&": + case "||": + if (parent.left === self) drop = false; + continue; + default: + return false; + } + if (parent instanceof AST_Conditional) { + if (parent.condition === self) return true; + continue; + } + if (parent instanceof AST_DWLoop) return parent.condition === self; + if (parent instanceof AST_For) return parent.condition === self; + if (parent instanceof AST_If) return parent.condition === self; + if (parent instanceof AST_Return) { + if (parent.in_bool) return true; + while (parent = this.parent(level++)) { + if (parent instanceof AST_Lambda) { + if (parent.name) return false; + parent = this.parent(level++); + if (parent.TYPE != "Call") return false; + break; + } + } + } + if (parent instanceof AST_Sequence) { + if (parent.tail_node() === self) continue; + return drop ? "d" : true; + } + if (parent instanceof AST_SimpleStatement) return drop ? "d" : true; + if (parent instanceof AST_UnaryPrefix) return parent.operator == "!"; + return false; + } + } +}; diff --git a/libs/events/node_modules/uglify-js/lib/compress.js b/libs/events/node_modules/uglify-js/lib/compress.js new file mode 100644 index 000000000..cde397cf2 --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/compress.js @@ -0,0 +1,14241 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function Compressor(options, false_by_default) { + if (!(this instanceof Compressor)) + return new Compressor(options, false_by_default); + TreeTransformer.call(this, this.before, this.after); + this.options = defaults(options, { + annotations : !false_by_default, + arguments : !false_by_default, + arrows : !false_by_default, + assignments : !false_by_default, + awaits : !false_by_default, + booleans : !false_by_default, + collapse_vars : !false_by_default, + comparisons : !false_by_default, + conditionals : !false_by_default, + dead_code : !false_by_default, + default_values : !false_by_default, + directives : !false_by_default, + drop_console : false, + drop_debugger : !false_by_default, + evaluate : !false_by_default, + expression : false, + functions : !false_by_default, + global_defs : false, + hoist_exports : !false_by_default, + hoist_funs : false, + hoist_props : !false_by_default, + hoist_vars : false, + ie : false, + if_return : !false_by_default, + imports : !false_by_default, + inline : !false_by_default, + join_vars : !false_by_default, + keep_fargs : false_by_default, + keep_fnames : false, + keep_infinity : false, + loops : !false_by_default, + merge_vars : !false_by_default, + module : false, + negate_iife : !false_by_default, + objects : !false_by_default, + optional_chains : !false_by_default, + passes : 1, + properties : !false_by_default, + pure_funcs : null, + pure_getters : !false_by_default && "strict", + reduce_funcs : !false_by_default, + reduce_vars : !false_by_default, + rests : !false_by_default, + sequences : !false_by_default, + side_effects : !false_by_default, + spreads : !false_by_default, + strings : !false_by_default, + switches : !false_by_default, + templates : !false_by_default, + top_retain : null, + toplevel : !!(options && (options["module"] || options["top_retain"])), + typeofs : !false_by_default, + unsafe : false, + unsafe_comps : false, + unsafe_Function : false, + unsafe_math : false, + unsafe_proto : false, + unsafe_regexp : false, + unsafe_undefined: false, + unused : !false_by_default, + varify : !false_by_default, + webkit : false, + yields : !false_by_default, + }, true); + var evaluate = this.options["evaluate"]; + this.eval_threshold = /eager/.test(evaluate) ? 1 / 0 : +evaluate; + var global_defs = this.options["global_defs"]; + if (typeof global_defs == "object") for (var key in global_defs) { + if (/^@/.test(key) && HOP(global_defs, key)) { + global_defs[key.slice(1)] = parse(global_defs[key], { expression: true }); + } + } + if (this.options["inline"] === true) this.options["inline"] = 4; + this.drop_fargs = this.options["keep_fargs"] ? return_false : function(lambda, parent) { + if (lambda.length_read) return false; + var name = lambda.name; + if (!name) return parent && parent.TYPE == "Call" && parent.expression === lambda; + if (name.fixed_value() !== lambda) return false; + var def = name.definition(); + if (def.direct_access) return false; + var escaped = def.escaped; + return escaped && escaped.depth != 1; + }; + if (this.options["module"]) this.directives["use strict"] = true; + var pure_funcs = this.options["pure_funcs"]; + if (typeof pure_funcs == "function") { + this.pure_funcs = pure_funcs; + } else if (typeof pure_funcs == "string") { + this.pure_funcs = function(node) { + var expr; + if (node instanceof AST_Call) { + expr = node.expression; + } else if (node instanceof AST_Template) { + expr = node.tag; + } + return !(expr && pure_funcs === expr.print_to_string()); + }; + } else if (Array.isArray(pure_funcs)) { + this.pure_funcs = function(node) { + var expr; + if (node instanceof AST_Call) { + expr = node.expression; + } else if (node instanceof AST_Template) { + expr = node.tag; + } + return !(expr && member(expr.print_to_string(), pure_funcs)); + }; + } else { + this.pure_funcs = return_true; + } + var sequences = this.options["sequences"]; + this.sequences_limit = sequences == 1 ? 800 : sequences | 0; + var top_retain = this.options["top_retain"]; + if (top_retain instanceof RegExp) { + this.top_retain = function(def) { + return top_retain.test(def.name); + }; + } else if (typeof top_retain == "function") { + this.top_retain = top_retain; + } else if (top_retain) { + if (typeof top_retain == "string") { + top_retain = top_retain.split(/,/); + } + this.top_retain = function(def) { + return member(def.name, top_retain); + }; + } + var toplevel = this.options["toplevel"]; + this.toplevel = typeof toplevel == "string" ? { + funcs: /funcs/.test(toplevel), + vars: /vars/.test(toplevel) + } : { + funcs: toplevel, + vars: toplevel + }; +} + +Compressor.prototype = new TreeTransformer(function(node, descend, in_list) { + if (node._squeezed) return node; + var is_scope = node instanceof AST_Scope; + if (is_scope) { + if (this.option("arrows") && is_arrow(node) && node.value) { + node.body = [ node.first_statement() ]; + node.value = null; + } + node.hoist_properties(this); + node.hoist_declarations(this); + node.process_returns(this); + } + // Before https://github.com/mishoo/UglifyJS/pull/1602 AST_Node.optimize() + // would call AST_Node.transform() if a different instance of AST_Node is + // produced after OPT(). + // This corrupts TreeWalker.stack, which cause AST look-ups to malfunction. + // Migrate and defer all children's AST_Node.transform() to below, which + // will now happen after this parent AST_Node has been properly substituted + // thus gives a consistent AST snapshot. + descend(node, this); + // Existing code relies on how AST_Node.optimize() worked, and omitting the + // following replacement call would result in degraded efficiency of both + // output and performance. + descend(node, this); + var opt = node.optimize(this); + if (is_scope && opt === node && !this.has_directive("use asm") && !opt.pinned()) { + opt.drop_unused(this); + if (opt.merge_variables(this)) opt.drop_unused(this); + descend(opt, this); + } + if (opt === node) opt._squeezed = true; + return opt; +}); +Compressor.prototype.option = function(key) { + return this.options[key]; +}; +Compressor.prototype.exposed = function(def) { + if (def.exported) return true; + if (def.undeclared) return true; + if (!(def.global || def.scope.resolve() instanceof AST_Toplevel)) return false; + var toplevel = this.toplevel; + return !all(def.orig, function(sym) { + return toplevel[sym instanceof AST_SymbolDefun ? "funcs" : "vars"]; + }); +}; +Compressor.prototype.compress = function(node) { + node = node.resolve_defines(this); + node.hoist_exports(this); + if (this.option("expression")) node.process_expression(true); + var merge_vars = this.options.merge_vars; + var passes = +this.options.passes || 1; + var min_count = 1 / 0; + var stopping = false; + var mangle = { ie: this.option("ie") }; + for (var pass = 0; pass < passes; pass++) { + node.figure_out_scope(mangle); + if (pass > 0 || this.option("reduce_vars")) + node.reset_opt_flags(this); + this.options.merge_vars = merge_vars && (stopping || pass == passes - 1); + node = node.transform(this); + if (passes > 1) { + var count = 0; + node.walk(new TreeWalker(function() { + count++; + })); + AST_Node.info("pass {pass}: last_count: {min_count}, count: {count}", { + pass: pass, + min_count: min_count, + count: count, + }); + if (count < min_count) { + min_count = count; + stopping = false; + } else if (stopping) { + break; + } else { + stopping = true; + } + } + } + if (this.option("expression")) node.process_expression(false); + return node; +}; + +(function(OPT) { + OPT(AST_Node, function(self, compressor) { + return self; + }); + + AST_Toplevel.DEFMETHOD("hoist_exports", function(compressor) { + if (!compressor.option("hoist_exports")) return; + var body = this.body, props = []; + for (var i = 0; i < body.length; i++) { + var stat = body[i]; + if (stat instanceof AST_ExportDeclaration) { + body[i] = stat = stat.body; + if (stat instanceof AST_Definitions) { + stat.definitions.forEach(function(defn) { + defn.name.match_symbol(export_symbol, true); + }); + } else { + export_symbol(stat.name); + } + } else if (stat instanceof AST_ExportReferences) { + body.splice(i--, 1); + [].push.apply(props, stat.properties); + } + } + if (props.length) body.push(make_node(AST_ExportReferences, this, { properties: props })); + + function export_symbol(sym) { + if (!(sym instanceof AST_SymbolDeclaration)) return; + var node = make_node(AST_SymbolExport, sym); + node.alias = make_node(AST_String, node, { value: node.name }); + props.push(node); + } + }); + + AST_Scope.DEFMETHOD("process_expression", function(insert, transform) { + var self = this; + var tt = new TreeTransformer(function(node) { + if (insert) { + if (node instanceof AST_Directive) node = make_node(AST_SimpleStatement, node, { + body: make_node(AST_String, node), + }); + if (node instanceof AST_SimpleStatement) { + return transform ? transform(node) : make_node(AST_Return, node, { value: node.body }); + } + } else if (node instanceof AST_Return) { + if (transform) return transform(node); + var value = node.value; + if (value instanceof AST_String) return make_node(AST_Directive, value); + return make_node(AST_SimpleStatement, node, { + body: value || make_node(AST_UnaryPrefix, node, { + operator: "void", + expression: make_node(AST_Number, node, { value: 0 }), + }), + }); + } + if (node instanceof AST_Block) { + if (node instanceof AST_Lambda) { + if (node !== self) return node; + } else if (insert === "awaits" && node instanceof AST_Try) { + if (node.bfinally) return node; + } + for (var index = node.body.length; --index >= 0;) { + var stat = node.body[index]; + if (!is_declaration(stat, true)) { + node.body[index] = stat.transform(tt); + break; + } + } + } else if (node instanceof AST_If) { + node.body = node.body.transform(tt); + if (node.alternative) node.alternative = node.alternative.transform(tt); + } else if (node instanceof AST_With) { + node.body = node.body.transform(tt); + } + return node; + }); + self.transform(tt); + }); + AST_Toplevel.DEFMETHOD("unwrap_expression", function() { + var self = this; + switch (self.body.length) { + case 0: + return make_node(AST_UnaryPrefix, self, { + operator: "void", + expression: make_node(AST_Number, self, { value: 0 }), + }); + case 1: + var stat = self.body[0]; + if (stat instanceof AST_Directive) return make_node(AST_String, stat); + if (stat instanceof AST_SimpleStatement) return stat.body; + default: + return make_node(AST_Call, self, { + expression: make_node(AST_Function, self, { + argnames: [], + body: self.body, + }).init_vars(self), + args: [], + }); + } + }); + AST_Node.DEFMETHOD("wrap_expression", function() { + var self = this; + if (!is_statement(self)) self = make_node(AST_SimpleStatement, self, { body: self }); + if (!(self instanceof AST_Toplevel)) self = make_node(AST_Toplevel, self, { body: [ self ] }); + return self; + }); + + function read_property(obj, node) { + var key = node.get_property(); + if (key instanceof AST_Node) return; + var value; + if (obj instanceof AST_Array) { + var elements = obj.elements; + if (key == "length") return make_node_from_constant(elements.length, obj); + if (typeof key == "number" && key in elements) value = elements[key]; + } else if (obj instanceof AST_Lambda) { + if (key == "length") { + obj.length_read = true; + return make_node_from_constant(obj.argnames.length, obj); + } + } else if (obj instanceof AST_Object) { + key = "" + key; + var props = obj.properties; + for (var i = props.length; --i >= 0;) { + var prop = props[i]; + if (!can_hoist_property(prop)) return; + if (!value && props[i].key === key) value = props[i].value; + } + } + return value instanceof AST_SymbolRef && value.fixed_value() || value; + } + + function is_read_only_fn(value, name) { + if (value instanceof AST_Boolean) return native_fns.Boolean[name]; + if (value instanceof AST_Number) return native_fns.Number[name]; + if (value instanceof AST_String) return native_fns.String[name]; + if (name == "valueOf") return false; + if (value instanceof AST_Array) return native_fns.Array[name]; + if (value instanceof AST_Lambda) return native_fns.Function[name]; + if (value instanceof AST_Object) return native_fns.Object[name]; + if (value instanceof AST_RegExp) return native_fns.RegExp[name] && !value.value.global; + } + + function is_modified(compressor, tw, node, value, level, immutable, recursive) { + var parent = tw.parent(level); + if (compressor.option("unsafe") && parent instanceof AST_Dot && is_read_only_fn(value, parent.property)) { + return; + } + var lhs = is_lhs(node, parent); + if (lhs) return lhs; + if (level == 0 && value && value.is_constant()) return; + if (parent instanceof AST_Array) return is_modified(compressor, tw, parent, parent, level + 1); + if (parent instanceof AST_Assign) switch (parent.operator) { + case "=": + return is_modified(compressor, tw, parent, value, level + 1, immutable, recursive); + case "&&=": + case "||=": + case "??=": + return is_modified(compressor, tw, parent, parent, level + 1); + default: + return; + } + if (parent instanceof AST_Binary) { + if (!lazy_op[parent.operator]) return; + return is_modified(compressor, tw, parent, parent, level + 1); + } + if (parent instanceof AST_Call) { + return !immutable + && parent.expression === node + && !parent.is_expr_pure(compressor) + && (!(value instanceof AST_LambdaExpression) || !(parent instanceof AST_New) && value.contains_this()); + } + if (parent instanceof AST_Conditional) { + if (parent.condition === node) return; + return is_modified(compressor, tw, parent, parent, level + 1); + } + if (parent instanceof AST_ForEnumeration) return parent.init === node; + if (parent instanceof AST_ObjectKeyVal) { + if (parent.value !== node) return; + var obj = tw.parent(level + 1); + return is_modified(compressor, tw, obj, obj, level + 2); + } + if (parent instanceof AST_PropAccess) { + if (parent.expression !== node) return; + var prop = read_property(value, parent); + return (!immutable || recursive) && is_modified(compressor, tw, parent, prop, level + 1); + } + if (parent instanceof AST_Sequence) { + if (parent.tail_node() !== node) return; + return is_modified(compressor, tw, parent, value, level + 1, immutable, recursive); + } + } + + function is_lambda(node) { + return node instanceof AST_Class || node instanceof AST_Lambda; + } + + function safe_for_extends(node) { + return node instanceof AST_Class || node instanceof AST_Defun || node instanceof AST_Function; + } + + function is_arguments(def) { + return def.name == "arguments" && def.scope.uses_arguments; + } + + function cross_scope(def, sym) { + do { + if (def === sym) return false; + if (sym instanceof AST_Scope) return true; + } while (sym = sym.parent_scope); + } + + function can_drop_symbol(ref, compressor, keep_lambda) { + var def = ref.redef || ref.definition(); + if (ref.in_arg && is_funarg(def)) return false; + return all(def.orig, function(sym) { + if (sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet) { + if (sym instanceof AST_SymbolImport) return true; + return compressor && can_varify(compressor, sym); + } + return !(keep_lambda && sym instanceof AST_SymbolLambda); + }); + } + + function has_escaped(d, scope, node, parent) { + if (parent instanceof AST_Assign) return parent.operator == "=" && parent.right === node; + if (parent instanceof AST_Call) return parent.expression !== node || parent instanceof AST_New; + if (parent instanceof AST_ClassField) return parent.value === node && !parent.static; + if (parent instanceof AST_Exit) return parent.value === node && scope.resolve() !== d.scope.resolve(); + if (parent instanceof AST_VarDef) return parent.value === node; + } + + function make_ref(ref, fixed) { + var node = make_node(AST_SymbolRef, ref); + node.fixed = fixed || make_node(AST_Undefined, ref); + return node; + } + + function replace_ref(resolve, fixed) { + return function(node) { + var ref = resolve(node); + var node = make_ref(ref, fixed); + var def = ref.definition(); + def.references.push(node); + def.replaced++; + return node; + }; + } + + var RE_POSITIVE_INTEGER = /^(0|[1-9][0-9]*)$/; + (function(def) { + def(AST_Node, noop); + + function reset_def(tw, compressor, def) { + def.assignments = 0; + def.bool_return = 0; + def.drop_return = 0; + def.cross_loop = false; + def.direct_access = false; + def.escaped = []; + def.fixed = !def.const_redefs + && !def.scope.pinned() + && !compressor.exposed(def) + && !(def.init instanceof AST_LambdaExpression && def.init !== def.scope) + && def.init; + def.reassigned = 0; + def.recursive_refs = 0; + def.references = []; + def.single_use = undefined; + } + + function reset_block_variables(tw, compressor, scope) { + scope.variables.each(function(def) { + reset_def(tw, compressor, def); + }); + } + + function reset_variables(tw, compressor, scope) { + scope.fn_defs = []; + scope.variables.each(function(def) { + reset_def(tw, compressor, def); + var init = def.init; + if (init instanceof AST_LambdaDefinition) { + scope.fn_defs.push(init); + init.safe_ids = null; + } + if (def.fixed === null) { + def.safe_ids = tw.safe_ids; + mark(tw, def); + } else if (def.fixed) { + tw.loop_ids[def.id] = tw.in_loop; + mark(tw, def); + } + }); + scope.may_call_this = function() { + scope.may_call_this = scope.contains_this() ? return_true : return_false; + }; + if (scope.uses_arguments) scope.each_argname(function(node) { + node.definition().last_ref = false; + }); + if (compressor.option("ie")) scope.variables.each(function(def) { + var d = def.orig[0].definition(); + if (d !== def) d.fixed = false; + }); + } + + function safe_to_visit(tw, fn) { + var marker = fn.safe_ids; + return marker === undefined || marker === tw.safe_ids; + } + + function walk_fn_def(tw, fn) { + var was_scanning = tw.fn_scanning; + tw.fn_scanning = fn; + fn.walk(tw); + tw.fn_scanning = was_scanning; + } + + function revisit_fn_def(tw, fn) { + fn.enclosed.forEach(function(d) { + if (fn.variables.get(d.name) === d) return; + if (safe_to_read(tw, d)) return; + d.single_use = false; + var fixed = d.fixed; + if (typeof fixed == "function") fixed = fixed(); + if (fixed instanceof AST_Lambda && fixed.safe_ids !== undefined) return; + d.fixed = false; + }); + } + + function mark_fn_def(tw, def, fn) { + var marker = fn.safe_ids; + if (marker === undefined) return; + if (marker === false) return; + if (fn.parent_scope.resolve().may_call_this === return_true) { + if (member(fn, tw.fn_visited)) revisit_fn_def(tw, fn); + } else if (marker) { + var visited = member(fn, tw.fn_visited); + if (marker === tw.safe_ids) { + if (!visited) walk_fn_def(tw, fn); + } else if (visited) { + revisit_fn_def(tw, fn); + } else { + fn.safe_ids = false; + } + } else if (tw.fn_scanning && tw.fn_scanning !== def.scope.resolve()) { + fn.safe_ids = false; + } else { + fn.safe_ids = tw.safe_ids; + walk_fn_def(tw, fn); + } + } + + function pop_scope(tw, scope) { + var fn_defs = scope.fn_defs; + var tangled = scope.may_call_this === return_true ? fn_defs : fn_defs.filter(function(fn) { + if (fn.safe_ids === false) return true; + fn.safe_ids = tw.safe_ids; + walk_fn_def(tw, fn); + return false; + }); + pop(tw); + tangled.forEach(function(fn) { + fn.safe_ids = tw.safe_ids; + walk_fn_def(tw, fn); + }); + fn_defs.forEach(function(fn) { + fn.safe_ids = undefined; + }); + scope.fn_defs = undefined; + scope.may_call_this = undefined; + } + + function push(tw, sequential) { + var safe_ids = Object.create(tw.safe_ids); + if (!sequential) safe_ids.seq = {}; + tw.safe_ids = safe_ids; + } + + function pop(tw) { + tw.safe_ids = Object.getPrototypeOf(tw.safe_ids); + } + + function mark(tw, def) { + tw.safe_ids[def.id] = {}; + } + + function push_ref(def, ref) { + def.references.push(ref); + if (def.last_ref !== false) def.last_ref = ref; + } + + function safe_to_read(tw, def) { + if (def.single_use == "m") return false; + var safe = tw.safe_ids[def.id]; + if (safe) { + var in_order = HOP(tw.safe_ids, def.id); + if (!in_order) { + var seq = tw.safe_ids.seq; + if (!safe.read) { + safe.read = seq; + } else if (safe.read !== seq) { + safe.read = true; + } + } + if (def.fixed == null) { + if (is_arguments(def)) return false; + if (def.global && def.name == "arguments") return false; + tw.loop_ids[def.id] = null; + def.fixed = make_node(AST_Undefined, def.orig[0]); + if (in_order) def.safe_ids = undefined; + return true; + } + return !safe.assign || safe.assign === tw.safe_ids; + } + return def.fixed instanceof AST_LambdaDefinition; + } + + function safe_to_assign(tw, def, declare) { + if (!declare) { + if (is_funarg(def) && def.scope.uses_arguments && !tw.has_directive("use strict")) return false; + if (!all(def.orig, function(sym) { + return !(sym instanceof AST_SymbolConst); + })) return false; + } + if (def.fixed === undefined) return declare || all(def.orig, function(sym) { + return !(sym instanceof AST_SymbolLet); + }); + if (def.fixed === false || def.fixed === 0) return false; + var safe = tw.safe_ids[def.id]; + if (def.safe_ids) { + def.safe_ids[def.id] = false; + def.safe_ids = undefined; + return def.fixed === null || HOP(tw.safe_ids, def.id) && !safe.read; + } + if (!HOP(tw.safe_ids, def.id)) { + if (!safe) return false; + if (safe.read || tw.in_loop) { + var scope = tw.find_parent(AST_BlockScope); + if (scope instanceof AST_Class) return false; + if (def.scope.resolve() !== scope.resolve()) return false; + } + safe.assign = safe.assign && safe.assign !== tw.safe_ids ? true : tw.safe_ids; + } + if (def.fixed != null && safe.read) { + if (safe.read !== tw.safe_ids.seq) return false; + if (tw.loop_ids[def.id] !== tw.in_loop) return false; + } + return safe_to_read(tw, def) && all(def.orig, function(sym) { + return !(sym instanceof AST_SymbolLambda); + }); + } + + function ref_once(compressor, def) { + return compressor.option("unused") + && !def.scope.pinned() + && def.single_use !== false + && def.references.length - def.recursive_refs == 1 + && !(is_funarg(def) && def.scope.uses_arguments); + } + + function is_immutable(value) { + if (!value) return false; + if (value instanceof AST_Assign) { + var op = value.operator; + return op == "=" ? is_immutable(value.right) : !lazy_op[op.slice(0, -1)]; + } + if (value instanceof AST_Sequence) return is_immutable(value.tail_node()); + return value.is_constant() || is_lambda(value) || value instanceof AST_ObjectIdentity; + } + + function value_in_use(node, parent) { + if (parent instanceof AST_Array) return true; + if (parent instanceof AST_Binary) return lazy_op[parent.operator]; + if (parent instanceof AST_Conditional) return parent.condition !== node; + if (parent instanceof AST_Sequence) return parent.tail_node() === node; + if (parent instanceof AST_Spread) return true; + } + + function mark_escaped(tw, d, scope, node, value, level, depth) { + var parent = tw.parent(level); + if (value && value.is_constant()) return; + if (has_escaped(d, scope, node, parent)) { + d.escaped.push(parent); + if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1; + if (!d.escaped.depth || d.escaped.depth > depth) d.escaped.depth = depth; + if (d.scope.resolve() !== scope.resolve()) d.escaped.cross_scope = true; + if (d.fixed) d.fixed.escaped = d.escaped; + return; + } else if (value_in_use(node, parent)) { + mark_escaped(tw, d, scope, parent, parent, level + 1, depth); + } else if (parent instanceof AST_ObjectKeyVal && parent.value === node) { + var obj = tw.parent(level + 1); + mark_escaped(tw, d, scope, obj, obj, level + 2, depth); + } else if (parent instanceof AST_PropAccess && parent.expression === node) { + value = read_property(value, parent); + mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1); + if (value) return; + } + if (level > 0) return; + if (parent instanceof AST_Call && parent.expression === node) return; + if (parent instanceof AST_Sequence && parent.tail_node() !== node) return; + if (parent instanceof AST_SimpleStatement) return; + if (parent instanceof AST_Unary && !unary_side_effects[parent.operator]) return; + d.direct_access = true; + if (d.fixed) d.fixed.direct_access = true; + } + + function mark_assignment_to_arguments(node) { + if (!(node instanceof AST_Sub)) return; + var expr = node.expression; + if (!(expr instanceof AST_SymbolRef)) return; + var def = expr.definition(); + if (!is_arguments(def)) return; + var key = node.property; + if (key.is_constant()) key = key.value; + if (!(key instanceof AST_Node) && !RE_POSITIVE_INTEGER.test(key)) return; + def.reassigned++; + (key instanceof AST_Node ? def.scope.argnames : [ def.scope.argnames[key] ]).forEach(function(argname) { + if (argname instanceof AST_SymbolFunarg) argname.definition().fixed = false; + }); + } + + function make_fixed(save, fn) { + var prev_save, prev_value; + return function() { + var current = save(); + if (prev_save !== current) { + prev_save = current; + prev_value = fn(current); + } + return prev_value; + }; + } + + function make_fixed_default(compressor, node, save) { + var prev_save, prev_seq; + return function() { + if (prev_seq === node) return node; + var current = save(); + var ev = fuzzy_eval(compressor, current, true); + if (ev instanceof AST_Node) { + prev_seq = node; + } else if (prev_save !== current) { + prev_save = current; + prev_seq = ev === undefined ? make_sequence(node, [ current, node.value ]) : current; + } + return prev_seq; + }; + } + + function scan_declaration(tw, compressor, lhs, fixed, visit) { + var scanner = new TreeWalker(function(node) { + if (node instanceof AST_DefaultValue) { + reset_flags(node); + push(tw, true); + node.value.walk(tw); + pop(tw); + var save = fixed; + if (save) fixed = make_fixed_default(compressor, node, save); + node.name.walk(scanner); + fixed = save; + return true; + } + if (node instanceof AST_DestructuredArray) { + reset_flags(node); + var save = fixed; + node.elements.forEach(function(node, index) { + if (node instanceof AST_Hole) return reset_flags(node); + if (save) fixed = make_fixed(save, function(value) { + return make_node(AST_Sub, node, { + expression: value, + property: make_node(AST_Number, node, { value: index }), + }); + }); + node.walk(scanner); + }); + if (node.rest) { + var fixed_node; + if (save) fixed = compressor.option("rests") && make_fixed(save, function(value) { + if (!(value instanceof AST_Array)) return node; + for (var i = 0, len = node.elements.length; i < len; i++) { + if (value.elements[i] instanceof AST_Spread) return node; + } + if (!fixed_node) fixed_node = make_node(AST_Array, node, {}); + fixed_node.elements = value.elements.slice(len); + return fixed_node; + }); + node.rest.walk(scanner); + } + fixed = save; + return true; + } + if (node instanceof AST_DestructuredObject) { + reset_flags(node); + var save = fixed; + node.properties.forEach(function(node) { + reset_flags(node); + if (node.key instanceof AST_Node) { + push(tw); + node.key.walk(tw); + pop(tw); + } + if (save) fixed = make_fixed(save, function(value) { + var key = node.key; + var type = AST_Sub; + if (typeof key == "string") { + if (is_identifier_string(key)) { + type = AST_Dot; + } else { + key = make_node_from_constant(key, node); + } + } + return make_node(type, node, { + expression: value, + property: key, + }); + }); + node.value.walk(scanner); + }); + if (node.rest) { + fixed = false; + node.rest.walk(scanner); + } + fixed = save; + return true; + } + visit(node, fixed, function() { + var save_len = tw.stack.length; + for (var i = 0, len = scanner.stack.length - 1; i < len; i++) { + tw.stack.push(scanner.stack[i]); + } + node.walk(tw); + tw.stack.length = save_len; + }); + return true; + }); + lhs.walk(scanner); + } + + function reduce_iife(tw, descend, compressor) { + var fn = this; + fn.inlined = false; + var iife = tw.parent(); + var sequential = !is_async(fn) && !is_generator(fn); + var hit = !sequential; + var aborts = false; + fn.walk(new TreeWalker(function(node) { + if (hit) return aborts = true; + if (node instanceof AST_Return) return hit = true; + if (node instanceof AST_Scope && node !== fn) return true; + })); + if (aborts) push(tw, sequential); + reset_variables(tw, compressor, fn); + // Virtually turn IIFE parameters into variable definitions: + // (function(a,b) {...})(c,d) ---> (function() {var a=c,b=d; ...})() + // So existing transformation rules can work on them. + var safe = !fn.uses_arguments || tw.has_directive("use strict"); + fn.argnames.forEach(function(argname, i) { + var value = iife.args[i]; + scan_declaration(tw, compressor, argname, function() { + var j = fn.argnames.indexOf(argname); + var arg = j < 0 ? value : iife.args[j]; + if (arg instanceof AST_Sequence && arg.expressions.length < 2) arg = arg.expressions[0]; + return arg || make_node(AST_Undefined, iife); + }, visit); + }); + var rest = fn.rest, fixed_node; + if (rest) scan_declaration(tw, compressor, rest, compressor.option("rests") && function() { + if (fn.rest !== rest) return rest; + if (!fixed_node) fixed_node = make_node(AST_Array, fn, {}); + fixed_node.elements = iife.args.slice(fn.argnames.length); + return fixed_node; + }, visit); + walk_lambda(fn, tw); + var safe_ids = tw.safe_ids; + pop_scope(tw, fn); + if (!aborts) tw.safe_ids = safe_ids; + return true; + + function visit(node, fixed) { + var d = node.definition(); + if (fixed && safe && d.fixed === undefined) { + mark(tw, d); + tw.loop_ids[d.id] = tw.in_loop; + d.fixed = fixed; + d.fixed.assigns = [ node ]; + } else { + d.fixed = false; + } + } + } + + def(AST_Assign, function(tw, descend, compressor) { + var node = this; + var left = node.left; + var right = node.right; + var ld = left instanceof AST_SymbolRef && left.definition(); + var scan = ld || left instanceof AST_Destructured; + switch (node.operator) { + case "=": + if (left.equals(right) && !left.has_side_effects(compressor)) { + right.walk(tw); + walk_prop(left); + node.redundant = true; + return true; + } + if (ld && right instanceof AST_LambdaExpression) { + walk_assign(); + right.parent_scope.resolve().fn_defs.push(right); + right.safe_ids = null; + if (!ld.fixed || !node.write_only) mark_fn_def(tw, ld, right); + return true; + } + if (scan) { + right.walk(tw); + walk_assign(); + return true; + } + mark_assignment_to_arguments(left); + return; + case "&&=": + case "||=": + case "??=": + var lazy = true; + default: + if (!scan) { + mark_assignment_to_arguments(left); + return walk_lazy(); + } + ld.assignments++; + var fixed = ld.fixed; + if (is_modified(compressor, tw, node, node, 0)) { + ld.fixed = false; + return walk_lazy(); + } + var safe = safe_to_read(tw, ld); + if (lazy) push(tw, true); + right.walk(tw); + if (lazy) pop(tw); + if (safe && !left.in_arg && safe_to_assign(tw, ld)) { + push_ref(ld, left); + mark(tw, ld); + if (ld.single_use) ld.single_use = false; + left.fixed = ld.fixed = function() { + return make_node(AST_Binary, node, { + operator: node.operator.slice(0, -1), + left: make_ref(left, fixed), + right: node.right, + }); + }; + left.fixed.assigns = !fixed || !fixed.assigns ? [ ld.orig[0] ] : fixed.assigns.slice(); + left.fixed.assigns.push(node); + left.fixed.to_binary = replace_ref(function(node) { + return node.left; + }, fixed); + } else { + left.walk(tw); + ld.fixed = false; + } + return true; + } + + function walk_prop(lhs) { + reset_flags(lhs); + if (lhs instanceof AST_Dot) { + walk_prop(lhs.expression); + } else if (lhs instanceof AST_Sub) { + walk_prop(lhs.expression); + lhs.property.walk(tw); + } else if (lhs instanceof AST_SymbolRef) { + var d = lhs.definition(); + push_ref(d, lhs); + if (d.fixed) { + lhs.fixed = d.fixed; + if (lhs.fixed.assigns) { + lhs.fixed.assigns.push(node); + } else { + lhs.fixed.assigns = [ node ]; + } + } + } else { + lhs.walk(tw); + } + } + + function walk_assign() { + var recursive = ld && recursive_ref(tw, ld); + var modified = is_modified(compressor, tw, node, right, 0, is_immutable(right), recursive); + scan_declaration(tw, compressor, left, function() { + return node.right; + }, function(sym, fixed, walk) { + if (!(sym instanceof AST_SymbolRef)) { + mark_assignment_to_arguments(sym); + walk(); + return; + } + var d = sym.definition(); + d.assignments++; + if (!fixed || sym.in_arg || !safe_to_assign(tw, d)) { + walk(); + d.fixed = false; + } else { + push_ref(d, sym); + mark(tw, d); + if (left instanceof AST_Destructured + || d.orig.length == 1 && d.orig[0] instanceof AST_SymbolDefun) { + d.single_use = false; + } + tw.loop_ids[d.id] = tw.in_loop; + d.fixed = modified ? 0 : fixed; + sym.fixed = fixed; + sym.fixed.assigns = [ node ]; + mark_escaped(tw, d, sym.scope, node, right, 0, 1); + } + }); + } + + function walk_lazy() { + if (!lazy) return; + left.walk(tw); + push(tw, true); + right.walk(tw); + pop(tw); + return true; + } + }); + def(AST_Binary, function(tw) { + if (!lazy_op[this.operator]) return; + this.left.walk(tw); + push(tw, true); + this.right.walk(tw); + pop(tw); + return true; + }); + def(AST_BlockScope, function(tw, descend, compressor) { + reset_block_variables(tw, compressor, this); + }); + def(AST_Call, function(tw, descend) { + var node = this; + var exp = node.expression; + if (exp instanceof AST_LambdaExpression) { + var iife = is_iife_single(node); + node.args.forEach(function(arg) { + arg.walk(tw); + if (arg instanceof AST_Spread) iife = false; + }); + if (iife) exp.reduce_vars = reduce_iife; + exp.walk(tw); + if (iife) delete exp.reduce_vars; + return true; + } + if (node.TYPE == "Call") switch (tw.in_boolean_context()) { + case "d": + var drop = true; + case true: + mark_refs(exp, drop); + } + exp.walk(tw); + var optional = node.optional; + if (optional) push(tw, true); + node.args.forEach(function(arg) { + arg.walk(tw); + }); + if (optional) pop(tw); + var fixed = exp instanceof AST_SymbolRef && exp.fixed_value(); + if (fixed instanceof AST_Lambda) { + mark_fn_def(tw, exp.definition(), fixed); + } else { + tw.find_parent(AST_Scope).may_call_this(); + } + return true; + + function mark_refs(node, drop) { + if (node instanceof AST_Assign) { + if (node.operator != "=") return; + mark_refs(node.left, drop); + mark_refs(node.right, drop); + } else if (node instanceof AST_Binary) { + if (!lazy_op[node.operator]) return; + mark_refs(node.left, drop); + mark_refs(node.right, drop); + } else if (node instanceof AST_Conditional) { + mark_refs(node.consequent, drop); + mark_refs(node.alternative, drop); + } else if (node instanceof AST_SymbolRef) { + var def = node.definition(); + def.bool_return++; + if (drop) def.drop_return++; + } + } + }); + def(AST_Class, function(tw, descend, compressor) { + var node = this; + reset_block_variables(tw, compressor, node); + if (node.extends) node.extends.walk(tw); + var props = node.properties.filter(function(prop) { + reset_flags(prop); + if (prop.key instanceof AST_Node) { + tw.push(prop); + prop.key.walk(tw); + tw.pop(); + } + return prop.value; + }); + if (node.name) { + var d = node.name.definition(); + var parent = tw.parent(); + if (parent instanceof AST_ExportDeclaration || parent instanceof AST_ExportDefault) d.single_use = false; + if (safe_to_assign(tw, d, true)) { + mark(tw, d); + tw.loop_ids[d.id] = tw.in_loop; + d.fixed = function() { + return node; + }; + d.fixed.assigns = [ node ]; + if (!is_safe_lexical(d)) d.single_use = false; + } else { + d.fixed = false; + } + } + props.forEach(function(prop) { + tw.push(prop); + if (!prop.static || is_static_field_or_init(prop) && prop.value.contains_this()) { + push(tw); + prop.value.walk(tw); + pop(tw); + } else { + prop.value.walk(tw); + } + tw.pop(); + }); + return true; + }); + def(AST_ClassInitBlock, function(tw, descend, compressor) { + var node = this; + push(tw, true); + reset_variables(tw, compressor, node); + descend(); + pop_scope(tw, node); + return true; + }); + def(AST_Conditional, function(tw) { + this.condition.walk(tw); + push(tw, true); + this.consequent.walk(tw); + pop(tw); + push(tw, true); + this.alternative.walk(tw); + pop(tw); + return true; + }); + def(AST_DefaultValue, function(tw) { + push(tw, true); + this.value.walk(tw); + pop(tw); + this.name.walk(tw); + return true; + }); + def(AST_Do, function(tw) { + var save_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + this.body.walk(tw); + if (has_loop_control(this, tw.parent())) { + pop(tw); + push(tw); + } + this.condition.walk(tw); + pop(tw); + tw.in_loop = save_loop; + return true; + }); + def(AST_For, function(tw, descend, compressor) { + var node = this; + reset_block_variables(tw, compressor, node); + if (node.init) node.init.walk(tw); + var save_loop = tw.in_loop; + tw.in_loop = node; + push(tw); + if (node.condition) node.condition.walk(tw); + node.body.walk(tw); + if (node.step) { + if (has_loop_control(node, tw.parent())) { + pop(tw); + push(tw); + } + node.step.walk(tw); + } + pop(tw); + tw.in_loop = save_loop; + return true; + }); + def(AST_ForEnumeration, function(tw, descend, compressor) { + var node = this; + reset_block_variables(tw, compressor, node); + node.object.walk(tw); + var save_loop = tw.in_loop; + tw.in_loop = node; + push(tw); + var init = node.init; + if (init instanceof AST_Definitions) { + init.definitions[0].name.mark_symbol(function(node) { + if (node instanceof AST_SymbolDeclaration) { + var def = node.definition(); + def.assignments++; + def.fixed = false; + } + }, tw); + } else if (init instanceof AST_Destructured || init instanceof AST_SymbolRef) { + init.mark_symbol(function(node) { + if (node instanceof AST_SymbolRef) { + var def = node.definition(); + push_ref(def, node); + def.assignments++; + if (!node.is_immutable()) def.fixed = false; + } + }, tw); + } else { + init.walk(tw); + } + node.body.walk(tw); + pop(tw); + tw.in_loop = save_loop; + return true; + }); + def(AST_If, function(tw) { + this.condition.walk(tw); + push(tw, true); + this.body.walk(tw); + pop(tw); + if (this.alternative) { + push(tw, true); + this.alternative.walk(tw); + pop(tw); + } + return true; + }); + def(AST_LabeledStatement, function(tw) { + push(tw, true); + this.body.walk(tw); + pop(tw); + return true; + }); + def(AST_Lambda, function(tw, descend, compressor) { + var fn = this; + if (!safe_to_visit(tw, fn)) return true; + if (!push_uniq(tw.fn_visited, fn)) return true; + fn.inlined = false; + push(tw); + reset_variables(tw, compressor, fn); + descend(); + pop_scope(tw, fn); + if (fn.name) mark_escaped(tw, fn.name.definition(), fn, fn.name, fn, 0, 1); + return true; + }); + def(AST_LambdaDefinition, function(tw, descend, compressor) { + var fn = this; + var def = fn.name.definition(); + var parent = tw.parent(); + if (parent instanceof AST_ExportDeclaration || parent instanceof AST_ExportDefault) def.single_use = false; + if (!safe_to_visit(tw, fn)) return true; + if (!push_uniq(tw.fn_visited, fn)) return true; + fn.inlined = false; + push(tw); + reset_variables(tw, compressor, fn); + descend(); + pop_scope(tw, fn); + return true; + }); + def(AST_Sub, function(tw) { + if (!this.optional) return; + this.expression.walk(tw); + push(tw, true); + this.property.walk(tw); + pop(tw); + return true; + }); + def(AST_Switch, function(tw, descend, compressor) { + var node = this; + reset_block_variables(tw, compressor, node); + node.expression.walk(tw); + var first = true; + node.body.forEach(function(branch) { + if (branch instanceof AST_Default) return; + branch.expression.walk(tw); + if (first) { + first = false; + push(tw, true); + } + }) + if (!first) pop(tw); + walk_body(node, tw); + return true; + }); + def(AST_SwitchBranch, function(tw) { + push(tw, true); + walk_body(this, tw); + pop(tw); + return true; + }); + def(AST_SymbolCatch, function() { + this.definition().fixed = false; + }); + def(AST_SymbolImport, function() { + this.definition().fixed = false; + }); + def(AST_SymbolRef, function(tw, descend, compressor) { + var ref = this; + var d = ref.definition(); + var fixed = d.fixed || d.last_ref && d.last_ref.fixed; + push_ref(d, ref); + if (d.references.length == 1 && !d.fixed && d.orig[0] instanceof AST_SymbolDefun) { + tw.loop_ids[d.id] = tw.in_loop; + } + var recursive = recursive_ref(tw, d); + if (recursive) recursive.enclosed.forEach(function(def) { + if (d === def) return; + if (def.scope.resolve() === recursive) return; + var assigns = def.fixed && def.fixed.assigns; + if (!assigns) return; + if (assigns[assigns.length - 1] instanceof AST_VarDef) return; + var safe = tw.safe_ids[def.id]; + if (!safe) return; + safe.assign = true; + }); + if (d.single_use == "m" && d.fixed) { + d.fixed = 0; + d.single_use = false; + } + switch (d.fixed) { + case 0: + if (!safe_to_read(tw, d)) d.fixed = false; + case false: + var redef = d.redefined(); + if (redef && cross_scope(d.scope, ref.scope)) redef.single_use = false; + break; + case undefined: + d.fixed = false; + break; + default: + if (!safe_to_read(tw, d)) { + d.fixed = false; + break; + } + if (ref.in_arg && d.orig[0] instanceof AST_SymbolLambda) ref.fixed = d.scope; + var value = ref.fixed_value(); + if (recursive) { + d.recursive_refs++; + } else if (value && ref_once(compressor, d)) { + d.in_loop = tw.loop_ids[d.id] !== tw.in_loop; + d.single_use = is_lambda(value) + && !value.pinned() + && (!d.in_loop || tw.parent() instanceof AST_Call) + || !d.in_loop + && d.scope === ref.scope.resolve() + && value.is_constant_expression(); + } else { + d.single_use = false; + } + if (is_modified(compressor, tw, ref, value, 0, is_immutable(value), recursive)) { + if (d.single_use) { + d.single_use = "m"; + } else { + d.fixed = 0; + } + } + if (d.fixed && tw.loop_ids[d.id] !== tw.in_loop) d.cross_loop = true; + mark_escaped(tw, d, ref.scope, ref, value, 0, 1); + break; + } + if (!ref.fixed) ref.fixed = d.fixed === 0 ? fixed : d.fixed; + var parent; + if (value instanceof AST_Lambda + && !((parent = tw.parent()) instanceof AST_Call && parent.expression === ref)) { + mark_fn_def(tw, d, value); + } + }); + def(AST_Template, function(tw, descend) { + var node = this; + var tag = node.tag; + if (!tag) return; + if (tag instanceof AST_LambdaExpression) { + node.expressions.forEach(function(exp) { + exp.walk(tw); + }); + tag.walk(tw); + return true; + } + tag.walk(tw); + node.expressions.forEach(function(exp) { + exp.walk(tw); + }); + var fixed = tag instanceof AST_SymbolRef && tag.fixed_value(); + if (fixed instanceof AST_Lambda) { + mark_fn_def(tw, tag.definition(), fixed); + } else { + tw.find_parent(AST_Scope).may_call_this(); + } + return true; + }); + def(AST_Toplevel, function(tw, descend, compressor) { + var node = this; + node.globals.each(function(def) { + reset_def(tw, compressor, def); + }); + push(tw, true); + reset_variables(tw, compressor, node); + descend(); + pop_scope(tw, node); + return true; + }); + def(AST_Try, function(tw, descend, compressor) { + var node = this; + reset_block_variables(tw, compressor, node); + push(tw, true); + walk_body(node, tw); + pop(tw); + if (node.bcatch) { + push(tw, true); + node.bcatch.walk(tw); + pop(tw); + } + if (node.bfinally) node.bfinally.walk(tw); + return true; + }); + def(AST_Unary, function(tw, descend) { + var node = this; + if (!UNARY_POSTFIX[node.operator]) return; + var exp = node.expression; + if (!(exp instanceof AST_SymbolRef)) { + mark_assignment_to_arguments(exp); + return; + } + var d = exp.definition(); + d.assignments++; + var fixed = d.fixed; + if (safe_to_read(tw, d) && !exp.in_arg && safe_to_assign(tw, d)) { + push_ref(d, exp); + mark(tw, d); + if (d.single_use) d.single_use = false; + d.fixed = function() { + return make_node(AST_Binary, node, { + operator: node.operator.slice(0, -1), + left: make_node(AST_UnaryPrefix, node, { + operator: "+", + expression: make_ref(exp, fixed), + }), + right: make_node(AST_Number, node, { value: 1 }), + }); + }; + d.fixed.assigns = fixed && fixed.assigns ? fixed.assigns.slice() : []; + d.fixed.assigns.push(node); + if (node instanceof AST_UnaryPrefix) { + exp.fixed = d.fixed; + } else { + exp.fixed = function() { + return make_node(AST_UnaryPrefix, node, { + operator: "+", + expression: make_ref(exp, fixed), + }); + }; + exp.fixed.assigns = fixed && fixed.assigns; + exp.fixed.to_prefix = replace_ref(function(node) { + return node.expression; + }, d.fixed); + } + } else { + exp.walk(tw); + d.fixed = false; + } + return true; + }); + def(AST_VarDef, function(tw, descend, compressor) { + var node = this; + var value = node.value; + if (value instanceof AST_LambdaExpression && node.name instanceof AST_SymbolDeclaration) { + walk_defn(); + value.parent_scope.resolve().fn_defs.push(value); + value.safe_ids = null; + var ld = node.name.definition(); + if (!ld.fixed) mark_fn_def(tw, ld, value); + } else if (value) { + value.walk(tw); + walk_defn(); + } else if (tw.parent() instanceof AST_Let) { + walk_defn(); + } + return true; + + function walk_defn() { + scan_declaration(tw, compressor, node.name, function() { + return node.value || make_node(AST_Undefined, node); + }, function(name, fixed) { + var d = name.definition(); + if (fixed && safe_to_assign(tw, d, true)) { + mark(tw, d); + tw.loop_ids[d.id] = tw.in_loop; + d.fixed = fixed; + d.fixed.assigns = [ node ]; + if (name instanceof AST_SymbolConst && d.redefined() + || !(can_drop_symbol(name) || is_safe_lexical(d))) { + d.single_use = false; + } + } else { + d.fixed = false; + } + }); + } + }); + def(AST_While, function(tw, descend) { + var save_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + descend(); + pop(tw); + tw.in_loop = save_loop; + return true; + }); + })(function(node, func) { + node.DEFMETHOD("reduce_vars", func); + }); + + function reset_flags(node) { + node._squeezed = false; + node._optimized = false; + if (node instanceof AST_BlockScope) node._var_names = undefined; + if (node instanceof AST_SymbolRef) node.fixed = undefined; + } + + AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) { + var tw = new TreeWalker(compressor.option("reduce_vars") ? function(node, descend) { + reset_flags(node); + return node.reduce_vars(tw, descend, compressor); + } : reset_flags); + // Flow control for visiting lambda definitions + tw.fn_scanning = null; + tw.fn_visited = []; + // Record the loop body in which `AST_SymbolDeclaration` is first encountered + tw.in_loop = null; + tw.loop_ids = Object.create(null); + // Stack of look-up tables to keep track of whether a `SymbolDef` has been + // properly assigned before use: + // - `push()` & `pop()` when visiting conditional branches + // - backup & restore via `save_ids` when visiting out-of-order sections + tw.safe_ids = Object.create(null); + tw.safe_ids.seq = {}; + this.walk(tw); + }); + + AST_Symbol.DEFMETHOD("fixed_value", function(ref_only) { + var def = this.definition(); + var fixed = def.fixed; + if (fixed) { + if (this.fixed) fixed = this.fixed; + return (fixed instanceof AST_Node ? fixed : fixed()).tail_node(); + } + fixed = fixed === 0 && this.fixed; + if (!fixed) return fixed; + var value = (fixed instanceof AST_Node ? fixed : fixed()).tail_node(); + if (ref_only && def.escaped.depth != 1 && is_object(value, true)) return value; + if (value.is_constant()) return value; + }); + + AST_SymbolRef.DEFMETHOD("is_immutable", function() { + var def = this.redef || this.definition(); + if (!(def.orig[0] instanceof AST_SymbolLambda)) return false; + if (def.orig.length == 1) return true; + if (!this.in_arg) return false; + return !(def.orig[1] instanceof AST_SymbolFunarg); + }); + + AST_Node.DEFMETHOD("convert_symbol", noop); + function convert_destructured(type, process) { + return this.transform(new TreeTransformer(function(node, descend) { + if (node instanceof AST_DefaultValue) { + node = node.clone(); + node.name = node.name.transform(this); + return node; + } + if (node instanceof AST_Destructured) { + node = node.clone(); + descend(node, this); + return node; + } + if (node instanceof AST_DestructuredKeyVal) { + node = node.clone(); + node.value = node.value.transform(this); + return node; + } + return node.convert_symbol(type, process); + })); + } + AST_DefaultValue.DEFMETHOD("convert_symbol", convert_destructured); + AST_Destructured.DEFMETHOD("convert_symbol", convert_destructured); + function convert_symbol(type, process) { + var node = make_node(type, this); + return process(node, this) || node; + } + AST_SymbolDeclaration.DEFMETHOD("convert_symbol", convert_symbol); + AST_SymbolRef.DEFMETHOD("convert_symbol", convert_symbol); + + function process_to_assign(ref) { + var def = ref.definition(); + def.assignments++; + def.references.push(ref); + } + + function mark_destructured(process, tw) { + var marker = new TreeWalker(function(node) { + if (node instanceof AST_DefaultValue) { + node.value.walk(tw); + node.name.walk(marker); + return true; + } + if (node instanceof AST_DestructuredKeyVal) { + if (node.key instanceof AST_Node) node.key.walk(tw); + node.value.walk(marker); + return true; + } + return process(node); + }); + this.walk(marker); + } + AST_DefaultValue.DEFMETHOD("mark_symbol", mark_destructured); + AST_Destructured.DEFMETHOD("mark_symbol", mark_destructured); + function mark_symbol(process) { + return process(this); + } + AST_SymbolDeclaration.DEFMETHOD("mark_symbol", mark_symbol); + AST_SymbolRef.DEFMETHOD("mark_symbol", mark_symbol); + + AST_Node.DEFMETHOD("match_symbol", function(predicate) { + return predicate(this); + }); + function match_destructured(predicate, ignore_side_effects) { + var found = false; + var tw = new TreeWalker(function(node) { + if (found) return true; + if (node instanceof AST_DefaultValue) { + if (!ignore_side_effects) return found = true; + node.name.walk(tw); + return true; + } + if (node instanceof AST_DestructuredKeyVal) { + if (!ignore_side_effects && node.key instanceof AST_Node) return found = true; + node.value.walk(tw); + return true; + } + if (predicate(node)) return found = true; + }); + this.walk(tw); + return found; + } + AST_DefaultValue.DEFMETHOD("match_symbol", match_destructured); + AST_Destructured.DEFMETHOD("match_symbol", match_destructured); + + function in_async_generator(scope) { + return scope instanceof AST_AsyncGeneratorDefun || scope instanceof AST_AsyncGeneratorFunction; + } + + function find_scope(compressor) { + var level = 0, node = compressor.self(); + do { + if (node.variables) return node; + } while (node = compressor.parent(level++)); + } + + function find_try(compressor, level, node, scope, may_throw, sync) { + for (var parent; parent = compressor.parent(level++); node = parent) { + if (parent === scope) return false; + if (sync && parent instanceof AST_Lambda) { + if (parent.name || is_async(parent) || is_generator(parent)) return true; + } else if (parent instanceof AST_Try) { + if (parent.bfinally && parent.bfinally !== node) return true; + if (may_throw && parent.bcatch && parent.bcatch !== node) return true; + } + } + return false; + } + + var identifier_atom = makePredicate("Infinity NaN undefined"); + function is_lhs_read_only(lhs, compressor) { + if (lhs instanceof AST_Atom) return true; + if (lhs instanceof AST_ObjectIdentity) return true; + if (lhs instanceof AST_PropAccess) { + if (lhs.property === "__proto__") return true; + lhs = lhs.expression; + if (lhs instanceof AST_SymbolRef) { + if (lhs.is_immutable()) return false; + lhs = lhs.fixed_value(); + } + if (!lhs) return true; + if (lhs.tail_node().is_constant()) return true; + return is_lhs_read_only(lhs, compressor); + } + if (lhs instanceof AST_SymbolRef) { + if (lhs.is_immutable()) return true; + var def = lhs.definition(); + return compressor.exposed(def) && identifier_atom[def.name]; + } + return false; + } + + function make_node(ctor, orig, props) { + if (props) { + props.start = orig.start; + props.end = orig.end; + } else { + props = orig; + } + return new ctor(props); + } + + function make_sequence(orig, expressions) { + if (expressions.length == 1) return expressions[0]; + return make_node(AST_Sequence, orig, { expressions: expressions.reduce(merge_sequence, []) }); + } + + function make_node_from_constant(val, orig) { + switch (typeof val) { + case "string": + return make_node(AST_String, orig, { value: val }); + case "number": + if (isNaN(val)) return make_node(AST_NaN, orig); + if (isFinite(val)) { + return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, { + operator: "-", + expression: make_node(AST_Number, orig, { value: -val }), + }) : make_node(AST_Number, orig, { value: val }); + } + return val < 0 ? make_node(AST_UnaryPrefix, orig, { + operator: "-", + expression: make_node(AST_Infinity, orig), + }) : make_node(AST_Infinity, orig); + case "boolean": + return make_node(val ? AST_True : AST_False, orig); + case "undefined": + return make_node(AST_Undefined, orig); + default: + if (val === null) { + return make_node(AST_Null, orig); + } + if (val instanceof RegExp) { + return make_node(AST_RegExp, orig, { value: val }); + } + throw new Error(string_template("Can't handle constant of type: {type}", { type: typeof val })); + } + } + + function needs_unbinding(val) { + return val instanceof AST_PropAccess + || is_undeclared_ref(val) && val.name == "eval"; + } + + // we shouldn't compress (1,func)(something) to + // func(something) because that changes the meaning of + // the func (becomes lexical instead of global). + function maintain_this_binding(parent, orig, val) { + var wrap = false; + if (parent.TYPE == "Call") { + wrap = parent.expression === orig && needs_unbinding(val); + } else if (parent instanceof AST_Template) { + wrap = parent.tag === orig && needs_unbinding(val); + } else if (parent instanceof AST_UnaryPrefix) { + wrap = parent.operator == "delete" + || parent.operator == "typeof" && is_undeclared_ref(val); + } + return wrap ? make_sequence(orig, [ make_node(AST_Number, orig, { value: 0 }), val ]) : val; + } + + function merge_expression(base, target) { + var fixed_by_id = new Dictionary(); + base.walk(new TreeWalker(function(node) { + if (!(node instanceof AST_SymbolRef)) return; + var def = node.definition(); + var fixed = node.fixed; + if (!fixed || !fixed_by_id.has(def.id)) { + fixed_by_id.set(def.id, fixed); + } else if (fixed_by_id.get(def.id) !== fixed) { + fixed_by_id.set(def.id, false); + } + })); + if (fixed_by_id.size() > 0) target.walk(new TreeWalker(function(node) { + if (!(node instanceof AST_SymbolRef)) return; + var def = node.definition(); + var fixed = node.fixed; + if (!fixed || !fixed_by_id.has(def.id)) return; + if (fixed_by_id.get(def.id) !== fixed) node.fixed = false; + })); + return target; + } + + function merge_sequence(array, node) { + if (node instanceof AST_Sequence) { + [].push.apply(array, node.expressions); + } else { + array.push(node); + } + return array; + } + + function is_lexical_definition(stat) { + return stat instanceof AST_Const || stat instanceof AST_DefClass || stat instanceof AST_Let; + } + + function safe_to_trim(stat) { + if (stat instanceof AST_LambdaDefinition) { + var def = stat.name.definition(); + var scope = stat.name.scope; + return def.scope === scope || all(def.references, function(ref) { + var s = ref.scope; + do { + if (s === scope) return true; + } while (s = s.parent_scope); + }); + } + return !is_lexical_definition(stat); + } + + function as_statement_array(thing) { + if (thing === null) return []; + if (thing instanceof AST_BlockStatement) return all(thing.body, safe_to_trim) ? thing.body : [ thing ]; + if (thing instanceof AST_EmptyStatement) return []; + if (is_statement(thing)) return [ thing ]; + throw new Error("Can't convert thing to statement array"); + } + + function is_empty(thing) { + if (thing === null) return true; + if (thing instanceof AST_EmptyStatement) return true; + if (thing instanceof AST_BlockStatement) return thing.body.length == 0; + return false; + } + + function has_declarations_only(block) { + return all(block.body, function(stat) { + return is_empty(stat) + || stat instanceof AST_Defun + || stat instanceof AST_Var && declarations_only(stat); + }); + } + + function loop_body(x) { + if (x instanceof AST_IterationStatement) { + return x.body instanceof AST_BlockStatement ? x.body : x; + } + return x; + } + + function is_iife_call(node) { + if (node.TYPE != "Call") return false; + do { + node = node.expression; + } while (node instanceof AST_PropAccess); + return node instanceof AST_LambdaExpression ? !is_arrow(node) : is_iife_call(node); + } + + function is_iife_single(call) { + var exp = call.expression; + if (exp.name) return false; + if (!(call instanceof AST_New)) return true; + var found = false; + exp.walk(new TreeWalker(function(node) { + if (found) return true; + if (node instanceof AST_NewTarget) return found = true; + if (node instanceof AST_Scope && node !== exp) return true; + })); + return !found; + } + + function is_undeclared_ref(node) { + return node instanceof AST_SymbolRef && node.definition().undeclared; + } + + var global_names = makePredicate("Array Boolean clearInterval clearTimeout console Date decodeURI decodeURIComponent encodeURI encodeURIComponent Error escape eval EvalError Function isFinite isNaN JSON Map Math Number parseFloat parseInt RangeError ReferenceError RegExp Object Set setInterval setTimeout String SyntaxError TypeError unescape URIError WeakMap WeakSet"); + AST_SymbolRef.DEFMETHOD("is_declared", function(compressor) { + return this.defined + || !this.definition().undeclared + || compressor.option("unsafe") && global_names[this.name]; + }); + + function is_static_field_or_init(prop) { + return prop.static && prop.value && (prop instanceof AST_ClassField || prop instanceof AST_ClassInit); + } + + function declarations_only(node) { + return all(node.definitions, function(var_def) { + return !var_def.value; + }); + } + + function is_declaration(stat, lexical) { + if (stat instanceof AST_DefClass) return lexical && !stat.extends && all(stat.properties, function(prop) { + if (prop.key instanceof AST_Node) return false; + return !is_static_field_or_init(prop); + }); + if (stat instanceof AST_Definitions) return (lexical || stat instanceof AST_Var) && declarations_only(stat); + if (stat instanceof AST_ExportDeclaration) return is_declaration(stat.body, lexical); + if (stat instanceof AST_ExportDefault) return is_declaration(stat.body, lexical); + return stat instanceof AST_LambdaDefinition; + } + + function is_last_statement(body, stat) { + var index = body.lastIndexOf(stat); + if (index < 0) return false; + while (++index < body.length) { + if (!is_declaration(body[index], true)) return false; + } + return true; + } + + // Certain combination of unused name + side effect leads to invalid AST: + // https://github.com/mishoo/UglifyJS/issues/44 + // https://github.com/mishoo/UglifyJS/issues/1838 + // https://github.com/mishoo/UglifyJS/issues/3371 + // We fix it at this stage by moving the `var` outside the `for`. + function patch_for_init(node, in_list) { + var block; + if (node.init instanceof AST_BlockStatement) { + block = node.init; + node.init = block.body.pop(); + block.body.push(node); + } + if (node.init instanceof AST_Defun) { + if (!block) block = make_node(AST_BlockStatement, node, { body: [ node ] }); + block.body.splice(-1, 0, node.init); + node.init = null; + } else if (node.init instanceof AST_SimpleStatement) { + node.init = node.init.body; + } else if (is_empty(node.init)) { + node.init = null; + } + if (!block) return; + return in_list ? List.splice(block.body) : block; + } + + function tighten_body(statements, compressor) { + var in_lambda = last_of(compressor, function(node) { + return node instanceof AST_Lambda; + }); + var block_scope, iife_in_try, in_iife_single, in_loop, in_try, scope; + find_loop_scope_try(); + var changed, last_changed, max_iter = 10; + do { + last_changed = changed; + changed = 0; + if (eliminate_spurious_blocks(statements)) changed = 1; + if (!changed && last_changed == 1) break; + if (compressor.option("dead_code")) { + if (eliminate_dead_code(statements, compressor)) changed = 2; + if (!changed && last_changed == 2) break; + } + if (compressor.option("if_return")) { + if (handle_if_return(statements, compressor)) changed = 3; + if (!changed && last_changed == 3) break; + } + if (compressor.option("awaits") && compressor.option("side_effects")) { + if (trim_awaits(statements, compressor)) changed = 4; + if (!changed && last_changed == 4) break; + } + if (compressor.option("inline") >= 4) { + if (inline_iife(statements, compressor)) changed = 5; + if (!changed && last_changed == 5) break; + } + if (compressor.sequences_limit > 0) { + if (sequencesize(statements, compressor)) changed = 6; + if (!changed && last_changed == 6) break; + if (sequencesize_2(statements, compressor)) changed = 7; + if (!changed && last_changed == 7) break; + } + if (compressor.option("join_vars")) { + if (join_consecutive_vars(statements)) changed = 8; + if (!changed && last_changed == 8) break; + } + if (compressor.option("collapse_vars")) { + if (collapse(statements, compressor)) changed = 9; + } + } while (changed && max_iter-- > 0); + return statements; + + function last_of(compressor, predicate) { + var block = compressor.self(), level = 0, stat; + do { + if (block instanceof AST_Catch) { + block = compressor.parent(level++); + } else if (block instanceof AST_LabeledStatement) { + block = block.body; + } else if (block instanceof AST_SwitchBranch) { + var branches = compressor.parent(level); + if (branches.body[branches.body.length - 1] === block || has_break(block.body)) { + level++; + block = branches; + } + } + do { + stat = block; + if (predicate(stat)) return stat; + block = compressor.parent(level++); + } while (block instanceof AST_If); + } while (stat + && (block instanceof AST_BlockStatement + || block instanceof AST_Catch + || block instanceof AST_Scope + || block instanceof AST_SwitchBranch + || block instanceof AST_Try) + && is_last_statement(block.body, stat)); + + function has_break(stats) { + for (var i = stats.length; --i >= 0;) { + if (stats[i] instanceof AST_Break) return true; + } + return false; + } + } + + function find_loop_scope_try() { + var node = compressor.self(), level = 0; + do { + if (!block_scope && node.variables) block_scope = node; + if (node instanceof AST_Catch) { + if (compressor.parent(level).bfinally) { + if (!in_try) in_try = {}; + in_try.bfinally = true; + } + level++; + } else if (node instanceof AST_Finally) { + level++; + } else if (node instanceof AST_IterationStatement) { + in_loop = true; + } else if (node instanceof AST_Scope) { + scope = node; + break; + } else if (node instanceof AST_Try) { + if (!in_try) in_try = {}; + if (node.bcatch) in_try.bcatch = true; + if (node.bfinally) in_try.bfinally = true; + } + } while (node = compressor.parent(level++)); + } + + // Search from right to left for assignment-like expressions: + // - `var a = x;` + // - `a = x;` + // - `++a` + // For each candidate, scan from left to right for first usage, then try + // to fold assignment into the site for compression. + // Will not attempt to collapse assignments into or past code blocks + // which are not sequentially executed, e.g. loops and conditionals. + function collapse(statements, compressor) { + if (scope.pinned()) return; + var args; + var assignments = new Dictionary(); + var candidates = []; + var changed = false; + var declare_only = new Dictionary(); + var force_single; + var stat_index = statements.length; + var scanner = new TreeTransformer(function(node, descend) { + if (abort) return node; + // Skip nodes before `candidate` as quickly as possible + if (!hit) { + if (node !== hit_stack[hit_index]) return node; + hit_index++; + if (hit_index < hit_stack.length) return handle_custom_scan_order(node, scanner); + hit = true; + stop_after = (value_def ? find_stop_value : find_stop)(node, 0); + if (stop_after === node) abort = true; + return node; + } + var parent = scanner.parent(); + // Stop only if candidate is found within conditional branches + if (!stop_if_hit && in_conditional(node, parent)) { + stop_if_hit = parent; + } + // Cascade compound assignments + if (compound && scan_lhs && can_replace && !stop_if_hit + && node instanceof AST_Assign && node.operator != "=" && node.left.equals(lhs)) { + replaced++; + changed = true; + AST_Node.info("Cascading {this} [{start}]", node); + can_replace = false; + lvalues = get_lvalues(lhs); + node.right.transform(scanner); + clear_write_only(candidate); + var folded; + if (abort) { + folded = candidate; + } else { + abort = true; + folded = make_node(AST_Binary, candidate, { + operator: compound, + left: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_binary(candidate) : lhs, + right: rvalue, + }); + } + return make_node(AST_Assign, node, { + operator: "=", + left: node.left, + right: make_node(AST_Binary, node, { + operator: node.operator.slice(0, -1), + left: folded, + right: node.right, + }), + }); + } + // Stop immediately if these node types are encountered + if (should_stop(node, parent)) { + abort = true; + return node; + } + // Skip transient nodes caused by single-use variable replacement + if (node.single_use) return node; + // Replace variable with assignment when found + var hit_rhs; + if (!(node instanceof AST_SymbolDeclaration) + && (scan_lhs && lhs.equals(node) + || scan_rhs && (hit_rhs = scan_rhs(node, this)))) { + if (!can_replace || stop_if_hit && (hit_rhs || !lhs_local || !replace_all)) { + if (!hit_rhs && !value_def) abort = true; + return node; + } + if (is_lhs(node, parent)) { + if (value_def && !hit_rhs) assign_used = true; + return node; + } + if (!hit_rhs && verify_ref && node.fixed !== lhs.fixed) { + abort = true; + return node; + } + if (value_def) { + if (stop_if_hit && assign_pos == 0) assign_pos = remaining - replaced; + if (!hit_rhs) replaced++; + return node; + } + replaced++; + changed = abort = true; + AST_Node.info("Collapsing {this} [{start}]", node); + if (candidate.TYPE == "Binary") { + update_symbols(candidate, node); + return make_node(AST_Assign, candidate, { + operator: "=", + left: candidate.right.left, + right: candidate.operator == "&&" ? make_node(AST_Conditional, candidate, { + condition: candidate.left, + consequent: candidate.right.right, + alternative: node, + }) : make_node(AST_Conditional, candidate, { + condition: candidate.left, + consequent: node, + alternative: candidate.right.right, + }), + }); + } + if (candidate instanceof AST_UnaryPostfix) return make_node(AST_UnaryPrefix, candidate, { + operator: candidate.operator, + expression: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_prefix(candidate) : lhs, + }); + if (candidate instanceof AST_UnaryPrefix) { + clear_write_only(candidate); + return candidate; + } + update_symbols(rvalue, node); + if (candidate instanceof AST_VarDef) { + var def = candidate.name.definition(); + if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) { + def.replaced++; + return maintain_this_binding(parent, node, rvalue); + } + return make_node(AST_Assign, candidate, { + operator: "=", + left: node, + right: rvalue, + }); + } + clear_write_only(rvalue); + var assign = candidate.clone(); + assign.right = rvalue; + return assign; + } + // Stop signals related to AST_SymbolRef + if (should_stop_ref(node, parent)) { + abort = true; + return node; + } + // These node types have child nodes that execute sequentially, + // but are otherwise not safe to scan into or beyond them. + if (is_last_node(node, parent) || may_throw(node)) { + stop_after = node; + if (node instanceof AST_Scope) abort = true; + } + // Scan but don't replace inside getter/setter + if (node instanceof AST_Accessor) { + var replace = can_replace; + can_replace = false; + descend(node, scanner); + can_replace = replace; + return signal_abort(node); + } + // Scan but don't replace inside destructuring expression + if (node instanceof AST_Destructured) { + var replace = can_replace; + can_replace = false; + descend(node, scanner); + can_replace = replace; + return signal_abort(node); + } + // Scan but don't replace inside default value + if (node instanceof AST_DefaultValue) { + node.name = node.name.transform(scanner); + var replace = can_replace; + can_replace = false; + node.value = node.value.transform(scanner); + can_replace = replace; + return signal_abort(node); + } + // Scan but don't replace inside block scope with colliding variable + if (node instanceof AST_BlockScope + && !(node instanceof AST_Scope) + && !(node.variables && node.variables.all(function(def) { + return !enclosed.has(def.name) && !lvalues.has(def.name); + }))) { + var replace = can_replace; + can_replace = false; + if (!handle_custom_scan_order(node, scanner)) descend(node, scanner); + can_replace = replace; + return signal_abort(node); + } + if (handle_custom_scan_order(node, scanner)) return signal_abort(node); + }, signal_abort); + var multi_replacer = new TreeTransformer(function(node) { + if (abort) return node; + // Skip nodes before `candidate` as quickly as possible + if (!hit) { + if (node !== hit_stack[hit_index]) return node; + hit_index++; + switch (hit_stack.length - hit_index) { + case 0: + hit = true; + if (assign_used) return node; + if (node !== candidate) return node; + if (node instanceof AST_VarDef) return node; + def.replaced++; + var parent = multi_replacer.parent(); + if (parent instanceof AST_Sequence && parent.tail_node() !== node) { + value_def.replaced++; + if (rvalue === rhs_value) return List.skip; + return make_sequence(rhs_value, rhs_value.expressions.slice(0, -1)); + } + return rvalue; + case 1: + if (!assign_used && node.body === candidate) { + hit = true; + def.replaced++; + value_def.replaced++; + return null; + } + default: + return handle_custom_scan_order(node, multi_replacer); + } + } + // Replace variable when found + if (node instanceof AST_SymbolRef && node.definition() === def) { + if (is_lhs(node, multi_replacer.parent())) return node; + if (!--replaced) abort = true; + AST_Node.info("Replacing {this} [{start}]", node); + var ref = rvalue.clone(); + ref.scope = node.scope; + ref.reference(); + if (replaced == assign_pos) { + abort = true; + return make_node(AST_Assign, candidate, { + operator: "=", + left: node, + right: ref, + }); + } + def.replaced++; + return ref; + } + // Skip (non-executed) functions and (leading) default case in switch statements + if (node instanceof AST_Default || node instanceof AST_Scope) return node; + }, function(node) { + return patch_sequence(node, multi_replacer); + }); + while (--stat_index >= 0) { + // Treat parameters as collapsible in IIFE, i.e. + // function(a, b){ ... }(x()); + // would be translated into equivalent assignments: + // var a = x(), b = undefined; + if (stat_index == 0 && compressor.option("unused")) extract_args(); + // Find collapsible assignments + var hit_stack = []; + extract_candidates(statements[stat_index]); + while (candidates.length > 0) { + hit_stack = candidates.pop(); + var hit_index = 0; + var candidate = hit_stack[hit_stack.length - 1]; + var assign_pos = -1; + var assign_used = false; + var verify_ref = false; + var remaining; + var value_def = null; + var stop_after = null; + var stop_if_hit = null; + var lhs = get_lhs(candidate); + var side_effects = lhs && lhs.has_side_effects(compressor); + var scan_lhs = lhs && (!side_effects || lhs instanceof AST_SymbolRef) + && !is_lhs_read_only(lhs, compressor); + var scan_rhs = foldable(candidate); + if (!scan_lhs && !scan_rhs) continue; + var compound = candidate instanceof AST_Assign && candidate.operator.slice(0, -1); + var funarg = candidate.name instanceof AST_SymbolFunarg; + var may_throw = return_false; + if (candidate.may_throw(compressor)) { + if (funarg && is_async(scope)) continue; + may_throw = in_try ? function(node) { + return node.has_side_effects(compressor); + } : side_effects_external; + } + var read_toplevel = false; + var modify_toplevel = false; + // Locate symbols which may execute code outside of scanning range + var enclosed = new Dictionary(); + var well_defined = true; + var lvalues = get_lvalues(candidate); + var lhs_local = is_lhs_local(lhs); + var rhs_value = get_rvalue(candidate); + var rvalue = rhs_value; + if (!side_effects) { + if (!compound && rvalue instanceof AST_Sequence) rvalue = rvalue.tail_node(); + side_effects = value_has_side_effects(); + } + var check_destructured = in_try || !lhs_local ? function(node) { + return node instanceof AST_Destructured; + } : return_false; + var replace_all = replace_all_symbols(candidate); + var hit = funarg; + var abort = false; + var replaced = 0; + var can_replace = !args || !hit; + if (!can_replace) { + for (var j = candidate.arg_index + 1; !abort && j < args.length; j++) { + if (args[j]) args[j].transform(scanner); + } + can_replace = true; + } + for (var i = stat_index; !abort && i < statements.length; i++) { + statements[i].transform(scanner); + } + if (value_def) { + if (!replaced || remaining > replaced + assign_used) { + candidates.push(hit_stack); + force_single = true; + continue; + } + if (replaced == assign_pos) assign_used = true; + var def = lhs.definition(); + abort = false; + hit_index = 0; + hit = funarg; + for (var i = stat_index; !abort && i < statements.length; i++) { + if (!statements[i].transform(multi_replacer)) statements.splice(i--, 1); + } + replaced = candidate instanceof AST_VarDef + && candidate === hit_stack[hit_stack.length - 1] + && def.references.length == def.replaced + && !compressor.exposed(def); + value_def.last_ref = false; + value_def.single_use = false; + changed = true; + } + if (replaced) remove_candidate(candidate); + } + } + return changed; + + function signal_abort(node) { + if (abort) return node; + if (stop_after === node) abort = true; + if (stop_if_hit === node) stop_if_hit = null; + return node; + } + + function handle_custom_scan_order(node, tt) { + if (!(node instanceof AST_BlockScope)) return; + // Skip (non-executed) functions + if (node instanceof AST_Scope) return node; + // Scan computed keys, static fields & initializers in class + if (node instanceof AST_Class) { + if (node.name) node.name = node.name.transform(tt); + if (!abort && node.extends) node.extends = node.extends.transform(tt); + var fields = [], stats = []; + for (var i = 0; !abort && i < node.properties.length; i++) { + var prop = node.properties[i]; + if (prop.key instanceof AST_Node) prop.key = prop.key.transform(tt); + if (!prop.static) continue; + if (prop instanceof AST_ClassField) { + if (prop.value) fields.push(prop); + } else if (prop instanceof AST_ClassInit) { + [].push.apply(stats, prop.value.body); + } + } + for (var i = 0; !abort && i < stats.length; i++) { + stats[i].transform(tt); + } + for (var i = 0; !abort && i < fields.length; i++) { + var prop = fields[i]; + prop.value = prop.value.transform(tt); + } + return node; + } + // Scan object only in a for-in/of statement + if (node instanceof AST_ForEnumeration) { + node.object = node.object.transform(tt); + abort = true; + return node; + } + // Scan first case expression only in a switch statement + if (node instanceof AST_Switch) { + node.expression = node.expression.transform(tt); + for (var i = 0; !abort && i < node.body.length; i++) { + var branch = node.body[i]; + if (branch instanceof AST_Case) { + if (!hit) { + if (branch !== hit_stack[hit_index]) continue; + hit_index++; + } + branch.expression = branch.expression.transform(tt); + if (!replace_all) break; + scan_rhs = false; + } + } + abort = true; + return node; + } + } + + function is_direct_assignment(node, parent) { + if (parent instanceof AST_Assign) return parent.operator == "=" && parent.left === node; + if (parent instanceof AST_DefaultValue) return parent.name === node; + if (parent instanceof AST_DestructuredArray) return true; + if (parent instanceof AST_DestructuredKeyVal) return parent.value === node; + } + + function should_stop(node, parent) { + if (node === rvalue) return true; + if (parent instanceof AST_For) { + if (node !== parent.init) return true; + } + if (node instanceof AST_Assign) { + return node.operator != "=" && lhs.equals(node.left); + } + if (node instanceof AST_Call) { + if (!(lhs instanceof AST_PropAccess)) return false; + if (!lhs.equals(node.expression)) return false; + return !(rvalue instanceof AST_LambdaExpression && !rvalue.contains_this()); + } + if (node instanceof AST_Class) return !compressor.has_directive("use strict"); + if (node instanceof AST_Debugger) return true; + if (node instanceof AST_Defun) return funarg && lhs.name === node.name.name; + if (node instanceof AST_DestructuredKeyVal) return node.key instanceof AST_Node; + if (node instanceof AST_DWLoop) return true; + if (node instanceof AST_LoopControl) return true; + if (node instanceof AST_Try) return true; + if (node instanceof AST_With) return true; + return false; + } + + function should_stop_ref(node, parent) { + if (!(node instanceof AST_SymbolRef)) return false; + if (node.is_declared(compressor)) { + if (node.fixed_value()) return false; + if (can_drop_symbol(node)) { + return !(parent instanceof AST_PropAccess && parent.expression === node) + && is_arguments(node.definition()); + } + } else if (is_direct_assignment(node, parent)) { + return false; + } + if (!replace_all) return true; + scan_rhs = false; + return false; + } + + function in_conditional(node, parent) { + if (parent instanceof AST_Assign) return parent.left !== node && lazy_op[parent.operator.slice(0, -1)]; + if (parent instanceof AST_Binary) return parent.left !== node && lazy_op[parent.operator]; + if (parent instanceof AST_Call) return parent.optional && parent.expression !== node; + if (parent instanceof AST_Case) return parent.expression !== node; + if (parent instanceof AST_Conditional) return parent.condition !== node; + if (parent instanceof AST_If) return parent.condition !== node; + if (parent instanceof AST_Sub) return parent.optional && parent.expression !== node; + } + + function is_last_node(node, parent) { + if (node instanceof AST_Await) return true; + if (node.TYPE == "Binary") return !can_drop_op(node.operator, node.right, compressor); + if (node instanceof AST_Call) { + var def, fn = node.expression; + if (fn instanceof AST_SymbolRef) { + def = fn.definition(); + fn = fn.fixed_value(); + } + if (!(fn instanceof AST_Lambda)) return !node.is_expr_pure(compressor); + if (def && recursive_ref(compressor, def, fn)) return true; + if (fn.collapse_scanning) return false; + fn.collapse_scanning = true; + var replace = can_replace; + can_replace = false; + var after = stop_after; + var if_hit = stop_if_hit; + for (var i = 0; !abort && i < fn.argnames.length; i++) { + if (arg_may_throw(reject, fn.argnames[i], node.args[i])) abort = true; + } + if (!abort) { + if (fn.rest && arg_may_throw(reject, fn.rest, make_node(AST_Array, node, { + elements: node.args.slice(i), + }))) { + abort = true; + } else if (is_arrow(fn) && fn.value) { + fn.value.transform(scanner); + } else for (var i = 0; !abort && i < fn.body.length; i++) { + var stat = fn.body[i]; + if (stat instanceof AST_Return) { + if (stat.value) stat.value.transform(scanner); + break; + } + stat.transform(scanner); + } + } + stop_if_hit = if_hit; + stop_after = after; + can_replace = replace; + fn.collapse_scanning = false; + if (!abort) return false; + abort = false; + return true; + } + if (node instanceof AST_Class) { + if (!in_try) return false; + var base = node.extends; + if (!base) return false; + if (base instanceof AST_SymbolRef) base = base.fixed_value(); + return !safe_for_extends(base); + } + if (node instanceof AST_Exit) { + if (in_try) { + if (in_try.bfinally) return true; + if (in_try.bcatch && node instanceof AST_Throw) return true; + } + return side_effects || lhs instanceof AST_PropAccess || may_modify(lhs); + } + if (node instanceof AST_Function) { + return compressor.option("ie") && node.name && lvalues.has(node.name.name); + } + if (node instanceof AST_ObjectIdentity) return symbol_in_lvalues(node, parent); + if (node instanceof AST_PropAccess) { + if (side_effects) return true; + var exp = node.expression; + if (exp instanceof AST_SymbolRef && is_arguments(exp.definition())) return true; + if (compressor.option("unsafe")) { + if (is_undeclared_ref(exp) && global_names[exp.name]) return false; + if (is_static_fn(exp)) return false; + } + if (!well_defined) return true; + if (value_def) return false; + if (!in_try && lhs_local) return false; + if (node.optional) return false; + return exp.may_throw_on_access(compressor); + } + if (node instanceof AST_Spread) return true; + if (node instanceof AST_SymbolRef) { + if (symbol_in_lvalues(node, parent)) return !is_direct_assignment(node, parent); + if (side_effects && may_modify(node)) return true; + var def = node.definition(); + return (in_try || def.scope.resolve() !== scope) && !can_drop_symbol(node); + } + if (node instanceof AST_Template) return !node.is_expr_pure(compressor); + if (node instanceof AST_VarDef) { + if (check_destructured(node.name)) return true; + return (node.value || parent instanceof AST_Let) && node.name.match_symbol(function(node) { + return node instanceof AST_SymbolDeclaration + && (lvalues.has(node.name) || side_effects && may_modify(node)); + }, true); + } + if (node instanceof AST_Yield) return true; + var sym = is_lhs(node.left, node); + if (!sym) return false; + if (sym instanceof AST_PropAccess) return true; + if (check_destructured(sym)) return true; + return sym.match_symbol(function(node) { + return node instanceof AST_SymbolRef + && (lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition())); + }, true); + + function reject(node) { + node.transform(scanner); + return abort; + } + } + + function arg_may_throw(reject, node, value) { + if (node instanceof AST_DefaultValue) { + return reject(node.value) + || arg_may_throw(reject, node.name, node.value) + || !is_undefined(value) && arg_may_throw(reject, node.name, value); + } + if (!value) return !(node instanceof AST_Symbol); + if (node instanceof AST_Destructured) { + if (node.rest && arg_may_throw(reject, node.rest)) return true; + if (node instanceof AST_DestructuredArray) { + if (value instanceof AST_Array) return !all(node.elements, function(element, index) { + return !arg_may_throw(reject, element, value[index]); + }); + if (!value.is_string(compressor)) return true; + return !all(node.elements, function(element) { + return !arg_may_throw(reject, element); + }); + } + if (node instanceof AST_DestructuredObject) { + if (value.may_throw_on_access(compressor)) return true; + return !all(node.properties, function(prop) { + if (prop.key instanceof AST_Node && reject(prop.key)) return false; + return !arg_may_throw(reject, prop.value); + }); + } + } + } + + function extract_args() { + if (in_iife_single === false) return; + var iife = compressor.parent(), fn = compressor.self(); + if (in_iife_single === undefined) { + if (!(fn instanceof AST_LambdaExpression) + || is_generator(fn) + || fn.uses_arguments + || fn.pinned() + || !(iife instanceof AST_Call) + || iife.expression !== fn + || !all(iife.args, function(arg) { + return !(arg instanceof AST_Spread); + })) { + in_iife_single = false; + return; + } + if (!is_iife_single(iife)) return; + in_iife_single = true; + } + var fn_strict = fn.in_strict_mode(compressor) + && !fn.parent_scope.resolve(true).in_strict_mode(compressor); + var has_await; + if (is_async(fn)) { + has_await = function(node) { + return node instanceof AST_Symbol && node.name == "await"; + }; + iife_in_try = true; + } else { + has_await = function(node) { + return node instanceof AST_Await && !tw.find_parent(AST_Scope); + }; + if (iife_in_try === undefined) iife_in_try = find_try(compressor, 1, iife, null, true, true); + } + var arg_scope = null; + var tw = new TreeWalker(function(node, descend) { + if (!arg) return true; + if (has_await(node) || node instanceof AST_Yield) { + arg = null; + return true; + } + if (node instanceof AST_ObjectIdentity) { + if (fn_strict || !arg_scope) arg = null; + return true; + } + if (node instanceof AST_SymbolRef) { + var def; + if (node.in_arg && !is_safe_lexical(node.definition()) + || (def = fn.variables.get(node.name)) && def !== node.definition()) { + arg = null; + } + return true; + } + if (node instanceof AST_Scope && !is_arrow(node)) { + var save_scope = arg_scope; + arg_scope = node; + descend(); + arg_scope = save_scope; + return true; + } + }); + args = iife.args.slice(); + var len = args.length; + var names = new Dictionary(); + for (var i = fn.argnames.length; --i >= 0;) { + var sym = fn.argnames[i]; + var arg = args[i]; + var value = null; + if (sym instanceof AST_DefaultValue) { + value = sym.value; + sym = sym.name; + args[len + i] = value; + } + if (sym instanceof AST_Destructured) { + if (iife_in_try && arg_may_throw(function(node) { + return node.has_side_effects(compressor); + }, sym, arg)) { + candidates.length = 0; + break; + } + args[len + i] = fn.argnames[i]; + continue; + } + if (names.has(sym.name)) continue; + names.set(sym.name, true); + if (value) arg = is_undefined(arg) ? value : null; + if (!arg && !value) { + arg = make_node(AST_Undefined, sym).transform(compressor); + } else if (arg instanceof AST_Lambda && arg.pinned()) { + arg = null; + } else if (arg) { + arg.walk(tw); + } + if (!arg) continue; + var candidate = make_node(AST_VarDef, sym, { + name: sym, + value: arg, + }); + candidate.name_index = i; + candidate.arg_index = value ? len + i : i; + candidates.unshift([ candidate ]); + } + if (fn.rest) args.push(fn.rest); + } + + function extract_candidates(expr, unused) { + hit_stack.push(expr); + if (expr instanceof AST_Array) { + expr.elements.forEach(function(node) { + extract_candidates(node, unused); + }); + } else if (expr instanceof AST_Assign) { + var lhs = expr.left; + if (!(lhs instanceof AST_Destructured)) candidates.push(hit_stack.slice()); + extract_candidates(lhs); + extract_candidates(expr.right); + if (lhs instanceof AST_SymbolRef && expr.operator == "=") { + assignments.set(lhs.name, (assignments.get(lhs.name) || 0) + 1); + } + } else if (expr instanceof AST_Await) { + extract_candidates(expr.expression, unused); + } else if (expr instanceof AST_Binary) { + var lazy = lazy_op[expr.operator]; + if (unused + && lazy + && expr.operator != "??" + && expr.right instanceof AST_Assign + && expr.right.operator == "=" + && !(expr.right.left instanceof AST_Destructured)) { + candidates.push(hit_stack.slice()); + } + extract_candidates(expr.left, !lazy && unused); + extract_candidates(expr.right, unused); + } else if (expr instanceof AST_Call) { + extract_candidates(expr.expression); + expr.args.forEach(extract_candidates); + } else if (expr instanceof AST_Case) { + extract_candidates(expr.expression); + } else if (expr instanceof AST_Conditional) { + extract_candidates(expr.condition); + extract_candidates(expr.consequent, unused); + extract_candidates(expr.alternative, unused); + } else if (expr instanceof AST_Definitions) { + expr.definitions.forEach(extract_candidates); + } else if (expr instanceof AST_Dot) { + extract_candidates(expr.expression); + } else if (expr instanceof AST_DWLoop) { + extract_candidates(expr.condition); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + } else if (expr instanceof AST_Exit) { + if (expr.value) extract_candidates(expr.value); + } else if (expr instanceof AST_For) { + if (expr.init) extract_candidates(expr.init, true); + if (expr.condition) extract_candidates(expr.condition); + if (expr.step) extract_candidates(expr.step, true); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + } else if (expr instanceof AST_ForEnumeration) { + extract_candidates(expr.object); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + } else if (expr instanceof AST_If) { + extract_candidates(expr.condition); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + if (expr.alternative && !(expr.alternative instanceof AST_Block)) { + extract_candidates(expr.alternative); + } + } else if (expr instanceof AST_Object) { + expr.properties.forEach(function(prop) { + hit_stack.push(prop); + if (prop.key instanceof AST_Node) extract_candidates(prop.key); + if (prop instanceof AST_ObjectKeyVal) extract_candidates(prop.value, unused); + hit_stack.pop(); + }); + } else if (expr instanceof AST_Sequence) { + var end = expr.expressions.length - (unused ? 0 : 1); + expr.expressions.forEach(function(node, index) { + extract_candidates(node, index < end); + }); + } else if (expr instanceof AST_SimpleStatement) { + extract_candidates(expr.body, true); + } else if (expr instanceof AST_Spread) { + extract_candidates(expr.expression); + } else if (expr instanceof AST_Sub) { + extract_candidates(expr.expression); + extract_candidates(expr.property); + } else if (expr instanceof AST_Switch) { + extract_candidates(expr.expression); + expr.body.forEach(extract_candidates); + } else if (expr instanceof AST_Unary) { + if (UNARY_POSTFIX[expr.operator]) { + candidates.push(hit_stack.slice()); + } else { + extract_candidates(expr.expression); + } + } else if (expr instanceof AST_VarDef) { + if (expr.name instanceof AST_SymbolVar) { + if (expr.value) { + var def = expr.name.definition(); + if (def.references.length > def.replaced) { + candidates.push(hit_stack.slice()); + } + } else { + declare_only.set(expr.name.name, (declare_only.get(expr.name.name) || 0) + 1); + } + } + if (expr.value) extract_candidates(expr.value); + } else if (expr instanceof AST_Yield) { + if (expr.expression) extract_candidates(expr.expression); + } + hit_stack.pop(); + } + + function find_stop(node, level) { + var parent = scanner.parent(level); + if (parent instanceof AST_Array) return node; + if (parent instanceof AST_Assign) return node; + if (parent instanceof AST_Await) return node; + if (parent instanceof AST_Binary) return node; + if (parent instanceof AST_Call) return node; + if (parent instanceof AST_Case) return node; + if (parent instanceof AST_Conditional) return node; + if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Exit) return node; + if (parent instanceof AST_If) return node; + if (parent instanceof AST_IterationStatement) return node; + if (parent instanceof AST_ObjectProperty) return node; + if (parent instanceof AST_PropAccess) return node; + if (parent instanceof AST_Sequence) { + return (parent.tail_node() === node ? find_stop : find_stop_unused)(parent, level + 1); + } + if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Spread) return node; + if (parent instanceof AST_Switch) return node; + if (parent instanceof AST_Unary) return node; + if (parent instanceof AST_VarDef) return node; + if (parent instanceof AST_Yield) return node; + return null; + } + + function find_stop_logical(parent, op, level) { + var node; + do { + node = parent; + parent = scanner.parent(++level); + } while (parent instanceof AST_Assign && parent.operator.slice(0, -1) == op + || parent instanceof AST_Binary && parent.operator == op); + return node; + } + + function find_stop_expr(expr, cont, node, parent, level) { + var replace = can_replace; + can_replace = false; + var after = stop_after; + var if_hit = stop_if_hit; + var stack = scanner.stack; + scanner.stack = [ parent ]; + expr.transform(scanner); + scanner.stack = stack; + stop_if_hit = if_hit; + stop_after = after; + can_replace = replace; + if (abort) { + abort = false; + return node; + } + return cont(parent, level + 1); + } + + function find_stop_value(node, level) { + var parent = scanner.parent(level); + if (parent instanceof AST_Array) return find_stop_value(parent, level + 1); + if (parent instanceof AST_Assign) { + if (may_throw(parent)) return node; + if (parent.left.match_symbol(function(ref) { + return ref instanceof AST_SymbolRef && (lhs.name == ref.name || value_def.name == ref.name); + })) return node; + var op; + if (parent.left === node || !lazy_op[op = parent.operator.slice(0, -1)]) { + return find_stop_value(parent, level + 1); + } + return find_stop_logical(parent, op, level); + } + if (parent instanceof AST_Await) return find_stop_value(parent, level + 1); + if (parent instanceof AST_Binary) { + var op; + if (parent.left === node || !lazy_op[op = parent.operator]) { + return find_stop_value(parent, level + 1); + } + return find_stop_logical(parent, op, level); + } + if (parent instanceof AST_Call) return parent; + if (parent instanceof AST_Case) { + if (parent.expression !== node) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_Conditional) { + if (parent.condition !== node) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Do) return node; + if (parent instanceof AST_Exit) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_For) { + if (parent.init !== node && parent.condition !== node) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_ForEnumeration) { + if (parent.init !== node) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_If) { + if (parent.condition !== node) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_ObjectProperty) { + var obj = scanner.parent(level + 1); + return all(obj.properties, function(prop) { + return prop instanceof AST_ObjectKeyVal; + }) ? find_stop_value(obj, level + 2) : obj; + } + if (parent instanceof AST_PropAccess) { + var exp = parent.expression; + return exp === node ? find_stop_value(parent, level + 1) : node; + } + if (parent instanceof AST_Sequence) { + return (parent.tail_node() === node ? find_stop_value : find_stop_unused)(parent, level + 1); + } + if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Spread) return find_stop_value(parent, level + 1); + if (parent instanceof AST_Switch) { + if (parent.expression !== node) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_Unary) { + if (parent.operator == "delete") return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_VarDef) return parent.name.match_symbol(function(sym) { + return sym instanceof AST_SymbolDeclaration && (lhs.name == sym.name || value_def.name == sym.name); + }) ? node : find_stop_value(parent, level + 1); + if (parent instanceof AST_While) { + if (parent.condition !== node) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_Yield) return find_stop_value(parent, level + 1); + return null; + } + + function find_stop_unused(node, level) { + var parent = scanner.parent(level); + if (is_last_node(node, parent)) return node; + if (in_conditional(node, parent)) return node; + if (parent instanceof AST_Array) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Assign) return check_assignment(parent.left); + if (parent instanceof AST_Await) return node; + if (parent instanceof AST_Binary) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Call) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Case) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Conditional) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Exit) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_If) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_IterationStatement) return node; + if (parent instanceof AST_ObjectProperty) { + var obj = scanner.parent(level + 1); + return all(obj.properties, function(prop) { + return prop instanceof AST_ObjectKeyVal; + }) ? find_stop_unused(obj, level + 2) : obj; + } + if (parent instanceof AST_PropAccess) { + var exp = parent.expression; + if (exp === node) return find_stop_unused(parent, level + 1); + return find_stop_expr(exp, find_stop_unused, node, parent, level); + } + if (parent instanceof AST_Sequence) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Spread) return node; + if (parent instanceof AST_Switch) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Unary) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_VarDef) return check_assignment(parent.name); + if (parent instanceof AST_Yield) return node; + return null; + + function check_assignment(lhs) { + if (may_throw(parent)) return node; + if (lhs !== node && lhs instanceof AST_Destructured) { + return find_stop_expr(lhs, find_stop_unused, node, parent, level); + } + return find_stop_unused(parent, level + 1); + } + } + + function mangleable_var(rhs) { + if (force_single) { + force_single = false; + return; + } + if (remaining < 1) return; + rhs = rhs.tail_node(); + var value = rhs instanceof AST_Assign && rhs.operator == "=" ? rhs.left : rhs; + if (!(value instanceof AST_SymbolRef)) return; + var def = value.definition(); + if (def.undeclared) return; + if (is_arguments(def)) return; + if (value !== rhs) { + if (is_lhs_read_only(value, compressor)) return; + var referenced = def.references.length - def.replaced; + if (referenced < 2) return; + var expr = candidate.clone(); + expr[expr instanceof AST_Assign ? "right" : "value"] = value; + if (candidate.name_index >= 0) { + expr.name_index = candidate.name_index; + expr.arg_index = candidate.arg_index; + } + candidate = expr; + } + return value_def = def; + } + + function remaining_refs(def) { + return def.references.length - def.replaced - (assignments.get(def.name) || 0); + } + + function get_lhs(expr) { + if (expr instanceof AST_Assign) { + var lhs = expr.left; + if (!(lhs instanceof AST_SymbolRef)) return lhs; + var def = lhs.definition(); + if (scope.uses_arguments && is_funarg(def)) return lhs; + if (compressor.exposed(def)) return lhs; + remaining = remaining_refs(def); + if (def.fixed && lhs.fixed) { + var matches = def.references.filter(function(ref) { + return ref.fixed === lhs.fixed; + }).length - 1; + if (matches < remaining) { + remaining = matches; + assign_pos = 0; + verify_ref = true; + } + } + if (expr.operator == "=") mangleable_var(expr.right); + return lhs; + } + if (expr instanceof AST_Binary) return expr.right.left; + if (expr instanceof AST_Unary) return expr.expression; + if (expr instanceof AST_VarDef) { + var lhs = expr.name; + var def = lhs.definition(); + if (def.const_redefs) return; + if (!member(lhs, def.orig)) return; + if (scope.uses_arguments && is_funarg(def)) return; + var declared = def.orig.length - def.eliminated - (declare_only.get(def.name) || 0); + remaining = remaining_refs(def); + if (def.fixed) remaining = Math.min(remaining, def.references.filter(function(ref) { + if (!ref.fixed) return true; + if (!ref.fixed.assigns) return true; + var assign = ref.fixed.assigns[0]; + return assign === lhs || get_rvalue(assign) === expr.value; + }).length); + if (declared > 1 && !(lhs instanceof AST_SymbolFunarg)) { + mangleable_var(expr.value); + return make_node(AST_SymbolRef, lhs); + } + if (mangleable_var(expr.value) || remaining == 1 && !compressor.exposed(def)) { + return make_node(AST_SymbolRef, lhs); + } + return; + } + } + + function get_rvalue(expr) { + if (expr instanceof AST_Assign) return expr.right; + if (expr instanceof AST_Binary) { + var node = expr.clone(); + node.right = expr.right.right; + return node; + } + if (expr instanceof AST_VarDef) return expr.value; + } + + function invariant(expr) { + if (expr instanceof AST_Array) return false; + if (expr instanceof AST_Binary && lazy_op[expr.operator]) { + return invariant(expr.left) && invariant(expr.right); + } + if (expr instanceof AST_Call) return false; + if (expr instanceof AST_Conditional) { + return invariant(expr.consequent) && invariant(expr.alternative); + } + if (expr instanceof AST_Object) return false; + return !expr.has_side_effects(compressor); + } + + function foldable(expr) { + if (expr instanceof AST_Assign && expr.right.single_use) return; + var lhs_ids = Object.create(null); + var marker = new TreeWalker(function(node) { + if (node instanceof AST_SymbolRef) lhs_ids[node.definition().id] = true; + }); + while (expr instanceof AST_Assign && expr.operator == "=") { + expr.left.walk(marker); + expr = expr.right; + } + if (expr instanceof AST_ObjectIdentity) return rhs_exact_match; + if (expr instanceof AST_SymbolRef) { + var value = expr.evaluate(compressor); + if (value === expr) return rhs_exact_match; + return rhs_fuzzy_match(value, rhs_exact_match); + } + if (expr.is_truthy()) return rhs_fuzzy_match(true, return_false); + if (expr.is_constant()) { + var ev = expr.evaluate(compressor); + if (!(ev instanceof AST_Node)) return rhs_fuzzy_match(ev, rhs_exact_match); + } + if (!(lhs instanceof AST_SymbolRef)) return false; + if (!invariant(expr)) return false; + var circular; + expr.walk(new TreeWalker(function(node) { + if (circular) return true; + if (node instanceof AST_SymbolRef && lhs_ids[node.definition().id]) circular = true; + })); + return !circular && rhs_exact_match; + + function rhs_exact_match(node) { + return expr.equals(node); + } + } + + function rhs_fuzzy_match(value, fallback) { + return function(node, tw) { + if (tw.in_boolean_context()) { + if (value && node.is_truthy() && !node.has_side_effects(compressor)) { + return true; + } + if (node.is_constant()) { + var ev = node.evaluate(compressor); + if (!(ev instanceof AST_Node)) return !ev == !value; + } + } + return fallback(node); + }; + } + + function clear_write_only(assign) { + while (assign.write_only) { + assign.write_only = false; + if (!(assign instanceof AST_Assign)) break; + assign = assign.right; + } + } + + function update_symbols(value, node) { + var scope = node.scope || find_scope(scanner) || block_scope; + value.walk(new TreeWalker(function(node) { + if (node instanceof AST_BlockScope) return true; + if (node instanceof AST_Symbol) node.scope = scope; + })); + } + + function may_be_global(node) { + if (node instanceof AST_SymbolRef) { + node = node.fixed_value(); + if (!node) return true; + } + if (node instanceof AST_Assign) return node.operator == "=" && may_be_global(node.right); + return node instanceof AST_PropAccess || node instanceof AST_ObjectIdentity; + } + + function get_lvalues(expr) { + var lvalues = new Dictionary(); + if (expr instanceof AST_VarDef) { + if (!expr.name.definition().fixed) well_defined = false; + lvalues.add(expr.name.name, lhs); + } + var find_arguments = scope.uses_arguments && !compressor.has_directive("use strict"); + var scan_toplevel = scope instanceof AST_Toplevel; + var tw = new TreeWalker(function(node) { + var value; + if (node instanceof AST_SymbolRef) { + value = node.fixed_value(); + if (!value) { + value = node; + var def = node.definition(); + var escaped = node.fixed && node.fixed.escaped || def.escaped; + if (!def.undeclared + && (def.assignments || !escaped || escaped.cross_scope) + && (has_escaped(def, node.scope, node, tw.parent()) || !same_scope(def))) { + well_defined = false; + } + } + } else if (node instanceof AST_ObjectIdentity) { + value = node; + } + if (value) { + lvalues.add(node.name, is_modified(compressor, tw, node, value, 0)); + } else if (node instanceof AST_Lambda) { + for (var level = 0, parent, child = node; parent = tw.parent(level++); child = parent) { + if (parent instanceof AST_Assign) { + if (parent.left === child) break; + if (parent.operator == "=") continue; + if (lazy_op[parent.operator.slice(0, -1)]) continue; + break; + } + if (parent instanceof AST_Binary) { + if (lazy_op[parent.operator]) continue; + break; + } + if (parent instanceof AST_Call) return; + if (parent instanceof AST_Scope) return; + if (parent instanceof AST_Sequence) { + if (parent.tail_node() === child) continue; + break; + } + if (parent instanceof AST_Template) { + if (parent.tag) return; + break; + } + } + node.enclosed.forEach(function(def) { + if (def.scope !== node) enclosed.set(def.name, true); + }); + return true; + } else if (find_arguments && node instanceof AST_Sub) { + scope.each_argname(function(argname) { + if (!compressor.option("reduce_vars") || argname.definition().assignments) { + if (!argname.definition().fixed) well_defined = false; + lvalues.add(argname.name, true); + } + }); + find_arguments = false; + } + if (!scan_toplevel) return; + if (node.TYPE == "Call") { + if (modify_toplevel) return; + var exp = node.expression; + if (exp instanceof AST_PropAccess) return; + if (exp instanceof AST_LambdaExpression && !exp.contains_this()) return; + modify_toplevel = true; + } else if (node instanceof AST_PropAccess && may_be_global(node.expression)) { + if (node === lhs && !(expr instanceof AST_Unary)) { + modify_toplevel = true; + } else { + read_toplevel = true; + } + } + }); + expr.walk(tw); + return lvalues; + } + + function remove_candidate(expr) { + var value = rvalue === rhs_value ? null : make_sequence(rhs_value, rhs_value.expressions.slice(0, -1)); + var index = expr.name_index; + if (index >= 0) { + var args, argname = scope.argnames[index]; + if (argname instanceof AST_DefaultValue) { + scope.argnames[index] = argname = argname.clone(); + argname.value = value || make_node(AST_Number, argname, { value: 0 }); + } else if ((args = compressor.parent().args)[index]) { + scope.argnames[index] = argname.clone(); + args[index] = value || make_node(AST_Number, args[index], { value: 0 }); + } + return; + } + var end = hit_stack.length - 1; + var last = hit_stack[end]; + if (last instanceof AST_VarDef || hit_stack[end - 1].body === last) end--; + var tt = new TreeTransformer(function(node, descend, in_list) { + if (hit) return node; + if (node !== hit_stack[hit_index]) return node; + hit_index++; + if (hit_index <= end) return handle_custom_scan_order(node, tt); + hit = true; + if (node instanceof AST_Definitions) { + declare_only.set(last.name.name, (declare_only.get(last.name.name) || 0) + 1); + if (value_def) value_def.replaced++; + var defns = node.definitions; + var index = defns.indexOf(last); + var defn = last.clone(); + defn.value = null; + if (!value) { + node.definitions[index] = defn; + return node; + } + var body = [ make_node(AST_SimpleStatement, value, { body: value }) ]; + if (index > 0) { + var head = node.clone(); + head.definitions = defns.slice(0, index); + body.unshift(head); + node = node.clone(); + node.definitions = defns.slice(index); + } + body.push(node); + node.definitions[0] = defn; + return in_list ? List.splice(body) : make_node(AST_BlockStatement, node, { body: body }); + } + if (!value) return in_list ? List.skip : null; + return is_statement(node) ? make_node(AST_SimpleStatement, value, { body: value }) : value; + }, function(node, in_list) { + if (node instanceof AST_For) return patch_for_init(node, in_list); + return patch_sequence(node, tt); + }); + abort = false; + hit = false; + hit_index = 0; + if (!(statements[stat_index] = statements[stat_index].transform(tt))) statements.splice(stat_index, 1); + } + + function patch_sequence(node, tt) { + if (node instanceof AST_Sequence) switch (node.expressions.length) { + case 0: return null; + case 1: return maintain_this_binding(tt.parent(), node, node.expressions[0]); + } + } + + function is_lhs_local(lhs) { + var sym = root_expr(lhs); + if (!(sym instanceof AST_SymbolRef)) return false; + if (sym.definition().scope.resolve() !== scope) return false; + if (!in_loop) return true; + if (compound) return false; + if (candidate instanceof AST_Unary) return false; + var lvalue = lvalues.get(sym.name); + return !lvalue || lvalue[0] === lhs; + } + + function value_has_side_effects() { + if (candidate instanceof AST_Unary) return false; + return rvalue.has_side_effects(compressor); + } + + function replace_all_symbols(expr) { + if (expr instanceof AST_Unary) return false; + if (side_effects) return false; + if (value_def) return true; + if (!(lhs instanceof AST_SymbolRef)) return false; + var referenced; + if (expr instanceof AST_VarDef) { + referenced = 1; + } else if (expr.operator == "=") { + referenced = 2; + } else { + return false; + } + var def = lhs.definition(); + if (def.references.length - def.replaced == referenced) return true; + if (!def.fixed) return false; + if (!lhs.fixed) return false; + var assigns = lhs.fixed.assigns; + var matched = 0; + if (!all(def.references, function(ref, index) { + var fixed = ref.fixed; + if (!fixed) return false; + if (fixed.to_binary || fixed.to_prefix) return false; + if (fixed === lhs.fixed) { + matched++; + return true; + } + return assigns && fixed.assigns && assigns[0] !== fixed.assigns[0]; + })) return false; + if (matched != referenced) return false; + verify_ref = true; + return true; + } + + function symbol_in_lvalues(sym, parent) { + var lvalue = lvalues.get(sym.name); + if (!lvalue || all(lvalue, function(lhs) { + return !lhs; + })) return; + if (lvalue[0] !== lhs) return true; + scan_rhs = false; + } + + function may_modify(sym) { + var def = sym.definition(); + if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) return false; + if (def.scope.resolve() !== scope) return true; + if (modify_toplevel && compressor.exposed(def)) return true; + return !all(def.references, function(ref) { + return ref.scope.resolve(true) === scope; + }); + } + + function side_effects_external(node, lhs) { + if (node instanceof AST_Assign) return side_effects_external(node.left, true); + if (node instanceof AST_Unary) return side_effects_external(node.expression, true); + if (node instanceof AST_VarDef) return node.value && side_effects_external(node.value); + if (lhs) { + if (node instanceof AST_Dot) return side_effects_external(node.expression, true); + if (node instanceof AST_Sub) return side_effects_external(node.expression, true); + if (node instanceof AST_SymbolRef) return node.definition().scope.resolve() !== scope; + } + return false; + } + } + + function eliminate_spurious_blocks(statements) { + var changed = false, seen_dirs = []; + for (var i = 0; i < statements.length;) { + var stat = statements[i]; + if (stat instanceof AST_BlockStatement) { + if (all(stat.body, safe_to_trim)) { + changed = true; + eliminate_spurious_blocks(stat.body); + [].splice.apply(statements, [i, 1].concat(stat.body)); + i += stat.body.length; + continue; + } + } + if (stat instanceof AST_Directive) { + if (member(stat.value, seen_dirs)) { + changed = true; + statements.splice(i, 1); + continue; + } + seen_dirs.push(stat.value); + } + if (stat instanceof AST_EmptyStatement) { + changed = true; + statements.splice(i, 1); + continue; + } + i++; + } + return changed; + } + + function handle_if_return(statements, compressor) { + var changed = false; + var parent = compressor.parent(); + var self = compressor.self(); + var declare_only, jump, merge_jump; + var in_iife = in_lambda && parent && parent.TYPE == "Call" && parent.expression === self; + var chain_if_returns = in_lambda && compressor.option("conditionals") && compressor.option("sequences"); + var drop_return_void = !(in_try && in_try.bfinally && in_async_generator(scope)); + var multiple_if_returns = has_multiple_if_returns(statements); + for (var i = statements.length; --i >= 0;) { + var stat = statements[i]; + var j = next_index(i); + var next = statements[j]; + + if (in_lambda && declare_only && !next && stat instanceof AST_Return + && drop_return_void && !(self instanceof AST_SwitchBranch)) { + var body = stat.value; + if (!body) { + changed = true; + statements.splice(i, 1); + continue; + } + var tail = body.tail_node(); + if (is_undefined(tail)) { + changed = true; + if (body instanceof AST_UnaryPrefix) { + body = body.expression; + } else if (tail instanceof AST_UnaryPrefix) { + body = body.clone(); + body.expressions[body.expressions.length - 1] = tail.expression; + } + statements[i] = make_node(AST_SimpleStatement, stat, { body: body }); + continue; + } + } + + if (stat instanceof AST_If) { + var ab = aborts(stat.body); + // if (foo()) { bar(); return; } else baz(); moo(); ---> if (foo()) bar(); else { baz(); moo(); } + if (can_merge_flow(ab)) { + if (ab.label) remove(ab.label.thedef.references, ab); + changed = true; + stat = stat.clone(); + stat.body = make_node(AST_BlockStatement, stat, { + body: as_statement_array_with_return(stat.body, ab), + }); + stat.alternative = make_node(AST_BlockStatement, stat, { + body: as_statement_array(stat.alternative).concat(extract_functions(merge_jump, jump)), + }); + adjust_refs(ab.value, merge_jump); + statements[i] = stat; + statements[i] = stat.transform(compressor); + continue; + } + // if (foo()) { bar(); return x; } return y; ---> if (!foo()) return y; bar(); return x; + if (ab && !stat.alternative && next instanceof AST_Jump) { + var cond = stat.condition; + var preference = i + 1 == j && stat.body instanceof AST_BlockStatement; + cond = best_of_expression(cond, cond.negate(compressor), preference); + if (cond !== stat.condition) { + changed = true; + stat = stat.clone(); + stat.condition = cond; + var body = stat.body; + stat.body = make_node(AST_BlockStatement, next, { + body: extract_functions(true, null, j + 1), + }); + statements.splice(i, 1, stat, body); + // proceed further only if `TreeWalker.stack` is in a consistent state + // https://github.com/mishoo/UglifyJS/issues/5595 + // https://github.com/mishoo/UglifyJS/issues/5597 + if (!in_lambda || self instanceof AST_Block && self.body === statements) { + statements[i] = stat.transform(compressor); + } + continue; + } + } + var alt = aborts(stat.alternative); + // if (foo()) bar(); else { baz(); return; } moo(); ---> if (foo()) { bar(); moo(); } else baz(); + if (can_merge_flow(alt)) { + if (alt.label) remove(alt.label.thedef.references, alt); + changed = true; + stat = stat.clone(); + stat.body = make_node(AST_BlockStatement, stat.body, { + body: as_statement_array(stat.body).concat(extract_functions(merge_jump, jump)), + }); + stat.alternative = make_node(AST_BlockStatement, stat.alternative, { + body: as_statement_array_with_return(stat.alternative, alt), + }); + adjust_refs(alt.value, merge_jump); + statements[i] = stat; + statements[i] = stat.transform(compressor); + continue; + } + if (compressor.option("typeofs")) { + if (ab && !alt) { + var stats = make_node(AST_BlockStatement, self, { body: statements.slice(i + 1) }); + mark_locally_defined(stat.condition, null, stats); + } + if (!ab && alt) { + var stats = make_node(AST_BlockStatement, self, { body: statements.slice(i + 1) }); + mark_locally_defined(stat.condition, stats); + } + } + } + + if (stat instanceof AST_If && stat.body instanceof AST_Return) { + var value = stat.body.value; + var in_bool = stat.body.in_bool || next instanceof AST_Return && next.in_bool; + // if (foo()) return x; return y; ---> return foo() ? x : y; + if (!stat.alternative && next instanceof AST_Return + && (drop_return_void || !value == !next.value)) { + changed = true; + stat = stat.clone(); + stat.alternative = make_node(AST_BlockStatement, next, { + body: extract_functions(true, null, j + 1), + }); + statements[i] = stat; + statements[i] = stat.transform(compressor); + continue; + } + // if (foo()) return x; [ return ; ] ---> return foo() ? x : undefined; + // if (foo()) return bar() ? x : void 0; ---> return foo() && bar() ? x : void 0; + // if (foo()) return bar() ? void 0 : x; ---> return !foo() || bar() ? void 0 : x; + if (in_lambda && declare_only && !next && !stat.alternative && (in_bool + || value && multiple_if_returns + || value instanceof AST_Conditional && (is_undefined(value.consequent, compressor) + || is_undefined(value.alternative, compressor)))) { + changed = true; + stat = stat.clone(); + stat.alternative = make_node(AST_Return, stat, { value: null }); + statements[i] = stat; + statements[i] = stat.transform(compressor); + continue; + } + // if (a) return b; if (c) return d; e; ---> return a ? b : c ? d : void e; + // + // if sequences is not enabled, this can lead to an endless loop (issue #866). + // however, with sequences on this helps producing slightly better output for + // the example code. + var prev, prev_stat; + if (chain_if_returns && !stat.alternative + && (!(prev_stat = statements[prev = prev_index(i)]) && in_iife + || prev_stat instanceof AST_If && prev_stat.body instanceof AST_Return) + && (!next ? !declare_only + : next instanceof AST_SimpleStatement && next_index(j) == statements.length)) { + changed = true; + var exprs = []; + stat = stat.clone(); + exprs.push(stat.condition); + stat.condition = make_sequence(stat, exprs); + stat.alternative = make_node(AST_BlockStatement, self, { + body: extract_functions().concat(make_node(AST_Return, self, { value: null })), + }); + statements[i] = stat.transform(compressor); + i = prev + 1; + continue; + } + } + + if (stat instanceof AST_Break || stat instanceof AST_Exit) { + jump = stat; + continue; + } + + if (declare_only && jump && jump === next) eliminate_returns(stat); + } + return changed; + + function has_multiple_if_returns(statements) { + var n = 0; + for (var i = statements.length; --i >= 0;) { + var stat = statements[i]; + if (stat instanceof AST_If && stat.body instanceof AST_Return) { + if (++n > 1) return true; + } + } + return false; + } + + function match_target(target) { + return last_of(compressor, function(node) { + return node === target; + }); + } + + function match_return(ab, exact) { + if (!jump) return false; + if (jump.TYPE != ab.TYPE) return false; + var value = ab.value; + if (!value) return false; + var equals = jump.equals(ab); + if (!equals && value instanceof AST_Sequence) { + value = value.tail_node(); + if (jump.value && jump.value.equals(value)) equals = 2; + } + if (!equals && !exact && jump.value instanceof AST_Sequence) { + if (jump.value.tail_node().equals(value)) equals = 3; + } + return equals; + } + + function can_drop_abort(ab) { + if (ab instanceof AST_Exit) { + if (merge_jump = match_return(ab)) return true; + if (!in_lambda) return false; + if (!(ab instanceof AST_Return)) return false; + var value = ab.value; + if (value && !is_undefined(value.tail_node())) return false; + if (!(self instanceof AST_SwitchBranch)) return true; + if (!jump) return false; + if (jump instanceof AST_Exit && jump.value) return false; + merge_jump = 4; + return true; + } + if (!(ab instanceof AST_LoopControl)) return false; + if (self instanceof AST_SwitchBranch) { + if (jump instanceof AST_Exit) { + if (!in_lambda) return false; + if (jump.value) return false; + merge_jump = true; + } else if (jump) { + if (compressor.loopcontrol_target(jump) !== parent) return false; + merge_jump = true; + } else if (jump === false) { + return false; + } + } + var lct = compressor.loopcontrol_target(ab); + if (ab instanceof AST_Continue) return match_target(loop_body(lct)); + if (lct instanceof AST_IterationStatement) return false; + return match_target(lct); + } + + function can_merge_flow(ab) { + merge_jump = false; + if (!can_drop_abort(ab)) return false; + for (var j = statements.length; --j > i;) { + var stat = statements[j]; + if (stat instanceof AST_DefClass) { + if (stat.name.definition().preinit) return false; + } else if (stat instanceof AST_Const || stat instanceof AST_Let) { + if (!all(stat.definitions, function(defn) { + return !defn.name.match_symbol(function(node) { + return node instanceof AST_SymbolDeclaration && node.definition().preinit; + }); + })) return false; + } + } + return true; + } + + function extract_functions(mode, stop, end) { + var defuns = []; + var lexical = false; + var start = i + 1; + if (!mode) { + end = statements.length; + jump = null; + } else if (stop) { + end = statements.lastIndexOf(stop); + } else { + stop = statements[end]; + if (stop !== jump) jump = false; + } + var tail = statements.splice(start, end - start).filter(function(stat) { + if (stat instanceof AST_LambdaDefinition) { + defuns.push(stat); + return false; + } + if (is_lexical_definition(stat)) lexical = true; + return true; + }); + if (mode === 3) { + tail.push(make_node(AST_SimpleStatement, stop.value, { + body: make_sequence(stop.value, stop.value.expressions.slice(0, -1)), + })); + stop.value = stop.value.tail_node(); + } + [].push.apply(lexical ? tail : statements, defuns); + return tail; + } + + function trim_return(value, mode) { + if (value) switch (mode) { + case 4: + return value; + case 3: + if (!(value instanceof AST_Sequence)) break; + case 2: + return make_sequence(value, value.expressions.slice(0, -1)); + } + } + + function as_statement_array_with_return(node, ab) { + var body = as_statement_array(node); + var block = body, last; + while ((last = block[block.length - 1]) !== ab) { + block = last.body; + } + block.pop(); + var value = ab.value; + if (merge_jump) value = trim_return(value, merge_jump); + if (value) block.push(make_node(AST_SimpleStatement, value, { body: value })); + return body; + } + + function adjust_refs(value, mode) { + if (!mode) return; + if (!value) return; + switch (mode) { + case 4: + return; + case 3: + case 2: + value = value.tail_node(); + } + merge_expression(value, jump.value); + } + + function next_index(i) { + declare_only = true; + for (var j = i; ++j < statements.length;) { + var stat = statements[j]; + if (is_declaration(stat)) continue; + if (stat instanceof AST_Var) { + declare_only = false; + continue; + } + break; + } + return j; + } + + function prev_index(i) { + for (var j = i; --j >= 0;) { + var stat = statements[j]; + if (stat instanceof AST_Var) continue; + if (is_declaration(stat)) continue; + break; + } + return j; + } + + function eliminate_returns(stat, keep_throws, in_block) { + if (stat instanceof AST_Exit) { + var mode = !(keep_throws && stat instanceof AST_Throw) && match_return(stat, true); + if (mode) { + changed = true; + var value = trim_return(stat.value, mode); + if (value) return make_node(AST_SimpleStatement, value, { body: value }); + return in_block ? null : make_node(AST_EmptyStatement, stat); + } + } else if (stat instanceof AST_If) { + stat.body = eliminate_returns(stat.body, keep_throws); + if (stat.alternative) stat.alternative = eliminate_returns(stat.alternative, keep_throws); + } else if (stat instanceof AST_LabeledStatement) { + stat.body = eliminate_returns(stat.body, keep_throws); + } else if (stat instanceof AST_Try) { + if (!stat.bfinally || !jump.value || jump.value.is_constant()) { + if (stat.bcatch) eliminate_returns(stat.bcatch, keep_throws); + var trimmed = eliminate_returns(stat.body.pop(), true, true); + if (trimmed) stat.body.push(trimmed); + } + } else if (stat instanceof AST_Block && !(stat instanceof AST_Scope || stat instanceof AST_Switch)) { + var trimmed = eliminate_returns(stat.body.pop(), keep_throws, true); + if (trimmed) stat.body.push(trimmed); + } + return stat; + } + } + + function eliminate_dead_code(statements, compressor) { + var has_quit; + var self = compressor.self(); + if (self instanceof AST_Catch) { + self = compressor.parent(); + } else if (self instanceof AST_LabeledStatement) { + self = self.body; + } + for (var i = 0, n = 0, len = statements.length; i < len; i++) { + var stat = statements[i]; + if (stat instanceof AST_LoopControl) { + var lct = compressor.loopcontrol_target(stat); + if (loop_body(lct) !== self + || stat instanceof AST_Break && lct instanceof AST_IterationStatement) { + statements[n++] = stat; + } else if (stat.label) { + remove(stat.label.thedef.references, stat); + } + } else { + statements[n++] = stat; + } + if (aborts(stat)) { + has_quit = statements.slice(i + 1); + break; + } + } + statements.length = n; + if (has_quit) has_quit.forEach(function(stat) { + extract_declarations_from_unreachable_code(compressor, stat, statements); + }); + return statements.length != len; + } + + function trim_awaits(statements, compressor) { + if (!in_lambda || in_try && in_try.bfinally) return; + var changed = false; + for (var index = statements.length; --index >= 0;) { + var stat = statements[index]; + if (!(stat instanceof AST_SimpleStatement)) break; + var node = stat.body; + if (!(node instanceof AST_Await)) break; + var exp = node.expression; + if (!needs_enqueuing(compressor, exp)) break; + changed = true; + exp = exp.drop_side_effect_free(compressor, true); + if (exp) { + stat.body = exp; + break; + } + } + statements.length = index + 1; + return changed; + } + + function inline_iife(statements, compressor) { + var changed = false; + var index = statements.length - 1; + if (in_lambda && index >= 0) { + var no_return = in_try && in_try.bfinally && in_async_generator(scope); + var inlined = statements[index].try_inline(compressor, block_scope, no_return); + if (inlined) { + statements[index--] = inlined; + changed = true; + } + } + var loop = in_loop && in_try && in_try.bfinally ? "try" : in_loop; + for (; index >= 0; index--) { + var inlined = statements[index].try_inline(compressor, block_scope, true, loop); + if (!inlined) continue; + statements[index] = inlined; + changed = true; + } + return changed; + } + + function sequencesize(statements, compressor) { + if (statements.length < 2) return; + var seq = [], n = 0; + function push_seq() { + if (!seq.length) return; + var body = make_sequence(seq[0], seq); + statements[n++] = make_node(AST_SimpleStatement, body, { body: body }); + seq = []; + } + for (var i = 0, len = statements.length; i < len; i++) { + var stat = statements[i]; + if (stat instanceof AST_SimpleStatement) { + if (seq.length >= compressor.sequences_limit) push_seq(); + merge_sequence(seq, stat.body); + } else if (is_declaration(stat)) { + statements[n++] = stat; + } else { + push_seq(); + statements[n++] = stat; + } + } + push_seq(); + statements.length = n; + return n != len; + } + + function to_simple_statement(block, decls) { + if (!(block instanceof AST_BlockStatement)) return block; + var stat = null; + for (var i = 0; i < block.body.length; i++) { + var line = block.body[i]; + if (line instanceof AST_Var && declarations_only(line)) { + decls.push(line); + } else if (stat || is_lexical_definition(line)) { + return false; + } else { + stat = line; + } + } + return stat; + } + + function sequencesize_2(statements, compressor) { + var changed = false, n = 0, prev; + for (var i = 0; i < statements.length; i++) { + var stat = statements[i]; + if (prev) { + if (stat instanceof AST_Exit) { + if (stat.value || !in_async_generator(scope)) { + stat.value = cons_seq(stat.value || make_node(AST_Undefined, stat)).optimize(compressor); + } + } else if (stat instanceof AST_For) { + if (!(stat.init instanceof AST_Definitions)) { + var abort = false; + prev.body.walk(new TreeWalker(function(node) { + if (abort || node instanceof AST_Scope) return true; + if (node instanceof AST_Binary && node.operator == "in") { + abort = true; + return true; + } + })); + if (!abort) { + if (stat.init) stat.init = cons_seq(stat.init); + else { + stat.init = prev.body; + n--; + changed = true; + } + } + } + } else if (stat instanceof AST_ForIn) { + if (!is_lexical_definition(stat.init)) stat.object = cons_seq(stat.object); + } else if (stat instanceof AST_If) { + stat.condition = cons_seq(stat.condition); + } else if (stat instanceof AST_Switch) { + stat.expression = cons_seq(stat.expression); + } else if (stat instanceof AST_With) { + stat.expression = cons_seq(stat.expression); + } + } + if (compressor.option("conditionals") && stat instanceof AST_If) { + var decls = []; + var body = to_simple_statement(stat.body, decls); + var alt = to_simple_statement(stat.alternative, decls); + if (body !== false && alt !== false && decls.length > 0) { + var len = decls.length; + decls.push(make_node(AST_If, stat, { + condition: stat.condition, + body: body || make_node(AST_EmptyStatement, stat.body), + alternative: alt, + })); + decls.unshift(n, 1); + [].splice.apply(statements, decls); + i += len; + n += len + 1; + prev = null; + changed = true; + continue; + } + } + statements[n++] = stat; + prev = stat instanceof AST_SimpleStatement ? stat : null; + } + statements.length = n; + return changed; + + function cons_seq(right) { + n--; + changed = true; + var left = prev.body; + return make_sequence(left, [ left, right ]); + } + } + + function extract_exprs(body) { + if (body instanceof AST_Assign) return [ body ]; + if (body instanceof AST_Sequence) return body.expressions.slice(); + } + + function join_assigns(defn, body, keep) { + var exprs = extract_exprs(body); + if (!exprs) return; + keep = keep || 0; + var trimmed = false; + for (var i = exprs.length - keep; --i >= 0;) { + var expr = exprs[i]; + if (!can_trim(expr)) continue; + var tail; + if (expr.left instanceof AST_SymbolRef) { + tail = exprs.slice(i + 1); + } else if (expr.left instanceof AST_PropAccess && can_trim(expr.left.expression)) { + tail = exprs.slice(i + 1); + var flattened = expr.clone(); + expr = expr.left.expression; + flattened.left = flattened.left.clone(); + flattened.left.expression = expr.left.clone(); + tail.unshift(flattened); + } else { + continue; + } + if (tail.length == 0) continue; + if (!trim_assigns(expr.left, expr.right, tail)) continue; + trimmed = true; + exprs = exprs.slice(0, i).concat(expr, tail); + } + if (defn instanceof AST_Definitions) { + for (var i = defn.definitions.length; --i >= 0;) { + var def = defn.definitions[i]; + if (!def.value) continue; + if (trim_assigns(def.name, def.value, exprs)) trimmed = true; + if (merge_conditional_assignments(def, exprs, keep)) trimmed = true; + break; + } + if (defn instanceof AST_Var && join_var_assign(defn.definitions, exprs, keep)) trimmed = true; + } + return trimmed && exprs; + + function can_trim(node) { + return node instanceof AST_Assign && node.operator == "="; + } + } + + function merge_assigns(prev, defn) { + if (!(prev instanceof AST_SimpleStatement)) return; + if (declarations_only(defn)) return; + var exprs = extract_exprs(prev.body); + if (!exprs) return; + var definitions = []; + if (!join_var_assign(definitions, exprs.reverse(), 0)) return; + defn.definitions = definitions.reverse().concat(defn.definitions); + return exprs.reverse(); + } + + function merge_conditional_assignments(var_def, exprs, keep) { + if (!compressor.option("conditionals")) return; + if (var_def.name instanceof AST_Destructured) return; + var trimmed = false; + var def = var_def.name.definition(); + while (exprs.length > keep) { + var cond = to_conditional_assignment(compressor, def, var_def.value, exprs[0]); + if (!cond) break; + var_def.value = cond; + exprs.shift(); + trimmed = true; + } + return trimmed; + } + + function join_var_assign(definitions, exprs, keep) { + var trimmed = false; + while (exprs.length > keep) { + var expr = exprs[0]; + if (!(expr instanceof AST_Assign)) break; + if (expr.operator != "=") break; + var lhs = expr.left; + if (!(lhs instanceof AST_SymbolRef)) break; + if (is_undeclared_ref(lhs)) break; + if (lhs.scope.resolve() !== scope) break; + var def = lhs.definition(); + if (def.scope !== scope) break; + if (def.orig.length > def.eliminated + 1) break; + if (def.orig[0].TYPE != "SymbolVar") break; + var name = make_node(AST_SymbolVar, lhs); + definitions.push(make_node(AST_VarDef, expr, { + name: name, + value: expr.right, + })); + def.orig.push(name); + def.replaced++; + exprs.shift(); + trimmed = true; + } + return trimmed; + } + + function trim_assigns(name, value, exprs) { + var names = new Dictionary(); + names.set(name.name, true); + while (value instanceof AST_Assign && value.operator == "=") { + if (value.left instanceof AST_SymbolRef) names.set(value.left.name, true); + value = value.right; + } + if (!(value instanceof AST_Object)) return; + var trimmed = false; + do { + if (!try_join(exprs[0])) break; + exprs.shift(); + trimmed = true; + } while (exprs.length); + return trimmed; + + function try_join(node) { + if (!(node instanceof AST_Assign)) return; + if (node.operator != "=") return; + if (!(node.left instanceof AST_PropAccess)) return; + var sym = node.left.expression; + if (!(sym instanceof AST_SymbolRef)) return; + if (!names.has(sym.name)) return; + if (!node.right.is_constant_expression(scope)) return; + var prop = node.left.property; + if (prop instanceof AST_Node) { + if (try_join(prop)) prop = node.left.property = prop.right.clone(); + prop = prop.evaluate(compressor); + } + if (prop instanceof AST_Node) return; + prop = "" + prop; + var diff = prop == "__proto__" || compressor.has_directive("use strict") ? function(node) { + var key = node.key; + return typeof key == "string" && key != prop && key != "__proto__"; + } : function(node) { + var key = node.key; + if (node instanceof AST_ObjectGetter || node instanceof AST_ObjectSetter) { + return typeof key == "string" && key != prop; + } + return key !== "__proto__"; + }; + if (!all(value.properties, diff)) return; + value.properties.push(make_node(AST_ObjectKeyVal, node, { + key: prop, + value: node.right, + })); + return true; + } + } + + function join_consecutive_vars(statements) { + var changed = false, defs; + for (var i = 0, j = -1; i < statements.length; i++) { + var stat = statements[i]; + var prev = statements[j]; + if (stat instanceof AST_Definitions) { + if (prev && prev.TYPE == stat.TYPE) { + prev.definitions = prev.definitions.concat(stat.definitions); + changed = true; + } else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) { + defs.definitions = defs.definitions.concat(stat.definitions); + changed = true; + } else if (stat instanceof AST_Var) { + var exprs = merge_assigns(prev, stat); + if (exprs) { + if (exprs.length) { + prev.body = make_sequence(prev, exprs); + j++; + } + changed = true; + } else { + j++; + } + statements[j] = defs = stat; + } else { + statements[++j] = stat; + } + continue; + } else if (stat instanceof AST_Exit) { + stat.value = join_assigns_expr(stat.value); + } else if (stat instanceof AST_For) { + var exprs = join_assigns(prev, stat.init); + if (exprs) { + changed = true; + stat.init = exprs.length ? make_sequence(stat.init, exprs) : null; + } else if (prev instanceof AST_Var && (!stat.init || stat.init.TYPE == prev.TYPE)) { + if (stat.init) { + prev.definitions = prev.definitions.concat(stat.init.definitions); + } + stat = stat.clone(); + defs = stat.init = prev; + statements[j] = merge_defns(stat); + changed = true; + continue; + } else if (defs && stat.init && defs.TYPE == stat.init.TYPE && declarations_only(stat.init)) { + defs.definitions = defs.definitions.concat(stat.init.definitions); + stat.init = null; + changed = true; + } else if (stat.init instanceof AST_Var) { + defs = stat.init; + exprs = merge_assigns(prev, stat.init); + if (exprs) { + changed = true; + if (exprs.length == 0) { + statements[j] = merge_defns(stat); + continue; + } + prev.body = make_sequence(prev, exprs); + } + } + } else if (stat instanceof AST_ForEnumeration) { + if (defs && defs.TYPE == stat.init.TYPE) { + var defns = defs.definitions.slice(); + stat.init = stat.init.definitions[0].name.convert_symbol(AST_SymbolRef, function(ref, name) { + defns.push(make_node(AST_VarDef, name, { + name: name, + value: null, + })); + name.definition().references.push(ref); + }); + defs.definitions = defns; + changed = true; + } + stat.object = join_assigns_expr(stat.object); + } else if (stat instanceof AST_If) { + stat.condition = join_assigns_expr(stat.condition); + } else if (stat instanceof AST_SimpleStatement) { + var exprs = join_assigns(prev, stat.body), next; + if (exprs) { + changed = true; + if (!exprs.length) continue; + stat.body = make_sequence(stat.body, exprs); + } else if (prev instanceof AST_Definitions + && (next = statements[i + 1]) + && prev.TYPE == next.TYPE + && (next = next.definitions[0]).value) { + changed = true; + next.value = make_sequence(stat, [ stat.body, next.value ]); + continue; + } + } else if (stat instanceof AST_Switch) { + stat.expression = join_assigns_expr(stat.expression); + } else if (stat instanceof AST_With) { + stat.expression = join_assigns_expr(stat.expression); + } + statements[++j] = defs ? merge_defns(stat) : stat; + } + statements.length = j + 1; + return changed; + + function join_assigns_expr(value) { + var exprs = join_assigns(prev, value, 1); + if (!exprs) return value; + changed = true; + var tail = value.tail_node(); + if (exprs[exprs.length - 1] !== tail) exprs.push(tail.left); + return make_sequence(value, exprs); + } + + function merge_defns(stat) { + return stat.transform(new TreeTransformer(function(node, descend, in_list) { + if (node instanceof AST_Definitions) { + if (defs === node) return node; + if (defs.TYPE != node.TYPE) return node; + var parent = this.parent(); + if (parent instanceof AST_ForEnumeration && parent.init === node) return node; + if (!declarations_only(node)) return node; + defs.definitions = defs.definitions.concat(node.definitions); + changed = true; + if (parent instanceof AST_For && parent.init === node) return null; + return in_list ? List.skip : make_node(AST_EmptyStatement, node); + } + if (node instanceof AST_ExportDeclaration) return node; + if (node instanceof AST_Scope) return node; + if (!is_statement(node)) return node; + })); + } + } + } + + function extract_declarations_from_unreachable_code(compressor, stat, target) { + var block; + var dropped = false; + stat.walk(new TreeWalker(function(node, descend) { + if (node instanceof AST_DefClass) { + node.extends = null; + node.properties = []; + push(node); + return true; + } + if (node instanceof AST_Definitions) { + var defns = []; + if (node.remove_initializers(compressor, defns)) { + AST_Node.warn("Dropping initialization in unreachable code [{start}]", node); + } + if (defns.length > 0) { + node.definitions = defns; + push(node); + } + return true; + } + if (node instanceof AST_LambdaDefinition) { + push(node); + return true; + } + if (node instanceof AST_Scope) return true; + if (node instanceof AST_BlockScope) { + var save = block; + block = []; + descend(); + if (block.required) { + target.push(make_node(AST_BlockStatement, stat, { body: block })); + } else if (block.length) { + [].push.apply(target, block); + } + block = save; + return true; + } + if (!(node instanceof AST_LoopControl)) dropped = true; + })); + if (dropped) AST_Node.warn("Dropping unreachable code [{start}]", stat); + + function push(node) { + if (block) { + block.push(node); + if (!safe_to_trim(node)) block.required = true; + } else { + target.push(node); + } + } + } + + function is_undefined(node, compressor) { + return node == null + || node.is_undefined + || node instanceof AST_Undefined + || node instanceof AST_UnaryPrefix + && node.operator == "void" + && !(compressor && node.expression.has_side_effects(compressor)); + } + + // in_strict_mode() + // return true if scope executes in Strict Mode + (function(def) { + def(AST_Class, return_true); + def(AST_Scope, function(compressor) { + var body = this.body; + for (var i = 0; i < body.length; i++) { + var stat = body[i]; + if (!(stat instanceof AST_Directive)) break; + if (stat.value == "use strict") return true; + } + var parent = this.parent_scope; + if (!parent) return compressor.option("module"); + return parent.resolve(true).in_strict_mode(compressor); + }); + })(function(node, func) { + node.DEFMETHOD("in_strict_mode", func); + }); + + // is_truthy() + // return true if `!!node === true` + (function(def) { + def(AST_Node, return_false); + def(AST_Array, return_true); + def(AST_Assign, function() { + return this.operator == "=" && this.right.is_truthy(); + }); + def(AST_Lambda, return_true); + def(AST_Object, return_true); + def(AST_RegExp, return_true); + def(AST_Sequence, function() { + return this.tail_node().is_truthy(); + }); + def(AST_SymbolRef, function() { + var fixed = this.fixed_value(); + if (!fixed) return false; + this.is_truthy = return_false; + var result = fixed.is_truthy(); + delete this.is_truthy; + return result; + }); + })(function(node, func) { + node.DEFMETHOD("is_truthy", func); + }); + + // is_negative_zero() + // return true if the node may represent -0 + (function(def) { + def(AST_Node, return_true); + def(AST_Array, return_false); + function binary(op, left, right) { + switch (op) { + case "-": + return left.is_negative_zero() + && (!(right instanceof AST_Constant) || right.value == 0); + case "&&": + case "||": + return left.is_negative_zero() || right.is_negative_zero(); + case "*": + case "/": + case "%": + case "**": + return true; + default: + return false; + } + } + def(AST_Assign, function() { + var op = this.operator; + if (op == "=") return this.right.is_negative_zero(); + return binary(op.slice(0, -1), this.left, this.right); + }); + def(AST_Binary, function() { + return binary(this.operator, this.left, this.right); + }); + def(AST_Constant, function() { + return this.value == 0 && 1 / this.value < 0; + }); + def(AST_Lambda, return_false); + def(AST_Object, return_false); + def(AST_RegExp, return_false); + def(AST_Sequence, function() { + return this.tail_node().is_negative_zero(); + }); + def(AST_SymbolRef, function() { + var fixed = this.fixed_value(); + if (!fixed) return true; + this.is_negative_zero = return_true; + var result = fixed.is_negative_zero(); + delete this.is_negative_zero; + return result; + }); + def(AST_UnaryPrefix, function() { + return this.operator == "+" && this.expression.is_negative_zero() + || this.operator == "-"; + }); + })(function(node, func) { + node.DEFMETHOD("is_negative_zero", func); + }); + + // may_throw_on_access() + // returns true if this node may be null, undefined or contain `AST_Accessor` + (function(def) { + AST_Node.DEFMETHOD("may_throw_on_access", function(compressor, force) { + return !compressor.option("pure_getters") || this._dot_throw(compressor, force); + }); + function is_strict(compressor, force) { + return force || /strict/.test(compressor.option("pure_getters")); + } + def(AST_Node, is_strict); + def(AST_Array, return_false); + def(AST_Assign, function(compressor) { + var op = this.operator; + var sym = this.left; + var rhs = this.right; + if (op != "=") { + return lazy_op[op.slice(0, -1)] && (sym._dot_throw(compressor) || rhs._dot_throw(compressor)); + } + if (!rhs._dot_throw(compressor)) return false; + if (!(sym instanceof AST_SymbolRef)) return true; + if (rhs instanceof AST_Binary && rhs.operator == "||" && sym.name == rhs.left.name) { + return rhs.right._dot_throw(compressor); + } + return true; + }); + def(AST_Binary, function(compressor) { + return lazy_op[this.operator] && (this.left._dot_throw(compressor) || this.right._dot_throw(compressor)); + }); + def(AST_Class, function(compressor, force) { + return is_strict(compressor, force) && !all(this.properties, function(prop) { + if (prop.private) return true; + if (!prop.static) return true; + return !(prop instanceof AST_ClassGetter || prop instanceof AST_ClassSetter); + }); + }); + def(AST_Conditional, function(compressor) { + return this.consequent._dot_throw(compressor) || this.alternative._dot_throw(compressor); + }); + def(AST_Constant, return_false); + def(AST_Dot, function(compressor, force) { + if (!is_strict(compressor, force)) return false; + var exp = this.expression; + if (exp instanceof AST_SymbolRef) exp = exp.fixed_value(); + return !(this.property == "prototype" && is_lambda(exp)); + }); + def(AST_Lambda, return_false); + def(AST_Null, return_true); + def(AST_Object, function(compressor, force) { + return is_strict(compressor, force) && !all(this.properties, function(prop) { + if (prop instanceof AST_ObjectGetter || prop instanceof AST_ObjectSetter) return false; + return !(prop.key === "__proto__" && prop.value._dot_throw(compressor, force)); + }); + }); + def(AST_ObjectIdentity, function(compressor, force) { + return is_strict(compressor, force) && !this.scope.resolve().new; + }); + def(AST_Sequence, function(compressor) { + return this.tail_node()._dot_throw(compressor); + }); + def(AST_SymbolRef, function(compressor, force) { + if (this.is_undefined) return true; + if (!is_strict(compressor, force)) return false; + if (is_undeclared_ref(this) && this.is_declared(compressor)) return false; + if (this.is_immutable()) return false; + var def = this.definition(); + if (is_arguments(def) && !def.scope.rest && all(def.scope.argnames, function(argname) { + return argname instanceof AST_SymbolFunarg; + })) return def.scope.uses_arguments > 2; + var fixed = this.fixed_value(true); + if (!fixed) return true; + this._dot_throw = return_true; + if (fixed._dot_throw(compressor)) { + delete this._dot_throw; + return true; + } + this._dot_throw = return_false; + return false; + }); + def(AST_UnaryPrefix, function() { + return this.operator == "void"; + }); + def(AST_UnaryPostfix, return_false); + def(AST_Undefined, return_true); + })(function(node, func) { + node.DEFMETHOD("_dot_throw", func); + }); + + (function(def) { + def(AST_Node, return_false); + def(AST_Array, return_true); + function is_binary_defined(compressor, op, node) { + switch (op) { + case "&&": + return node.left.is_defined(compressor) && node.right.is_defined(compressor); + case "||": + return node.left.is_truthy() || node.right.is_defined(compressor); + case "??": + return node.left.is_defined(compressor) || node.right.is_defined(compressor); + default: + return true; + } + } + def(AST_Assign, function(compressor) { + var op = this.operator; + if (op == "=") return this.right.is_defined(compressor); + return is_binary_defined(compressor, op.slice(0, -1), this); + }); + def(AST_Binary, function(compressor) { + return is_binary_defined(compressor, this.operator, this); + }); + def(AST_Conditional, function(compressor) { + return this.consequent.is_defined(compressor) && this.alternative.is_defined(compressor); + }); + def(AST_Constant, return_true); + def(AST_Hole, return_false); + def(AST_Lambda, return_true); + def(AST_Object, return_true); + def(AST_Sequence, function(compressor) { + return this.tail_node().is_defined(compressor); + }); + def(AST_SymbolRef, function(compressor) { + if (this.is_undefined) return false; + if (is_undeclared_ref(this) && this.is_declared(compressor)) return true; + if (this.is_immutable()) return true; + var fixed = this.fixed_value(); + if (!fixed) return false; + this.is_defined = return_false; + var result = fixed.is_defined(compressor); + delete this.is_defined; + return result; + }); + def(AST_UnaryPrefix, function() { + return this.operator != "void"; + }); + def(AST_UnaryPostfix, return_true); + def(AST_Undefined, return_false); + })(function(node, func) { + node.DEFMETHOD("is_defined", func); + }); + + /* -----[ boolean/negation helpers ]----- */ + + // methods to determine whether an expression has a boolean result type + (function(def) { + def(AST_Node, return_false); + def(AST_Assign, function(compressor) { + return this.operator == "=" && this.right.is_boolean(compressor); + }); + var binary = makePredicate("in instanceof == != === !== < <= >= >"); + def(AST_Binary, function(compressor) { + return binary[this.operator] || lazy_op[this.operator] + && this.left.is_boolean(compressor) + && this.right.is_boolean(compressor); + }); + def(AST_Boolean, return_true); + var fn = makePredicate("every hasOwnProperty isPrototypeOf propertyIsEnumerable some"); + def(AST_Call, function(compressor) { + if (!compressor.option("unsafe")) return false; + var exp = this.expression; + return exp instanceof AST_Dot && (fn[exp.property] + || exp.property == "test" && exp.expression instanceof AST_RegExp); + }); + def(AST_Conditional, function(compressor) { + return this.consequent.is_boolean(compressor) && this.alternative.is_boolean(compressor); + }); + def(AST_New, return_false); + def(AST_Sequence, function(compressor) { + return this.tail_node().is_boolean(compressor); + }); + def(AST_SymbolRef, function(compressor) { + var fixed = this.fixed_value(); + if (!fixed) return false; + this.is_boolean = return_false; + var result = fixed.is_boolean(compressor); + delete this.is_boolean; + return result; + }); + var unary = makePredicate("! delete"); + def(AST_UnaryPrefix, function() { + return unary[this.operator]; + }); + })(function(node, func) { + node.DEFMETHOD("is_boolean", func); + }); + + // methods to determine if an expression has a numeric result type + (function(def) { + def(AST_Node, return_false); + var binary = makePredicate("- * / % ** & | ^ << >> >>>"); + def(AST_Assign, function(compressor) { + return binary[this.operator.slice(0, -1)] + || this.operator == "=" && this.right.is_number(compressor); + }); + def(AST_Binary, function(compressor) { + if (binary[this.operator]) return true; + if (this.operator != "+") return false; + return (this.left.is_boolean(compressor) || this.left.is_number(compressor)) + && (this.right.is_boolean(compressor) || this.right.is_number(compressor)); + }); + var fn = makePredicate([ + "charCodeAt", + "getDate", + "getDay", + "getFullYear", + "getHours", + "getMilliseconds", + "getMinutes", + "getMonth", + "getSeconds", + "getTime", + "getTimezoneOffset", + "getUTCDate", + "getUTCDay", + "getUTCFullYear", + "getUTCHours", + "getUTCMilliseconds", + "getUTCMinutes", + "getUTCMonth", + "getUTCSeconds", + "getYear", + "indexOf", + "lastIndexOf", + "localeCompare", + "push", + "search", + "setDate", + "setFullYear", + "setHours", + "setMilliseconds", + "setMinutes", + "setMonth", + "setSeconds", + "setTime", + "setUTCDate", + "setUTCFullYear", + "setUTCHours", + "setUTCMilliseconds", + "setUTCMinutes", + "setUTCMonth", + "setUTCSeconds", + "setYear", + ]); + def(AST_Call, function(compressor) { + if (!compressor.option("unsafe")) return false; + var exp = this.expression; + return exp instanceof AST_Dot && (fn[exp.property] + || is_undeclared_ref(exp.expression) && exp.expression.name == "Math"); + }); + def(AST_Conditional, function(compressor) { + return this.consequent.is_number(compressor) && this.alternative.is_number(compressor); + }); + def(AST_New, return_false); + def(AST_Number, return_true); + def(AST_Sequence, function(compressor) { + return this.tail_node().is_number(compressor); + }); + def(AST_SymbolRef, function(compressor, keep_unary) { + var fixed = this.fixed_value(); + if (!fixed) return false; + if (keep_unary + && fixed instanceof AST_UnaryPrefix + && fixed.operator == "+" + && fixed.expression.equals(this)) { + return false; + } + this.is_number = return_false; + var result = fixed.is_number(compressor); + delete this.is_number; + return result; + }); + var unary = makePredicate("+ - ~ ++ --"); + def(AST_Unary, function() { + return unary[this.operator]; + }); + })(function(node, func) { + node.DEFMETHOD("is_number", func); + }); + + // methods to determine if an expression has a string result type + (function(def) { + def(AST_Node, return_false); + def(AST_Assign, function(compressor) { + switch (this.operator) { + case "+=": + if (this.left.is_string(compressor)) return true; + case "=": + return this.right.is_string(compressor); + } + }); + def(AST_Binary, function(compressor) { + return this.operator == "+" && + (this.left.is_string(compressor) || this.right.is_string(compressor)); + }); + var fn = makePredicate([ + "charAt", + "substr", + "substring", + "toExponential", + "toFixed", + "toLowerCase", + "toPrecision", + "toString", + "toUpperCase", + "trim", + ]); + def(AST_Call, function(compressor) { + if (!compressor.option("unsafe")) return false; + var exp = this.expression; + return exp instanceof AST_Dot && fn[exp.property]; + }); + def(AST_Conditional, function(compressor) { + return this.consequent.is_string(compressor) && this.alternative.is_string(compressor); + }); + def(AST_Sequence, function(compressor) { + return this.tail_node().is_string(compressor); + }); + def(AST_String, return_true); + def(AST_SymbolRef, function(compressor) { + var fixed = this.fixed_value(); + if (!fixed) return false; + this.is_string = return_false; + var result = fixed.is_string(compressor); + delete this.is_string; + return result; + }); + def(AST_Template, function(compressor) { + return !this.tag || is_raw_tag(compressor, this.tag); + }); + def(AST_UnaryPrefix, function() { + return this.operator == "typeof"; + }); + })(function(node, func) { + node.DEFMETHOD("is_string", func); + }); + + var lazy_op = makePredicate("&& || ??"); + + (function(def) { + function to_node(value, orig) { + if (value instanceof AST_Node) return value.clone(true); + if (Array.isArray(value)) return make_node(AST_Array, orig, { + elements: value.map(function(value) { + return to_node(value, orig); + }) + }); + if (value && typeof value == "object") { + var props = []; + for (var key in value) if (HOP(value, key)) { + props.push(make_node(AST_ObjectKeyVal, orig, { + key: key, + value: to_node(value[key], orig), + })); + } + return make_node(AST_Object, orig, { properties: props }); + } + return make_node_from_constant(value, orig); + } + + function warn(node) { + AST_Node.warn("global_defs {this} redefined [{start}]", node); + } + + AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) { + if (!compressor.option("global_defs")) return this; + this.figure_out_scope({ ie: compressor.option("ie") }); + return this.transform(new TreeTransformer(function(node) { + var def = node._find_defs(compressor, ""); + if (!def) return; + var level = 0, child = node, parent; + while (parent = this.parent(level++)) { + if (!(parent instanceof AST_PropAccess)) break; + if (parent.expression !== child) break; + child = parent; + } + if (is_lhs(child, parent)) { + warn(node); + return; + } + return def; + })); + }); + def(AST_Node, noop); + def(AST_Dot, function(compressor, suffix) { + return this.expression._find_defs(compressor, "." + this.property + suffix); + }); + def(AST_SymbolDeclaration, function(compressor) { + if (!this.definition().global) return; + if (HOP(compressor.option("global_defs"), this.name)) warn(this); + }); + def(AST_SymbolRef, function(compressor, suffix) { + if (!this.definition().global) return; + var defines = compressor.option("global_defs"); + var name = this.name + suffix; + if (HOP(defines, name)) return to_node(defines[name], this); + }); + })(function(node, func) { + node.DEFMETHOD("_find_defs", func); + }); + + function best_of_expression(ast1, ast2, threshold) { + var delta = ast2.print_to_string().length - ast1.print_to_string().length; + return delta < (threshold || 0) ? ast2 : ast1; + } + + function best_of_statement(ast1, ast2, threshold) { + return best_of_expression(make_node(AST_SimpleStatement, ast1, { + body: ast1, + }), make_node(AST_SimpleStatement, ast2, { + body: ast2, + }), threshold).body; + } + + function best_of(compressor, ast1, ast2, threshold) { + return (first_in_statement(compressor) ? best_of_statement : best_of_expression)(ast1, ast2, threshold); + } + + function convert_to_predicate(obj) { + var map = Object.create(null); + Object.keys(obj).forEach(function(key) { + map[key] = makePredicate(obj[key]); + }); + return map; + } + + function skip_directives(body) { + for (var i = 0; i < body.length; i++) { + var stat = body[i]; + if (!(stat instanceof AST_Directive)) return stat; + } + } + + function arrow_first_statement() { + if (this.value) return make_node(AST_Return, this.value, { value: this.value }); + return skip_directives(this.body); + } + AST_Arrow.DEFMETHOD("first_statement", arrow_first_statement); + AST_AsyncArrow.DEFMETHOD("first_statement", arrow_first_statement); + AST_Lambda.DEFMETHOD("first_statement", function() { + return skip_directives(this.body); + }); + + AST_Lambda.DEFMETHOD("length", function() { + var argnames = this.argnames; + for (var i = 0; i < argnames.length; i++) { + if (argnames[i] instanceof AST_DefaultValue) break; + } + return i; + }); + + function try_evaluate(compressor, node) { + var ev = node.evaluate(compressor); + if (ev === node) return node; + ev = make_node_from_constant(ev, node).optimize(compressor); + return best_of(compressor, node, ev, compressor.eval_threshold); + } + + var object_fns = [ + "constructor", + "toString", + "valueOf", + ]; + var native_fns = convert_to_predicate({ + Array: [ + "indexOf", + "join", + "lastIndexOf", + "slice", + ].concat(object_fns), + Boolean: object_fns, + Function: object_fns, + Number: [ + "toExponential", + "toFixed", + "toPrecision", + ].concat(object_fns), + Object: object_fns, + RegExp: [ + "exec", + "test", + ].concat(object_fns), + String: [ + "charAt", + "charCodeAt", + "concat", + "indexOf", + "italics", + "lastIndexOf", + "match", + "replace", + "search", + "slice", + "split", + "substr", + "substring", + "toLowerCase", + "toUpperCase", + "trim", + ].concat(object_fns), + }); + var static_fns = convert_to_predicate({ + Array: [ + "isArray", + ], + Math: [ + "abs", + "acos", + "asin", + "atan", + "ceil", + "cos", + "exp", + "floor", + "log", + "round", + "sin", + "sqrt", + "tan", + "atan2", + "pow", + "max", + "min", + ], + Number: [ + "isFinite", + "isNaN", + ], + Object: [ + "create", + "getOwnPropertyDescriptor", + "getOwnPropertyNames", + "getPrototypeOf", + "isExtensible", + "isFrozen", + "isSealed", + "keys", + ], + String: [ + "fromCharCode", + "raw", + ], + }); + + function is_static_fn(node) { + if (!(node instanceof AST_Dot)) return false; + var expr = node.expression; + if (!is_undeclared_ref(expr)) return false; + var static_fn = static_fns[expr.name]; + return static_fn && (static_fn[node.property] || expr.name == "Math" && node.property == "random"); + } + + // Accommodate when compress option evaluate=false + // as well as the common constant expressions !0 and -1 + (function(def) { + def(AST_Node, return_false); + def(AST_Constant, return_true); + def(AST_RegExp, return_false); + var unaryPrefix = makePredicate("! ~ - + void"); + def(AST_UnaryPrefix, function() { + return unaryPrefix[this.operator] && this.expression instanceof AST_Constant; + }); + })(function(node, func) { + node.DEFMETHOD("is_constant", func); + }); + + // methods to evaluate a constant expression + (function(def) { + // If the node has been successfully reduced to a constant, + // then its value is returned; otherwise the element itself + // is returned. + // + // They can be distinguished as constant value is never a + // descendant of AST_Node. + // + // When `ignore_side_effects` is `true`, inspect the constant value + // produced without worrying about any side effects caused by said + // expression. + AST_Node.DEFMETHOD("evaluate", function(compressor, ignore_side_effects) { + if (!compressor.option("evaluate")) return this; + var cached = []; + var val = this._eval(compressor, ignore_side_effects, cached, 1); + cached.forEach(function(node) { + delete node._eval; + }); + if (ignore_side_effects) return val; + if (!val || val instanceof RegExp) return val; + if (typeof val == "function" || typeof val == "object") return this; + return val; + }); + var scan_modified = new TreeWalker(function(node) { + if (node instanceof AST_Assign) modified(node.left); + if (node instanceof AST_ForEnumeration) modified(node.init); + if (node instanceof AST_Unary && UNARY_POSTFIX[node.operator]) modified(node.expression); + }); + function modified(node) { + if (node instanceof AST_DestructuredArray) { + node.elements.forEach(modified); + } else if (node instanceof AST_DestructuredObject) { + node.properties.forEach(function(prop) { + modified(prop.value); + }); + } else if (node instanceof AST_PropAccess) { + modified(node.expression); + } else if (node instanceof AST_SymbolRef) { + node.definition().references.forEach(function(ref) { + delete ref._eval; + }); + } + } + def(AST_Statement, function() { + throw new Error(string_template("Cannot evaluate a statement [{start}]", this)); + }); + def(AST_Accessor, return_this); + def(AST_BigInt, return_this); + def(AST_Class, return_this); + def(AST_Node, return_this); + def(AST_Constant, function() { + return this.value; + }); + def(AST_Assign, function(compressor, ignore_side_effects, cached, depth) { + var lhs = this.left; + if (!ignore_side_effects) { + if (!(lhs instanceof AST_SymbolRef)) return this; + if (!HOP(lhs, "_eval")) { + if (!lhs.fixed) return this; + var def = lhs.definition(); + if (!def.fixed) return this; + if (def.undeclared) return this; + if (def.last_ref !== lhs) return this; + if (def.single_use == "m") return this; + if (this.right.has_side_effects(compressor)) return this; + } + } + var op = this.operator; + var node; + if (!HOP(lhs, "_eval") && lhs instanceof AST_SymbolRef && lhs.fixed && lhs.definition().fixed) { + node = lhs; + } else if (op == "=") { + node = this.right; + } else { + node = make_node(AST_Binary, this, { + operator: op.slice(0, -1), + left: lhs, + right: this.right, + }); + } + lhs.walk(scan_modified); + var value = node._eval(compressor, ignore_side_effects, cached, depth); + if (typeof value == "object") return this; + modified(lhs); + return value; + }); + def(AST_Sequence, function(compressor, ignore_side_effects, cached, depth) { + if (!ignore_side_effects) return this; + var exprs = this.expressions; + for (var i = 0, last = exprs.length - 1; i < last; i++) { + exprs[i].walk(scan_modified); + } + var tail = exprs[last]; + var value = tail._eval(compressor, ignore_side_effects, cached, depth); + return value === tail ? this : value; + }); + def(AST_Lambda, function(compressor) { + if (compressor.option("unsafe")) { + var fn = function() {}; + fn.node = this; + fn.toString = function() { + return "function(){}"; + }; + return fn; + } + return this; + }); + def(AST_Array, function(compressor, ignore_side_effects, cached, depth) { + if (compressor.option("unsafe")) { + var elements = []; + for (var i = 0; i < this.elements.length; i++) { + var element = this.elements[i]; + if (element instanceof AST_Hole) return this; + var value = element._eval(compressor, ignore_side_effects, cached, depth); + if (element === value) return this; + elements.push(value); + } + return elements; + } + return this; + }); + def(AST_Object, function(compressor, ignore_side_effects, cached, depth) { + if (compressor.option("unsafe")) { + var val = {}; + for (var i = 0; i < this.properties.length; i++) { + var prop = this.properties[i]; + if (!(prop instanceof AST_ObjectKeyVal)) return this; + var key = prop.key; + if (key instanceof AST_Node) { + key = key._eval(compressor, ignore_side_effects, cached, depth); + if (key === prop.key) return this; + } + switch (key) { + case "__proto__": + case "toString": + case "valueOf": + return this; + } + val[key] = prop.value._eval(compressor, ignore_side_effects, cached, depth); + if (val[key] === prop.value) return this; + } + return val; + } + return this; + }); + var non_converting_unary = makePredicate("! typeof void"); + def(AST_UnaryPrefix, function(compressor, ignore_side_effects, cached, depth) { + var e = this.expression; + var op = this.operator; + // Function would be evaluated to an array and so typeof would + // incorrectly return "object". Hence making is a special case. + if (compressor.option("typeofs") + && op == "typeof" + && (e instanceof AST_Lambda + || e instanceof AST_SymbolRef + && e.fixed_value() instanceof AST_Lambda)) { + return typeof function(){}; + } + var def = e instanceof AST_SymbolRef && e.definition(); + if (!non_converting_unary[op] && !(def && def.fixed)) depth++; + e.walk(scan_modified); + var v = e._eval(compressor, ignore_side_effects, cached, depth); + if (v === e) { + if (ignore_side_effects && op == "void") return; + return this; + } + switch (op) { + case "!": return !v; + case "typeof": + // typeof returns "object" or "function" on different platforms + // so cannot evaluate reliably + if (v instanceof RegExp) return this; + return typeof v; + case "void": return; + case "~": return ~v; + case "-": return -v; + case "+": return +v; + case "++": + case "--": + if (!def) return this; + if (!ignore_side_effects) { + if (def.undeclared) return this; + if (def.last_ref !== e) return this; + } + if (HOP(e, "_eval")) v = +(op[0] + 1) + +v; + modified(e); + return v; + } + return this; + }); + def(AST_UnaryPostfix, function(compressor, ignore_side_effects, cached, depth) { + var e = this.expression; + if (!(e instanceof AST_SymbolRef)) { + if (!ignore_side_effects) return this; + } else if (!HOP(e, "_eval")) { + if (!e.fixed) return this; + if (!ignore_side_effects) { + var def = e.definition(); + if (!def.fixed) return this; + if (def.undeclared) return this; + if (def.last_ref !== e) return this; + } + } + if (!(e instanceof AST_SymbolRef && e.definition().fixed)) depth++; + e.walk(scan_modified); + var v = e._eval(compressor, ignore_side_effects, cached, depth); + if (v === e) return this; + modified(e); + return +v; + }); + var non_converting_binary = makePredicate("&& || === !=="); + def(AST_Binary, function(compressor, ignore_side_effects, cached, depth) { + if (!non_converting_binary[this.operator]) depth++; + var left = this.left._eval(compressor, ignore_side_effects, cached, depth); + if (left === this.left) return this; + if (this.operator == (left ? "||" : "&&")) return left; + var rhs_ignore_side_effects = ignore_side_effects && !(left && typeof left == "object"); + var right = this.right._eval(compressor, rhs_ignore_side_effects, cached, depth); + if (right === this.right) return this; + var result; + switch (this.operator) { + case "&&" : result = left && right; break; + case "||" : result = left || right; break; + case "??" : + result = left == null ? right : left; + break; + case "|" : result = left | right; break; + case "&" : result = left & right; break; + case "^" : result = left ^ right; break; + case "+" : result = left + right; break; + case "-" : result = left - right; break; + case "*" : result = left * right; break; + case "/" : result = left / right; break; + case "%" : result = left % right; break; + case "<<" : result = left << right; break; + case ">>" : result = left >> right; break; + case ">>>": result = left >>> right; break; + case "==" : result = left == right; break; + case "===": result = left === right; break; + case "!=" : result = left != right; break; + case "!==": result = left !== right; break; + case "<" : result = left < right; break; + case "<=" : result = left <= right; break; + case ">" : result = left > right; break; + case ">=" : result = left >= right; break; + case "**": + result = Math.pow(left, right); + break; + case "in": + if (right && typeof right == "object" && HOP(right, left)) { + result = true; + break; + } + default: + return this; + } + if (isNaN(result)) return compressor.find_parent(AST_With) ? this : result; + if (compressor.option("unsafe_math") + && !ignore_side_effects + && result + && typeof result == "number" + && (this.operator == "+" || this.operator == "-")) { + var digits = Math.max(0, decimals(left), decimals(right)); + // 53-bit significand ---> 15.95 decimal places + if (digits < 16) return +result.toFixed(digits); + } + return result; + + function decimals(operand) { + var match = /(\.[0-9]*)?(e[^e]+)?$/.exec(+operand); + return (match[1] || ".").length - 1 - (match[2] || "").slice(1); + } + }); + def(AST_Conditional, function(compressor, ignore_side_effects, cached, depth) { + var condition = this.condition._eval(compressor, ignore_side_effects, cached, depth); + if (condition === this.condition) return this; + var node = condition ? this.consequent : this.alternative; + var value = node._eval(compressor, ignore_side_effects, cached, depth); + return value === node ? this : value; + }); + function verify_escaped(ref, depth) { + var escaped = ref.definition().escaped; + switch (escaped.length) { + case 0: + return true; + case 1: + var found = false; + escaped[0].walk(new TreeWalker(function(node) { + if (found) return true; + if (node === ref) return found = true; + if (node instanceof AST_Scope) return true; + })); + return found; + default: + return depth <= escaped.depth; + } + } + def(AST_SymbolRef, function(compressor, ignore_side_effects, cached, depth) { + var fixed = this.fixed_value(); + if (!fixed) return this; + var value; + if (HOP(fixed, "_eval")) { + value = fixed._eval(); + } else { + this._eval = return_this; + value = fixed._eval(compressor, ignore_side_effects, cached, depth); + delete this._eval; + if (value === fixed) return this; + fixed._eval = function() { + return value; + }; + cached.push(fixed); + } + return value && typeof value == "object" && !verify_escaped(this, depth) ? this : value; + }); + var global_objs = { + Array: Array, + Math: Math, + Number: Number, + Object: Object, + String: String, + }; + var static_values = convert_to_predicate({ + Math: [ + "E", + "LN10", + "LN2", + "LOG2E", + "LOG10E", + "PI", + "SQRT1_2", + "SQRT2", + ], + Number: [ + "MAX_VALUE", + "MIN_VALUE", + "NaN", + "NEGATIVE_INFINITY", + "POSITIVE_INFINITY", + ], + }); + var regexp_props = makePredicate("global ignoreCase multiline source"); + def(AST_PropAccess, function(compressor, ignore_side_effects, cached, depth) { + if (compressor.option("unsafe")) { + var val; + var exp = this.expression; + if (!is_undeclared_ref(exp)) { + val = exp._eval(compressor, ignore_side_effects, cached, depth + 1); + if (val == null || val === exp) return this; + } + var key = this.property; + if (key instanceof AST_Node) { + key = key._eval(compressor, ignore_side_effects, cached, depth); + if (key === this.property) return this; + } + if (val === undefined) { + var static_value = static_values[exp.name]; + if (!static_value || !static_value[key]) return this; + val = global_objs[exp.name]; + } else if (val instanceof RegExp) { + if (!regexp_props[key]) return this; + } else if (typeof val == "object") { + if (!HOP(val, key)) return this; + } else if (typeof val == "function") switch (key) { + case "name": + return val.node.name ? val.node.name.name : ""; + case "length": + return val.node.length(); + default: + return this; + } + return val[key]; + } + return this; + }); + function eval_all(nodes, compressor, ignore_side_effects, cached, depth) { + var values = []; + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var value = node._eval(compressor, ignore_side_effects, cached, depth); + if (node === value) return; + values.push(value); + } + return values; + } + def(AST_Call, function(compressor, ignore_side_effects, cached, depth) { + var exp = this.expression; + var fn = exp instanceof AST_SymbolRef ? exp.fixed_value() : exp; + if (fn instanceof AST_Arrow || fn instanceof AST_Defun || fn instanceof AST_Function) { + if (fn.evaluating) return this; + if (fn.name && fn.name.definition().recursive_refs > 0) return this; + if (this.is_expr_pure(compressor)) return this; + var args = eval_all(this.args, compressor, ignore_side_effects, cached, depth); + if (!all(fn.argnames, function(sym, index) { + if (sym instanceof AST_DefaultValue) { + if (!args) return false; + if (args[index] === undefined) { + var value = sym.value._eval(compressor, ignore_side_effects, cached, depth); + if (value === sym.value) return false; + args[index] = value; + } + sym = sym.name; + } + return !(sym instanceof AST_Destructured); + })) return this; + if (fn.rest instanceof AST_Destructured) return this; + if (!args && !ignore_side_effects) return this; + var stat = fn.first_statement(); + if (!(stat instanceof AST_Return)) { + if (ignore_side_effects) { + fn.walk(scan_modified); + var found = false; + fn.evaluating = true; + walk_body(fn, new TreeWalker(function(node) { + if (found) return true; + if (node instanceof AST_Return) { + if (node.value && node.value._eval(compressor, true, cached, depth) !== undefined) { + found = true; + } + return true; + } + if (node instanceof AST_Scope && node !== fn) return true; + })); + fn.evaluating = false; + if (!found) return; + } + return this; + } + var val = stat.value; + if (!val) return; + var cached_args = []; + if (!args || all(fn.argnames, function(sym, i) { + return assign(sym, args[i]); + }) && !(fn.rest && !assign(fn.rest, args.slice(fn.argnames.length))) || ignore_side_effects) { + if (ignore_side_effects) fn.argnames.forEach(function(sym) { + if (sym instanceof AST_DefaultValue) sym.value.walk(scan_modified); + }); + fn.evaluating = true; + val = val._eval(compressor, ignore_side_effects, cached, depth); + fn.evaluating = false; + } + cached_args.forEach(function(node) { + delete node._eval; + }); + return val === stat.value ? this : val; + } else if (compressor.option("unsafe") && exp instanceof AST_PropAccess) { + var key = exp.property; + if (key instanceof AST_Node) { + key = key._eval(compressor, ignore_side_effects, cached, depth); + if (key === exp.property) return this; + } + var val; + var e = exp.expression; + if (is_undeclared_ref(e)) { + var static_fn = static_fns[e.name]; + if (!static_fn || !static_fn[key]) return this; + val = global_objs[e.name]; + } else { + val = e._eval(compressor, ignore_side_effects, cached, depth + 1); + if (val == null || val === e) return this; + var native_fn = native_fns[val.constructor.name]; + if (!native_fn || !native_fn[key]) return this; + if (val instanceof RegExp && val.global && !(e instanceof AST_RegExp)) return this; + } + var args = eval_all(this.args, compressor, ignore_side_effects, cached, depth); + if (!args) return this; + if (key == "replace" && typeof args[1] == "function") return this; + try { + return val[key].apply(val, args); + } catch (ex) { + AST_Node.warn("Error evaluating {this} [{start}]", this); + } finally { + if (val instanceof RegExp) val.lastIndex = 0; + } + } + return this; + + function assign(sym, arg) { + if (sym instanceof AST_DefaultValue) sym = sym.name; + var def = sym.definition(); + if (def.orig[def.orig.length - 1] !== sym) return false; + var value = arg; + def.references.forEach(function(node) { + node._eval = function() { + return value; + }; + cached_args.push(node); + }); + return true; + } + }); + def(AST_New, return_this); + def(AST_Template, function(compressor, ignore_side_effects, cached, depth) { + if (!compressor.option("templates")) return this; + if (this.tag) { + if (!is_raw_tag(compressor, this.tag)) return this; + decode = function(str) { + return str; + }; + } + var exprs = eval_all(this.expressions, compressor, ignore_side_effects, cached, depth); + if (!exprs) return this; + var malformed = false; + var ret = decode(this.strings[0]); + for (var i = 0; i < exprs.length; i++) { + ret += exprs[i] + decode(this.strings[i + 1]); + } + if (!malformed) return ret; + this._eval = return_this; + return this; + + function decode(str) { + str = decode_template(str); + if (typeof str != "string") malformed = true; + return str; + } + }); + })(function(node, func) { + node.DEFMETHOD("_eval", func); + }); + + // method to negate an expression + (function(def) { + function basic_negation(exp) { + return make_node(AST_UnaryPrefix, exp, { + operator: "!", + expression: exp, + }); + } + function best(orig, alt, first_in_statement) { + var negated = basic_negation(orig); + if (first_in_statement) return best_of_expression(negated, make_node(AST_SimpleStatement, alt, { + body: alt, + })) === negated ? negated : alt; + return best_of_expression(negated, alt); + } + def(AST_Node, function() { + return basic_negation(this); + }); + def(AST_Statement, function() { + throw new Error("Cannot negate a statement"); + }); + def(AST_Binary, function(compressor, first_in_statement) { + var self = this.clone(), op = this.operator; + if (compressor.option("unsafe_comps")) { + switch (op) { + case "<=" : self.operator = ">" ; return self; + case "<" : self.operator = ">=" ; return self; + case ">=" : self.operator = "<" ; return self; + case ">" : self.operator = "<=" ; return self; + } + } + switch (op) { + case "==" : self.operator = "!="; return self; + case "!=" : self.operator = "=="; return self; + case "===": self.operator = "!=="; return self; + case "!==": self.operator = "==="; return self; + case "&&": + self.operator = "||"; + self.left = self.left.negate(compressor, first_in_statement); + self.right = self.right.negate(compressor); + return best(this, self, first_in_statement); + case "||": + self.operator = "&&"; + self.left = self.left.negate(compressor, first_in_statement); + self.right = self.right.negate(compressor); + return best(this, self, first_in_statement); + } + return basic_negation(this); + }); + def(AST_ClassExpression, function() { + return basic_negation(this); + }); + def(AST_Conditional, function(compressor, first_in_statement) { + var self = this.clone(); + self.consequent = self.consequent.negate(compressor); + self.alternative = self.alternative.negate(compressor); + return best(this, self, first_in_statement); + }); + def(AST_LambdaExpression, function() { + return basic_negation(this); + }); + def(AST_Sequence, function(compressor) { + var expressions = this.expressions.slice(); + expressions.push(expressions.pop().negate(compressor)); + return make_sequence(this, expressions); + }); + def(AST_UnaryPrefix, function() { + if (this.operator == "!") + return this.expression; + return basic_negation(this); + }); + })(function(node, func) { + node.DEFMETHOD("negate", function(compressor, first_in_statement) { + return func.call(this, compressor, first_in_statement); + }); + }); + + var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError"); + var global_pure_constructors = makePredicate("Map Set WeakMap WeakSet"); + AST_Call.DEFMETHOD("is_expr_pure", function(compressor) { + if (compressor.option("unsafe")) { + var expr = this.expression; + if (is_undeclared_ref(expr)) { + if (global_pure_fns[expr.name]) return true; + if (this instanceof AST_New && global_pure_constructors[expr.name]) return true; + } + if (is_static_fn(expr)) return true; + } + return compressor.option("annotations") && this.pure || !compressor.pure_funcs(this); + }); + AST_Template.DEFMETHOD("is_expr_pure", function(compressor) { + var tag = this.tag; + if (!tag) return true; + if (compressor.option("unsafe")) { + if (is_undeclared_ref(tag) && global_pure_fns[tag.name]) return true; + if (tag instanceof AST_Dot && is_undeclared_ref(tag.expression)) { + var static_fn = static_fns[tag.expression.name]; + return static_fn && (static_fn[tag.property] + || tag.expression.name == "Math" && tag.property == "random"); + } + } + return !compressor.pure_funcs(this); + }); + AST_Node.DEFMETHOD("is_call_pure", return_false); + AST_Call.DEFMETHOD("is_call_pure", function(compressor) { + if (!compressor.option("unsafe")) return false; + var dot = this.expression; + if (!(dot instanceof AST_Dot)) return false; + var exp = dot.expression; + var map; + var prop = dot.property; + if (exp instanceof AST_Array) { + map = native_fns.Array; + } else if (exp.is_boolean(compressor)) { + map = native_fns.Boolean; + } else if (exp.is_number(compressor)) { + map = native_fns.Number; + } else if (exp instanceof AST_RegExp) { + map = native_fns.RegExp; + } else if (exp.is_string(compressor)) { + map = native_fns.String; + if (prop == "replace") { + var arg = this.args[1]; + if (arg && !arg.is_string(compressor)) return false; + } + } else if (!dot.may_throw_on_access(compressor)) { + map = native_fns.Object; + } + return map && map[prop]; + }); + + // determine if object spread syntax may cause runtime exception + (function(def) { + def(AST_Node, return_false); + def(AST_Array, return_true); + def(AST_Assign, function() { + switch (this.operator) { + case "=": + return this.right.safe_to_spread(); + case "&&=": + case "||=": + case "??=": + return this.left.safe_to_spread() && this.right.safe_to_spread(); + } + return true; + }); + def(AST_Binary, function() { + return !lazy_op[this.operator] || this.left.safe_to_spread() && this.right.safe_to_spread(); + }); + def(AST_Constant, return_true); + def(AST_Lambda, return_true); + def(AST_Object, function() { + return all(this.properties, function(prop) { + return !(prop instanceof AST_ObjectGetter || prop instanceof AST_Spread); + }); + }); + def(AST_Sequence, function() { + return this.tail_node().safe_to_spread(); + }); + def(AST_SymbolRef, function() { + var fixed = this.fixed_value(); + return fixed && fixed.safe_to_spread(); + }); + def(AST_Unary, return_true); + })(function(node, func) { + node.DEFMETHOD("safe_to_spread", func); + }); + + // determine if expression has side effects + (function(def) { + function any(list, compressor, spread) { + return !all(list, spread ? function(node) { + return node instanceof AST_Spread ? !spread(node, compressor) : !node.has_side_effects(compressor); + } : function(node) { + return !node.has_side_effects(compressor); + }); + } + function array_spread(node, compressor) { + var exp = node.expression; + return !exp.is_string(compressor) || exp.has_side_effects(compressor); + } + def(AST_Node, return_true); + def(AST_Array, function(compressor) { + return any(this.elements, compressor, array_spread); + }); + def(AST_Assign, function(compressor) { + var lhs = this.left; + if (!(lhs instanceof AST_PropAccess)) return true; + var node = lhs.expression; + return !(node instanceof AST_ObjectIdentity) + || !node.scope.resolve().new + || lhs instanceof AST_Sub && lhs.property.has_side_effects(compressor) + || this.right.has_side_effects(compressor); + }); + def(AST_Binary, function(compressor) { + return this.left.has_side_effects(compressor) + || this.right.has_side_effects(compressor) + || !can_drop_op(this.operator, this.right, compressor); + }); + def(AST_Block, function(compressor) { + return any(this.body, compressor); + }); + def(AST_Call, function(compressor) { + if (!this.is_expr_pure(compressor) + && (!this.is_call_pure(compressor) || this.expression.has_side_effects(compressor))) { + return true; + } + return any(this.args, compressor, array_spread); + }); + def(AST_Case, function(compressor) { + return this.expression.has_side_effects(compressor) + || any(this.body, compressor); + }); + def(AST_Class, function(compressor) { + var base = this.extends; + if (base) { + if (base instanceof AST_SymbolRef) base = base.fixed_value(); + if (!safe_for_extends(base)) return true; + } + return any(this.properties, compressor); + }); + def(AST_ClassProperty, function(compressor) { + return this.key instanceof AST_Node && this.key.has_side_effects(compressor) + || this.static && this.value && this.value.has_side_effects(compressor); + }); + def(AST_Conditional, function(compressor) { + return this.condition.has_side_effects(compressor) + || this.consequent.has_side_effects(compressor) + || this.alternative.has_side_effects(compressor); + }); + def(AST_Constant, return_false); + def(AST_Definitions, function(compressor) { + return any(this.definitions, compressor); + }); + def(AST_DestructuredArray, function(compressor) { + return any(this.elements, compressor); + }); + def(AST_DestructuredKeyVal, function(compressor) { + return this.key instanceof AST_Node && this.key.has_side_effects(compressor) + || this.value.has_side_effects(compressor); + }); + def(AST_DestructuredObject, function(compressor) { + return any(this.properties, compressor); + }); + def(AST_Dot, function(compressor) { + return this.expression.may_throw_on_access(compressor) + || this.expression.has_side_effects(compressor); + }); + def(AST_EmptyStatement, return_false); + def(AST_If, function(compressor) { + return this.condition.has_side_effects(compressor) + || this.body && this.body.has_side_effects(compressor) + || this.alternative && this.alternative.has_side_effects(compressor); + }); + def(AST_LabeledStatement, function(compressor) { + return this.body.has_side_effects(compressor); + }); + def(AST_Lambda, return_false); + def(AST_Object, function(compressor) { + return any(this.properties, compressor, function(node, compressor) { + var exp = node.expression; + return !exp.safe_to_spread() || exp.has_side_effects(compressor); + }); + }); + def(AST_ObjectIdentity, return_false); + def(AST_ObjectProperty, function(compressor) { + return this.key instanceof AST_Node && this.key.has_side_effects(compressor) + || this.value.has_side_effects(compressor); + }); + def(AST_Sequence, function(compressor) { + return any(this.expressions, compressor); + }); + def(AST_SimpleStatement, function(compressor) { + return this.body.has_side_effects(compressor); + }); + def(AST_Sub, function(compressor) { + return this.expression.may_throw_on_access(compressor) + || this.expression.has_side_effects(compressor) + || this.property.has_side_effects(compressor); + }); + def(AST_Switch, function(compressor) { + return this.expression.has_side_effects(compressor) + || any(this.body, compressor); + }); + def(AST_SymbolDeclaration, return_false); + def(AST_SymbolRef, function(compressor) { + return !this.is_declared(compressor) || !can_drop_symbol(this, compressor); + }); + def(AST_Template, function(compressor) { + return !this.is_expr_pure(compressor) || any(this.expressions, compressor); + }); + def(AST_Try, function(compressor) { + return any(this.body, compressor) + || this.bcatch && this.bcatch.has_side_effects(compressor) + || this.bfinally && this.bfinally.has_side_effects(compressor); + }); + def(AST_Unary, function(compressor) { + return unary_side_effects[this.operator] + || this.expression.has_side_effects(compressor); + }); + def(AST_VarDef, function() { + return this.value; + }); + })(function(node, func) { + node.DEFMETHOD("has_side_effects", func); + }); + + // determine if expression may throw + (function(def) { + def(AST_Node, return_true); + + def(AST_Constant, return_false); + def(AST_EmptyStatement, return_false); + def(AST_Lambda, return_false); + def(AST_ObjectIdentity, return_false); + def(AST_SymbolDeclaration, return_false); + + function any(list, compressor) { + for (var i = list.length; --i >= 0;) + if (list[i].may_throw(compressor)) + return true; + return false; + } + + function call_may_throw(exp, compressor) { + if (exp.may_throw(compressor)) return true; + if (exp instanceof AST_SymbolRef) exp = exp.fixed_value(); + if (!(exp instanceof AST_Lambda)) return true; + if (any(exp.argnames, compressor)) return true; + if (any(exp.body, compressor)) return true; + return is_arrow(exp) && exp.value && exp.value.may_throw(compressor); + } + + def(AST_Array, function(compressor) { + return any(this.elements, compressor); + }); + def(AST_Assign, function(compressor) { + if (this.right.may_throw(compressor)) return true; + if (!compressor.has_directive("use strict") + && this.operator == "=" + && this.left instanceof AST_SymbolRef) { + return false; + } + return this.left.may_throw(compressor); + }); + def(AST_Await, function(compressor) { + return this.expression.may_throw(compressor); + }); + def(AST_Binary, function(compressor) { + return this.left.may_throw(compressor) + || this.right.may_throw(compressor) + || !can_drop_op(this.operator, this.right, compressor); + }); + def(AST_Block, function(compressor) { + return any(this.body, compressor); + }); + def(AST_Call, function(compressor) { + if (any(this.args, compressor)) return true; + if (this.is_expr_pure(compressor)) return false; + this.may_throw = return_true; + var ret = call_may_throw(this.expression, compressor); + delete this.may_throw; + return ret; + }); + def(AST_Case, function(compressor) { + return this.expression.may_throw(compressor) + || any(this.body, compressor); + }); + def(AST_Conditional, function(compressor) { + return this.condition.may_throw(compressor) + || this.consequent.may_throw(compressor) + || this.alternative.may_throw(compressor); + }); + def(AST_DefaultValue, function(compressor) { + return this.name.may_throw(compressor) + || this.value && this.value.may_throw(compressor); + }); + def(AST_Definitions, function(compressor) { + return any(this.definitions, compressor); + }); + def(AST_Dot, function(compressor) { + return !this.optional && this.expression.may_throw_on_access(compressor) + || this.expression.may_throw(compressor); + }); + def(AST_ForEnumeration, function(compressor) { + if (this.init.may_throw(compressor)) return true; + var obj = this.object; + if (obj.may_throw(compressor)) return true; + obj = obj.tail_node(); + if (!(obj instanceof AST_Array || obj.is_string(compressor))) return true; + return this.body.may_throw(compressor); + }); + def(AST_If, function(compressor) { + return this.condition.may_throw(compressor) + || this.body && this.body.may_throw(compressor) + || this.alternative && this.alternative.may_throw(compressor); + }); + def(AST_LabeledStatement, function(compressor) { + return this.body.may_throw(compressor); + }); + def(AST_Object, function(compressor) { + return any(this.properties, compressor); + }); + def(AST_ObjectProperty, function(compressor) { + return this.value.may_throw(compressor) + || this.key instanceof AST_Node && this.key.may_throw(compressor); + }); + def(AST_Return, function(compressor) { + return this.value && this.value.may_throw(compressor); + }); + def(AST_Sequence, function(compressor) { + return any(this.expressions, compressor); + }); + def(AST_SimpleStatement, function(compressor) { + return this.body.may_throw(compressor); + }); + def(AST_Sub, function(compressor) { + return !this.optional && this.expression.may_throw_on_access(compressor) + || this.expression.may_throw(compressor) + || this.property.may_throw(compressor); + }); + def(AST_Switch, function(compressor) { + return this.expression.may_throw(compressor) + || any(this.body, compressor); + }); + def(AST_SymbolRef, function(compressor) { + return !this.is_declared(compressor) || !can_drop_symbol(this, compressor); + }); + def(AST_Template, function(compressor) { + if (any(this.expressions, compressor)) return true; + if (this.is_expr_pure(compressor)) return false; + if (!this.tag) return false; + this.may_throw = return_true; + var ret = call_may_throw(this.tag, compressor); + delete this.may_throw; + return ret; + }); + def(AST_Try, function(compressor) { + return (this.bcatch ? this.bcatch.may_throw(compressor) : any(this.body, compressor)) + || this.bfinally && this.bfinally.may_throw(compressor); + }); + def(AST_Unary, function(compressor) { + return this.expression.may_throw(compressor) + && !(this.operator == "typeof" && this.expression instanceof AST_SymbolRef); + }); + def(AST_VarDef, function(compressor) { + return this.name.may_throw(compressor) + || this.value && this.value.may_throw(compressor); + }); + })(function(node, func) { + node.DEFMETHOD("may_throw", func); + }); + + // determine if expression is constant + (function(def) { + function all_constant(list, scope) { + for (var i = list.length; --i >= 0;) + if (!list[i].is_constant_expression(scope)) + return false; + return true; + } + def(AST_Node, return_false); + def(AST_Array, function(scope) { + return all_constant(this.elements, scope); + }); + def(AST_Binary, function(scope) { + return this.left.is_constant_expression(scope) + && this.right.is_constant_expression(scope) + && can_drop_op(this.operator, this.right); + }); + def(AST_Class, function(scope) { + var base = this.extends; + if (base && !safe_for_extends(base)) return false; + return all_constant(this.properties, scope); + }); + def(AST_ClassProperty, function(scope) { + return typeof this.key == "string" && (!this.value || this.value.is_constant_expression(scope)); + }); + def(AST_Constant, return_true); + def(AST_Lambda, function(scope) { + var self = this; + var result = true; + var scopes = []; + self.walk(new TreeWalker(function(node, descend) { + if (!result) return true; + if (node instanceof AST_BlockScope) { + if (node === self) return; + scopes.push(node); + descend(); + scopes.pop(); + return true; + } + if (node instanceof AST_SymbolRef) { + if (self.inlined || node.redef || node.in_arg) { + result = false; + return true; + } + if (self.variables.has(node.name)) return true; + var def = node.definition(); + if (member(def.scope, scopes)) return true; + if (scope && !def.redefined()) { + var scope_def = scope.find_variable(node.name); + if (scope_def ? scope_def === def : def.undeclared) { + result = "f"; + return true; + } + } + result = false; + return true; + } + if (node instanceof AST_ObjectIdentity) { + if (is_arrow(self) && all(scopes, function(s) { + return !(s instanceof AST_Scope) || is_arrow(s); + })) result = false; + return true; + } + })); + return result; + }); + def(AST_Object, function(scope) { + return all_constant(this.properties, scope); + }); + def(AST_ObjectProperty, function(scope) { + return typeof this.key == "string" && this.value.is_constant_expression(scope); + }); + def(AST_Unary, function(scope) { + return this.expression.is_constant_expression(scope); + }); + })(function(node, func) { + node.DEFMETHOD("is_constant_expression", func); + }); + + // tell me if a statement aborts + function aborts(thing) { + return thing && thing.aborts(); + } + (function(def) { + def(AST_Statement, return_null); + def(AST_Jump, return_this); + function block_aborts() { + var n = this.body.length; + return n > 0 && aborts(this.body[n - 1]); + } + def(AST_BlockStatement, block_aborts); + def(AST_SwitchBranch, block_aborts); + def(AST_If, function() { + return this.alternative && aborts(this.body) && aborts(this.alternative) && this; + }); + })(function(node, func) { + node.DEFMETHOD("aborts", func); + }); + + /* -----[ optimizers ]----- */ + + var directives = makePredicate(["use asm", "use strict"]); + OPT(AST_Directive, function(self, compressor) { + if (compressor.option("directives") + && (!directives[self.value] || compressor.has_directive(self.value) !== self)) { + return make_node(AST_EmptyStatement, self); + } + return self; + }); + + OPT(AST_Debugger, function(self, compressor) { + if (compressor.option("drop_debugger")) + return make_node(AST_EmptyStatement, self); + return self; + }); + + OPT(AST_LabeledStatement, function(self, compressor) { + if (self.body instanceof AST_If || self.body instanceof AST_Break) { + var body = tighten_body([ self.body ], compressor); + switch (body.length) { + case 0: + self.body = make_node(AST_EmptyStatement, self); + break; + case 1: + self.body = body[0]; + break; + default: + self.body = make_node(AST_BlockStatement, self, { body: body }); + break; + } + } + return compressor.option("unused") && self.label.references.length == 0 ? self.body : self; + }); + + OPT(AST_LoopControl, function(self, compressor) { + if (!compressor.option("dead_code")) return self; + var label = self.label; + if (label) { + var lct = compressor.loopcontrol_target(self); + self.label = null; + if (compressor.loopcontrol_target(self) === lct) { + remove(label.thedef.references, self); + } else { + self.label = label; + } + } + return self; + }); + + OPT(AST_Block, function(self, compressor) { + self.body = tighten_body(self.body, compressor); + return self; + }); + + function trim_block(node, parent, in_list) { + switch (node.body.length) { + case 0: + return in_list ? List.skip : make_node(AST_EmptyStatement, node); + case 1: + var stat = node.body[0]; + if (!safe_to_trim(stat)) return node; + if (parent instanceof AST_IterationStatement && stat instanceof AST_LambdaDefinition) return node; + return stat; + } + return node; + } + + OPT(AST_BlockStatement, function(self, compressor) { + self.body = tighten_body(self.body, compressor); + return trim_block(self, compressor.parent()); + }); + + function drop_rest_farg(fn, compressor) { + if (!compressor.option("rests")) return; + if (fn.uses_arguments) return; + if (!(fn.rest instanceof AST_DestructuredArray)) return; + if (!compressor.drop_fargs(fn, compressor.parent())) return; + fn.argnames = fn.argnames.concat(fn.rest.elements); + fn.rest = fn.rest.rest; + } + + OPT(AST_Lambda, function(self, compressor) { + drop_rest_farg(self, compressor); + self.body = tighten_body(self.body, compressor); + return self; + }); + + function opt_arrow(self, compressor) { + if (!compressor.option("arrows")) return self; + drop_rest_farg(self, compressor); + if (self.value) self.body = [ self.first_statement() ]; + var body = tighten_body(self.body, compressor); + switch (body.length) { + case 1: + var stat = body[0]; + if (stat instanceof AST_Return) { + self.body.length = 0; + self.value = stat.value; + break; + } + default: + self.body = body; + self.value = null; + break; + } + return self; + } + OPT(AST_Arrow, opt_arrow); + OPT(AST_AsyncArrow, opt_arrow); + + OPT(AST_Function, function(self, compressor) { + drop_rest_farg(self, compressor); + self.body = tighten_body(self.body, compressor); + var parent = compressor.parent(); + if (compressor.option("inline")) for (var i = 0; i < self.body.length; i++) { + var stat = self.body[i]; + if (stat instanceof AST_Directive) continue; + if (stat instanceof AST_Return) { + if (i != self.body.length - 1) break; + var call = stat.value; + if (!call || call.TYPE != "Call") break; + if (call.is_expr_pure(compressor)) break; + var exp = call.expression, fn; + if (!(exp instanceof AST_SymbolRef)) { + fn = exp; + } else if (self.name && self.name.definition() === exp.definition()) { + break; + } else { + fn = exp.fixed_value(); + } + if (!(fn instanceof AST_Defun || fn instanceof AST_Function)) break; + if (fn.rest) break; + if (fn.uses_arguments) break; + if (fn === exp) { + if (fn.parent_scope !== self) break; + if (!all(fn.enclosed, function(def) { + return def.scope !== self; + })) break; + } + if ((fn !== exp || fn.name) + && (parent instanceof AST_ClassMethod || parent instanceof AST_ObjectMethod) + && parent.value === compressor.self()) break; + if (fn.contains_this()) break; + var len = fn.argnames.length; + if (len > 0 && compressor.option("inline") < 2) break; + if (len > self.argnames.length) break; + if (!all(self.argnames, function(argname) { + return argname instanceof AST_SymbolFunarg; + })) break; + if (!all(call.args, function(arg) { + return !(arg instanceof AST_Spread); + })) break; + for (var j = 0; j < len; j++) { + var arg = call.args[j]; + if (!(arg instanceof AST_SymbolRef)) break; + if (arg.definition() !== self.argnames[j].definition()) break; + } + if (j < len) break; + for (; j < call.args.length; j++) { + if (call.args[j].has_side_effects(compressor)) break; + } + if (j < call.args.length) break; + if (len < self.argnames.length && !compressor.drop_fargs(self, parent)) { + if (!compressor.drop_fargs(fn, call)) break; + do { + fn.argnames.push(fn.make_var(AST_SymbolFunarg, fn, "argument_" + len)); + } while (++len < self.argnames.length); + } + return exp; + } + break; + } + return self; + }); + + var NO_MERGE = makePredicate("arguments await yield"); + AST_Scope.DEFMETHOD("merge_variables", function(compressor) { + if (!compressor.option("merge_vars")) return; + var in_arg = [], in_try, root, segment = {}, self = this; + var first = [], last = [], index = 0; + var declarations = new Dictionary(); + var references = Object.create(null); + var prev = Object.create(null); + var tw = new TreeWalker(function(node, descend) { + if (node instanceof AST_Assign) { + var lhs = node.left; + var rhs = node.right; + if (lhs instanceof AST_Destructured) { + rhs.walk(tw); + walk_destructured(AST_SymbolRef, mark, lhs); + return true; + } + if (lazy_op[node.operator.slice(0, -1)]) { + lhs.walk(tw); + push(); + rhs.walk(tw); + if (lhs instanceof AST_SymbolRef) mark(lhs); + pop(); + return true; + } + if (lhs instanceof AST_SymbolRef) { + if (node.operator != "=") mark(lhs, true); + rhs.walk(tw); + mark(lhs); + return true; + } + return; + } + if (node instanceof AST_Binary) { + if (!lazy_op[node.operator]) return; + walk_cond(node); + return true; + } + if (node instanceof AST_Break) { + var target = tw.loopcontrol_target(node); + if (!(target instanceof AST_IterationStatement)) insert(target); + return true; + } + if (node instanceof AST_Call) { + var exp = node.expression; + if (exp instanceof AST_LambdaExpression) { + node.args.forEach(function(arg) { + arg.walk(tw); + }); + exp.walk(tw); + } else { + descend(); + mark_expression(exp); + } + return true; + } + if (node instanceof AST_Class) { + if (node.name) node.name.walk(tw); + if (node.extends) node.extends.walk(tw); + node.properties.filter(function(prop) { + if (prop.key instanceof AST_Node) prop.key.walk(tw); + return prop.value; + }).forEach(function(prop) { + if (prop.static) { + prop.value.walk(tw); + } else { + push(); + segment.block = node; + prop.value.walk(tw); + pop(); + } + }); + return true; + } + if (node instanceof AST_Conditional) { + walk_cond(node.condition, node.consequent, node.alternative); + return true; + } + if (node instanceof AST_Continue) { + var target = tw.loopcontrol_target(node); + if (target instanceof AST_Do) insert(target); + return true; + } + if (node instanceof AST_Do) { + push(); + segment.block = node; + segment.loop = true; + var save = segment; + node.body.walk(tw); + if (segment.inserted === node) segment = save; + node.condition.walk(tw); + pop(); + return true; + } + if (node instanceof AST_For) { + if (node.init) node.init.walk(tw); + push(); + segment.block = node; + segment.loop = true; + if (node.condition) node.condition.walk(tw); + node.body.walk(tw); + if (node.step) node.step.walk(tw); + pop(); + return true; + } + if (node instanceof AST_ForEnumeration) { + node.object.walk(tw); + push(); + segment.block = node; + segment.loop = true; + node.init.walk(tw); + node.body.walk(tw); + pop(); + return true; + } + if (node instanceof AST_If) { + walk_cond(node.condition, node.body, node.alternative); + return true; + } + if (node instanceof AST_LabeledStatement) { + push(); + segment.block = node; + var save = segment; + node.body.walk(tw); + if (segment.inserted === node) segment = save; + pop(); + return true; + } + if (node instanceof AST_Scope) { + push(); + segment.block = node; + if (node === self) root = segment; + if (node instanceof AST_Lambda) { + if (node.name) references[node.name.definition().id] = false; + var marker = node.uses_arguments && !tw.has_directive("use strict") ? function(node) { + references[node.definition().id] = false; + } : function(node) { + mark(node); + }; + in_arg.push(node); + node.argnames.forEach(function(argname) { + walk_destructured(AST_SymbolFunarg, marker, argname); + }); + if (node.rest) walk_destructured(AST_SymbolFunarg, marker, node.rest); + in_arg.pop(); + } + walk_lambda(node, tw); + pop(); + return true; + } + if (node instanceof AST_Sub) { + var exp = node.expression; + if (node.optional) { + exp.walk(tw); + push(); + node.property.walk(tw); + pop(); + } else { + descend(); + } + mark_expression(exp); + return true; + } + if (node instanceof AST_Switch) { + node.expression.walk(tw); + var save = segment; + node.body.forEach(function(branch) { + if (branch instanceof AST_Default) return; + branch.expression.walk(tw); + if (save === segment) push(); + }); + segment = save; + node.body.forEach(function(branch) { + push(); + segment.block = node; + var save = segment; + walk_body(branch, tw); + if (segment.inserted === node) segment = save; + pop(); + }); + return true; + } + if (node instanceof AST_SymbolConst || node instanceof AST_SymbolLet) { + references[node.definition().id] = false; + return true; + } + if (node instanceof AST_SymbolRef) { + mark(node, true); + return true; + } + if (node instanceof AST_Try) { + var save_try = in_try; + in_try = node; + walk_body(node, tw); + if (node.bcatch) { + if (node.bcatch.argname) node.bcatch.argname.mark_symbol(function(node) { + if (node instanceof AST_SymbolCatch) { + var def = node.definition(); + references[def.id] = false; + if (def = def.redefined()) references[def.id] = false; + } + }, tw); + if (node.bfinally || (in_try = save_try)) { + walk_body(node.bcatch, tw); + } else { + push(); + walk_body(node.bcatch, tw); + pop(); + } + } + in_try = save_try; + if (node.bfinally) node.bfinally.walk(tw); + return true; + } + if (node instanceof AST_Unary) { + if (!UNARY_POSTFIX[node.operator]) return; + var sym = node.expression; + if (!(sym instanceof AST_SymbolRef)) return; + mark(sym, true); + return true; + } + if (node instanceof AST_VarDef) { + var assigned = node.value; + if (assigned) { + assigned.walk(tw); + } else { + assigned = segment.block instanceof AST_ForEnumeration && segment.block.init === tw.parent(); + } + walk_destructured(AST_SymbolDeclaration, assigned ? function(node) { + if (node instanceof AST_SymbolVar) { + mark(node); + } else { + node.walk(tw); + } + } : function(node) { + if (node instanceof AST_SymbolVar) { + var id = node.definition().id; + var refs = references[id]; + if (refs) { + refs.push(node); + } else if (!(id in references)) { + declarations.add(id, node); + } + } else { + node.walk(tw); + } + }, node.name); + return true; + } + if (node instanceof AST_While) { + push(); + segment.block = node; + segment.loop = true; + descend(); + pop(); + return true; + } + + function mark_expression(exp) { + if (!compressor.option("ie")) return; + var sym = root_expr(exp); + if (sym instanceof AST_SymbolRef) sym.walk(tw); + } + + function walk_cond(condition, consequent, alternative) { + var save = segment; + var segments = [ save, save ]; + if (condition instanceof AST_Binary) switch (condition.operator) { + case "&&": + segments[0] = walk_cond(condition.left, condition.right)[0]; + break; + case "||": + case "??": + segments[1] = walk_cond(condition.left, null, condition.right)[1]; + break; + default: + condition.walk(tw); + break; + } else if (condition instanceof AST_Conditional) { + walk_cond(condition.condition, condition.consequent, condition.alternative); + } else { + condition.walk(tw); + } + segment = segments[0]; + if (consequent) { + push(); + consequent.walk(tw); + } + segments[0] = segment; + segment = segments[1]; + if (alternative) { + push(); + alternative.walk(tw); + } + segments[1] = segment; + segment = save; + return segments; + } + }); + tw.directives = Object.create(compressor.directives); + self.walk(tw); + var changed = false; + var merged = Object.create(null); + while (first.length && last.length) { + var tail = last.shift(); + if (!tail) continue; + var def = tail.definition; + var tail_refs = references[def.id]; + if (!tail_refs) continue; + tail_refs = { end: tail_refs.end }; + while (def.id in merged) def = merged[def.id]; + tail_refs.start = references[def.id].start; + var skipped = []; + do { + var head = first.shift(); + if (tail.index > head.index) continue; + var prev_def = head.definition; + if (!(prev_def.id in prev)) continue; + var head_refs = references[prev_def.id]; + if (!head_refs) continue; + if (head_refs.start.block !== tail_refs.start.block + || !mergeable(head_refs, tail_refs) + || (head_refs.start.loop || !same_scope(def)) && !mergeable(tail_refs, head_refs) + || compressor.option("webkit") && is_funarg(def) !== is_funarg(prev_def) + || prev_def.const_redefs + || !all(head_refs.scopes, function(scope) { + return scope.find_variable(def.name) === def; + })) { + skipped.push(head); + continue; + } + head_refs.forEach(function(sym) { + sym.thedef = def; + sym.name = def.name; + if (sym instanceof AST_SymbolRef) { + def.references.push(sym); + prev_def.replaced++; + } else { + def.orig.push(sym); + prev_def.eliminated++; + } + }); + if (!prev_def.fixed) def.fixed = false; + merged[prev_def.id] = def; + changed = true; + break; + } while (first.length); + if (skipped.length) first = skipped.concat(first); + } + return changed; + + function push() { + segment = Object.create(segment); + } + + function pop() { + segment = Object.getPrototypeOf(segment); + } + + function walk_destructured(symbol_type, mark, lhs) { + var marker = new TreeWalker(function(node) { + if (node instanceof AST_Destructured) return; + if (node instanceof AST_DefaultValue) { + push(); + node.value.walk(tw); + pop(); + node.name.walk(marker); + } else if (node instanceof AST_DestructuredKeyVal) { + if (!(node.key instanceof AST_Node)) { + node.value.walk(marker); + } else if (node.value instanceof AST_PropAccess) { + push(); + segment.block = node; + node.key.walk(tw); + node.value.walk(marker); + pop(); + } else { + node.key.walk(tw); + node.value.walk(marker); + } + } else if (node instanceof symbol_type) { + mark(node); + } else { + node.walk(tw); + } + return true; + }); + lhs.walk(marker); + } + + function mark(sym, read) { + var def = sym.definition(), ldef; + if (read && !all(in_arg, function(fn) { + ldef = fn.variables.get(sym.name); + if (!ldef) return true; + if (!is_funarg(ldef)) return true; + return ldef !== def + && !def.undeclared + && fn.parent_scope.find_variable(sym.name) !== def; + })) return references[def.id] = references[ldef.id] = false; + var seg = segment; + if (in_try) { + push(); + seg = segment; + pop(); + } + if (def.id in references) { + var refs = references[def.id]; + if (!refs) return; + if (refs.start.block !== seg.block) return references[def.id] = false; + push_ref(sym); + refs.end = seg; + if (def.id in prev) { + last[prev[def.id]] = null; + } else if (!read) { + return; + } + } else if ((ldef = self.variables.get(def.name)) !== def) { + if (ldef && root === seg) references[ldef.id] = false; + return references[def.id] = false; + } else if (compressor.exposed(def) || NO_MERGE[sym.name]) { + return references[def.id] = false; + } else { + var refs = declarations.get(def.id) || []; + refs.scopes = []; + push_ref(sym); + references[def.id] = refs; + if (!read) { + refs.start = seg; + return first.push({ + index: index++, + definition: def, + }); + } + if (seg.block !== self) return references[def.id] = false; + refs.start = root; + } + prev[def.id] = last.length; + last.push({ + index: index++, + definition: def, + }); + + function push_ref(sym) { + refs.push(sym); + push_uniq(refs.scopes, sym.scope); + var scope = find_scope(tw); + if (scope !== sym.scope) push_uniq(refs.scopes, scope); + } + } + + function insert(target) { + var stack = []; + while (true) { + if (HOP(segment, "block")) { + var block = segment.block; + if (block instanceof AST_LabeledStatement) block = block.body; + if (block === target) break; + } + stack.push(segment); + pop(); + } + segment.inserted = segment.block; + push(); + while (stack.length) { + var seg = stack.pop(); + push(); + if (HOP(seg, "block")) segment.block = seg.block; + if (HOP(seg, "loop")) segment.loop = seg.loop; + } + } + + function must_visit(base, segment) { + return base === segment || base.isPrototypeOf(segment); + } + + function mergeable(head, tail) { + return must_visit(head.start, head.end) || must_visit(head.start, tail.start); + } + }); + + function fill_holes(orig, elements) { + for (var i = elements.length; --i >= 0;) { + if (!elements[i]) elements[i] = make_node(AST_Hole, orig); + } + } + + function to_class_expr(defcl, drop_name) { + var cl = make_node(AST_ClassExpression, defcl); + if (cl.name) cl.name = drop_name ? null : make_node(AST_SymbolClass, cl.name); + return cl; + } + + function to_func_expr(defun, drop_name) { + var ctor; + switch (defun.CTOR) { + case AST_AsyncDefun: + ctor = AST_AsyncFunction; + break; + case AST_AsyncGeneratorDefun: + ctor = AST_AsyncGeneratorFunction; + break; + case AST_Defun: + ctor = AST_Function; + break; + case AST_GeneratorDefun: + ctor = AST_GeneratorFunction; + break; + } + var fn = make_node(ctor, defun); + fn.name = drop_name ? null : make_node(AST_SymbolLambda, defun.name); + return fn; + } + + AST_Scope.DEFMETHOD("drop_unused", function(compressor) { + if (!compressor.option("unused")) return; + var self = this; + var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs; + var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars; + var assign_as_unused = /keep_assign/.test(compressor.option("unused")) ? return_false : function(node, props) { + var sym, nested = false; + if (node instanceof AST_Assign) { + if (node.write_only || node.operator == "=") sym = extract_reference(node.left, props); + } else if (node instanceof AST_Unary) { + if (node.write_only) sym = extract_reference(node.expression, props); + } + if (!(sym instanceof AST_SymbolRef)) return; + var def = sym.definition(); + if (export_defaults[def.id]) return; + if (compressor.exposed(def)) return; + if (!can_drop_symbol(sym, compressor, nested)) return; + return sym; + + function extract_reference(node, props) { + if (node instanceof AST_PropAccess) { + var expr = node.expression; + if (!expr.may_throw_on_access(compressor, true)) { + nested = true; + if (props && node instanceof AST_Sub) props.unshift(node.property); + return extract_reference(expr, props); + } + } else if (node instanceof AST_Assign && node.operator == "=") { + node.write_only = "p"; + var ref = extract_reference(node.right); + if (!props) return ref; + props.assign = node; + return ref instanceof AST_SymbolRef ? ref : node.left; + } + return node; + } + }; + var assign_in_use = Object.create(null); + var export_defaults = Object.create(null); + var find_variable = function(name) { + find_variable = compose(self, 0, noop); + return find_variable(name); + + function compose(child, level, find) { + var parent = compressor.parent(level); + if (!parent) return find; + var in_arg = parent instanceof AST_Lambda && member(child, parent.argnames); + return compose(parent, level + 1, in_arg ? function(name) { + var def = find(name); + if (def) return def; + def = parent.variables.get(name); + if (def) { + var sym = def.orig[0]; + if (sym instanceof AST_SymbolFunarg || sym instanceof AST_SymbolLambda) return def; + } + } : parent.variables ? function(name) { + return find(name) || parent.variables.get(name); + } : find); + } + }; + var for_ins = Object.create(null); + var in_use = []; + var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use + var lambda_ids = Object.create(null); + var value_read = Object.create(null); + var value_modified = Object.create(null); + var var_defs = Object.create(null); + if (self instanceof AST_Toplevel && compressor.top_retain) { + self.variables.each(function(def) { + if (compressor.top_retain(def) && !(def.id in in_use_ids)) { + AST_Node.info("Retaining variable {name}", def); + in_use_ids[def.id] = true; + in_use.push(def); + } + }); + } + var assignments = new Dictionary(); + var initializations = new Dictionary(); + // pass 1: find out which symbols are directly used in + // this scope (not in nested scopes). + var scope = this; + var tw = new TreeWalker(function(node, descend) { + if (node instanceof AST_Lambda && node.uses_arguments && !tw.has_directive("use strict")) { + node.each_argname(function(argname) { + var def = argname.definition(); + if (!(def.id in in_use_ids)) { + in_use_ids[def.id] = true; + in_use.push(def); + } + }); + } + if (node === self) return; + if (scope === self) { + if (node instanceof AST_DefClass) { + var def = node.name.definition(); + var drop = drop_funcs && !def.exported; + if (!drop && !(def.id in in_use_ids)) { + in_use_ids[def.id] = true; + in_use.push(def); + } + var used = tw.parent() instanceof AST_ExportDefault; + if (used) { + export_defaults[def.id] = true; + } else if (drop && !(def.id in lambda_ids)) { + lambda_ids[def.id] = 1; + } + if (node.extends) node.extends.walk(tw); + var values = []; + node.properties.forEach(function(prop) { + if (prop.key instanceof AST_Node) prop.key.walk(tw); + var value = prop.value; + if (!value) return; + if (is_static_field_or_init(prop)) { + if (!used && value.contains_this()) used = true; + walk_class_prop(value); + } else { + values.push(value); + } + }); + values.forEach(drop && used ? walk_class_prop : function(value) { + initializations.add(def.id, value); + }); + return true; + } + if (node instanceof AST_LambdaDefinition) { + var def = node.name.definition(); + var drop = drop_funcs && !def.exported; + if (!drop && !(def.id in in_use_ids)) { + in_use_ids[def.id] = true; + in_use.push(def); + } + initializations.add(def.id, node); + if (tw.parent() instanceof AST_ExportDefault) { + export_defaults[def.id] = true; + return scan_ref_scoped(node, descend, true); + } + if (drop && !(def.id in lambda_ids)) lambda_ids[def.id] = 1; + return true; + } + if (node instanceof AST_Definitions) { + node.definitions.forEach(function(defn) { + var value = defn.value; + var side_effects = value + && (defn.name instanceof AST_Destructured || value.has_side_effects(compressor)); + var shared = side_effects && value.tail_node().operator == "="; + defn.name.mark_symbol(function(name) { + if (!(name instanceof AST_SymbolDeclaration)) return; + var def = name.definition(); + var_defs[def.id] = (var_defs[def.id] || 0) + 1; + if (node instanceof AST_Var && def.orig[0] instanceof AST_SymbolCatch) { + var redef = def.redefined(); + if (redef) var_defs[redef.id] = (var_defs[redef.id] || 0) + 1; + } + if (!(def.id in in_use_ids) && (!drop_vars || def.exported + || (node instanceof AST_Const ? def.redefined() : def.const_redefs) + || !(node instanceof AST_Var || is_safe_lexical(def)))) { + in_use_ids[def.id] = true; + in_use.push(def); + } + if (value) { + if (!side_effects) { + initializations.add(def.id, value); + } else if (shared) { + verify_safe_usage(def, name, value_modified[def.id]); + } + assignments.add(def.id, defn); + } + unmark_lambda(def); + return true; + }, tw); + if (side_effects) value.walk(tw); + }); + return true; + } + if (node instanceof AST_SymbolFunarg) { + var def = node.definition(); + var_defs[def.id] = (var_defs[def.id] || 0) + 1; + assignments.add(def.id, node); + return true; + } + if (node instanceof AST_SymbolImport) { + var def = node.definition(); + if (!(def.id in in_use_ids) && (!drop_vars || !is_safe_lexical(def))) { + in_use_ids[def.id] = true; + in_use.push(def); + } + return true; + } + } + return scan_ref_scoped(node, descend, true); + + function walk_class_prop(value) { + var save_scope = scope; + scope = node; + value.walk(tw); + scope = save_scope; + } + }); + tw.directives = Object.create(compressor.directives); + self.walk(tw); + var drop_fn_name = compressor.option("keep_fnames") ? return_false : compressor.option("ie") ? function(def) { + return !compressor.exposed(def) && def.references.length == def.replaced; + } : function(def) { + if (!(def.id in in_use_ids)) return true; + if (def.orig.length - def.eliminated < 2) return false; + // function argument will always overshadow its name + if (def.orig[1] instanceof AST_SymbolFunarg) return true; + // retain if referenced within destructured object of argument + return all(def.references, function(ref) { + return !ref.in_arg; + }); + }; + if (compressor.option("ie")) initializations.each(function(init, id) { + if (id in in_use_ids) return; + init.forEach(function(init) { + init.walk(new TreeWalker(function(node) { + if (node instanceof AST_Function && node.name && !drop_fn_name(node.name.definition())) { + node.walk(tw); + return true; + } + if (node instanceof AST_Scope) return true; + })); + }); + }); + // pass 2: for every used symbol we need to walk its + // initialization code to figure out if it uses other + // symbols (that may not be in_use). + tw = new TreeWalker(scan_ref_scoped); + for (var i = 0; i < in_use.length; i++) { + var init = initializations.get(in_use[i].id); + if (init) init.forEach(function(init) { + init.walk(tw); + }); + } + Object.keys(assign_in_use).forEach(function(id) { + var assigns = assign_in_use[id]; + if (!assigns) { + delete assign_in_use[id]; + return; + } + assigns = assigns.reduce(function(in_use, assigns) { + assigns.forEach(function(assign) { + push_uniq(in_use, assign); + }); + return in_use; + }, []); + var in_use = (assignments.get(id) || []).filter(function(node) { + return find_if(node instanceof AST_Unary ? function(assign) { + return assign === node; + } : function(assign) { + if (assign === node) return true; + if (assign instanceof AST_Unary) return false; + return get_rvalue(assign) === get_rvalue(node); + }, assigns); + }); + if (assigns.length == in_use.length) { + assign_in_use[id] = in_use; + } else { + delete assign_in_use[id]; + } + }); + // pass 3: we should drop declarations not in_use + var calls_to_drop_args = []; + var fns_with_marked_args = []; + var trimmer = new TreeTransformer(function(node) { + if (node instanceof AST_DefaultValue) return trim_default(trimmer, node); + if (node instanceof AST_Destructured && node.rest) node.rest = node.rest.transform(trimmer); + if (node instanceof AST_DestructuredArray) { + var trim = !node.rest; + for (var i = node.elements.length; --i >= 0;) { + var element = node.elements[i].transform(trimmer); + if (element) { + node.elements[i] = element; + trim = false; + } else if (trim) { + node.elements.pop(); + } else { + node.elements[i] = make_node(AST_Hole, node.elements[i]); + } + } + return node; + } + if (node instanceof AST_DestructuredObject) { + var properties = []; + node.properties.forEach(function(prop) { + var retain = false; + if (prop.key instanceof AST_Node) { + prop.key = prop.key.transform(tt); + retain = prop.key.has_side_effects(compressor); + } + if ((retain || node.rest) && is_decl(prop.value)) { + prop.value = prop.value.transform(tt); + properties.push(prop); + } else { + var value = prop.value.transform(trimmer); + if (!value && node.rest) { + if (prop.value instanceof AST_DestructuredArray) { + value = make_node(AST_DestructuredArray, prop.value, { elements: [] }); + } else { + value = make_node(AST_DestructuredObject, prop.value, { properties: [] }); + } + } + if (value) { + prop.value = value; + properties.push(prop); + } + } + }); + node.properties = properties; + return node; + } + if (node instanceof AST_SymbolDeclaration) return trim_decl(node); + }); + var tt = new TreeTransformer(function(node, descend, in_list) { + var parent = tt.parent(); + if (drop_vars) { + var props = [], sym = assign_as_unused(node, props); + if (sym) { + var value; + if (can_drop_lhs(sym, node)) { + if (node instanceof AST_Assign) { + value = get_rhs(node); + if (node.write_only === true) value = value.drop_side_effect_free(compressor); + } + if (!value) value = make_node(AST_Number, node, { value: 0 }); + } + if (value) { + if (props.assign) { + var assign = props.assign.drop_side_effect_free(compressor); + if (assign) { + assign.write_only = true; + props.unshift(assign); + } + } + if (!(parent instanceof AST_Sequence) + || parent.tail_node() === node + || value.has_side_effects(compressor)) { + props.push(value); + } + switch (props.length) { + case 0: + return List.skip; + case 1: + return maintain_this_binding(parent, node, props[0].transform(tt)); + default: + return make_sequence(node, props.map(function(prop) { + return prop.transform(tt); + })); + } + } + } else if (node instanceof AST_UnaryPostfix + && node.expression instanceof AST_SymbolRef + && indexOf_assign(node.expression.definition(), node) < 0) { + return make_node(AST_UnaryPrefix, node, { + operator: "+", + expression: node.expression, + }); + } + } + if (node instanceof AST_Binary && node.operator == "instanceof") { + var sym = node.right; + if (!(sym instanceof AST_SymbolRef)) return; + if (sym.definition().id in in_use_ids) return; + var lhs = node.left.drop_side_effect_free(compressor); + var value = make_node(AST_False, node).optimize(compressor); + return lhs ? make_sequence(node, [ lhs, value ]) : value; + } + if (node instanceof AST_Call) { + calls_to_drop_args.push(node); + node.args = node.args.map(function(arg) { + return arg.transform(tt); + }); + node.expression = node.expression.transform(tt); + return node; + } + if (scope !== self) return; + if (drop_funcs && node !== self && node instanceof AST_DefClass) { + var def = node.name.definition(); + if (!(def.id in in_use_ids)) { + log(node.name, "Dropping unused class {name}"); + def.eliminated++; + descend(node, tt); + var trimmed = to_class_expr(node, true); + if (parent instanceof AST_ExportDefault) return trimmed; + trimmed = trimmed.drop_side_effect_free(compressor, true); + if (trimmed) return make_node(AST_SimpleStatement, node, { body: trimmed }); + return in_list ? List.skip : make_node(AST_EmptyStatement, node); + } + } + if (node instanceof AST_ClassExpression && node.name && drop_fn_name(node.name.definition())) { + node.name = null; + } + if (node instanceof AST_Lambda) { + if (drop_funcs && node !== self && node instanceof AST_LambdaDefinition) { + var def = node.name.definition(); + if (!(def.id in in_use_ids)) { + log(node.name, "Dropping unused function {name}"); + def.eliminated++; + if (parent instanceof AST_ExportDefault) { + descend_scope(); + return to_func_expr(node, true); + } + return in_list ? List.skip : make_node(AST_EmptyStatement, node); + } + } + descend_scope(); + if (node instanceof AST_LambdaExpression && node.name && drop_fn_name(node.name.definition())) { + node.name = null; + } + if (!(node instanceof AST_Accessor)) { + var args, spread, trim = compressor.drop_fargs(node, parent); + if (trim && parent instanceof AST_Call && parent.expression === node) { + args = parent.args; + for (spread = 0; spread < args.length; spread++) { + if (args[spread] instanceof AST_Spread) break; + } + } + var argnames = node.argnames; + var rest = node.rest; + var after = false, before = false; + if (rest) { + before = true; + if (!args || spread < argnames.length || rest instanceof AST_SymbolFunarg) { + rest = rest.transform(trimmer); + } else { + var trimmed = trim_destructured(rest, make_node(AST_Array, parent, { + elements: args.slice(argnames.length), + }), trim_decl, !node.uses_arguments, rest); + rest = trimmed.name; + args.length = argnames.length; + if (trimmed.value.elements.length) [].push.apply(args, trimmed.value.elements); + } + if (rest instanceof AST_Destructured && !rest.rest) { + if (rest instanceof AST_DestructuredArray) { + if (rest.elements.length == 0) rest = null; + } else if (rest.properties.length == 0) { + rest = null; + } + } + node.rest = rest; + if (rest) { + trim = false; + after = true; + } + } + var default_length = trim ? -1 : node.length(); + var trim_value = args && !node.uses_arguments && parent !== compressor.parent(); + for (var i = argnames.length; --i >= 0;) { + var sym = argnames[i]; + if (sym instanceof AST_SymbolFunarg) { + var def = sym.definition(); + if (def.id in in_use_ids) { + trim = false; + if (indexOf_assign(def, sym) < 0) sym.unused = null; + } else if (trim) { + log(sym, "Dropping unused function argument {name}"); + argnames.pop(); + def.eliminated++; + sym.unused = true; + } else { + sym.unused = true; + } + } else { + before = true; + var funarg; + if (!args || spread < i) { + funarg = sym.transform(trimmer); + } else { + var trimmed = trim_destructured(sym, args[i], trim_decl, trim_value, sym); + funarg = trimmed.name; + if (trimmed.value) args[i] = trimmed.value; + } + if (funarg) { + trim = false; + argnames[i] = funarg; + if (!after) after = !(funarg instanceof AST_SymbolFunarg); + } else if (trim) { + log_default(sym, "Dropping unused default argument {name}"); + argnames.pop(); + } else if (i > default_length) { + log_default(sym, "Dropping unused default argument assignment {name}"); + if (sym.name instanceof AST_SymbolFunarg) { + sym.name.unused = true; + } else { + after = true; + } + argnames[i] = sym.name; + } else { + log_default(sym, "Dropping unused default argument value {name}"); + argnames[i] = sym = sym.clone(); + sym.value = make_node(AST_Number, sym, { value: 0 }); + after = true; + } + } + } + if (before && !after && node.uses_arguments && !tt.has_directive("use strict")) { + node.rest = make_node(AST_DestructuredArray, node, { elements: [] }); + } + fns_with_marked_args.push(node); + } + return node; + } + if (node instanceof AST_Catch && node.argname instanceof AST_Destructured) { + node.argname.transform(trimmer); + } + if (node instanceof AST_Definitions && !(parent instanceof AST_ForEnumeration && parent.init === node)) { + // place uninitialized names at the start + var body = [], head = [], tail = []; + // for unused names whose initialization has + // side effects, we can cascade the init. code + // into the next one, or next statement. + var side_effects = []; + var duplicated = 0; + var is_var = node instanceof AST_Var; + node.definitions.forEach(function(def) { + if (def.value) def.value = def.value.transform(tt); + var value = def.value; + if (def.name instanceof AST_Destructured) { + var trimmed = trim_destructured(def.name, value, function(node) { + if (!drop_vars) return node; + if (node.definition().id in in_use_ids) return node; + if (is_catch(node)) return node; + if (is_var && !can_drop_symbol(node)) return node; + return null; + }, true); + if (trimmed.name) { + def = make_node(AST_VarDef, def, { + name: trimmed.name, + value: value = trimmed.value, + }); + flush(); + } else if (trimmed.value) { + side_effects.push(trimmed.value); + } + return; + } + var sym = def.name.definition(); + var drop_sym = is_var ? can_drop_symbol(def.name) : is_safe_lexical(sym); + if (!drop_sym || !drop_vars || sym.id in in_use_ids) { + var index; + if (value && ((index = indexOf_assign(sym, def)) < 0 || self_assign(value.tail_node()))) { + def = def.clone(); + value = value.drop_side_effect_free(compressor); + if (value) AST_Node.warn("Side effects in definition of variable {name} [{start}]", def.name); + if (node instanceof AST_Const) { + def.value = value || make_node(AST_Number, def, { value: 0 }); + } else { + def.value = null; + if (value) side_effects.push(value); + } + value = null; + if (index >= 0) assign_in_use[sym.id][index] = def; + } + var old_def, fn; + if (!value && !(node instanceof AST_Let)) { + if (parent instanceof AST_ExportDeclaration) { + flush(); + } else if (drop_sym && var_defs[sym.id] > 1) { + AST_Node.info("Dropping declaration of variable {name} [{start}]", def.name); + var_defs[sym.id]--; + sym.eliminated++; + } else { + head.push(def); + } + } else if (compressor.option("functions") + && !compressor.option("ie") + && drop_sym + && value + && var_defs[sym.id] == 1 + && sym.assignments == 0 + && (fn = value.tail_node()) instanceof AST_LambdaExpression + && !is_arguments(sym) + && !is_arrow(fn) + && assigned_once(fn, sym.references) + && can_declare_defun(fn) + && (old_def = rename_def(fn, def.name.name)) !== false) { + AST_Node.warn("Declaring {name} as function [{start}]", def.name); + var ctor; + switch (fn.CTOR) { + case AST_AsyncFunction: + ctor = AST_AsyncDefun; + break; + case AST_AsyncGeneratorFunction: + ctor = AST_AsyncGeneratorDefun; + break; + case AST_Function: + ctor = AST_Defun; + break; + case AST_GeneratorFunction: + ctor = AST_GeneratorDefun; + break; + } + var defun = make_node(ctor, fn); + defun.name = make_node(AST_SymbolDefun, def.name); + var name_def = def.name.scope.resolve().def_function(defun.name); + if (old_def) old_def.forEach(function(node) { + node.name = name_def.name; + node.thedef = name_def; + node.reference(); + }); + body.push(defun); + if (value !== fn) [].push.apply(side_effects, value.expressions.slice(0, -1)); + } else { + if (drop_sym + && var_defs[sym.id] > 1 + && !(parent instanceof AST_ExportDeclaration) + && sym.orig.indexOf(def.name) > sym.eliminated) { + var_defs[sym.id]--; + duplicated++; + } + flush(); + } + } else if (is_catch(def.name)) { + value = value && value.drop_side_effect_free(compressor); + if (value) side_effects.push(value); + if (var_defs[sym.id] > 1) { + AST_Node.warn("Dropping duplicated declaration of variable {name} [{start}]", def.name); + var_defs[sym.id]--; + sym.eliminated++; + } else { + def.value = null; + head.push(def); + } + } else { + value = value && value.drop_side_effect_free(compressor); + if (value) { + AST_Node.warn("Side effects in initialization of unused variable {name} [{start}]", def.name); + side_effects.push(value); + } else { + log(def.name, "Dropping unused variable {name}"); + } + sym.eliminated++; + } + + function self_assign(ref) { + return ref instanceof AST_SymbolRef && ref.definition() === sym; + } + + function assigned_once(fn, refs) { + if (refs.length == 0) return fn === def.name.fixed_value(); + return all(refs, function(ref) { + return fn === ref.fixed_value(); + }); + } + + function can_declare_defun(fn) { + if (!is_var || compressor.has_directive("use strict") || !(fn instanceof AST_Function)) { + return parent instanceof AST_Scope; + } + return parent instanceof AST_Block + || parent instanceof AST_For && parent.init === node + || parent instanceof AST_If; + } + + function rename_def(fn, name) { + if (!fn.name) return null; + var def = fn.name.definition(); + if (def.orig.length > 1) return null; + if (def.assignments > 0) return false; + if (def.name == name) return def; + if (compressor.option("keep_fnames")) return false; + var forbidden; + switch (name) { + case "await": + forbidden = is_async; + break; + case "yield": + forbidden = is_generator; + break; + } + return all(def.references, function(ref) { + var scope = ref.scope; + if (scope.find_variable(name) !== sym) return false; + if (forbidden) do { + scope = scope.resolve(); + if (forbidden(scope)) return false; + } while (scope !== fn && (scope = scope.parent_scope)); + return true; + }) && def; + } + + function is_catch(node) { + var sym = node.definition(); + return sym.orig[0] instanceof AST_SymbolCatch && sym.scope.resolve() === node.scope.resolve(); + } + + function flush() { + if (side_effects.length > 0) { + if (tail.length == 0) { + body.push(make_node(AST_SimpleStatement, node, { + body: make_sequence(node, side_effects), + })); + } else if (value) { + side_effects.push(value); + def.value = make_sequence(value, side_effects); + } else { + def.value = make_node(AST_UnaryPrefix, def, { + operator: "void", + expression: make_sequence(def, side_effects), + }); + } + side_effects = []; + } + tail.push(def); + } + }); + switch (head.length) { + case 0: + if (tail.length == 0) break; + if (tail.length == duplicated) { + [].unshift.apply(side_effects, tail.map(function(def) { + AST_Node.info("Dropping duplicated definition of variable {name} [{start}]", def.name); + var sym = def.name.definition(); + var ref = make_node(AST_SymbolRef, def.name); + sym.references.push(ref); + var assign = make_node(AST_Assign, def, { + operator: "=", + left: ref, + right: def.value, + }); + var index = indexOf_assign(sym, def); + if (index >= 0) assign_in_use[sym.id][index] = assign; + sym.assignments++; + sym.eliminated++; + return assign; + })); + break; + } + case 1: + if (tail.length == 0) { + var id = head[0].name.definition().id; + if (id in for_ins) { + node.definitions = head; + for_ins[id].init = node; + break; + } + } + default: + var seq; + if (tail.length > 0 && (seq = tail[0].value) instanceof AST_Sequence) { + tail[0].value = seq.tail_node(); + body.push(make_node(AST_SimpleStatement, node, { + body: make_sequence(seq, seq.expressions.slice(0, -1)), + })); + } + node.definitions = head.concat(tail); + body.push(node); + } + if (side_effects.length > 0) { + body.push(make_node(AST_SimpleStatement, node, { body: make_sequence(node, side_effects) })); + } + return insert_statements(body, node, in_list); + } + if (node instanceof AST_Assign) { + descend(node, tt); + if (!(node.left instanceof AST_Destructured)) return node; + var trimmed = trim_destructured(node.left, node.right, function(node) { + return node; + }, node.write_only === true); + if (trimmed.name) return make_node(AST_Assign, node, { + operator: node.operator, + left: trimmed.name, + right: trimmed.value, + }); + if (trimmed.value) return trimmed.value; + if (parent instanceof AST_Sequence && parent.tail_node() !== node) return List.skip; + return make_node(AST_Number, node, { value: 0 }); + } + if (node instanceof AST_LabeledStatement && node.body instanceof AST_For) { + // Certain combination of unused name + side effect leads to invalid AST: + // https://github.com/mishoo/UglifyJS/issues/1830 + // We fix it at this stage by moving the label inwards, back to the `for`. + descend(node, tt); + if (node.body instanceof AST_BlockStatement) { + var block = node.body; + node.body = block.body.pop(); + block.body.push(node); + return in_list ? List.splice(block.body) : block; + } + return node; + } + if (node instanceof AST_Scope) { + descend_scope(); + return node; + } + if (node instanceof AST_SymbolImport) { + if (!compressor.option("imports") || node.definition().id in in_use_ids) return node; + return in_list ? List.skip : null; + } + + function descend_scope() { + var save_scope = scope; + scope = node; + descend(node, tt); + scope = save_scope; + } + }, function(node, in_list) { + if (node instanceof AST_BlockStatement) return trim_block(node, tt.parent(), in_list); + if (node instanceof AST_ExportDeclaration) { + var block = node.body; + if (!(block instanceof AST_BlockStatement)) return; + node.body = block.body.pop(); + block.body.push(node); + return in_list ? List.splice(block.body) : block; + } + if (node instanceof AST_For) return patch_for_init(node, in_list); + if (node instanceof AST_ForIn) { + if (!drop_vars || !compressor.option("loops")) return; + if (!is_empty(node.body)) return; + var sym = get_init_symbol(node); + if (!sym) return; + var def = sym.definition(); + if (def.id in in_use_ids) return; + log(sym, "Dropping unused loop variable {name}"); + if (for_ins[def.id] === node) delete for_ins[def.id]; + var body = []; + var value = node.object.drop_side_effect_free(compressor); + if (value) { + AST_Node.warn("Side effects in object of for-in loop [{start}]", value); + body.push(make_node(AST_SimpleStatement, node, { body: value })); + } + if (node.init instanceof AST_Definitions && def.orig[0] instanceof AST_SymbolCatch) { + body.push(node.init); + } + return insert_statements(body, node, in_list); + } + if (node instanceof AST_Import) { + if (node.properties && node.properties.length == 0) node.properties = null; + return node; + } + if (node instanceof AST_Sequence) { + if (node.expressions.length > 1) return; + return maintain_this_binding(tt.parent(), node, node.expressions[0]); + } + }); + tt.push(compressor.parent()); + tt.directives = Object.create(compressor.directives); + self.transform(tt); + if (self instanceof AST_Lambda + && self.body.length == 1 + && self.body[0] instanceof AST_Directive + && self.body[0].value == "use strict") { + self.body.length = 0; + } + calls_to_drop_args.forEach(function(call) { + drop_unused_call_args(call, compressor, fns_with_marked_args); + }); + + function log(sym, text) { + AST_Node[sym.definition().references.length > 0 ? "info" : "warn"](text + " [{start}]", sym); + } + + function log_default(node, text) { + if (node.name instanceof AST_SymbolFunarg) { + log(node.name, text); + } else { + AST_Node.info(text + " [{start}]", node); + } + } + + function get_rvalue(expr) { + return expr[expr instanceof AST_Assign ? "right" : "value"]; + } + + function insert_statements(body, orig, in_list) { + switch (body.length) { + case 0: + return in_list ? List.skip : make_node(AST_EmptyStatement, orig); + case 1: + return body[0]; + default: + return in_list ? List.splice(body) : make_node(AST_BlockStatement, orig, { body: body }); + } + } + + function track_assigns(def, node) { + if (def.scope.resolve() !== self) return false; + if (!def.fixed || !node.fixed) assign_in_use[def.id] = false; + return assign_in_use[def.id] !== false; + } + + function add_assigns(def, node) { + if (!assign_in_use[def.id]) assign_in_use[def.id] = []; + if (node.fixed.assigns) push_uniq(assign_in_use[def.id], node.fixed.assigns); + } + + function indexOf_assign(def, node) { + var nodes = assign_in_use[def.id]; + return nodes && nodes.indexOf(node); + } + + function unmark_lambda(def) { + if (lambda_ids[def.id] > 1 && !(def.id in in_use_ids)) { + in_use_ids[def.id] = true; + in_use.push(def); + } + lambda_ids[def.id] = 0; + } + + function verify_safe_usage(def, read, modified) { + if (def.id in in_use_ids) return; + if (read && modified) { + in_use_ids[def.id] = read; + in_use.push(def); + } else { + value_read[def.id] = read; + value_modified[def.id] = modified; + } + } + + function can_drop_lhs(sym, node) { + var def = sym.definition(); + var in_use = in_use_ids[def.id]; + if (!in_use) return true; + if (node[node instanceof AST_Assign ? "left" : "expression"] !== sym) return false; + return in_use === sym && def.references.length - def.replaced == 1 || indexOf_assign(def, node) < 0; + } + + function get_rhs(assign) { + var rhs = assign.right; + if (!assign.write_only) return rhs; + if (!(rhs instanceof AST_Binary && lazy_op[rhs.operator])) return rhs; + if (!(rhs.left instanceof AST_SymbolRef)) return rhs; + if (!(assign.left instanceof AST_SymbolRef)) return rhs; + var def = assign.left.definition(); + if (rhs.left.definition() !== def) return rhs; + if (rhs.right.has_side_effects(compressor)) return rhs; + if (track_assigns(def, rhs.left)) add_assigns(def, rhs.left); + return rhs.right; + } + + function get_init_symbol(for_in) { + var init = for_in.init; + if (init instanceof AST_Definitions) { + init = init.definitions[0].name; + return init instanceof AST_SymbolDeclaration && init; + } + while (init instanceof AST_PropAccess) init = init.expression.tail_node(); + if (init instanceof AST_SymbolRef) return init; + } + + function scan_ref_scoped(node, descend, init) { + if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) { + var def = node.left.definition(); + if (def.scope.resolve() === self) assignments.add(def.id, node); + } + if (node instanceof AST_SymbolRef && node.in_arg) var_defs[node.definition().id] = 0; + if (node instanceof AST_Unary && node.expression instanceof AST_SymbolRef) { + var def = node.expression.definition(); + if (def.scope.resolve() === self) assignments.add(def.id, node); + } + var props = [], sym = assign_as_unused(node, props); + if (sym) { + var node_def = sym.definition(); + if (node_def.scope.resolve() !== self && self.variables.get(sym.name) !== node_def) return; + if (is_arguments(node_def) && !all(self.argnames, function(argname) { + return !argname.match_symbol(function(node) { + if (node instanceof AST_SymbolFunarg) { + var def = node.definition(); + return def.references.length > def.replaced; + } + }, true); + })) return; + if (node.write_only === "p" && node.right.may_throw_on_access(compressor, true)) return; + var assign = props.assign; + if (assign) { + assign.write_only = true; + assign.walk(tw); + } + props.forEach(function(prop) { + prop.walk(tw); + }); + if (node instanceof AST_Assign) { + var right = get_rhs(node), shared = false; + if (init && node.write_only === true && !right.has_side_effects(compressor)) { + initializations.add(node_def.id, right); + } else { + right.walk(tw); + shared = right.tail_node().operator == "="; + } + if (node.left === sym) { + if (!node.write_only || shared) { + verify_safe_usage(node_def, sym, value_modified[node_def.id]); + } + } else { + var fixed = sym.fixed_value(); + if (!fixed || !fixed.is_constant()) { + verify_safe_usage(node_def, value_read[node_def.id], true); + } + } + } + if (track_assigns(node_def, sym) && is_lhs(sym, node) !== sym) add_assigns(node_def, sym); + unmark_lambda(node_def); + return true; + } + if (node instanceof AST_Binary) { + if (node.operator != "instanceof") return; + var sym = node.right; + if (!(sym instanceof AST_SymbolRef)) return; + var id = sym.definition().id; + if (!lambda_ids[id]) return; + node.left.walk(tw); + lambda_ids[id]++; + return true; + } + if (node instanceof AST_ForIn) { + if (node.init instanceof AST_SymbolRef && scope === self) { + var id = node.init.definition().id; + if (!(id in for_ins)) for_ins[id] = node; + } + if (!drop_vars || !compressor.option("loops")) return; + if (!is_empty(node.body)) return; + if (node.init.has_side_effects(compressor)) return; + var sym = get_init_symbol(node); + if (!sym) return; + var def = sym.definition(); + if (def.scope.resolve() !== self) { + var d = find_variable(sym.name); + if (d === def || d && d.redefined() === def) return; + } + node.object.walk(tw); + return true; + } + if (node instanceof AST_SymbolRef) { + var node_def = node.definition(); + if (!(node_def.id in in_use_ids)) { + in_use_ids[node_def.id] = true; + in_use.push(node_def); + } + if (cross_scope(node_def.scope, node.scope)) { + var redef = node_def.redefined(); + if (redef && !(redef.id in in_use_ids)) { + in_use_ids[redef.id] = true; + in_use.push(redef); + } + } + if (track_assigns(node_def, node)) add_assigns(node_def, node); + return true; + } + if (node instanceof AST_Scope) { + var save_scope = scope; + scope = node; + descend(); + scope = save_scope; + return true; + } + } + + function is_decl(node) { + return (node instanceof AST_DefaultValue ? node.name : node) instanceof AST_SymbolDeclaration; + } + + function trim_decl(node) { + if (node.definition().id in in_use_ids) return node; + if (node instanceof AST_SymbolFunarg) node.unused = true; + return null; + } + + function trim_default(trimmer, node) { + node.value = node.value.transform(tt); + var name = node.name.transform(trimmer); + if (!name) { + if (node.name instanceof AST_Destructured) return null; + var value = node.value.drop_side_effect_free(compressor); + if (!value) return null; + log(node.name, "Side effects in default value of unused variable {name}"); + node = node.clone(); + node.name.unused = null; + node.value = value; + } + return node; + } + + function trim_destructured(node, value, process, drop, root) { + var trimmer = new TreeTransformer(function(node) { + if (node instanceof AST_DefaultValue) { + if (!(compressor.option("default_values") && value && value.is_defined(compressor))) { + var save_drop = drop; + drop = false; + var trimmed = trim_default(trimmer, node); + drop = save_drop; + if (!trimmed && drop && value) value = value.drop_side_effect_free(compressor); + return trimmed; + } else if (node === root) { + root = node = node.name; + } else { + node = node.name; + } + } + if (node instanceof AST_DestructuredArray) { + var save_drop = drop; + var save_value = value; + if (value instanceof AST_SymbolRef) { + drop = false; + value = value.fixed_value(); + } + var native, values; + if (value instanceof AST_Array) { + native = true; + values = value.elements; + } else { + native = value && value.is_string(compressor); + values = false; + } + var elements = [], newValues = drop && [], pos = 0; + node.elements.forEach(function(element, index) { + value = values && values[index]; + if (value instanceof AST_Hole) { + value = null; + } else if (value instanceof AST_Spread) { + if (drop) { + newValues.length = pos; + fill_holes(save_value, newValues); + [].push.apply(newValues, values.slice(index)); + save_value.elements = newValues; + } + value = values = false; + } + element = element.transform(trimmer); + if (element) elements[pos] = element; + if (drop && value) newValues[pos] = value; + if (element || value || !drop || !values) pos++; + }); + value = values && make_node(AST_Array, save_value, { + elements: values.slice(node.elements.length), + }); + if (node.rest) { + var was_drop = drop; + drop = false; + node.rest = node.rest.transform(compressor.option("rests") ? trimmer : tt); + drop = was_drop; + if (node.rest) elements.length = pos; + } + if (drop) { + if (value && !node.rest) value = value.drop_side_effect_free(compressor); + if (value instanceof AST_Array) { + value = value.elements; + } else if (value instanceof AST_Sequence) { + value = value.expressions; + } else if (value) { + value = [ value ]; + } + if (value && value.length) { + newValues.length = pos; + [].push.apply(newValues, value); + } + } + value = save_value; + drop = save_drop; + if (values && newValues) { + fill_holes(value, newValues); + value = value.clone(); + value.elements = newValues; + } + if (!native) { + elements.length = node.elements.length; + } else if (!node.rest) switch (elements.length) { + case 0: + if (node === root) break; + if (drop) value = value.drop_side_effect_free(compressor); + return null; + case 1: + if (!drop) break; + if (node === root) break; + var sym = elements[0]; + if (sym.has_side_effects(compressor)) break; + if (value.has_side_effects(compressor) && sym.match_symbol(function(node) { + return node instanceof AST_PropAccess; + })) break; + value = make_node(AST_Sub, node, { + expression: value, + property: make_node(AST_Number, node, { value: 0 }), + }); + return sym; + } + fill_holes(node, elements); + node.elements = elements; + return node; + } + if (node instanceof AST_DestructuredObject) { + var save_drop = drop; + var save_value = value; + if (value instanceof AST_SymbolRef) { + drop = false; + value = value.fixed_value(); + } + var prop_keys, prop_map, values; + if (value instanceof AST_Object) { + prop_keys = []; + prop_map = new Dictionary(); + values = value.properties.map(function(prop, index) { + prop = prop.clone(); + if (prop instanceof AST_Spread) { + prop_map = false; + } else { + var key = prop.key; + if (key instanceof AST_Node) key = key.evaluate(compressor, true); + if (key instanceof AST_Node) { + prop_map = false; + } else if (prop_map && !(prop instanceof AST_ObjectSetter)) { + prop_map.set(key, prop); + } + prop_keys[index] = key; + } + return prop; + }); + } + if (node.rest) { + value = false; + node.rest = node.rest.transform(compressor.option("rests") ? trimmer : tt); + } + var can_drop = new Dictionary(); + var drop_keys = drop && new Dictionary(); + var properties = []; + node.properties.map(function(prop) { + var key = prop.key; + if (key instanceof AST_Node) { + prop.key = key = key.transform(tt); + key = key.evaluate(compressor, true); + } + if (key instanceof AST_Node) { + drop_keys = false; + } else { + can_drop.set(key, !can_drop.has(key)); + } + return key; + }).forEach(function(key, index) { + var prop = node.properties[index], trimmed; + if (key instanceof AST_Node) { + drop = false; + value = false; + trimmed = prop.value.transform(trimmer) || retain_lhs(prop.value); + } else { + drop = drop_keys && can_drop.get(key); + var mapped = prop_map && prop_map.get(key); + if (mapped) { + value = mapped.value; + if (value instanceof AST_Accessor) value = false; + } else { + value = false; + } + trimmed = prop.value.transform(trimmer); + if (!trimmed) { + if (node.rest || retain_key(prop)) trimmed = retain_lhs(prop.value); + if (drop_keys && !drop_keys.has(key)) { + if (mapped) { + drop_keys.set(key, mapped); + if (value === null) { + prop_map.set(key, retain_key(mapped) && make_node(AST_ObjectKeyVal, mapped, { + key: mapped.key, + value: make_node(AST_Number, mapped, { value: 0 }), + })); + } + } else { + drop_keys.set(key, true); + } + } + } else if (drop_keys) { + drop_keys.set(key, false); + } + if (value) mapped.value = value; + } + if (trimmed) { + prop.value = trimmed; + properties.push(prop); + } + }); + value = save_value; + drop = save_drop; + if (drop_keys && prop_keys) { + value = value.clone(); + value.properties = List(values, function(prop, index) { + if (prop instanceof AST_Spread) return prop; + var key = prop_keys[index]; + if (key instanceof AST_Node) return prop; + if (drop_keys.has(key)) { + var mapped = drop_keys.get(key); + if (!mapped) return prop; + if (mapped === prop) return prop_map.get(key) || List.skip; + } else if (node.rest) { + return prop; + } + var trimmed = prop.value.drop_side_effect_free(compressor); + if (trimmed) { + prop.value = trimmed; + return prop; + } + return retain_key(prop) ? make_node(AST_ObjectKeyVal, prop, { + key: prop.key, + value: make_node(AST_Number, prop, { value: 0 }), + }) : List.skip; + }); + } + if (value && !node.rest) switch (properties.length) { + case 0: + if (node === root) break; + if (value.may_throw_on_access(compressor, true)) break; + if (drop) value = value.drop_side_effect_free(compressor); + return null; + case 1: + if (!drop) break; + if (node === root) break; + var prop = properties[0]; + if (prop.key instanceof AST_Node) break; + if (prop.value.has_side_effects(compressor)) break; + if (value.has_side_effects(compressor) && prop.value.match_symbol(function(node) { + return node instanceof AST_PropAccess; + })) break; + value = make_node(AST_Sub, node, { + expression: value, + property: make_node_from_constant(prop.key, prop), + }); + return prop.value; + } + node.properties = properties; + return node; + } + if (node instanceof AST_Hole) { + node = null; + } else { + node = process(node); + } + if (!node && drop && value) value = value.drop_side_effect_free(compressor); + return node; + }); + return { + name: node.transform(trimmer), + value: value, + }; + + function retain_key(prop) { + return prop.key instanceof AST_Node && prop.key.has_side_effects(compressor); + } + + function clear_write_only(node) { + if (node instanceof AST_Assign) { + node.write_only = false; + clear_write_only(node.right); + } else if (node instanceof AST_Binary) { + if (!lazy_op[node.operator]) return; + clear_write_only(node.left); + clear_write_only(node.right); + } else if (node instanceof AST_Conditional) { + clear_write_only(node.consequent); + clear_write_only(node.alternative); + } else if (node instanceof AST_Sequence) { + clear_write_only(node.tail_node()); + } else if (node instanceof AST_Unary) { + node.write_only = false; + } + } + + function retain_lhs(node) { + if (node instanceof AST_DefaultValue) return retain_lhs(node.name); + if (node instanceof AST_Destructured) { + if (value === null) { + value = make_node(AST_Number, node, { value: 0 }); + } else if (value) { + if (value.may_throw_on_access(compressor, true)) { + value = make_node(AST_Array, node, { + elements: value instanceof AST_Sequence ? value.expressions : [ value ], + }); + } else { + clear_write_only(value); + } + } + return make_node(AST_DestructuredObject, node, { properties: [] }); + } + node.unused = null; + return node; + } + } + }); + + AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) { + if (compressor.has_directive("use asm")) return; + var hoist_funs = compressor.option("hoist_funs"); + var hoist_vars = compressor.option("hoist_vars"); + var self = this; + if (hoist_vars) { + // let's count var_decl first, we seem to waste a lot of + // space if we hoist `var` when there's only one. + var var_decl = 0; + self.walk(new TreeWalker(function(node) { + if (var_decl > 1) return true; + if (node instanceof AST_ExportDeclaration) return true; + if (node instanceof AST_Scope && node !== self) return true; + if (node instanceof AST_Var) { + var_decl++; + return true; + } + })); + if (var_decl <= 1) hoist_vars = false; + } + if (!hoist_funs && !hoist_vars) return; + var consts = new Dictionary(); + var dirs = []; + var hoisted = []; + var vars = new Dictionary(); + var tt = new TreeTransformer(function(node, descend, in_list) { + if (node === self) return; + if (node instanceof AST_Directive) { + dirs.push(node); + return in_list ? List.skip : make_node(AST_EmptyStatement, node); + } + if (node instanceof AST_LambdaDefinition) { + if (!hoist_funs) return node; + var p = tt.parent(); + if (p instanceof AST_ExportDeclaration) return node; + if (p instanceof AST_ExportDefault) return node; + if (p !== self && compressor.has_directive("use strict")) return node; + hoisted.push(node); + return in_list ? List.skip : make_node(AST_EmptyStatement, node); + } + if (node instanceof AST_Var) { + if (!hoist_vars) return node; + var p = tt.parent(); + if (p instanceof AST_ExportDeclaration) return node; + if (!all(node.definitions, function(defn) { + var sym = defn.name; + return sym instanceof AST_SymbolVar + && !consts.has(sym.name) + && self.find_variable(sym.name) === sym.definition(); + })) return node; + node.definitions.forEach(function(defn) { + vars.set(defn.name.name, defn); + }); + var seq = node.to_assignments(); + if (p instanceof AST_ForEnumeration && p.init === node) { + if (seq) return seq; + var sym = node.definitions[0].name; + return make_node(AST_SymbolRef, sym); + } + if (p instanceof AST_For && p.init === node) return seq; + if (!seq) return in_list ? List.skip : make_node(AST_EmptyStatement, node); + return make_node(AST_SimpleStatement, node, { body: seq }); + } + if (node instanceof AST_Scope) return node; + if (node instanceof AST_SymbolConst) { + consts.set(node.name, true); + return node; + } + }); + self.transform(tt); + if (vars.size() > 0) { + // collect only vars which don't show up in self's arguments list + var defns = []; + if (self instanceof AST_Lambda) self.each_argname(function(argname) { + if (all(argname.definition().references, function(ref) { + return !ref.in_arg; + })) vars.del(argname.name); + }); + vars.each(function(defn, name) { + defn = defn.clone(); + defn.name = defn.name.clone(); + defn.value = null; + defns.push(defn); + vars.set(name, defn); + defn.name.definition().orig.unshift(defn.name); + }); + if (defns.length > 0) hoisted.push(make_node(AST_Var, self, { definitions: defns })); + } + self.body = dirs.concat(hoisted, self.body); + }); + + function scan_local_returns(fn, transform) { + fn.walk(new TreeWalker(function(node) { + if (node instanceof AST_Return) { + transform(node); + return true; + } + if (node instanceof AST_Scope && node !== fn) return true; + })); + } + + function map_self_returns(fn) { + var map = Object.create(null); + scan_local_returns(fn, function(node) { + var value = node.value; + if (value) value = value.tail_node(); + if (value instanceof AST_SymbolRef) { + var id = value.definition().id; + map[id] = (map[id] || 0) + 1; + } + }); + return map; + } + + function can_trim_returns(def, self_returns, compressor) { + if (compressor.exposed(def)) return false; + switch (def.references.length - def.replaced - (self_returns[def.id] || 0)) { + case def.drop_return: + return "d"; + case def.bool_return: + return true; + } + } + + function process_boolean_returns(fn, compressor) { + scan_local_returns(fn, function(node) { + node.in_bool = true; + var value = node.value; + if (value) { + var ev = fuzzy_eval(compressor, value); + if (!ev) { + value = value.drop_side_effect_free(compressor); + node.value = value ? make_sequence(node.value, [ + value, + make_node(AST_Number, node.value, { value: 0 }), + ]) : null; + } else if (!(ev instanceof AST_Node)) { + value = value.drop_side_effect_free(compressor); + node.value = value ? make_sequence(node.value, [ + value, + make_node(AST_Number, node.value, { value: 1 }), + ]) : make_node(AST_Number, node.value, { value: 1 }); + } + } + }); + } + + AST_Scope.DEFMETHOD("process_returns", noop); + AST_Defun.DEFMETHOD("process_returns", function(compressor) { + if (!compressor.option("booleans")) return; + if (compressor.parent() instanceof AST_ExportDefault) return; + switch (can_trim_returns(this.name.definition(), map_self_returns(this), compressor)) { + case "d": + drop_returns(compressor, this, true); + break; + case true: + process_boolean_returns(this, compressor); + break; + } + }); + AST_Function.DEFMETHOD("process_returns", function(compressor) { + if (!compressor.option("booleans")) return; + var drop = true; + var self_returns = map_self_returns(this); + if (this.name && !can_trim(this.name.definition())) return; + var parent = compressor.parent(); + if (parent instanceof AST_Assign) { + if (parent.operator != "=") return; + var sym = parent.left; + if (!(sym instanceof AST_SymbolRef)) return; + if (!can_trim(sym.definition())) return; + } else if (parent instanceof AST_Call && parent.expression !== this) { + var exp = parent.expression; + if (exp instanceof AST_SymbolRef) exp = exp.fixed_value(); + if (!(exp instanceof AST_Lambda)) return; + if (exp.uses_arguments || exp.pinned()) return; + var args = parent.args, sym; + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + if (arg === this) { + sym = exp.argnames[i]; + if (!sym && exp.rest) return; + break; + } + if (arg instanceof AST_Spread) return; + } + if (sym instanceof AST_DefaultValue) sym = sym.name; + if (sym instanceof AST_SymbolFunarg && !can_trim(sym.definition())) return; + } else if (parent.TYPE == "Call") { + compressor.pop(); + var in_bool = compressor.in_boolean_context(); + compressor.push(this); + switch (in_bool) { + case true: + drop = false; + case "d": + break; + default: + return; + } + } else return; + if (drop) { + drop_returns(compressor, this, true); + } else { + process_boolean_returns(this, compressor); + } + + function can_trim(def) { + switch (can_trim_returns(def, self_returns, compressor)) { + case true: + drop = false; + case "d": + return true; + } + } + }); + + AST_BlockScope.DEFMETHOD("var_names", function() { + var var_names = this._var_names; + if (!var_names) { + this._var_names = var_names = new Dictionary(); + this.enclosed.forEach(function(def) { + var_names.set(def.name, true); + }); + this.variables.each(function(def, name) { + var_names.set(name, true); + }); + } + return var_names; + }); + + AST_Scope.DEFMETHOD("make_var", function(type, orig, prefix) { + var scopes = [ this ]; + if (orig instanceof AST_SymbolDeclaration) orig.definition().references.forEach(function(ref) { + var s = ref.scope; + do { + if (!push_uniq(scopes, s)) return; + s = s.parent_scope; + } while (s && s !== this); + }); + prefix = prefix.replace(/^[^a-z_$]|[^a-z0-9_$]/gi, "_"); + var name = prefix; + for (var i = 0; !all(scopes, function(scope) { + return !scope.var_names().has(name); + }); i++) name = prefix + "$" + i; + var sym = make_node(type, orig, { + name: name, + scope: this, + }); + var def = this.def_variable(sym); + scopes.forEach(function(scope) { + scope.enclosed.push(def); + scope.var_names().set(name, true); + }); + return sym; + }); + + AST_Scope.DEFMETHOD("hoist_properties", function(compressor) { + if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return; + var self = this; + if (is_arrow(self) && self.value) return; + var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false; + var defs_by_id = Object.create(null); + var tt = new TreeTransformer(function(node, descend) { + if (node instanceof AST_Assign) { + if (node.operator != "=") return; + if (!node.write_only) return; + if (!can_hoist(node.left, node.right, 1)) return; + descend(node, tt); + var defs = new Dictionary(); + var assignments = []; + var decls = []; + node.right.properties.forEach(function(prop) { + var decl = make_sym(AST_SymbolVar, node.left, prop.key); + decls.push(make_node(AST_VarDef, node, { + name: decl, + value: null, + })); + var sym = make_node(AST_SymbolRef, node, { + name: decl.name, + scope: self, + thedef: decl.definition(), + }); + sym.reference(); + assignments.push(make_node(AST_Assign, node, { + operator: "=", + left: sym, + right: prop.value, + })); + }); + defs.value = node.right; + defs_by_id[node.left.definition().id] = defs; + self.body.splice(self.body.indexOf(tt.stack[1]) + 1, 0, make_node(AST_Var, node, { + definitions: decls, + })); + return make_sequence(node, assignments); + } + if (node instanceof AST_Scope) { + if (node === self) return; + var parent = tt.parent(); + if (parent.TYPE == "Call" && parent.expression === node) return; + return node; + } + if (node instanceof AST_VarDef) { + if (!can_hoist(node.name, node.value, 0)) return; + descend(node, tt); + var defs = new Dictionary(); + var var_defs = []; + var decl = node.clone(); + decl.value = node.name instanceof AST_SymbolConst ? make_node(AST_Number, node, { value: 0 }) : null; + var_defs.push(decl); + node.value.properties.forEach(function(prop) { + var_defs.push(make_node(AST_VarDef, node, { + name: make_sym(node.name.CTOR, node.name, prop.key), + value: prop.value, + })); + }); + defs.value = node.value; + defs_by_id[node.name.definition().id] = defs; + return List.splice(var_defs); + } + + function make_sym(type, sym, key) { + var new_var = self.make_var(type, sym, sym.name + "_" + key); + defs.set(key, new_var.definition()); + return new_var; + } + }); + self.transform(tt); + self.transform(new TreeTransformer(function(node, descend) { + if (node instanceof AST_PropAccess) { + if (!(node.expression instanceof AST_SymbolRef)) return; + var defs = defs_by_id[node.expression.definition().id]; + if (!defs) return; + if (node.expression.fixed_value() !== defs.value) return; + var def = defs.get(node.get_property()); + var sym = make_node(AST_SymbolRef, node, { + name: def.name, + scope: node.expression.scope, + thedef: def, + }); + sym.reference(); + return sym; + } + if (node instanceof AST_SymbolRef) { + var defs = defs_by_id[node.definition().id]; + if (!defs) return; + if (node.fixed_value() !== defs.value) return; + return make_node(AST_Object, node, { properties: [] }); + } + })); + + function can_hoist(sym, right, count) { + if (!(sym instanceof AST_Symbol)) return; + var def = sym.definition(); + if (def.assignments != count) return; + if (def.references.length - def.replaced == count) return; + if (def.single_use) return; + if (self.find_variable(sym.name) !== def) return; + if (top_retain(def)) return; + if (sym.fixed_value() !== right) return; + var fixed = sym.fixed || def.fixed; + if (fixed.direct_access) return; + if (fixed.escaped && fixed.escaped.depth == 1) return; + return right instanceof AST_Object + && right.properties.length > 0 + && can_drop_symbol(sym, compressor) + && all(right.properties, function(prop) { + return can_hoist_property(prop) && prop.key !== "__proto__"; + }); + } + }); + + function fn_name_unused(fn, compressor) { + if (!fn.name || !compressor.option("ie")) return true; + var def = fn.name.definition(); + if (compressor.exposed(def)) return false; + return all(def.references, function(sym) { + return !(sym instanceof AST_SymbolRef); + }); + } + + function drop_returns(compressor, exp, ignore_name) { + if (!(exp instanceof AST_Lambda)) return; + var arrow = is_arrow(exp); + var async = is_async(exp); + var changed = false; + var drop_body = false; + if (arrow && compressor.option("arrows")) { + if (!exp.value) { + drop_body = true; + } else if (!async || needs_enqueuing(compressor, exp.value)) { + var dropped = exp.value.drop_side_effect_free(compressor); + if (dropped !== exp.value) { + changed = true; + exp.value = dropped; + } + } + } else if (!is_generator(exp)) { + if (!ignore_name && exp.name) { + var def = exp.name.definition(); + drop_body = def.references.length == def.replaced; + } else { + drop_body = true; + } + } + if (drop_body) { + exp.process_expression(false, function(node) { + var value = node.value; + if (value) { + if (async && !needs_enqueuing(compressor, value)) return node; + value = value.drop_side_effect_free(compressor, true); + } + changed = true; + if (!value) return make_node(AST_EmptyStatement, node); + return make_node(AST_SimpleStatement, node, { body: value }); + }); + scan_local_returns(exp, function(node) { + var value = node.value; + if (value) { + if (async && !needs_enqueuing(compressor, value)) return; + var dropped = value.drop_side_effect_free(compressor); + if (dropped !== value) { + changed = true; + if (dropped && async && !needs_enqueuing(compressor, dropped)) { + dropped = dropped.negate(compressor); + } + node.value = dropped; + } + } + }); + } + if (async && compressor.option("awaits")) { + if (drop_body) exp.process_expression("awaits", function(node) { + var body = node.body; + if (body instanceof AST_Await) { + if (needs_enqueuing(compressor, body.expression)) { + changed = true; + body = body.expression.drop_side_effect_free(compressor, true); + if (!body) return make_node(AST_EmptyStatement, node); + node.body = body; + } + } else if (body instanceof AST_Sequence) { + var exprs = body.expressions; + for (var i = exprs.length; --i >= 0;) { + var tail = exprs[i]; + if (!(tail instanceof AST_Await)) break; + var value = tail.expression; + if (!needs_enqueuing(compressor, value)) break; + changed = true; + if (exprs[i] = value.drop_side_effect_free(compressor)) break; + } + switch (i) { + case -1: + return make_node(AST_EmptyStatement, node); + case 0: + node.body = exprs[0]; + break; + default: + exprs.length = i + 1; + break; + } + } + return node; + }); + var abort = !drop_body && exp.name || arrow && exp.value && !needs_enqueuing(compressor, exp.value); + var tw = new TreeWalker(function(node) { + if (abort) return true; + if (tw.parent() === exp && node.may_throw(compressor)) return abort = true; + if (node instanceof AST_Await) return abort = true; + if (node instanceof AST_ForAwaitOf) return abort = true; + if (node instanceof AST_Return) { + if (node.value && !needs_enqueuing(compressor, node.value)) return abort = true; + return; + } + if (node instanceof AST_Scope && node !== exp) return true; + }); + exp.walk(tw); + if (!abort) { + var ctor; + switch (exp.CTOR) { + case AST_AsyncArrow: + ctor = AST_Arrow; + break; + case AST_AsyncFunction: + ctor = AST_Function; + break; + case AST_AsyncGeneratorFunction: + ctor = AST_GeneratorFunction; + break; + } + return make_node(ctor, exp); + } + } + return changed && exp.clone(); + } + + // drop_side_effect_free() + // remove side-effect-free parts which only affects return value + (function(def) { + // Drop side-effect-free elements from an array of expressions. + // Returns an array of expressions with side-effects or null + // if all elements were dropped. Note: original array may be + // returned if nothing changed. + function trim(nodes, compressor, first_in_statement, spread) { + var len = nodes.length; + var ret = [], changed = false; + for (var i = 0; i < len; i++) { + var node = nodes[i]; + var trimmed; + if (spread && node instanceof AST_Spread) { + trimmed = spread(node, compressor, first_in_statement); + } else { + trimmed = node.drop_side_effect_free(compressor, first_in_statement); + } + if (trimmed !== node) changed = true; + if (trimmed) { + ret.push(trimmed); + first_in_statement = false; + } + } + return ret.length ? changed ? ret : nodes : null; + } + function array_spread(node, compressor, first_in_statement) { + var exp = node.expression; + if (!exp.is_string(compressor)) return node; + return exp.drop_side_effect_free(compressor, first_in_statement); + } + function convert_spread(node) { + return node instanceof AST_Spread ? make_node(AST_Array, node, { elements: [ node ] }) : node; + } + def(AST_Node, return_this); + def(AST_Accessor, return_null); + def(AST_Array, function(compressor, first_in_statement) { + var values = trim(this.elements, compressor, first_in_statement, array_spread); + if (!values) return null; + if (values === this.elements && all(values, function(node) { + return node instanceof AST_Spread; + })) return this; + return make_sequence(this, values.map(convert_spread)); + }); + def(AST_Assign, function(compressor) { + var left = this.left; + if (left instanceof AST_PropAccess) { + var expr = left.expression; + if (expr.may_throw_on_access(compressor, true)) return this; + if (compressor.has_directive("use strict") && expr.is_constant()) return this; + } + if (left.has_side_effects(compressor)) return this; + if (lazy_op[this.operator.slice(0, -1)]) return this; + this.write_only = true; + if (!root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) return this; + return this.right.drop_side_effect_free(compressor); + }); + def(AST_Await, function(compressor) { + if (!compressor.option("awaits")) return this; + var exp = this.expression; + if (!needs_enqueuing(compressor, exp)) return this; + if (exp instanceof AST_UnaryPrefix && exp.operator == "!") exp = exp.expression; + var dropped = exp.drop_side_effect_free(compressor); + if (dropped === exp) return this; + if (!dropped) { + dropped = make_node(AST_Number, exp, { value: 0 }); + } else if (!needs_enqueuing(compressor, dropped)) { + dropped = dropped.negate(compressor); + } + var node = this.clone(); + node.expression = dropped; + return node; + }); + def(AST_Binary, function(compressor, first_in_statement) { + var left = this.left; + var right = this.right; + var op = this.operator; + if (!can_drop_op(op, right, compressor)) { + var lhs = left.drop_side_effect_free(compressor, first_in_statement); + if (lhs === left) return this; + var node = this.clone(); + node.left = lhs || make_node(AST_Number, left, { value: 0 }); + return node; + } + var rhs = right.drop_side_effect_free(compressor, first_in_statement); + if (!rhs) return left.drop_side_effect_free(compressor, first_in_statement); + if (lazy_op[op] && rhs.has_side_effects(compressor)) { + var node = this; + if (rhs !== right) { + node = node.clone(); + node.right = rhs.drop_side_effect_free(compressor); + } + if (op == "??") return node; + var negated = node.clone(); + negated.operator = op == "&&" ? "||" : "&&"; + negated.left = left.negate(compressor, first_in_statement); + var negated_rhs = negated.right.tail_node(); + if (negated_rhs instanceof AST_Binary && negated.operator == negated_rhs.operator) swap_chain(negated); + var best = first_in_statement ? best_of_statement : best_of_expression; + return op == "&&" ? best(node, negated) : best(negated, node); + } + var lhs = left.drop_side_effect_free(compressor, first_in_statement); + if (!lhs) return rhs; + rhs = rhs.drop_side_effect_free(compressor); + if (!rhs) return lhs; + return make_sequence(this, [ lhs, rhs ]); + }); + function assign_this_only(fn, compressor) { + fn.new = true; + var result = all(fn.body, function(stat) { + return !stat.has_side_effects(compressor); + }) && all(fn.argnames, function(argname) { + return !argname.match_symbol(return_false); + }) && !(fn.rest && fn.rest.match_symbol(return_false)); + fn.new = false; + return result; + } + def(AST_Call, function(compressor, first_in_statement) { + var self = this; + if (self.is_expr_pure(compressor)) { + if (self.pure) AST_Node.warn("Dropping __PURE__ call [{start}]", self); + var args = trim(self.args, compressor, first_in_statement, array_spread); + return args && make_sequence(self, args.map(convert_spread)); + } + var exp = self.expression; + if (self.is_call_pure(compressor)) { + var exprs = self.args.slice(); + exprs.unshift(exp.expression); + exprs = trim(exprs, compressor, first_in_statement, array_spread); + return exprs && make_sequence(self, exprs.map(convert_spread)); + } + if (compressor.option("yields") && is_generator(exp)) { + var call = self.clone(); + call.expression = make_node(AST_Function, exp); + call.expression.body = []; + var opt = call.transform(compressor); + if (opt !== call) return opt.drop_side_effect_free(compressor, first_in_statement); + } + var dropped = drop_returns(compressor, exp); + if (dropped) { + // always shallow clone to ensure stripping of negated IIFEs + self = self.clone(); + self.expression = dropped; + // avoid extraneous traversal + if (exp._squeezed) self.expression._squeezed = true; + } + if (self instanceof AST_New) { + var fn = exp; + if (fn instanceof AST_SymbolRef) fn = fn.fixed_value(); + if (fn instanceof AST_Lambda) { + if (assign_this_only(fn, compressor)) { + var exprs = self.args.slice(); + exprs.unshift(exp); + exprs = trim(exprs, compressor, first_in_statement, array_spread); + return exprs && make_sequence(self, exprs.map(convert_spread)); + } + if (!fn.contains_this()) { + self = make_node(AST_Call, self); + self.expression = self.expression.clone(); + self.args = self.args.slice(); + } + } + } + self.call_only = true; + return self; + }); + def(AST_ClassExpression, function(compressor, first_in_statement) { + var self = this; + var exprs = [], values = [], init = 0; + var props = self.properties; + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + if (prop.key instanceof AST_Node) exprs.push(prop.key); + if (!is_static_field_or_init(prop)) continue; + var value = prop.value; + if (!value.has_side_effects(compressor)) continue; + if (value.contains_this()) return self; + if (prop instanceof AST_ClassInit) { + init++; + values.push(prop); + } else { + values.push(value); + } + } + var base = self.extends; + if (base) { + if (base instanceof AST_SymbolRef) base = base.fixed_value(); + base = !safe_for_extends(base); + if (!base) exprs.unshift(self.extends); + } + exprs = trim(exprs, compressor, first_in_statement); + if (exprs) first_in_statement = false; + values = trim(values, compressor, first_in_statement); + if (!exprs) { + if (!base && !values && !self.name) return null; + exprs = []; + } + if (base || self.name || !compressor.has_directive("use strict")) { + var node = to_class_expr(self); + if (!base) node.extends = null; + node.properties = []; + if (values) { + if (values.length == init) { + if (exprs.length) values.unshift(make_node(AST_ClassField, self, { + key: make_sequence(self, exprs), + value: null, + })); + node.properties = values; + } else node.properties.push(make_node(AST_ClassField, self, { + static: true, + key: exprs.length ? make_sequence(self, exprs) : "c", + value: make_value(), + })); + } else if (exprs.length) node.properties.push(make_node(AST_ClassMethod, self, { + key: make_sequence(self, exprs), + value: make_node(AST_Function, self, { + argnames: [], + body: [], + }).init_vars(node), + })); + return node; + } + if (values) exprs.push(make_node(AST_Call, self, { + expression: make_node(AST_Arrow, self, { + argnames: [], + body: [], + value: make_value(), + }).init_vars(self.parent_scope), + args: [], + })); + return make_sequence(self, exprs); + + function make_value() { + return make_sequence(self, values.map(function(node) { + if (!(node instanceof AST_ClassInit)) return node; + var fn = make_node(AST_Arrow, node.value); + fn.argnames = []; + return make_node(AST_Call, node, { + expression: fn, + args: [], + }); + })); + } + }); + def(AST_Conditional, function(compressor) { + var consequent = this.consequent.drop_side_effect_free(compressor); + var alternative = this.alternative.drop_side_effect_free(compressor); + if (consequent === this.consequent && alternative === this.alternative) return this; + var exprs; + if (compressor.option("ie")) { + exprs = []; + if (consequent instanceof AST_Function) { + exprs.push(consequent); + consequent = null; + } + if (alternative instanceof AST_Function) { + exprs.push(alternative); + alternative = null; + } + } + var node; + if (!consequent) { + node = alternative ? make_node(AST_Binary, this, { + operator: "||", + left: this.condition, + right: alternative, + }) : this.condition.drop_side_effect_free(compressor); + } else if (!alternative) { + node = make_node(AST_Binary, this, { + operator: "&&", + left: this.condition, + right: consequent, + }); + } else { + node = this.clone(); + node.consequent = consequent; + node.alternative = alternative; + } + if (!exprs) return node; + if (node) exprs.push(node); + return exprs.length == 0 ? null : make_sequence(this, exprs); + }); + def(AST_Constant, return_null); + def(AST_Dot, function(compressor, first_in_statement) { + var expr = this.expression; + if (expr.may_throw_on_access(compressor)) return this; + return expr.drop_side_effect_free(compressor, first_in_statement); + }); + def(AST_Function, function(compressor) { + return fn_name_unused(this, compressor) ? null : this; + }); + def(AST_LambdaExpression, return_null); + def(AST_Object, function(compressor, first_in_statement) { + var exprs = []; + this.properties.forEach(function(prop) { + if (prop instanceof AST_Spread) { + exprs.push(prop); + } else { + if (prop.key instanceof AST_Node) exprs.push(prop.key); + exprs.push(prop.value); + } + }); + var values = trim(exprs, compressor, first_in_statement, function(node, compressor, first_in_statement) { + var exp = node.expression; + return exp.safe_to_spread() ? exp.drop_side_effect_free(compressor, first_in_statement) : node; + }); + if (!values) return null; + if (values === exprs && !all(values, function(node) { + return !(node instanceof AST_Spread); + })) return this; + return make_sequence(this, values.map(function(node) { + return node instanceof AST_Spread ? make_node(AST_Object, node, { properties: [ node ] }) : node; + })); + }); + def(AST_ObjectIdentity, return_null); + def(AST_Sequence, function(compressor, first_in_statement) { + var expressions = trim(this.expressions, compressor, first_in_statement); + if (!expressions) return null; + var end = expressions.length - 1; + var last = expressions[end]; + if (compressor.option("awaits") && end > 0 && last instanceof AST_Await && last.expression.is_constant()) { + expressions = expressions.slice(0, -1); + end--; + var expr = expressions[end]; + last.expression = needs_enqueuing(compressor, expr) ? expr : expr.negate(compressor); + expressions[end] = last; + } + var assign, cond, lhs; + if (compressor.option("conditionals") + && end > 0 + && (assign = expressions[end - 1]) instanceof AST_Assign + && assign.operator == "=" + && (lhs = assign.left) instanceof AST_SymbolRef + && (cond = to_conditional_assignment(compressor, lhs.definition(), assign.right, last))) { + assign = assign.clone(); + assign.right = cond; + expressions = expressions.slice(0, -2); + expressions.push(assign.drop_side_effect_free(compressor, first_in_statement)); + } + return expressions === this.expressions ? this : make_sequence(this, expressions); + }); + def(AST_Sub, function(compressor, first_in_statement) { + var expr = this.expression; + if (expr.may_throw_on_access(compressor)) return this; + var prop = this.property; + expr = expr.drop_side_effect_free(compressor, first_in_statement); + if (!expr) return prop.drop_side_effect_free(compressor, first_in_statement); + prop = prop.drop_side_effect_free(compressor); + if (!prop) return expr; + return make_sequence(this, [ expr, prop ]); + }); + def(AST_SymbolRef, function(compressor) { + return this.is_declared(compressor) && can_drop_symbol(this, compressor) ? null : this; + }); + def(AST_Template, function(compressor, first_in_statement) { + var self = this; + if (self.is_expr_pure(compressor)) { + var expressions = self.expressions; + if (expressions.length == 0) return null; + return make_sequence(self, expressions).drop_side_effect_free(compressor, first_in_statement); + } + var tag = self.tag; + var dropped = drop_returns(compressor, tag); + if (dropped) { + // always shallow clone to signal internal changes + self = self.clone(); + self.tag = dropped; + // avoid extraneous traversal + if (tag._squeezed) self.tag._squeezed = true; + } + return self; + }); + def(AST_Unary, function(compressor, first_in_statement) { + var exp = this.expression; + if (unary_side_effects[this.operator]) { + this.write_only = !exp.has_side_effects(compressor); + return this; + } + if (this.operator == "typeof" && exp instanceof AST_SymbolRef && can_drop_symbol(exp, compressor)) { + return null; + } + var node = exp.drop_side_effect_free(compressor, first_in_statement); + if (first_in_statement && node && is_iife_call(node)) { + if (node === exp && this.operator == "!") return this; + return node.negate(compressor, first_in_statement); + } + return node; + }); + })(function(node, func) { + node.DEFMETHOD("drop_side_effect_free", func); + }); + + OPT(AST_SimpleStatement, function(self, compressor) { + if (compressor.option("side_effects")) { + var body = self.body; + var node = body.drop_side_effect_free(compressor, true); + if (!node) { + AST_Node.warn("Dropping side-effect-free statement [{start}]", self); + return make_node(AST_EmptyStatement, self); + } + if (node !== body) { + return make_node(AST_SimpleStatement, self, { body: node }); + } + } + return self; + }); + + OPT(AST_While, function(self, compressor) { + return compressor.option("loops") ? make_node(AST_For, self).optimize(compressor) : self; + }); + + function has_loop_control(loop, parent, type) { + if (!type) type = AST_LoopControl; + var found = false; + var tw = new TreeWalker(function(node) { + if (found || node instanceof AST_Scope) return true; + if (node instanceof type && tw.loopcontrol_target(node) === loop) { + return found = true; + } + }); + if (parent instanceof AST_LabeledStatement) tw.push(parent); + tw.push(loop); + loop.body.walk(tw); + return found; + } + + OPT(AST_Do, function(self, compressor) { + if (!compressor.option("loops")) return self; + var cond = fuzzy_eval(compressor, self.condition); + if (!(cond instanceof AST_Node)) { + if (cond && !has_loop_control(self, compressor.parent(), AST_Continue)) return make_node(AST_For, self, { + body: make_node(AST_BlockStatement, self.body, { + body: [ + self.body, + make_node(AST_SimpleStatement, self.condition, { body: self.condition }), + ], + }), + }).optimize(compressor); + if (!has_loop_control(self, compressor.parent())) return make_node(AST_BlockStatement, self.body, { + body: [ + self.body, + make_node(AST_SimpleStatement, self.condition, { body: self.condition }), + ], + }).optimize(compressor); + } + if (self.body instanceof AST_BlockStatement && !has_loop_control(self, compressor.parent(), AST_Continue)) { + var body = self.body.body; + for (var i = body.length; --i >= 0;) { + var stat = body[i]; + if (stat instanceof AST_If + && !stat.alternative + && stat.body instanceof AST_Break + && compressor.loopcontrol_target(stat.body) === self) { + if (has_block_scope_refs(stat.condition)) break; + self.condition = make_node(AST_Binary, self, { + operator: "&&", + left: stat.condition.negate(compressor), + right: self.condition, + }); + body.splice(i, 1); + } else if (stat instanceof AST_SimpleStatement) { + if (has_block_scope_refs(stat.body)) break; + self.condition = make_sequence(self, [ + stat.body, + self.condition, + ]); + body.splice(i, 1); + } else if (!is_declaration(stat, true)) { + break; + } + } + self.body = trim_block(self.body, compressor.parent()); + } + if (self.body instanceof AST_EmptyStatement) return make_node(AST_For, self).optimize(compressor); + if (self.body instanceof AST_SimpleStatement) return make_node(AST_For, self, { + condition: make_sequence(self.condition, [ + self.body.body, + self.condition, + ]), + body: make_node(AST_EmptyStatement, self), + }).optimize(compressor); + return self; + + function has_block_scope_refs(node) { + var found = false; + node.walk(new TreeWalker(function(node) { + if (found) return true; + if (node instanceof AST_SymbolRef) { + if (!member(node.definition(), self.enclosed)) found = true; + return true; + } + })); + return found; + } + }); + + function if_break_in_loop(self, compressor) { + var first = first_statement(self.body); + if (compressor.option("dead_code") + && (first instanceof AST_Break + || first instanceof AST_Continue && external_target(first) + || first instanceof AST_Exit)) { + var body = []; + if (is_statement(self.init)) { + body.push(self.init); + } else if (self.init) { + body.push(make_node(AST_SimpleStatement, self.init, { body: self.init })); + } + var retain = external_target(first) || first instanceof AST_Exit; + if (self.condition && retain) { + body.push(make_node(AST_If, self, { + condition: self.condition, + body: first, + alternative: null, + })); + } else if (self.condition) { + body.push(make_node(AST_SimpleStatement, self.condition, { body: self.condition })); + } else if (retain) { + body.push(first); + } + extract_declarations_from_unreachable_code(compressor, self.body, body); + return make_node(AST_BlockStatement, self, { body: body }); + } + if (first instanceof AST_If) { + var ab = first_statement(first.body); + if (ab instanceof AST_Break && !external_target(ab)) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition.negate(compressor), + }); + } else { + self.condition = first.condition.negate(compressor); + } + var body = as_statement_array(first.alternative); + extract_declarations_from_unreachable_code(compressor, first.body, body); + return drop_it(body); + } + ab = first_statement(first.alternative); + if (ab instanceof AST_Break && !external_target(ab)) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition, + }); + } else { + self.condition = first.condition; + } + var body = as_statement_array(first.body); + extract_declarations_from_unreachable_code(compressor, first.alternative, body); + return drop_it(body); + } + } + return self; + + function first_statement(body) { + return body instanceof AST_BlockStatement ? body.body[0] : body; + } + + function external_target(node) { + return compressor.loopcontrol_target(node) !== compressor.self(); + } + + function drop_it(rest) { + if (self.body instanceof AST_BlockStatement) { + self.body = self.body.clone(); + self.body.body = rest.concat(self.body.body.slice(1)); + self.body = self.body.transform(compressor); + } else { + self.body = make_node(AST_BlockStatement, self.body, { body: rest }).transform(compressor); + } + return if_break_in_loop(self, compressor); + } + } + + OPT(AST_For, function(self, compressor) { + if (!compressor.option("loops")) return self; + if (compressor.option("side_effects")) { + if (self.init) self.init = self.init.drop_side_effect_free(compressor); + if (self.step) self.step = self.step.drop_side_effect_free(compressor); + } + if (self.condition) { + var cond = fuzzy_eval(compressor, self.condition); + if (!cond) { + if (compressor.option("dead_code")) { + var body = []; + if (is_statement(self.init)) { + body.push(self.init); + } else if (self.init) { + body.push(make_node(AST_SimpleStatement, self.init, { body: self.init })); + } + body.push(make_node(AST_SimpleStatement, self.condition, { body: self.condition })); + extract_declarations_from_unreachable_code(compressor, self.body, body); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } + } else if (!(cond instanceof AST_Node)) { + self.body = make_node(AST_BlockStatement, self.body, { + body: [ + make_node(AST_SimpleStatement, self.condition, { body: self.condition }), + self.body, + ], + }); + self.condition = null; + } + } + return if_break_in_loop(self, compressor); + }); + + OPT(AST_ForEnumeration, function(self, compressor) { + if (compressor.option("varify") && is_lexical_definition(self.init)) { + var name = self.init.definitions[0].name; + if ((name instanceof AST_Destructured || name instanceof AST_SymbolLet) + && !name.match_symbol(function(node) { + if (node instanceof AST_SymbolDeclaration) { + var def = node.definition(); + return !same_scope(def) || may_overlap(compressor, def); + } + }, true)) { + self.init = to_var(self.init, self.resolve()); + } + } + return self; + }); + + function mark_locally_defined(condition, consequent, alternative) { + if (condition instanceof AST_Sequence) condition = condition.tail_node(); + if (!(condition instanceof AST_Binary)) return; + if (!(condition.left instanceof AST_String)) { + switch (condition.operator) { + case "&&": + mark_locally_defined(condition.left, consequent); + mark_locally_defined(condition.right, consequent); + break; + case "||": + mark_locally_defined(negate(condition.left), alternative); + mark_locally_defined(negate(condition.right), alternative); + break; + } + return; + } + if (!(condition.right instanceof AST_UnaryPrefix)) return; + if (condition.right.operator != "typeof") return; + var sym = condition.right.expression; + if (!is_undeclared_ref(sym)) return; + var body; + var undef = condition.left.value == "undefined"; + switch (condition.operator) { + case "==": + body = undef ? alternative : consequent; + break; + case "!=": + body = undef ? consequent : alternative; + break; + default: + return; + } + if (!body) return; + var abort = false; + var def = sym.definition(); + var fn; + var refs = []; + var scanned = []; + var tw = new TreeWalker(function(node, descend) { + if (abort) return true; + if (node instanceof AST_Assign) { + var ref = node.left; + if (!(ref instanceof AST_SymbolRef && ref.definition() === def)) return; + node.right.walk(tw); + switch (node.operator) { + case "=": + case "&&=": + abort = true; + } + return true; + } + if (node instanceof AST_Call) { + descend(); + fn = node.expression.tail_node(); + var save; + if (fn instanceof AST_SymbolRef) { + fn = fn.fixed_value(); + save = refs.length; + } + if (!(fn instanceof AST_Lambda)) { + abort = true; + } else if (push_uniq(scanned, fn)) { + fn.walk(tw); + } + if (save >= 0) refs.length = save; + return true; + } + if (node instanceof AST_DWLoop) { + var save = refs.length; + descend(); + if (abort) refs.length = save; + return true; + } + if (node instanceof AST_For) { + if (node.init) node.init.walk(tw); + var save = refs.length; + if (node.condition) node.condition.walk(tw); + node.body.walk(tw); + if (node.step) node.step.walk(tw); + if (abort) refs.length = save; + return true; + } + if (node instanceof AST_ForEnumeration) { + node.object.walk(tw); + var save = refs.length; + node.init.walk(tw); + node.body.walk(tw); + if (abort) refs.length = save; + return true; + } + if (node instanceof AST_Scope) { + if (node === fn) return; + return true; + } + if (node instanceof AST_SymbolRef) { + if (node.definition() === def) refs.push(node); + return true; + } + }); + body.walk(tw); + refs.forEach(function(ref) { + ref.defined = true; + }); + + function negate(node) { + if (!(node instanceof AST_Binary)) return; + switch (node.operator) { + case "==": + node = node.clone(); + node.operator = "!="; + return node; + case "!=": + node = node.clone(); + node.operator = "=="; + return node; + } + } + } + + function fuzzy_eval(compressor, node, nullish) { + if (node.truthy) return true; + if (is_undefined(node)) return undefined; + if (node.falsy && !nullish) return false; + if (node.is_truthy()) return true; + return node.evaluate(compressor, true); + } + + function mark_duplicate_condition(compressor, node) { + var child; + var level = 0; + var negated = false; + var parent = compressor.self(); + if (!is_statement(parent)) while (true) { + child = parent; + parent = compressor.parent(level++); + if (parent instanceof AST_Binary) { + switch (child) { + case parent.left: + if (lazy_op[parent.operator]) continue; + break; + case parent.right: + if (match(parent.left)) switch (parent.operator) { + case "&&": + node[negated ? "falsy" : "truthy"] = true; + break; + case "||": + case "??": + node[negated ? "truthy" : "falsy"] = true; + break; + } + break; + } + } else if (parent instanceof AST_Conditional) { + var cond = parent.condition; + if (cond === child) continue; + if (match(cond)) switch (child) { + case parent.consequent: + node[negated ? "falsy" : "truthy"] = true; + break; + case parent.alternative: + node[negated ? "truthy" : "falsy"] = true; + break; + } + } else if (parent instanceof AST_Exit) { + break; + } else if (parent instanceof AST_If) { + break; + } else if (parent instanceof AST_Sequence) { + if (parent.expressions[0] === child) continue; + } else if (parent instanceof AST_SimpleStatement) { + break; + } + return; + } + while (true) { + child = parent; + parent = compressor.parent(level++); + if (parent instanceof AST_BlockStatement) { + if (parent.body[0] === child) continue; + } else if (parent instanceof AST_If) { + if (match(parent.condition)) switch (child) { + case parent.body: + node[negated ? "falsy" : "truthy"] = true; + break; + case parent.alternative: + node[negated ? "truthy" : "falsy"] = true; + break; + } + } + return; + } + + function match(cond) { + if (node.equals(cond)) return true; + if (!(cond instanceof AST_UnaryPrefix)) return false; + if (cond.operator != "!") return false; + if (!node.equals(cond.expression)) return false; + negated = true; + return true; + } + } + + OPT(AST_If, function(self, compressor) { + if (is_empty(self.alternative)) self.alternative = null; + + if (!compressor.option("conditionals")) return self; + if (compressor.option("booleans") && !self.condition.has_side_effects(compressor)) { + mark_duplicate_condition(compressor, self.condition); + } + // if condition can be statically determined, warn and drop + // one of the blocks. note, statically determined implies + // “has no side effects”; also it doesn't work for cases like + // `x && true`, though it probably should. + if (compressor.option("dead_code")) { + var cond = fuzzy_eval(compressor, self.condition); + if (!cond) { + AST_Node.warn("Condition always false [{start}]", self.condition); + var body = [ + make_node(AST_SimpleStatement, self.condition, { body: self.condition }).transform(compressor), + ]; + extract_declarations_from_unreachable_code(compressor, self.body, body); + if (self.alternative) body.push(self.alternative); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } else if (!(cond instanceof AST_Node)) { + AST_Node.warn("Condition always true [{start}]", self.condition); + var body = [ + make_node(AST_SimpleStatement, self.condition, { body: self.condition }).transform(compressor), + self.body, + ]; + if (self.alternative) extract_declarations_from_unreachable_code(compressor, self.alternative, body); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } + } + var negated = self.condition.negate(compressor); + var self_condition_length = self.condition.print_to_string().length; + var negated_length = negated.print_to_string().length; + var negated_is_best = negated_length < self_condition_length; + if (self.alternative && negated_is_best) { + negated_is_best = false; // because we already do the switch here. + // no need to swap values of self_condition_length and negated_length + // here because they are only used in an equality comparison later on. + self.condition = negated; + var tmp = self.body; + self.body = self.alternative; + self.alternative = is_empty(tmp) ? null : tmp; + } + var body_defuns = []; + var body_var_defs = []; + var body_refs = []; + var body_exprs = sequencesize(self.body, body_defuns, body_var_defs, body_refs); + var alt_defuns = []; + var alt_var_defs = []; + var alt_refs = []; + var alt_exprs = sequencesize(self.alternative, alt_defuns, alt_var_defs, alt_refs); + if (body_exprs instanceof AST_BlockStatement || alt_exprs instanceof AST_BlockStatement) { + var body = [], var_defs = []; + if (body_exprs) { + [].push.apply(body, body_defuns); + [].push.apply(var_defs, body_var_defs); + if (body_exprs instanceof AST_BlockStatement) { + self.body = body_exprs; + } else if (body_exprs.length == 0) { + self.body = make_node(AST_EmptyStatement, self.body); + } else { + self.body = make_node(AST_SimpleStatement, self.body, { + body: make_sequence(self.body, body_exprs), + }); + } + body_refs.forEach(process_to_assign); + } + if (alt_exprs) { + [].push.apply(body, alt_defuns); + [].push.apply(var_defs, alt_var_defs); + if (alt_exprs instanceof AST_BlockStatement) { + self.alternative = alt_exprs; + } else if (alt_exprs.length == 0) { + self.alternative = null; + } else { + self.alternative = make_node(AST_SimpleStatement, self.alternative, { + body: make_sequence(self.alternative, alt_exprs), + }); + } + alt_refs.forEach(process_to_assign); + } + if (var_defs.length > 0) body.push(make_node(AST_Var, self, { definitions: var_defs })); + if (body.length > 0) { + body.push(self.transform(compressor)); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } + } else if (body_exprs && alt_exprs) { + var body = body_defuns.concat(alt_defuns); + if (body_var_defs.length > 0 || alt_var_defs.length > 0) body.push(make_node(AST_Var, self, { + definitions: body_var_defs.concat(alt_var_defs), + })); + if (body_exprs.length == 0) { + body.push(make_node(AST_SimpleStatement, self.condition, { + body: alt_exprs.length > 0 ? make_node(AST_Binary, self, { + operator: "||", + left: self.condition, + right: make_sequence(self.alternative, alt_exprs), + }).transform(compressor) : self.condition.clone(), + }).optimize(compressor)); + } else if (alt_exprs.length == 0) { + if (self_condition_length === negated_length && !negated_is_best + && self.condition instanceof AST_Binary && self.condition.operator == "||") { + // although the code length of self.condition and negated are the same, + // negated does not require additional surrounding parentheses. + // see https://github.com/mishoo/UglifyJS/issues/979 + negated_is_best = true; + } + body.push(make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator: negated_is_best ? "||" : "&&", + left: negated_is_best ? negated : self.condition, + right: make_sequence(self.body, body_exprs), + }).transform(compressor), + }).optimize(compressor)); + } else { + body.push(make_node(AST_SimpleStatement, self, { + body: make_node(AST_Conditional, self, { + condition: self.condition, + consequent: make_sequence(self.body, body_exprs), + alternative: make_sequence(self.alternative, alt_exprs), + }), + }).optimize(compressor)); + } + body_refs.forEach(process_to_assign); + alt_refs.forEach(process_to_assign); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } + if (is_empty(self.body)) self = make_node(AST_If, self, { + condition: negated, + body: self.alternative, + alternative: null, + }); + if (self.alternative instanceof AST_Exit && self.body.TYPE == self.alternative.TYPE) { + var cons_value = self.body.value; + var alt_value = self.alternative.value; + if (!cons_value && !alt_value) return make_node(AST_BlockStatement, self, { + body: [ + make_node(AST_SimpleStatement, self, { body: self.condition }), + self.body, + ], + }).optimize(compressor); + if (cons_value && alt_value || !keep_return_void()) { + var exit = make_node(self.body.CTOR, self, { + value: make_node(AST_Conditional, self, { + condition: self.condition, + consequent: cons_value || make_node(AST_Undefined, self.body).transform(compressor), + alternative: alt_value || make_node(AST_Undefined, self.alternative).transform(compressor), + }), + }); + if (exit instanceof AST_Return) exit.in_bool = self.body.in_bool || self.alternative.in_bool; + return exit; + } + } + if (self.body instanceof AST_If && !self.body.alternative && !self.alternative) { + self = make_node(AST_If, self, { + condition: make_node(AST_Binary, self.condition, { + operator: "&&", + left: self.condition, + right: self.body.condition, + }), + body: self.body.body, + alternative: null, + }); + } + if (aborts(self.body) && self.alternative) { + var alt = self.alternative; + self.alternative = null; + return make_node(AST_BlockStatement, self, { body: [ self, alt ] }).optimize(compressor); + } + if (aborts(self.alternative)) { + var body = self.body; + self.body = self.alternative; + self.condition = negated_is_best ? negated : self.condition.negate(compressor); + self.alternative = null; + return make_node(AST_BlockStatement, self, { body: [ self, body ] }).optimize(compressor); + } + if (self.alternative) { + var body_stats = as_array(self.body); + var body_index = last_index(body_stats); + var alt_stats = as_array(self.alternative); + var alt_index = last_index(alt_stats); + for (var stats = []; body_index >= 0 && alt_index >= 0;) { + var stat = body_stats[body_index]; + var alt_stat = alt_stats[alt_index]; + if (stat.equals(alt_stat)) { + body_stats.splice(body_index--, 1); + alt_stats.splice(alt_index--, 1); + stats.unshift(merge_expression(stat, alt_stat)); + } else { + if (!(stat instanceof AST_SimpleStatement)) break; + if (!(alt_stat instanceof AST_SimpleStatement)) break; + var expr1 = stat.body.tail_node(); + var expr2 = alt_stat.body.tail_node(); + if (!expr1.equals(expr2)) break; + body_index = pop_expr(body_stats, stat.body, body_index); + alt_index = pop_expr(alt_stats, alt_stat.body, alt_index); + stats.unshift(make_node(AST_SimpleStatement, expr1, { body: merge_expression(expr1, expr2) })); + } + } + if (stats.length > 0) { + self.body = body_stats.length > 0 ? make_node(AST_BlockStatement, self, { + body: body_stats, + }) : make_node(AST_EmptyStatement, self); + self.alternative = alt_stats.length > 0 ? make_node(AST_BlockStatement, self, { + body: alt_stats, + }) : null; + stats.unshift(self); + return make_node(AST_BlockStatement, self, { body: stats }).optimize(compressor); + } + } + if (compressor.option("typeofs")) mark_locally_defined(self.condition, self.body, self.alternative); + return self; + + function as_array(node) { + return node instanceof AST_BlockStatement ? node.body : [ node ]; + } + + function keep_return_void() { + var has_finally = false, level = 0, node = compressor.self(); + do { + if (node instanceof AST_Catch) { + if (compressor.parent(level).bfinally) has_finally = true; + level++; + } else if (node instanceof AST_Finally) { + level++; + } else if (node instanceof AST_Scope) { + return has_finally && in_async_generator(node); + } else if (node instanceof AST_Try) { + if (node.bfinally) has_finally = true; + } + } while (node = compressor.parent(level++)); + } + + function last_index(stats) { + for (var index = stats.length; --index >= 0;) { + if (!is_declaration(stats[index], true)) break; + } + return index; + } + + function pop_expr(stats, body, index) { + if (body instanceof AST_Sequence) { + stats[index] = make_node(AST_SimpleStatement, body, { + body: make_sequence(body, body.expressions.slice(0, -1)), + }); + } else { + stats.splice(index--, 1); + } + return index; + } + + function sequencesize(stat, defuns, var_defs, refs) { + if (stat == null) return []; + if (stat instanceof AST_BlockStatement) { + var exprs = []; + for (var i = 0; i < stat.body.length; i++) { + var line = stat.body[i]; + if (line instanceof AST_EmptyStatement) continue; + if (line instanceof AST_Exit) { + if (i == 0) return; + if (exprs.length > 0) { + line = line.clone(); + exprs.push(line.value || make_node(AST_Undefined, line).transform(compressor)); + line.value = make_sequence(stat, exprs); + } + var block = stat.clone(); + block.body = block.body.slice(i + 1); + block.body.unshift(line); + return block; + } + if (line instanceof AST_LambdaDefinition) { + defuns.push(line); + } else if (line instanceof AST_SimpleStatement) { + if (!compressor.option("sequences") && exprs.length > 0) return; + exprs.push(line.body); + } else if (line instanceof AST_Var) { + if (!compressor.option("sequences") && exprs.length > 0) return; + line.remove_initializers(compressor, var_defs); + line.definitions.forEach(process_var_def); + } else { + return; + } + } + return exprs; + } + if (stat instanceof AST_LambdaDefinition) { + defuns.push(stat); + return []; + } + if (stat instanceof AST_EmptyStatement) return []; + if (stat instanceof AST_SimpleStatement) return [ stat.body ]; + if (stat instanceof AST_Var) { + var exprs = []; + stat.remove_initializers(compressor, var_defs); + stat.definitions.forEach(process_var_def); + return exprs; + } + + function process_var_def(var_def) { + if (!var_def.value) return; + exprs.push(make_node(AST_Assign, var_def, { + operator: "=", + left: var_def.name.convert_symbol(AST_SymbolRef, function(ref) { + refs.push(ref); + }), + right: var_def.value, + })); + } + } + }); + + OPT(AST_Switch, function(self, compressor) { + if (!compressor.option("switches")) return self; + if (!compressor.option("dead_code")) return self; + var body = []; + var branch; + var decl = []; + var default_branch; + var exact_match; + var side_effects = []; + for (var i = 0, len = self.body.length; i < len; i++) { + branch = self.body[i]; + if (branch instanceof AST_Default) { + var prev = body[body.length - 1]; + if (default_branch || is_break(branch.body[0], compressor) && (!prev || aborts(prev))) { + eliminate_branch(branch, prev); + continue; + } else { + default_branch = branch; + } + } else { + var exp = branch.expression; + var equals = make_node(AST_Binary, self, { + operator: "===", + left: self.expression, + right: exp, + }).evaluate(compressor, true); + if (!equals) { + if (exp.has_side_effects(compressor)) side_effects.push(exp); + eliminate_branch(branch, body[body.length - 1]); + continue; + } + if (!(equals instanceof AST_Node)) { + if (default_branch) { + var default_index = body.indexOf(default_branch); + body.splice(default_index, 1); + eliminate_branch(default_branch, body[default_index - 1]); + default_branch = null; + } + if (exp.has_side_effects(compressor)) { + exact_match = branch; + } else { + default_branch = branch = make_node(AST_Default, branch); + } + while (++i < len) eliminate_branch(self.body[i], branch); + } + } + if (i + 1 >= len || aborts(branch)) { + var prev = body[body.length - 1]; + var statements = branch.body; + if (aborts(prev)) switch (prev.body.length - statements.length) { + case 1: + var stat = prev.body[prev.body.length - 1]; + if (!is_break(stat, compressor)) break; + statements = statements.concat(stat); + case 0: + var prev_block = make_node(AST_BlockStatement, prev); + var next_block = make_node(AST_BlockStatement, branch, { body: statements }); + if (prev_block.equals(next_block)) prev.body = []; + } + } + if (side_effects.length) { + if (branch instanceof AST_Default) { + body.push(make_node(AST_Case, self, { expression: make_sequence(self, side_effects), body: [] })); + } else { + side_effects.push(branch.expression); + branch.expression = make_sequence(self, side_effects); + } + side_effects = []; + } + body.push(branch); + } + if (side_effects.length && !exact_match) { + body.push(make_node(AST_Case, self, { expression: make_sequence(self, side_effects), body: [] })); + } + while (branch = body[body.length - 1]) { + var stat = branch.body[branch.body.length - 1]; + if (is_break(stat, compressor)) branch.body.pop(); + if (branch === default_branch) { + if (!has_declarations_only(branch)) break; + } else if (branch.expression.has_side_effects(compressor)) { + break; + } else if (default_branch) { + if (!has_declarations_only(default_branch)) break; + if (body[body.length - 2] !== default_branch) break; + default_branch.body = default_branch.body.concat(branch.body); + branch.body = []; + } else if (!has_declarations_only(branch)) break; + eliminate_branch(branch); + if (body.pop() === default_branch) default_branch = null; + } + if (!branch) { + decl.push(make_node(AST_SimpleStatement, self.expression, { body: self.expression })); + if (side_effects.length) decl.push(make_node(AST_SimpleStatement, self, { + body: make_sequence(self, side_effects), + })); + return make_node(AST_BlockStatement, self, { body: decl }).optimize(compressor); + } + if (branch === default_branch) while (branch = body[body.length - 2]) { + if (branch instanceof AST_Default) break; + if (!has_declarations_only(branch)) break; + var exp = branch.expression; + if (exp.has_side_effects(compressor)) { + var prev = body[body.length - 3]; + if (prev && !aborts(prev)) break; + default_branch.body.unshift(make_node(AST_SimpleStatement, self, { body: exp })); + } + eliminate_branch(branch); + body.splice(-2, 1); + } + body[0].body = decl.concat(body[0].body); + self.body = body; + if (compressor.option("conditionals")) switch (body.length) { + case 1: + if (!no_break(body[0])) break; + var exp = body[0].expression; + var statements = body[0].body.slice(); + if (body[0] !== default_branch && body[0] !== exact_match) return make_node(AST_If, self, { + condition: make_node(AST_Binary, self, { + operator: "===", + left: self.expression, + right: exp, + }), + body: make_node(AST_BlockStatement, self, { body: statements }), + alternative: null, + }).optimize(compressor); + if (exp) statements.unshift(make_node(AST_SimpleStatement, exp, { body: exp })); + statements.unshift(make_node(AST_SimpleStatement, self.expression, { body: self.expression })); + return make_node(AST_BlockStatement, self, { body: statements }).optimize(compressor); + case 2: + if (!member(default_branch, body) || !no_break(body[1])) break; + var statements = body[0].body.slice(); + var exclusive = statements.length && is_break(statements[statements.length - 1], compressor); + if (exclusive) statements.pop(); + if (!all(statements, no_break)) break; + var alternative = body[1].body.length && make_node(AST_BlockStatement, body[1]); + var node = make_node(AST_If, self, { + condition: make_node(AST_Binary, self, body[0] === default_branch ? { + operator: "!==", + left: self.expression, + right: body[1].expression, + } : { + operator: "===", + left: self.expression, + right: body[0].expression, + }), + body: make_node(AST_BlockStatement, body[0], { body: statements }), + alternative: exclusive && alternative || null, + }); + if (!exclusive && alternative) node = make_node(AST_BlockStatement, self, { body: [ node, alternative ] }); + return node.optimize(compressor); + } + return self; + + function is_break(node, tw) { + return node instanceof AST_Break && tw.loopcontrol_target(node) === self; + } + + function no_break(node) { + var found = false; + var tw = new TreeWalker(function(node) { + if (found + || node instanceof AST_Lambda + || node instanceof AST_SimpleStatement) return true; + if (is_break(node, tw)) found = true; + }); + tw.push(self); + node.walk(tw); + return !found; + } + + function eliminate_branch(branch, prev) { + if (prev && !aborts(prev)) { + prev.body = prev.body.concat(branch.body); + } else { + extract_declarations_from_unreachable_code(compressor, branch, decl); + } + } + }); + + OPT(AST_Try, function(self, compressor) { + self.body = tighten_body(self.body, compressor); + if (compressor.option("dead_code")) { + if (has_declarations_only(self) + && !(self.bcatch && self.bcatch.argname && self.bcatch.argname.match_symbol(function(node) { + return node instanceof AST_SymbolCatch && !can_drop_symbol(node); + }, true))) { + var body = []; + if (self.bcatch) { + extract_declarations_from_unreachable_code(compressor, self.bcatch, body); + body.forEach(function(stat) { + if (!(stat instanceof AST_Var)) return; + stat.definitions.forEach(function(var_def) { + var def = var_def.name.definition().redefined(); + if (!def) return; + var_def.name = var_def.name.clone(); + var_def.name.thedef = def; + }); + }); + } + body.unshift(make_node(AST_BlockStatement, self).optimize(compressor)); + if (self.bfinally) { + body.push(make_node(AST_BlockStatement, self.bfinally).optimize(compressor)); + } + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } + if (self.bfinally && has_declarations_only(self.bfinally)) { + var body = make_node(AST_BlockStatement, self.bfinally).optimize(compressor); + body = self.body.concat(body); + if (!self.bcatch) return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + self.body = body; + self.bfinally = null; + } + } + return self; + }); + + function remove_initializers(make_value) { + return function(compressor, defns) { + var dropped = false; + this.definitions.forEach(function(defn) { + if (defn.value) dropped = true; + defn.name.match_symbol(function(node) { + if (node instanceof AST_SymbolDeclaration) defns.push(make_node(AST_VarDef, node, { + name: node, + value: make_value(compressor, node), + })); + }, true); + }); + return dropped; + }; + } + + AST_Const.DEFMETHOD("remove_initializers", remove_initializers(function(compressor, node) { + return make_node(AST_Undefined, node).optimize(compressor); + })); + AST_Let.DEFMETHOD("remove_initializers", remove_initializers(return_null)); + AST_Var.DEFMETHOD("remove_initializers", remove_initializers(return_null)); + + AST_Definitions.DEFMETHOD("to_assignments", function() { + var assignments = this.definitions.reduce(function(a, defn) { + var def = defn.name.definition(); + var value = defn.value; + if (value) { + if (value instanceof AST_Sequence) value = value.clone(); + var name = make_node(AST_SymbolRef, defn.name); + var assign = make_node(AST_Assign, defn, { + operator: "=", + left: name, + right: value, + }); + a.push(assign); + var fixed = function() { + return assign.right; + }; + fixed.assigns = [ assign ]; + fixed.direct_access = def.direct_access; + fixed.escaped = def.escaped; + name.fixed = fixed; + def.references.forEach(function(ref) { + if (!ref.fixed) return; + var assigns = ref.fixed.assigns; + if (!assigns) return; + if (assigns[0] !== defn) return; + if (assigns.length > 1 || ref.fixed.to_binary || ref.fixed.to_prefix) { + assigns[0] = assign; + } else { + ref.fixed = fixed; + if (def.fixed === ref.fixed) def.fixed = fixed; + } + }); + def.references.push(name); + } + def.assignments++; + def.eliminated++; + def.single_use = false; + return a; + }, []); + if (assignments.length == 0) return null; + return make_sequence(this, assignments); + }); + + function is_safe_lexical(def) { + return def.name != "arguments" && def.orig.length < (def.orig[0] instanceof AST_SymbolLambda ? 3 : 2); + } + + function may_overlap(compressor, def) { + if (compressor.exposed(def)) return true; + var scope = def.scope.resolve(); + for (var s = def.scope; s !== scope;) { + s = s.parent_scope; + if (s.var_names().has(def.name)) return true; + } + } + + function to_var(stat, scope) { + return make_node(AST_Var, stat, { + definitions: stat.definitions.map(function(defn) { + return make_node(AST_VarDef, defn, { + name: defn.name.convert_symbol(AST_SymbolVar, function(name, node) { + var def = name.definition(); + def.orig[def.orig.indexOf(node)] = name; + if (def.scope === scope) return; + def.scope = scope; + scope.variables.set(def.name, def); + scope.enclosed.push(def); + scope.var_names().set(def.name, true); + }), + value: defn.value, + }); + }), + }); + } + + function can_varify(compressor, sym) { + var def = sym.definition(); + return (def.fixed || def.fixed === 0) + && is_safe_lexical(def) + && same_scope(def) + && !may_overlap(compressor, def); + } + + function varify(self, compressor) { + return compressor.option("varify") && all(self.definitions, function(defn) { + return !defn.name.match_symbol(function(node) { + if (node instanceof AST_SymbolDeclaration) return !can_varify(compressor, node); + }, true); + }) ? to_var(self, compressor.find_parent(AST_Scope)) : self; + } + + OPT(AST_Const, varify); + OPT(AST_Let, varify); + + function trim_optional_chain(node, compressor) { + if (!compressor.option("optional_chains")) return; + if (node.terminal) do { + var expr = node.expression; + if (node.optional) { + var ev = fuzzy_eval(compressor, expr, true); + if (ev == null) return make_node(AST_UnaryPrefix, node, { + operator: "void", + expression: expr, + }).optimize(compressor); + if (!(ev instanceof AST_Node)) node.optional = false; + } + node = expr; + } while ((node.TYPE == "Call" || node instanceof AST_PropAccess) && !node.terminal); + } + + function lift_sequence_in_expression(node, compressor) { + var exp = node.expression; + if (!(exp instanceof AST_Sequence)) return node; + var x = exp.expressions.slice(); + var e = node.clone(); + e.expression = x.pop(); + x.push(e); + return make_sequence(node, x); + } + + function drop_unused_call_args(call, compressor, fns_with_marked_args) { + var exp = call.expression; + var fn = exp instanceof AST_SymbolRef ? exp.fixed_value() : exp; + if (!(fn instanceof AST_Lambda)) return; + if (fn.uses_arguments) return; + if (fn.pinned()) return; + if (fns_with_marked_args && fns_with_marked_args.indexOf(fn) < 0) return; + var args = call.args; + if (!all(args, function(arg) { + return !(arg instanceof AST_Spread); + })) return; + var argnames = fn.argnames; + var is_iife = fn === exp && !fn.name; + if (fn.rest) { + if (!(is_iife && compressor.option("rests"))) return; + var insert = argnames.length; + args = args.slice(0, insert); + while (args.length < insert) args.push(make_node(AST_Undefined, call).optimize(compressor)); + args.push(make_node(AST_Array, call, { elements: call.args.slice(insert) })); + argnames = argnames.concat(fn.rest); + fn.rest = null; + } else { + args = args.slice(); + argnames = argnames.slice(); + } + var pos = 0, last = 0; + var drop_defaults = is_iife && compressor.option("default_values"); + var drop_fargs = is_iife && compressor.drop_fargs(fn, call) ? function(argname, arg) { + if (!argname) return true; + if (argname instanceof AST_DestructuredArray) { + return argname.elements.length == 0 && !argname.rest && arg instanceof AST_Array; + } + if (argname instanceof AST_DestructuredObject) { + return argname.properties.length == 0 && !argname.rest && arg && !arg.may_throw_on_access(compressor); + } + return argname.unused; + } : return_false; + var side_effects = []; + for (var i = 0; i < args.length; i++) { + var argname = argnames[i]; + if (drop_defaults && argname instanceof AST_DefaultValue && args[i].is_defined(compressor)) { + argnames[i] = argname = argname.name; + } + if (!argname || argname.unused !== undefined) { + var node = args[i].drop_side_effect_free(compressor); + if (drop_fargs(argname)) { + if (argname) argnames.splice(i, 1); + args.splice(i, 1); + if (node) side_effects.push(node); + i--; + continue; + } else if (node) { + side_effects.push(node); + args[pos++] = make_sequence(call, side_effects); + side_effects = []; + } else if (argname) { + if (side_effects.length) { + args[pos++] = make_sequence(call, side_effects); + side_effects = []; + } else { + args[pos++] = make_node(AST_Number, args[i], { value: 0 }); + continue; + } + } + } else if (drop_fargs(argname, args[i])) { + var node = args[i].drop_side_effect_free(compressor); + argnames.splice(i, 1); + args.splice(i, 1); + if (node) side_effects.push(node); + i--; + continue; + } else { + side_effects.push(args[i]); + args[pos++] = make_sequence(call, side_effects); + side_effects = []; + } + last = pos; + } + for (; i < argnames.length; i++) { + if (drop_fargs(argnames[i])) argnames.splice(i--, 1); + } + fn.argnames = argnames; + args.length = last; + call.args = args; + if (!side_effects.length) return; + var arg = make_sequence(call, side_effects); + args.push(args.length < argnames.length ? make_node(AST_UnaryPrefix, call, { + operator: "void", + expression: arg, + }) : arg); + } + + function avoid_await_yield(compressor, parent_scope) { + if (!parent_scope) parent_scope = compressor.find_parent(AST_Scope); + var avoid = []; + if (is_async(parent_scope) || parent_scope instanceof AST_Toplevel && compressor.option("module")) { + avoid.push("await"); + } + if (is_generator(parent_scope)) avoid.push("yield"); + return avoid.length && makePredicate(avoid); + } + + function safe_from_await_yield(fn, avoid) { + if (!avoid) return true; + var safe = true; + var tw = new TreeWalker(function(node) { + if (!safe) return true; + if (node instanceof AST_Scope) { + if (node === fn) return; + if (is_arrow(node)) { + for (var i = 0; safe && i < node.argnames.length; i++) node.argnames[i].walk(tw); + } else if (node instanceof AST_LambdaDefinition && avoid[node.name.name]) { + safe = false; + } + return true; + } + if (node instanceof AST_Symbol && avoid[node.name] && node !== fn.name) safe = false; + }); + fn.walk(tw); + return safe; + } + + function safe_from_strict_mode(fn, compressor) { + return fn.in_strict_mode(compressor) || !compressor.has_directive("use strict"); + } + + OPT(AST_Call, function(self, compressor) { + var exp = self.expression; + var terminated = trim_optional_chain(self, compressor); + if (terminated) return terminated; + if (compressor.option("sequences")) { + if (exp instanceof AST_PropAccess) { + var seq = lift_sequence_in_expression(exp, compressor); + if (seq !== exp) { + var call = self.clone(); + call.expression = seq.expressions.pop(); + seq.expressions.push(call); + return seq.optimize(compressor); + } + } else if (!needs_unbinding(exp.tail_node())) { + var seq = lift_sequence_in_expression(self, compressor); + if (seq !== self) return seq.optimize(compressor); + } + } + if (compressor.option("unused")) drop_unused_call_args(self, compressor); + if (compressor.option("unsafe")) { + if (is_undeclared_ref(exp)) switch (exp.name) { + case "Array": + // Array(n) ---> [ , , ... , ] + if (self.args.length == 1) { + var first = self.args[0]; + if (first instanceof AST_Number) try { + var length = first.value; + if (length > 6) break; + var elements = Array(length); + for (var i = 0; i < length; i++) elements[i] = make_node(AST_Hole, self); + return make_node(AST_Array, self, { elements: elements }); + } catch (ex) { + AST_Node.warn("Invalid array length: {length} [{start}]", { + length: length, + start: self.start, + }); + break; + } + if (!first.is_boolean(compressor) && !first.is_string(compressor)) break; + } + // Array(...) ---> [ ... ] + return make_node(AST_Array, self, { elements: self.args }); + case "Object": + // Object() ---> {} + if (self.args.length == 0) return make_node(AST_Object, self, { properties: [] }); + break; + case "String": + // String() ---> "" + if (self.args.length == 0) return make_node(AST_String, self, { value: "" }); + // String(x) ---> "" + x + if (self.args.length == 1) return make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_String, self, { value: "" }), + right: self.args[0], + }).optimize(compressor); + break; + case "Number": + // Number() ---> 0 + if (self.args.length == 0) return make_node(AST_Number, self, { value: 0 }); + // Number(x) ---> +("" + x) + if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_String, self, { value: "" }), + right: self.args[0], + }), + }).optimize(compressor); + break; + case "Boolean": + // Boolean() ---> false + if (self.args.length == 0) return make_node(AST_False, self).optimize(compressor); + // Boolean(x) ---> !!x + if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: self.args[0], + }), + }).optimize(compressor); + break; + case "RegExp": + // attempt to convert RegExp(...) to literal + var params = []; + if (all(self.args, function(arg) { + var value = arg.evaluate(compressor); + params.unshift(value); + return arg !== value; + })) try { + return best_of(compressor, self, make_node(AST_RegExp, self, { + value: RegExp.apply(RegExp, params), + })); + } catch (ex) { + AST_Node.warn("Error converting {this} [{start}]", self); + } + break; + } else if (exp instanceof AST_Dot) switch (exp.property) { + case "toString": + // x.toString() ---> "" + x + var expr = exp.expression; + if (self.args.length == 0 && !(expr.may_throw_on_access(compressor) || expr instanceof AST_Super)) { + return make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_String, self, { value: "" }), + right: expr, + }).optimize(compressor); + } + break; + case "join": + if (exp.expression instanceof AST_Array && self.args.length < 2) EXIT: { + var separator = self.args[0]; + // [].join() ---> "" + // [].join(x) ---> (x, "") + if (exp.expression.elements.length == 0 && !(separator instanceof AST_Spread)) { + return separator ? make_sequence(self, [ + separator, + make_node(AST_String, self, { value: "" }), + ]).optimize(compressor) : make_node(AST_String, self, { value: "" }); + } + if (separator) { + separator = separator.evaluate(compressor); + if (separator instanceof AST_Node) break EXIT; // not a constant + } + var elements = []; + var consts = []; + for (var i = 0; i < exp.expression.elements.length; i++) { + var el = exp.expression.elements[i]; + var value = el.evaluate(compressor); + if (value !== el) { + consts.push(value); + } else if (el instanceof AST_Spread) { + break EXIT; + } else { + if (consts.length > 0) { + elements.push(make_node(AST_String, self, { value: consts.join(separator) })); + consts.length = 0; + } + elements.push(el); + } + } + if (consts.length > 0) elements.push(make_node(AST_String, self, { + value: consts.join(separator), + })); + // [ x ].join() ---> "" + x + // [ x ].join(".") ---> "" + x + // [ 1, 2, 3 ].join() ---> "1,2,3" + // [ 1, 2, 3 ].join(".") ---> "1.2.3" + if (elements.length == 1) { + if (elements[0].is_string(compressor)) return elements[0]; + return make_node(AST_Binary, elements[0], { + operator: "+", + left: make_node(AST_String, self, { value: "" }), + right: elements[0], + }); + } + // [ 1, 2, a, 3 ].join("") ---> "12" + a + "3" + if (separator == "") { + var first; + if (elements[0].is_string(compressor) || elements[1].is_string(compressor)) { + first = elements.shift(); + } else { + first = make_node(AST_String, self, { value: "" }); + } + return elements.reduce(function(prev, el) { + return make_node(AST_Binary, el, { + operator: "+", + left: prev, + right: el, + }); + }, first).optimize(compressor); + } + // [ x, "foo", "bar", y ].join() ---> [ x, "foo,bar", y ].join() + // [ x, "foo", "bar", y ].join("-") ---> [ x, "foo-bar", y ].join("-") + // need this awkward cloning to not affect original element + // best_of will decide which one to get through. + var node = self.clone(); + node.expression = node.expression.clone(); + node.expression.expression = node.expression.expression.clone(); + node.expression.expression.elements = elements; + return best_of(compressor, self, node); + } + break; + case "charAt": + if (self.args.length < 2) { + var node = make_node(AST_Binary, self, { + operator: "||", + left: make_node(AST_Sub, self, { + expression: exp.expression, + property: self.args.length ? make_node(AST_Binary, self.args[0], { + operator: "|", + left: make_node(AST_Number, self, { value: 0 }), + right: self.args[0], + }) : make_node(AST_Number, self, { value: 0 }), + }).optimize(compressor), + right: make_node(AST_String, self, { value: "" }), + }); + node.is_string = return_true; + return node.optimize(compressor); + } + break; + case "apply": + if (self.args.length == 2 && self.args[1] instanceof AST_Array) { + var args = self.args[1].elements.slice(); + args.unshift(self.args[0]); + return make_node(AST_Call, self, { + expression: make_node(AST_Dot, exp, { + expression: exp.expression, + property: "call", + }), + args: args, + }).optimize(compressor); + } + break; + case "call": + var func = exp.expression; + if (func instanceof AST_SymbolRef) { + func = func.fixed_value(); + } + if (func instanceof AST_Lambda && !func.contains_this()) { + return (self.args.length ? make_sequence(self, [ + self.args[0], + make_node(AST_Call, self, { + expression: exp.expression, + args: self.args.slice(1), + }), + ]) : make_node(AST_Call, self, { + expression: exp.expression, + args: [], + })).optimize(compressor); + } + break; + } else if (compressor.option("side_effects") + && exp instanceof AST_Call + && exp.args.length == 1 + && is_undeclared_ref(exp.expression) + && exp.expression.name == "Object") { + var call = self.clone(); + call.expression = maintain_this_binding(self, exp, exp.args[0]); + return call.optimize(compressor); + } + } + if (compressor.option("unsafe_Function") + && is_undeclared_ref(exp) + && exp.name == "Function") { + // new Function() ---> function(){} + if (self.args.length == 0) return make_node(AST_Function, self, { + argnames: [], + body: [], + }).init_vars(exp.scope); + if (all(self.args, function(x) { + return x instanceof AST_String; + })) { + // quite a corner-case, but we can handle it: + // https://github.com/mishoo/UglifyJS/issues/203 + // if the code argument is a constant, then we can minify it. + try { + var code = "n(function(" + self.args.slice(0, -1).map(function(arg) { + return arg.value; + }).join() + "){" + self.args[self.args.length - 1].value + "})"; + var ast = parse(code); + var mangle = { ie: compressor.option("ie") }; + ast.figure_out_scope(mangle); + var comp = new Compressor(compressor.options); + ast = ast.transform(comp); + ast.figure_out_scope(mangle); + ast.compute_char_frequency(mangle); + ast.mangle_names(mangle); + var fun; + ast.walk(new TreeWalker(function(node) { + if (fun) return true; + if (node instanceof AST_Lambda) { + fun = node; + return true; + } + })); + var code = OutputStream(); + AST_BlockStatement.prototype._codegen.call(fun, code); + self.args = [ + make_node(AST_String, self, { + value: fun.argnames.map(function(arg) { + return arg.print_to_string(); + }).join(), + }), + make_node(AST_String, self.args[self.args.length - 1], { + value: code.get().replace(/^\{|\}$/g, "") + }), + ]; + return self; + } catch (ex) { + if (ex instanceof JS_Parse_Error) { + AST_Node.warn("Error parsing code passed to new Function [{start}]", self.args[self.args.length - 1]); + AST_Node.warn(ex.toString()); + } else { + throw ex; + } + } + } + } + var fn = exp instanceof AST_SymbolRef ? exp.fixed_value() : exp; + var parent = compressor.parent(), current = compressor.self(); + var is_func = fn instanceof AST_Lambda + && (!is_async(fn) || compressor.option("awaits") && parent instanceof AST_Await) + && (!is_generator(fn) || compressor.option("yields") && current instanceof AST_Yield && current.nested); + var stat = is_func && fn.first_statement(); + var has_default = 0, has_destructured = false; + var has_spread = !all(self.args, function(arg) { + return !(arg instanceof AST_Spread); + }); + var can_drop = is_func && all(fn.argnames, function(argname, index) { + if (has_default == 1 && self.args[index] instanceof AST_Spread) has_default = 2; + if (argname instanceof AST_DefaultValue) { + if (!has_default) has_default = 1; + var arg = has_default == 1 && self.args[index]; + if (!is_undefined(arg)) has_default = 2; + if (has_arg_refs(fn, argname.value)) return false; + argname = argname.name; + } + if (argname instanceof AST_Destructured) { + has_destructured = true; + if (has_arg_refs(fn, argname)) return false; + } + return true; + }) && !(fn.rest instanceof AST_Destructured && has_arg_refs(fn, fn.rest)); + var can_inline = can_drop + && compressor.option("inline") + && !self.is_expr_pure(compressor) + && (exp === fn || safe_from_strict_mode(fn, compressor)); + if (can_inline && stat instanceof AST_Return) { + var value = stat.value; + if (exp === fn + && !fn.name + && (!value || value.is_constant_expression()) + && safe_from_await_yield(fn, avoid_await_yield(compressor))) { + return make_sequence(self, convert_args(value)).optimize(compressor); + } + } + if (is_func && !fn.contains_this()) { + var def, value, var_assigned = false; + if (can_inline + && !fn.uses_arguments + && !fn.pinned() + && !(fn.name && fn instanceof AST_LambdaExpression) + && (exp === fn || !recursive_ref(compressor, def = exp.definition(), fn) + && fn.is_constant_expression(find_scope(compressor))) + && (value = can_flatten_body(stat))) { + var replacing = exp === fn || def.single_use && def.references.length - def.replaced == 1; + if (can_substitute_directly()) { + var args = self.args.slice(); + var refs = []; + var retValue = value.clone(true).transform(new TreeTransformer(function(node) { + if (node instanceof AST_SymbolRef) { + var def = node.definition(); + if (fn.variables.get(node.name) !== def) { + refs.push(node); + return node; + } + var index = resolve_index(def); + var arg = args[index]; + if (!arg) return make_node(AST_Undefined, self); + args[index] = null; + var parent = this.parent(); + return parent ? maintain_this_binding(parent, node, arg) : arg; + } + })); + var save_inlined = fn.inlined; + if (exp !== fn) fn.inlined = true; + var exprs = []; + args.forEach(function(arg) { + if (!arg) return; + arg = arg.clone(true); + arg.walk(new TreeWalker(function(node) { + if (node instanceof AST_SymbolRef) refs.push(node); + })); + exprs.push(arg); + }, []); + exprs.push(retValue); + var node = make_sequence(self, exprs).optimize(compressor); + fn.inlined = save_inlined; + node = maintain_this_binding(parent, current, node); + if (replacing || best_of_expression(node, self) === node) { + refs.forEach(function(ref) { + ref.scope = exp === fn ? fn.parent_scope : exp.scope; + ref.reference(); + var def = ref.definition(); + if (replacing) def.replaced++; + def.single_use = false; + }); + return node; + } else if (!node.has_side_effects(compressor)) { + self.drop_side_effect_free = function(compressor, first_in_statement) { + var self = this; + var exprs = self.args.slice(); + exprs.unshift(self.expression); + return make_sequence(self, exprs).drop_side_effect_free(compressor, first_in_statement); + }; + } + } + var arg_used, insert, in_loop, scope; + if (replacing && can_inject_symbols()) { + fn._squeezed = true; + if (exp !== fn) fn.parent_scope = exp.scope; + var node = make_sequence(self, flatten_fn()).optimize(compressor); + return maintain_this_binding(parent, current, node); + } + } + if (compressor.option("side_effects") + && can_drop + && all(fn.body, is_empty) + && (fn === exp ? fn_name_unused(fn, compressor) : !has_default && !has_destructured && !fn.rest) + && !(is_arrow(fn) && fn.value) + && safe_from_await_yield(fn, avoid_await_yield(compressor))) { + return make_sequence(self, convert_args()).optimize(compressor); + } + } + if (compressor.option("drop_console")) { + if (exp instanceof AST_PropAccess) { + var name = exp.expression; + while (name.expression) { + name = name.expression; + } + if (is_undeclared_ref(name) && name.name == "console") { + return make_node(AST_Undefined, self).optimize(compressor); + } + } + } + if (compressor.option("negate_iife") && parent instanceof AST_SimpleStatement && is_iife_call(current)) { + return self.negate(compressor, true); + } + return try_evaluate(compressor, self); + + function make_void_lhs(orig) { + return make_node(AST_Sub, orig, { + expression: make_node(AST_Array, orig, { elements: [] }), + property: make_node(AST_Number, orig, { value: 0 }), + }); + } + + function convert_args(value) { + var args = self.args.slice(); + var destructured = has_default > 1 || has_destructured || fn.rest; + if (destructured || has_spread) args = [ make_node(AST_Array, self, { elements: args }) ]; + if (destructured) { + var tt = new TreeTransformer(function(node, descend) { + if (node instanceof AST_DefaultValue) return make_node(AST_DefaultValue, node, { + name: node.name.transform(tt) || make_void_lhs(node), + value: node.value, + }); + if (node instanceof AST_DestructuredArray) { + var elements = []; + node.elements.forEach(function(node, index) { + node = node.transform(tt); + if (node) elements[index] = node; + }); + fill_holes(node, elements); + return make_node(AST_DestructuredArray, node, { elements: elements }); + } + if (node instanceof AST_DestructuredObject) { + var properties = [], side_effects = []; + node.properties.forEach(function(prop) { + var key = prop.key; + var value = prop.value.transform(tt); + if (value) { + if (side_effects.length) { + if (!(key instanceof AST_Node)) key = make_node_from_constant(key, prop); + side_effects.push(key); + key = make_sequence(node, side_effects); + side_effects = []; + } + properties.push(make_node(AST_DestructuredKeyVal, prop, { + key: key, + value: value, + })); + } else if (key instanceof AST_Node) { + side_effects.push(key); + } + }); + if (side_effects.length) properties.push(make_node(AST_DestructuredKeyVal, node, { + key: make_sequence(node, side_effects), + value: make_void_lhs(node), + })); + return make_node(AST_DestructuredObject, node, { properties: properties }); + } + if (node instanceof AST_SymbolFunarg) return null; + }); + var lhs = []; + fn.argnames.forEach(function(argname, index) { + argname = argname.transform(tt); + if (argname) lhs[index] = argname; + }); + var rest = fn.rest && fn.rest.transform(tt); + if (rest) lhs.length = fn.argnames.length; + fill_holes(fn, lhs); + args[0] = make_node(AST_Assign, self, { + operator: "=", + left: make_node(AST_DestructuredArray, fn, { + elements: lhs, + rest: rest, + }), + right: args[0], + }); + } else fn.argnames.forEach(function(argname) { + if (argname instanceof AST_DefaultValue) args.push(argname.value); + }); + args.push(value || make_node(AST_Undefined, self)); + return args; + } + + function noop_value() { + return self.call_only ? make_node(AST_Number, self, { value: 0 }) : make_node(AST_Undefined, self); + } + + function return_value(stat) { + if (!stat) return noop_value(); + if (stat instanceof AST_Return) return stat.value || noop_value(); + if (stat instanceof AST_SimpleStatement) { + return self.call_only ? stat.body : make_node(AST_UnaryPrefix, stat, { + operator: "void", + expression: stat.body, + }); + } + } + + function can_flatten_body(stat) { + var len = fn.body.length; + if (len < 2) { + stat = return_value(stat); + if (stat) return stat; + } + if (compressor.option("inline") < 3) return false; + stat = null; + for (var i = 0; i < len; i++) { + var line = fn.body[i]; + if (line instanceof AST_Var) { + if (var_assigned) { + if (!stat) continue; + if (!(stat instanceof AST_SimpleStatement)) return false; + if (!declarations_only(line)) stat = null; + } else if (!declarations_only(line)) { + if (stat && !(stat instanceof AST_SimpleStatement)) return false; + stat = null; + var_assigned = true; + } + } else if (line instanceof AST_AsyncDefun + || line instanceof AST_Defun + || line instanceof AST_EmptyStatement) { + continue; + } else if (stat) { + return false; + } else { + stat = line; + } + } + return return_value(stat); + } + + function resolve_index(def) { + for (var i = fn.argnames.length; --i >= 0;) { + if (fn.argnames[i].definition() === def) return i; + } + } + + function can_substitute_directly() { + if (has_default || has_destructured || has_spread || var_assigned || fn.rest) return; + if (compressor.option("inline") < 2 && fn.argnames.length) return; + if (!fn.variables.all(function(def) { + return def.references.length - def.replaced < 2 && def.orig[0] instanceof AST_SymbolFunarg; + })) return; + var scope = compressor.find_parent(AST_Scope); + var abort = false; + var avoid = avoid_await_yield(compressor, scope); + var begin; + var in_order = []; + var side_effects = false; + var tw = new TreeWalker(function(node, descend) { + if (abort) return true; + if (node instanceof AST_Binary && lazy_op[node.operator] + || node instanceof AST_Conditional) { + in_order = null; + return; + } + if (node instanceof AST_Scope) return abort = true; + if (avoid && node instanceof AST_Symbol && avoid[node.name]) return abort = true; + if (node instanceof AST_SymbolRef) { + var def = node.definition(); + if (fn.variables.get(node.name) !== def) { + in_order = null; + return; + } + if (def.init instanceof AST_LambdaDefinition) return abort = true; + if (is_lhs(node, tw.parent())) return abort = true; + var index = resolve_index(def); + if (!(begin < index)) begin = index; + if (!in_order) return; + if (side_effects) { + in_order = null; + } else { + in_order.push(fn.argnames[index]); + } + return; + } + if (side_effects) return; + if (node instanceof AST_Assign && node.left instanceof AST_PropAccess) { + node.left.expression.walk(tw); + if (node.left instanceof AST_Sub) node.left.property.walk(tw); + node.right.walk(tw); + side_effects = true; + return true; + } + if (node.has_side_effects(compressor)) { + descend(); + side_effects = true; + return true; + } + }); + value.walk(tw); + if (abort) return; + var end = self.args.length; + if (in_order && fn.argnames.length >= end) { + end = fn.argnames.length; + while (end-- > begin && fn.argnames[end] === in_order.pop()); + end++; + } + return end <= begin || all(self.args.slice(begin, end), side_effects && !in_order ? function(funarg) { + return funarg.is_constant_expression(scope); + } : function(funarg) { + return !funarg.has_side_effects(compressor); + }); + } + + function var_exists(defined, name) { + return defined.has(name) || identifier_atom[name] || scope.var_names().has(name); + } + + function can_inject_args(defined, safe_to_inject) { + var abort = false; + fn.each_argname(function(arg) { + if (abort) return; + if (arg.unused) return; + if (!safe_to_inject || var_exists(defined, arg.name)) return abort = true; + arg_used.set(arg.name, true); + if (in_loop) in_loop.push(arg.definition()); + }); + return !abort; + } + + function can_inject_vars(defined, safe_to_inject) { + for (var i = 0; i < fn.body.length; i++) { + var stat = fn.body[i]; + if (stat instanceof AST_LambdaDefinition) { + var name = stat.name; + if (!safe_to_inject) return false; + if (arg_used.has(name.name)) return false; + if (var_exists(defined, name.name)) return false; + if (!all(stat.enclosed, function(def) { + return def.scope === scope || def.scope === stat || !defined.has(def.name); + })) return false; + if (in_loop) in_loop.push(name.definition()); + continue; + } + if (!(stat instanceof AST_Var)) continue; + if (!safe_to_inject) return false; + for (var j = stat.definitions.length; --j >= 0;) { + var name = stat.definitions[j].name; + if (var_exists(defined, name.name)) return false; + if (in_loop) in_loop.push(name.definition()); + } + } + return true; + } + + function can_inject_symbols() { + var defined = new Dictionary(); + var level = 0, child; + scope = current; + do { + if (scope.variables) scope.variables.each(function(def) { + defined.set(def.name, true); + }); + child = scope; + scope = compressor.parent(level++); + if (scope instanceof AST_ClassField) { + if (!scope.static) return false; + } else if (scope instanceof AST_DWLoop) { + in_loop = []; + } else if (scope instanceof AST_For) { + if (scope.init === child) continue; + in_loop = []; + } else if (scope instanceof AST_ForEnumeration) { + if (scope.init === child) continue; + if (scope.object === child) continue; + in_loop = []; + } + } while (!(scope instanceof AST_Scope)); + insert = scope.body.indexOf(child) + 1; + if (!insert) return false; + if (!safe_from_await_yield(fn, avoid_await_yield(compressor, scope))) return false; + var safe_to_inject = (exp !== fn || fn.parent_scope.resolve() === scope) && !scope.pinned(); + if (scope instanceof AST_Toplevel) { + if (compressor.toplevel.vars) { + defined.set("arguments", true); + } else { + safe_to_inject = false; + } + } + arg_used = new Dictionary(); + var inline = compressor.option("inline"); + if (!can_inject_args(defined, inline >= 2 && safe_to_inject)) return false; + if (!can_inject_vars(defined, inline >= 3 && safe_to_inject)) return false; + return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop); + } + + function append_var(decls, expressions, name, value) { + var def = name.definition(); + if (!scope.var_names().has(name.name)) { + scope.var_names().set(name.name, true); + decls.push(make_node(AST_VarDef, name, { + name: name, + value: null, + })); + } + scope.variables.set(name.name, def); + scope.enclosed.push(def); + if (!value) return; + var sym = make_node(AST_SymbolRef, name); + def.assignments++; + def.references.push(sym); + expressions.push(make_node(AST_Assign, self, { + operator: "=", + left: sym, + right: value, + })); + } + + function flatten_args(decls, expressions) { + var len = fn.argnames.length; + for (var i = self.args.length; --i >= len;) { + expressions.push(self.args[i]); + } + var default_args = []; + for (i = len; --i >= 0;) { + var argname = fn.argnames[i]; + var name; + if (argname instanceof AST_DefaultValue) { + default_args.push(argname); + name = argname.name; + } else { + name = argname; + } + var value = self.args[i]; + if (name.unused || scope.var_names().has(name.name)) { + if (value) expressions.push(value); + } else { + var symbol = make_node(AST_SymbolVar, name); + var def = name.definition(); + def.orig.push(symbol); + def.eliminated++; + if (name.unused !== undefined) { + append_var(decls, expressions, symbol); + if (value) expressions.push(value); + } else { + if (!value && argname === name && (in_loop + || name.name == "arguments" && !is_arrow(fn) && is_arrow(scope))) { + value = make_node(AST_Undefined, self); + } + append_var(decls, expressions, symbol, value); + } + } + } + decls.reverse(); + expressions.reverse(); + for (i = default_args.length; --i >= 0;) { + var node = default_args[i]; + if (node.name.unused !== undefined) { + expressions.push(node.value); + } else { + var sym = make_node(AST_SymbolRef, node.name); + node.name.definition().references.push(sym); + expressions.push(make_node(AST_Assign, node, { + operator: "=", + left: sym, + right: node.value, + })); + } + } + } + + function flatten_destructured(decls, expressions) { + expressions.push(make_node(AST_Assign, self, { + operator: "=", + left: make_node(AST_DestructuredArray, self, { + elements: fn.argnames.map(function(argname) { + if (argname.unused) return make_node(AST_Hole, argname); + return argname.convert_symbol(AST_SymbolRef, process); + }), + rest: fn.rest && fn.rest.convert_symbol(AST_SymbolRef, process), + }), + right: make_node(AST_Array, self, { elements: self.args.slice() }), + })); + + function process(ref, name) { + if (name.unused) return make_void_lhs(name); + var def = name.definition(); + def.assignments++; + def.references.push(ref); + var symbol = make_node(AST_SymbolVar, name); + def.orig.push(symbol); + def.eliminated++; + append_var(decls, expressions, symbol); + } + } + + function flatten_vars(decls, expressions) { + var args = [ insert, 0 ]; + var decl_var = [], expr_fn = [], expr_var = [], expr_loop = [], exprs = []; + fn.body.filter(in_loop ? function(stat) { + if (!(stat instanceof AST_LambdaDefinition)) return true; + var name = make_node(AST_SymbolVar, flatten_var(stat.name)); + var def = name.definition(); + def.fixed = false; + def.orig.push(name); + def.eliminated++; + append_var(decls, expr_fn, name, to_func_expr(stat, true)); + return false; + } : function(stat) { + if (!(stat instanceof AST_LambdaDefinition)) return true; + var def = stat.name.definition(); + scope.functions.set(def.name, def); + scope.variables.set(def.name, def); + scope.enclosed.push(def); + scope.var_names().set(def.name, true); + args.push(stat); + return false; + }).forEach(function(stat) { + if (!(stat instanceof AST_Var)) { + if (stat instanceof AST_SimpleStatement) exprs.push(stat.body); + return; + } + for (var j = 0; j < stat.definitions.length; j++) { + var var_def = stat.definitions[j]; + var name = flatten_var(var_def.name); + var value = var_def.value; + if (value && exprs.length > 0) { + exprs.push(value); + value = make_sequence(var_def, exprs); + exprs = []; + } + append_var(decl_var, expr_var, name, value); + if (!in_loop) continue; + if (arg_used.has(name.name)) continue; + if (name.definition().orig.length == 1 && fn.functions.has(name.name)) continue; + expr_loop.push(init_ref(compressor, name)); + } + }); + [].push.apply(decls, decl_var); + [].push.apply(expressions, expr_loop); + [].push.apply(expressions, expr_fn); + [].push.apply(expressions, expr_var); + return args; + } + + function flatten_fn() { + var decls = []; + var expressions = []; + if (has_default > 1 || has_destructured || has_spread || fn.rest) { + flatten_destructured(decls, expressions); + } else { + flatten_args(decls, expressions); + } + var args = flatten_vars(decls, expressions); + expressions.push(value); + if (decls.length) args.push(make_node(AST_Var, fn, { definitions: decls })); + [].splice.apply(scope.body, args); + fn.enclosed.forEach(function(def) { + if (scope.var_names().has(def.name)) return; + scope.enclosed.push(def); + scope.var_names().set(def.name, true); + }); + return expressions; + } + }); + + OPT(AST_New, function(self, compressor) { + if (compressor.option("unsafe")) { + var exp = self.expression; + if (is_undeclared_ref(exp)) switch (exp.name) { + case "Array": + case "Error": + case "Function": + case "Object": + case "RegExp": + return make_node(AST_Call, self).transform(compressor); + } + } + if (compressor.option("sequences")) { + var seq = lift_sequence_in_expression(self, compressor); + if (seq !== self) return seq.optimize(compressor); + } + if (compressor.option("unused")) drop_unused_call_args(self, compressor); + return self; + }); + + // (a = b, x && a = c) ---> a = x ? c : b + // (a = b, x || a = c) ---> a = x ? b : c + function to_conditional_assignment(compressor, def, value, node) { + if (!(node instanceof AST_Binary)) return; + if (!(node.operator == "&&" || node.operator == "||")) return; + if (!(node.right instanceof AST_Assign)) return; + if (node.right.operator != "=") return; + if (!(node.right.left instanceof AST_SymbolRef)) return; + if (node.right.left.definition() !== def) return; + if (value.has_side_effects(compressor)) return; + if (!safe_from_assignment(node.left)) return; + if (!safe_from_assignment(node.right.right)) return; + def.replaced++; + return node.operator == "&&" ? make_node(AST_Conditional, node, { + condition: node.left, + consequent: node.right.right, + alternative: value, + }) : make_node(AST_Conditional, node, { + condition: node.left, + consequent: value, + alternative: node.right.right, + }); + + function safe_from_assignment(node) { + if (node.has_side_effects(compressor)) return; + var hit = false; + node.walk(new TreeWalker(function(node) { + if (hit) return true; + if (node instanceof AST_SymbolRef && node.definition() === def) return hit = true; + })); + return !hit; + } + } + + OPT(AST_Sequence, function(self, compressor) { + var expressions = filter_for_side_effects(); + var end = expressions.length - 1; + merge_assignments(); + trim_right_for_undefined(); + if (end == 0) { + self = maintain_this_binding(compressor.parent(), compressor.self(), expressions[0]); + if (!(self instanceof AST_Sequence)) self = self.optimize(compressor); + return self; + } + self.expressions = expressions; + return self; + + function filter_for_side_effects() { + if (!compressor.option("side_effects")) return self.expressions; + var expressions = []; + var first = first_in_statement(compressor); + var last = self.expressions.length - 1; + self.expressions.forEach(function(expr, index) { + if (index < last) expr = expr.drop_side_effect_free(compressor, first); + if (expr) { + merge_sequence(expressions, expr); + first = false; + } + }); + return expressions; + } + + function trim_right_for_undefined() { + if (!compressor.option("side_effects")) return; + while (end > 0 && is_undefined(expressions[end], compressor)) end--; + if (end < expressions.length - 1) { + expressions[end] = make_node(AST_UnaryPrefix, self, { + operator: "void", + expression: expressions[end], + }); + expressions.length = end + 1; + } + } + + function is_simple_assign(node) { + return node instanceof AST_Assign + && node.operator == "=" + && node.left instanceof AST_SymbolRef + && node.left.definition(); + } + + function merge_assignments() { + for (var i = 1; i < end; i++) { + var prev = expressions[i - 1]; + var def = is_simple_assign(prev); + if (!def) continue; + var expr = expressions[i]; + if (compressor.option("conditionals")) { + var cond = to_conditional_assignment(compressor, def, prev.right, expr); + if (cond) { + prev.right = cond; + expressions.splice(i--, 1); + end--; + continue; + } + } + if (compressor.option("dead_code") + && is_simple_assign(expr) === def + && expr.right.is_constant_expression(def.scope.resolve())) { + expressions[--i] = prev.right; + } + } + } + }); + + OPT(AST_UnaryPostfix, function(self, compressor) { + if (compressor.option("sequences")) { + var seq = lift_sequence_in_expression(self, compressor); + if (seq !== self) return seq.optimize(compressor); + } + return try_evaluate(compressor, self); + }); + + var SIGN_OPS = makePredicate("+ -"); + var MULTIPLICATIVE_OPS = makePredicate("* / %"); + OPT(AST_UnaryPrefix, function(self, compressor) { + var op = self.operator; + var exp = self.expression; + if (compressor.option("sequences") && can_lift()) { + var seq = lift_sequence_in_expression(self, compressor); + if (seq !== self) return seq.optimize(compressor); + } + switch (op) { + case "+": + if (!compressor.option("evaluate")) break; + if (!exp.is_number(compressor, true)) break; + var parent = compressor.parent(); + if (parent instanceof AST_UnaryPrefix && parent.operator == "delete") break; + return exp; + case "-": + if (exp instanceof AST_Infinity) exp = exp.transform(compressor); + // avoids infinite recursion of numerals + if (exp instanceof AST_Number || exp instanceof AST_Infinity) return self; + break; + case "!": + if (!compressor.option("booleans")) break; + if (exp.is_truthy()) return make_sequence(self, [ exp, make_node(AST_False, self) ]).optimize(compressor); + if (compressor.in_boolean_context()) { + // !!foo ---> foo, if we're in boolean context + if (exp instanceof AST_UnaryPrefix && exp.operator == "!") return exp.expression; + if (exp instanceof AST_Binary) { + var first = first_in_statement(compressor); + self = (first ? best_of_statement : best_of_expression)(self, exp.negate(compressor, first)); + } + } + break; + case "delete": + if (!compressor.option("evaluate")) break; + if (may_not_delete(exp)) break; + return make_sequence(self, [ exp, make_node(AST_True, self) ]).optimize(compressor); + case "typeof": + if (!compressor.option("booleans")) break; + if (!compressor.in_boolean_context()) break; + // typeof always returns a non-empty string, thus always truthy + AST_Node.warn("Boolean expression always true [{start}]", self); + var exprs = [ make_node(AST_True, self) ]; + if (!(exp instanceof AST_SymbolRef && can_drop_symbol(exp, compressor))) exprs.unshift(exp); + return make_sequence(self, exprs).optimize(compressor); + case "void": + if (!compressor.option("side_effects")) break; + exp = exp.drop_side_effect_free(compressor); + if (!exp) return make_node(AST_Undefined, self).optimize(compressor); + self.expression = exp; + return self; + } + if (compressor.option("evaluate") + && exp instanceof AST_Binary + && SIGN_OPS[op] + && MULTIPLICATIVE_OPS[exp.operator] + && (exp.left.is_constant() || !exp.right.has_side_effects(compressor))) { + return make_node(AST_Binary, self, { + operator: exp.operator, + left: make_node(AST_UnaryPrefix, exp.left, { + operator: op, + expression: exp.left, + }), + right: exp.right, + }); + } + return try_evaluate(compressor, self); + + function may_not_delete(node) { + return node instanceof AST_Infinity + || node instanceof AST_NaN + || node instanceof AST_NewTarget + || node instanceof AST_PropAccess + || node instanceof AST_SymbolRef + || node instanceof AST_Undefined; + } + + function can_lift() { + switch (op) { + case "delete": + return !may_not_delete(exp.tail_node()); + case "typeof": + return !is_undeclared_ref(exp.tail_node()); + default: + return true; + } + } + }); + + OPT(AST_Await, function(self, compressor) { + if (!compressor.option("awaits")) return self; + if (compressor.option("sequences")) { + var seq = lift_sequence_in_expression(self, compressor); + if (seq !== self) return seq.optimize(compressor); + } + if (compressor.option("side_effects")) { + var exp = self.expression; + if (exp instanceof AST_Await) return exp.optimize(compressor); + if (exp instanceof AST_UnaryPrefix && exp.expression instanceof AST_Await) return exp.optimize(compressor); + for (var level = 0, node = self, parent; parent = compressor.parent(level++); node = parent) { + if (is_arrow(parent)) { + if (parent.value === node) return exp.optimize(compressor); + } else if (parent instanceof AST_Return) { + var drop = true; + do { + node = parent; + parent = compressor.parent(level++); + if (parent instanceof AST_Try && (parent.bfinally || parent.bcatch) !== node) { + drop = false; + break; + } + } while (parent && !(parent instanceof AST_Scope)); + if (drop) return exp.optimize(compressor); + } else if (parent instanceof AST_Sequence) { + if (parent.tail_node() === node) continue; + } + break; + } + } + return self; + }); + + OPT(AST_Yield, function(self, compressor) { + if (!compressor.option("yields")) return self; + if (compressor.option("sequences")) { + var seq = lift_sequence_in_expression(self, compressor); + if (seq !== self) return seq.optimize(compressor); + } + var exp = self.expression; + if (self.nested && exp.TYPE == "Call") { + var inlined = exp.clone().optimize(compressor); + if (inlined.TYPE != "Call") return inlined; + } + return self; + }); + + AST_Binary.DEFMETHOD("lift_sequences", function(compressor) { + if (this.left instanceof AST_PropAccess) { + if (!(this.left.expression instanceof AST_Sequence)) return this; + var x = this.left.expression.expressions.slice(); + var e = this.clone(); + e.left = e.left.clone(); + e.left.expression = x.pop(); + x.push(e); + return make_sequence(this, x); + } + if (this.left instanceof AST_Sequence) { + var x = this.left.expressions.slice(); + var e = this.clone(); + e.left = x.pop(); + x.push(e); + return make_sequence(this, x); + } + if (this.right instanceof AST_Sequence) { + if (this.left.has_side_effects(compressor)) return this; + var assign = this.operator == "=" && this.left instanceof AST_SymbolRef; + var x = this.right.expressions; + var last = x.length - 1; + for (var i = 0; i < last; i++) { + if (!assign && x[i].has_side_effects(compressor)) break; + } + if (i == last) { + x = x.slice(); + var e = this.clone(); + e.right = x.pop(); + x.push(e); + return make_sequence(this, x); + } + if (i > 0) { + var e = this.clone(); + e.right = make_sequence(this.right, x.slice(i)); + x = x.slice(0, i); + x.push(e); + return make_sequence(this, x); + } + } + return this; + }); + + var indexFns = makePredicate("indexOf lastIndexOf"); + var commutativeOperators = makePredicate("== === != !== * & | ^"); + function is_object(node, plain) { + if (node instanceof AST_Assign) return !plain && node.operator == "=" && is_object(node.right); + if (node instanceof AST_New) return !plain; + if (node instanceof AST_Sequence) return is_object(node.tail_node(), plain); + if (node instanceof AST_SymbolRef) return !plain && is_object(node.fixed_value()); + return node instanceof AST_Array + || node instanceof AST_Class + || node instanceof AST_Lambda + || node instanceof AST_Object; + } + + function can_drop_op(op, rhs, compressor) { + switch (op) { + case "in": + return is_object(rhs) || compressor && compressor.option("unsafe_comps"); + case "instanceof": + if (rhs instanceof AST_SymbolRef) rhs = rhs.fixed_value(); + return is_lambda(rhs) || compressor && compressor.option("unsafe_comps"); + default: + return true; + } + } + + function needs_enqueuing(compressor, node) { + if (node.is_constant()) return true; + if (node instanceof AST_Assign) return node.operator != "=" || needs_enqueuing(compressor, node.right); + if (node instanceof AST_Binary) { + return !lazy_op[node.operator] + || needs_enqueuing(compressor, node.left) && needs_enqueuing(compressor, node.right); + } + if (node instanceof AST_Call) return is_async(node.expression); + if (node instanceof AST_Conditional) { + return needs_enqueuing(compressor, node.consequent) && needs_enqueuing(compressor, node.alternative); + } + if (node instanceof AST_Sequence) return needs_enqueuing(compressor, node.tail_node()); + if (node instanceof AST_SymbolRef) { + var fixed = node.fixed_value(); + return fixed && needs_enqueuing(compressor, fixed); + } + if (node instanceof AST_Template) return !node.tag || is_raw_tag(compressor, node.tag); + if (node instanceof AST_Unary) return true; + } + + function extract_lhs(node, compressor) { + if (node instanceof AST_Assign) return is_lhs_read_only(node.left, compressor) ? node : node.left; + if (node instanceof AST_Sequence) return extract_lhs(node.tail_node(), compressor); + if (node instanceof AST_UnaryPrefix && UNARY_POSTFIX[node.operator]) { + return is_lhs_read_only(node.expression, compressor) ? node : node.expression; + } + return node; + } + + function repeatable(compressor, node) { + if (node instanceof AST_Dot) return repeatable(compressor, node.expression); + if (node instanceof AST_Sub) { + return repeatable(compressor, node.expression) && repeatable(compressor, node.property); + } + if (node instanceof AST_Symbol) return true; + return !node.has_side_effects(compressor); + } + + function swap_chain(self, compressor) { + var rhs = self.right.tail_node(); + if (rhs !== self.right) { + var exprs = self.right.expressions.slice(0, -1); + exprs.push(rhs.left); + rhs = rhs.clone(); + rhs.left = make_sequence(self.right, exprs); + self.right = rhs; + } + self.left = make_node(AST_Binary, self, { + operator: self.operator, + left: self.left, + right: rhs.left, + start: self.left.start, + end: rhs.left.end, + }); + self.right = rhs.right; + if (compressor) { + self.left = self.left.transform(compressor); + } else if (self.operator == rhs.left.operator) { + swap_chain(self.left); + } + } + + OPT(AST_Binary, function(self, compressor) { + if (commutativeOperators[self.operator] + && self.right.is_constant() + && !self.left.is_constant() + && !(self.left instanceof AST_Binary + && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { + // if right is a constant, whatever side effects the + // left side might have could not influence the + // result. hence, force switch. + reverse(); + } + if (compressor.option("sequences")) { + var seq = self.lift_sequences(compressor); + if (seq !== self) return seq.optimize(compressor); + } + if (compressor.option("assignments") && lazy_op[self.operator]) { + var lhs = extract_lhs(self.left, compressor); + var right = self.right; + // a || (a = x) ---> a = a || x + // (a = x) && (a = y) ---> a = (a = x) && y + if (lhs instanceof AST_SymbolRef + && right instanceof AST_Assign + && right.operator == "=" + && lhs.equals(right.left)) { + lhs = lhs.clone(); + var assign = make_node(AST_Assign, self, { + operator: "=", + left: lhs, + right: make_node(AST_Binary, self, { + operator: self.operator, + left: self.left, + right: right.right, + }), + }); + if (lhs.fixed) { + lhs.fixed = function() { + return assign.right; + }; + lhs.fixed.assigns = [ assign ]; + } + var def = lhs.definition(); + def.references.push(lhs); + def.replaced++; + return assign.optimize(compressor); + } + } + if (compressor.option("comparisons")) switch (self.operator) { + case "===": + case "!==": + if (is_undefined(self.left, compressor) && self.right.is_defined(compressor)) { + AST_Node.warn("Expression always defined [{start}]", self); + return make_sequence(self, [ + self.right, + make_node(self.operator == "===" ? AST_False : AST_True, self), + ]).optimize(compressor); + } + var is_strict_comparison = true; + if ((self.left.is_string(compressor) && self.right.is_string(compressor)) || + (self.left.is_number(compressor) && self.right.is_number(compressor)) || + (self.left.is_boolean(compressor) && self.right.is_boolean(compressor)) || + repeatable(compressor, self.left) && self.left.equals(self.right)) { + self.operator = self.operator.slice(0, 2); + } + // XXX: intentionally falling down to the next case + case "==": + case "!=": + // void 0 == x ---> null == x + if (!is_strict_comparison && is_undefined(self.left, compressor)) { + self.left = make_node(AST_Null, self.left); + } + // "undefined" == typeof x ---> undefined === x + else if (compressor.option("typeofs") + && self.left instanceof AST_String + && self.left.value == "undefined" + && self.right instanceof AST_UnaryPrefix + && self.right.operator == "typeof") { + var expr = self.right.expression; + if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor) + : !(expr instanceof AST_PropAccess && compressor.option("ie"))) { + self.right = expr; + self.left = make_node(AST_Undefined, self.left).optimize(compressor); + if (self.operator.length == 2) self.operator += "="; + } + } + // obj !== obj ---> false + else if (self.left instanceof AST_SymbolRef + && self.right instanceof AST_SymbolRef + && self.left.definition() === self.right.definition() + && is_object(self.left)) { + return make_node(self.operator[0] == "=" ? AST_True : AST_False, self).optimize(compressor); + } + break; + case "&&": + case "||": + // void 0 !== x && null !== x ---> null != x + // void 0 === x || null === x ---> null == x + var left = self.left; + if (!(left instanceof AST_Binary)) break; + if (left.operator != (self.operator == "&&" ? "!==" : "===")) break; + if (!(self.right instanceof AST_Binary)) break; + if (left.operator != self.right.operator) break; + if (is_undefined(left.left, compressor) && self.right.left instanceof AST_Null + || left.left instanceof AST_Null && is_undefined(self.right.left, compressor)) { + var expr = left.right; + if (expr instanceof AST_Assign && expr.operator == "=") expr = expr.left; + if (expr.has_side_effects(compressor)) break; + if (!expr.equals(self.right.right)) break; + left.operator = left.operator.slice(0, -1); + left.left = make_node(AST_Null, self); + return left; + } + break; + } + var in_bool = false; + var parent = compressor.parent(); + if (compressor.option("booleans")) { + var lhs = extract_lhs(self.left, compressor); + if (lazy_op[self.operator] && !lhs.has_side_effects(compressor)) { + // a || a ---> a + // (a = x) && a --> a = x + if (lhs.equals(self.right)) { + return maintain_this_binding(parent, compressor.self(), self.left).optimize(compressor); + } + mark_duplicate_condition(compressor, lhs); + } + in_bool = compressor.in_boolean_context(); + } + if (in_bool) switch (self.operator) { + case "+": + var ev = self.left.evaluate(compressor, true); + if (ev && typeof ev == "string" || (ev = self.right.evaluate(compressor, true)) && typeof ev == "string") { + AST_Node.warn("+ in boolean context always true [{start}]", self); + var exprs = []; + if (self.left.evaluate(compressor) instanceof AST_Node) exprs.push(self.left); + if (self.right.evaluate(compressor) instanceof AST_Node) exprs.push(self.right); + if (exprs.length < 2) { + exprs.push(make_node(AST_True, self)); + return make_sequence(self, exprs).optimize(compressor); + } + self.truthy = true; + } + break; + case "==": + if (self.left instanceof AST_String && self.left.value == "" && self.right.is_string(compressor)) { + return make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: self.right, + }).optimize(compressor); + } + break; + case "!=": + if (self.left instanceof AST_String && self.left.value == "" && self.right.is_string(compressor)) { + return self.right.optimize(compressor); + } + break; + } + if (compressor.option("comparisons") && self.is_boolean(compressor)) { + if (parent.TYPE != "Binary") { + var negated = make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: self.negate(compressor), + }); + if (best_of(compressor, self, negated) === negated) return negated; + } + switch (self.operator) { + case ">": reverse("<"); break; + case ">=": reverse("<="); break; + } + } + if (compressor.option("conditionals") && lazy_op[self.operator]) { + if (self.left instanceof AST_Binary && self.operator == self.left.operator) { + var before = make_node(AST_Binary, self, { + operator: self.operator, + left: self.left.right, + right: self.right, + }); + var after = before.transform(compressor); + if (before !== after) { + self.left = self.left.left; + self.right = after; + } + } + // x && (y && z) ---> x && y && z + // w || (x, y || z) ---> w || (x, y) || z + var rhs = self.right.tail_node(); + if (rhs instanceof AST_Binary && self.operator == rhs.operator) swap_chain(self, compressor); + } + if (compressor.option("strings") && self.operator == "+") { + // "foo" + 42 + "" ---> "foo" + 42 + if (self.right instanceof AST_String + && self.right.value == "" + && self.left.is_string(compressor)) { + return self.left.optimize(compressor); + } + // "" + ("foo" + 42) ---> "foo" + 42 + if (self.left instanceof AST_String + && self.left.value == "" + && self.right.is_string(compressor)) { + return self.right.optimize(compressor); + } + // "" + 42 + "foo" ---> 42 + "foo" + if (self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.left instanceof AST_String + && self.left.left.value == "" + && self.right.is_string(compressor) + && (self.left.right.is_constant() || !self.right.has_side_effects(compressor))) { + self.left = self.left.right; + return self.optimize(compressor); + } + // "x" + (y + "z") ---> "x" + y + "z" + // w + (x, "y" + z) ---> w + (x, "y") + z + var rhs = self.right.tail_node(); + if (rhs instanceof AST_Binary + && self.operator == rhs.operator + && (self.left.is_string(compressor) && rhs.is_string(compressor) + || rhs.left.is_string(compressor) + && (self.left.is_constant() || !rhs.right.has_side_effects(compressor)))) { + swap_chain(self, compressor); + } + } + if (compressor.option("evaluate")) { + var associative = true; + switch (self.operator) { + case "&&": + var ll = fuzzy_eval(compressor, self.left); + if (!ll) { + AST_Node.warn("Condition left of && always false [{start}]", self); + return maintain_this_binding(parent, compressor.self(), self.left).optimize(compressor); + } else if (!(ll instanceof AST_Node)) { + AST_Node.warn("Condition left of && always true [{start}]", self); + return make_sequence(self, [ self.left, self.right ]).optimize(compressor); + } + if (!self.right.evaluate(compressor, true)) { + if (in_bool && !(self.right.evaluate(compressor) instanceof AST_Node)) { + AST_Node.warn("Boolean && always false [{start}]", self); + return make_sequence(self, [ self.left, make_node(AST_False, self) ]).optimize(compressor); + } else self.falsy = true; + } else if ((in_bool || parent.operator == "&&" && parent.left === compressor.self()) + && !(self.right.evaluate(compressor) instanceof AST_Node)) { + AST_Node.warn("Dropping side-effect-free && [{start}]", self); + return self.left.optimize(compressor); + } + // (x || false) && y ---> x ? y : false + if (self.left.operator == "||") { + var lr = fuzzy_eval(compressor, self.left.right); + if (!lr) return make_node(AST_Conditional, self, { + condition: self.left.left, + consequent: self.right, + alternative: self.left.right, + }).optimize(compressor); + } + break; + case "??": + var nullish = true; + case "||": + var ll = fuzzy_eval(compressor, self.left, nullish); + if (nullish ? ll == null : !ll) { + AST_Node.warn("Condition left of {operator} always {value} [{start}]", { + operator: self.operator, + value: nullish ? "nullish" : "false", + start: self.start, + }); + return make_sequence(self, [ self.left, self.right ]).optimize(compressor); + } else if (!(ll instanceof AST_Node)) { + AST_Node.warn("Condition left of {operator} always {value} [{start}]", { + operator: self.operator, + value: nullish ? "defined" : "true", + start: self.start, + }); + return maintain_this_binding(parent, compressor.self(), self.left).optimize(compressor); + } + var rr; + if (!nullish && (rr = self.right.evaluate(compressor, true)) && !(rr instanceof AST_Node)) { + if (in_bool && !(self.right.evaluate(compressor) instanceof AST_Node)) { + AST_Node.warn("Boolean || always true [{start}]", self); + return make_sequence(self, [ self.left, make_node(AST_True, self) ]).optimize(compressor); + } else self.truthy = true; + } else if ((in_bool || parent.operator == "||" && parent.left === compressor.self()) + && !self.right.evaluate(compressor)) { + AST_Node.warn("Dropping side-effect-free {operator} [{start}]", self); + return self.left.optimize(compressor); + } + // x && true || y ---> x ? true : y + if (!nullish && self.left.operator == "&&") { + var lr = fuzzy_eval(compressor, self.left.right); + if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, { + condition: self.left.left, + consequent: self.left.right, + alternative: self.right, + }).optimize(compressor); + } + break; + case "+": + // "foo" + ("bar" + x) ---> "foobar" + x + if (self.left instanceof AST_Constant + && self.right instanceof AST_Binary + && self.right.operator == "+" + && self.right.left instanceof AST_Constant + && self.right.is_string(compressor)) { + self = make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_String, self.left, { + value: "" + self.left.value + self.right.left.value, + start: self.left.start, + end: self.right.left.end, + }), + right: self.right.right, + }); + } + // (x + "foo") + "bar" ---> x + "foobar" + if (self.right instanceof AST_Constant + && self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.right instanceof AST_Constant + && self.left.is_string(compressor)) { + self = make_node(AST_Binary, self, { + operator: "+", + left: self.left.left, + right: make_node(AST_String, self.right, { + value: "" + self.left.right.value + self.right.value, + start: self.left.right.start, + end: self.right.end, + }), + }); + } + // a + -b ---> a - b + if (self.right instanceof AST_UnaryPrefix + && self.right.operator == "-" + && self.left.is_number(compressor)) { + self = make_node(AST_Binary, self, { + operator: "-", + left: self.left, + right: self.right.expression, + }); + break; + } + // -a + b ---> b - a + if (self.left instanceof AST_UnaryPrefix + && self.left.operator == "-" + && reversible() + && self.right.is_number(compressor)) { + self = make_node(AST_Binary, self, { + operator: "-", + left: self.right, + right: self.left.expression, + }); + break; + } + // (a + b) + 3 ---> 3 + (a + b) + if (compressor.option("unsafe_math") + && self.left instanceof AST_Binary + && PRECEDENCE[self.left.operator] == PRECEDENCE[self.operator] + && self.right.is_constant() + && (self.right.is_boolean(compressor) || self.right.is_number(compressor)) + && self.left.is_number(compressor) + && !self.left.right.is_constant() + && (self.left.left.is_boolean(compressor) || self.left.left.is_number(compressor))) { + self = make_node(AST_Binary, self, { + operator: self.left.operator, + left: make_node(AST_Binary, self, { + operator: self.operator, + left: self.right, + right: self.left.left, + }), + right: self.left.right, + }); + break; + } + case "-": + // a - -b ---> a + b + if (self.right instanceof AST_UnaryPrefix + && self.right.operator == "-" + && self.left.is_number(compressor) + && self.right.expression.is_number(compressor)) { + self = make_node(AST_Binary, self, { + operator: "+", + left: self.left, + right: self.right.expression, + }); + break; + } + case "*": + case "/": + associative = compressor.option("unsafe_math"); + // +a - b ---> a - b + // a - +b ---> a - b + if (self.operator != "+") [ "left", "right" ].forEach(function(operand) { + var node = self[operand]; + if (node instanceof AST_UnaryPrefix && node.operator == "+") { + var exp = node.expression; + if (exp.is_boolean(compressor) || exp.is_number(compressor) || exp.is_string(compressor)) { + self[operand] = exp; + } + } + }); + case "&": + case "|": + case "^": + // a + +b ---> +b + a + if (self.operator != "-" + && self.operator != "/" + && (self.left.is_boolean(compressor) || self.left.is_number(compressor)) + && (self.right.is_boolean(compressor) || self.right.is_number(compressor)) + && reversible() + && !(self.left instanceof AST_Binary + && self.left.operator != self.operator + && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { + self = best_of(compressor, self, make_node(AST_Binary, self, { + operator: self.operator, + left: self.right, + right: self.left, + }), self.right instanceof AST_Constant && !(self.left instanceof AST_Constant)); + } + if (!associative || !self.is_number(compressor)) break; + // a + (b + c) ---> (a + b) + c + if (self.right instanceof AST_Binary + && self.right.operator != "%" + && PRECEDENCE[self.right.operator] == PRECEDENCE[self.operator] + && self.right.is_number(compressor) + && (self.operator != "+" + || self.right.left.is_boolean(compressor) + || self.right.left.is_number(compressor)) + && (self.operator != "-" || !self.left.is_negative_zero()) + && (self.right.left.is_constant_expression() + || !self.right.right.has_side_effects(compressor)) + && !is_modify_array(self.right.right)) { + self = make_node(AST_Binary, self, { + operator: align(self.operator, self.right.operator), + left: make_node(AST_Binary, self.left, { + operator: self.operator, + left: self.left, + right: self.right.left, + start: self.left.start, + end: self.right.left.end, + }), + right: self.right.right, + }); + if (self.operator == "+" + && !self.right.is_boolean(compressor) + && !self.right.is_number(compressor)) { + self.right = make_node(AST_UnaryPrefix, self.right, { + operator: "+", + expression: self.right, + }); + } + } + // (2 * n) * 3 ---> 6 * n + // (n + 2) + 3 ---> n + 5 + if (self.right instanceof AST_Constant + && self.left instanceof AST_Binary + && self.left.operator != "%" + && PRECEDENCE[self.left.operator] == PRECEDENCE[self.operator] + && self.left.is_number(compressor)) { + if (self.left.left instanceof AST_Constant) { + var lhs = make_binary(self.operator, self.left.left, self.right, { + start: self.left.left.start, + end: self.right.end, + }); + self = make_binary(self.left.operator, try_evaluate(compressor, lhs), self.left.right, self); + } else if (self.left.right instanceof AST_Constant) { + var op = align(self.left.operator, self.operator); + var rhs = try_evaluate(compressor, make_binary(op, self.left.right, self.right, self.left)); + if (rhs.is_constant() + && !(self.left.operator == "-" + && self.right.value != 0 + && +rhs.value == 0 + && self.left.left.is_negative_zero())) { + self = make_binary(self.left.operator, self.left.left, rhs, self); + } + } + } + break; + case "instanceof": + if (is_lambda(self.right)) return make_sequence(self, [ + self, + make_node(AST_False, self), + ]).optimize(compressor); + break; + } + if (!(parent instanceof AST_UnaryPrefix && parent.operator == "delete")) { + if (self.left instanceof AST_Number && !self.right.is_constant()) switch (self.operator) { + // 0 + n ---> n + case "+": + if (self.left.value == 0) { + if (self.right.is_boolean(compressor)) return make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: self.right, + }).optimize(compressor); + if (self.right.is_number(compressor) && !self.right.is_negative_zero()) return self.right; + } + break; + // 1 * n ---> n + case "*": + if (self.left.value == 1) return make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: self.right, + }).optimize(compressor); + break; + } + if (self.right instanceof AST_Number && !self.left.is_constant()) switch (self.operator) { + // n + 0 ---> n + case "+": + if (self.right.value == 0) { + if (self.left.is_boolean(compressor)) return make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: self.left, + }).optimize(compressor); + if (self.left.is_number(compressor) && !self.left.is_negative_zero()) return self.left; + } + break; + // n - 0 ---> n + case "-": + if (self.right.value == 0) return make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: self.left, + }).optimize(compressor); + break; + // n / 1 ---> n + case "/": + if (self.right.value == 1) return make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: self.left, + }).optimize(compressor); + break; + } + } + } + if (compressor.option("typeofs")) switch (self.operator) { + case "&&": + mark_locally_defined(self.left, self.right, null); + break; + case "||": + mark_locally_defined(self.left, null, self.right); + break; + } + if (compressor.option("unsafe")) { + var indexRight = is_indexFn(self.right); + if (in_bool + && indexRight + && (self.operator == "==" || self.operator == "!=") + && self.left instanceof AST_Number + && self.left.value == 0) { + return (self.operator == "==" ? make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: self.right, + }) : self.right).optimize(compressor); + } + var indexLeft = is_indexFn(self.left); + if (compressor.option("comparisons") && is_indexOf_match_pattern()) { + var node = make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: make_node(AST_UnaryPrefix, self, { + operator: "~", + expression: indexLeft ? self.left : self.right, + }), + }); + switch (self.operator) { + case "<": + if (indexLeft) break; + case "<=": + case "!=": + node = make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: node, + }); + break; + } + return node.optimize(compressor); + } + } + return try_evaluate(compressor, self); + + function is_modify_array(node) { + var found = false; + node.walk(new TreeWalker(function(node) { + if (found) return true; + if (node instanceof AST_Assign) { + if (node.left instanceof AST_PropAccess) return found = true; + } else if (node instanceof AST_Unary) { + if (unary_side_effects[node.operator] && node.expression instanceof AST_PropAccess) { + return found = true; + } + } + })); + return found; + } + + function align(ref, op) { + switch (ref) { + case "-": + return op == "+" ? "-" : "+"; + case "/": + return op == "*" ? "/" : "*"; + default: + return op; + } + } + + function make_binary(op, left, right, orig) { + if (op == "+") { + if (!left.is_boolean(compressor) && !left.is_number(compressor)) { + left = make_node(AST_UnaryPrefix, left, { + operator: "+", + expression: left, + }); + } + if (!right.is_boolean(compressor) && !right.is_number(compressor)) { + right = make_node(AST_UnaryPrefix, right, { + operator: "+", + expression: right, + }); + } + } + return make_node(AST_Binary, orig, { + operator: op, + left: left, + right: right, + }); + } + + function is_indexFn(node) { + return node.TYPE == "Call" + && node.expression instanceof AST_Dot + && indexFns[node.expression.property]; + } + + function is_indexOf_match_pattern() { + switch (self.operator) { + case "<=": + // 0 <= array.indexOf(string) ---> !!~array.indexOf(string) + return indexRight && self.left instanceof AST_Number && self.left.value == 0; + case "<": + // array.indexOf(string) < 0 ---> !~array.indexOf(string) + if (indexLeft && self.right instanceof AST_Number && self.right.value == 0) return true; + // -1 < array.indexOf(string) ---> !!~array.indexOf(string) + case "==": + case "!=": + // -1 == array.indexOf(string) ---> !~array.indexOf(string) + // -1 != array.indexOf(string) ---> !!~array.indexOf(string) + if (!indexRight) return false; + return self.left instanceof AST_Number && self.left.value == -1 + || self.left instanceof AST_UnaryPrefix && self.left.operator == "-" + && self.left.expression instanceof AST_Number && self.left.expression.value == 1; + } + } + + function reversible() { + return self.left.is_constant() + || self.right.is_constant() + || !self.left.has_side_effects(compressor) + && !self.right.has_side_effects(compressor); + } + + function reverse(op) { + if (reversible()) { + if (op) self.operator = op; + var tmp = self.left; + self.left = self.right; + self.right = tmp; + } + } + }); + + OPT(AST_SymbolExport, function(self) { + return self; + }); + + function recursive_ref(compressor, def, fn) { + var level = 0, node = compressor.self(); + do { + if (node === fn) return node; + if (is_lambda(node) && node.name && node.name.definition() === def) return node; + } while (node = compressor.parent(level++)); + } + + function same_scope(def) { + var scope = def.scope.resolve(); + return all(def.references, function(ref) { + return scope === ref.scope.resolve(); + }); + } + + OPT(AST_SymbolRef, function(self, compressor) { + if (!compressor.option("ie") + && is_undeclared_ref(self) + // testing against `self.scope.uses_with` is an optimization + && !(self.scope.resolve().uses_with && compressor.find_parent(AST_With))) { + switch (self.name) { + case "undefined": + return make_node(AST_Undefined, self).optimize(compressor); + case "NaN": + return make_node(AST_NaN, self).optimize(compressor); + case "Infinity": + return make_node(AST_Infinity, self).optimize(compressor); + } + } + var parent = compressor.parent(); + if (compressor.option("reduce_vars") && is_lhs(compressor.self(), parent) !== compressor.self()) { + var def = self.definition(); + var fixed = self.fixed_value(); + var single_use = def.single_use && !(parent instanceof AST_Call && parent.is_expr_pure(compressor)); + if (single_use) { + if (is_lambda(fixed)) { + if ((def.scope !== self.scope.resolve(true) || def.in_loop) + && (!compressor.option("reduce_funcs") || def.escaped.depth == 1 || fixed.inlined)) { + single_use = false; + } else if (def.redefined()) { + single_use = false; + } else if (recursive_ref(compressor, def, fixed)) { + single_use = false; + } else if (fixed.name && fixed.name.definition() !== def) { + single_use = false; + } else if (fixed.parent_scope !== self.scope || is_funarg(def)) { + if (!safe_from_strict_mode(fixed, compressor)) { + single_use = false; + } else if ((single_use = fixed.is_constant_expression(self.scope)) == "f") { + var scope = self.scope; + do { + if (scope instanceof AST_LambdaDefinition || scope instanceof AST_LambdaExpression) { + scope.inlined = true; + } + } while (scope = scope.parent_scope); + } + } else if (fixed.name && (fixed.name.name == "await" && is_async(fixed) + || fixed.name.name == "yield" && is_generator(fixed))) { + single_use = false; + } else if (fixed.has_side_effects(compressor)) { + single_use = false; + } else if (compressor.option("ie") && fixed instanceof AST_Class) { + single_use = false; + } + if (single_use) fixed.parent_scope = self.scope; + } else if (!fixed + || def.recursive_refs > 0 + || !fixed.is_constant_expression() + || fixed.drop_side_effect_free(compressor)) { + single_use = false; + } + } + if (single_use) { + def.single_use = false; + fixed._squeezed = true; + fixed.single_use = true; + if (fixed instanceof AST_DefClass) fixed = to_class_expr(fixed); + if (fixed instanceof AST_LambdaDefinition) fixed = to_func_expr(fixed); + if (is_lambda(fixed)) { + var scopes = []; + var scope = self.scope; + do { + scopes.push(scope); + if (scope === def.scope) break; + } while (scope = scope.parent_scope); + fixed.enclosed.forEach(function(def) { + if (fixed.variables.has(def.name)) return; + for (var i = 0; i < scopes.length; i++) { + var scope = scopes[i]; + if (!push_uniq(scope.enclosed, def)) return; + scope.var_names().set(def.name, true); + } + }); + } + var value; + if (def.recursive_refs > 0) { + value = fixed.clone(true); + var defun_def = value.name.definition(); + var lambda_def = value.variables.get(value.name.name); + var name = lambda_def && lambda_def.orig[0]; + var def_fn_name, symbol_type; + if (value instanceof AST_Class) { + def_fn_name = "def_function"; + symbol_type = AST_SymbolClass; + } else { + def_fn_name = "def_variable"; + symbol_type = AST_SymbolLambda; + } + if (!(name instanceof symbol_type)) { + name = make_node(symbol_type, value.name); + name.scope = value; + value.name = name; + lambda_def = value[def_fn_name](name); + lambda_def.recursive_refs = def.recursive_refs; + } + value.walk(new TreeWalker(function(node) { + if (node instanceof AST_SymbolDeclaration) { + if (node !== name) { + var def = node.definition(); + def.orig.push(node); + def.eliminated++; + } + return; + } + if (!(node instanceof AST_SymbolRef)) return; + var def = node.definition(); + if (def === defun_def) { + node.thedef = def = lambda_def; + } else { + def.single_use = false; + var fn = node.fixed_value(); + if (is_lambda(fn) + && fn.name + && fn.name.definition() === def + && def.scope === fn.name.scope + && fixed.variables.get(fn.name.name) === def) { + fn.name = fn.name.clone(); + node.thedef = def = value.variables.get(fn.name.name) || value[def_fn_name](fn.name); + } + } + def.references.push(node); + })); + } else { + if (fixed instanceof AST_Scope) { + compressor.push(fixed); + value = fixed.optimize(compressor); + compressor.pop(); + } else { + value = fixed.optimize(compressor); + } + value = value.transform(new TreeTransformer(function(node, descend) { + if (node instanceof AST_Scope) return node; + node = node.clone(); + descend(node, this); + return node; + })); + } + def.replaced++; + return value; + } + var state; + if (fixed && (state = self.fixed || def.fixed).should_replace !== false) { + var ev, init; + if (fixed instanceof AST_This) { + if (!is_funarg(def) && same_scope(def) && !cross_class(def)) init = fixed; + } else if ((ev = fixed.evaluate(compressor, true)) !== fixed + && typeof ev != "function" + && (ev === null + || typeof ev != "object" + || compressor.option("unsafe_regexp") + && ev instanceof RegExp && !def.cross_loop && same_scope(def))) { + init = make_node_from_constant(ev, fixed); + } + if (init) { + if (state.should_replace === undefined) { + var value_length = init.optimize(compressor).print_to_string().length; + if (!has_symbol_ref(fixed)) { + value_length = Math.min(value_length, fixed.print_to_string().length); + } + var name_length = def.name.length; + if (compressor.option("unused") && !compressor.exposed(def)) { + var refs = def.references.length - def.replaced - def.assignments; + refs = Math.min(refs, def.references.filter(function(ref) { + return ref.fixed === state; + }).length); + name_length += (name_length + 2 + value_length) / Math.max(1, refs); + } + state.should_replace = value_length - Math.floor(name_length) < compressor.eval_threshold; + } + if (state.should_replace) { + var value; + if (has_symbol_ref(fixed)) { + value = init.optimize(compressor); + if (value === init) value = value.clone(true); + } else { + value = best_of_expression(init.optimize(compressor), fixed); + if (value === init || value === fixed) value = value.clone(true); + } + def.replaced++; + return value; + } + } + } + } + return self; + + function cross_class(def) { + var scope = self.scope; + while (scope !== def.scope) { + if (scope instanceof AST_Class) return true; + scope = scope.parent_scope; + } + } + + function has_symbol_ref(value) { + var found; + value.walk(new TreeWalker(function(node) { + if (node instanceof AST_SymbolRef) found = true; + if (found) return true; + })); + return found; + } + }); + + function is_raw_tag(compressor, tag) { + return compressor.option("unsafe") + && tag instanceof AST_Dot + && tag.property == "raw" + && is_undeclared_ref(tag.expression) + && tag.expression.name == "String"; + } + + function decode_template(str) { + var malformed = false; + str = str.replace(/\\(u\{[^{}]*\}?|u[\s\S]{0,4}|x[\s\S]{0,2}|[0-9]+|[\s\S])/g, function(match, seq) { + var ch = decode_escape_sequence(seq); + if (typeof ch == "string") return ch; + malformed = true; + }); + if (!malformed) return str; + } + + OPT(AST_Template, function(self, compressor) { + if (!compressor.option("templates")) return self; + var tag = self.tag; + if (!tag || is_raw_tag(compressor, tag)) { + var exprs = []; + var strs = []; + for (var i = 0, status; i < self.strings.length; i++) { + var str = self.strings[i]; + if (!tag) { + var trimmed = decode_template(str); + if (trimmed) str = escape_literal(trimmed); + } + if (i > 0) { + var node = self.expressions[i - 1]; + var value = should_join(node); + if (value) { + var prev = strs[strs.length - 1]; + var joined = prev + value + str; + var decoded; + if (tag || typeof (decoded = decode_template(joined)) == status) { + strs[strs.length - 1] = decoded ? escape_literal(decoded) : joined; + continue; + } + } + exprs.push(node); + } + strs.push(str); + if (!tag) status = typeof trimmed; + } + if (!tag && strs.length > 1) { + if (strs[strs.length - 1] == "") return make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_Template, self, { + expressions: exprs.slice(0, -1), + strings: strs.slice(0, -1), + }).transform(compressor), + right: exprs[exprs.length - 1], + }).optimize(compressor); + if (strs[0] == "") { + var left = make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_String, self, { value: "" }), + right: exprs[0], + }); + for (var i = 1; strs[i] == "" && i < exprs.length; i++) { + left = make_node(AST_Binary, self, { + operator: "+", + left: left, + right: exprs[i], + }); + } + return best_of(compressor, self, make_node(AST_Binary, self, { + operator: "+", + left: left.transform(compressor), + right: make_node(AST_Template, self, { + expressions: exprs.slice(i), + strings: strs.slice(i), + }).transform(compressor), + }).optimize(compressor)); + } + } + self.expressions = exprs; + self.strings = strs; + } + return try_evaluate(compressor, self); + + function escape_literal(str) { + return str.replace(/\r|\\|`|\${/g, function(s) { + return "\\" + (s == "\r" ? "r" : s); + }); + } + + function should_join(node) { + var ev = node.evaluate(compressor); + if (ev === node) return; + if (tag && /\r|\\|`/.test(ev)) return; + ev = escape_literal("" + ev); + if (ev.length > node.print_to_string().length + "${}".length) return; + return ev; + } + }); + + function is_atomic(lhs, self) { + return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE; + } + + OPT(AST_Undefined, function(self, compressor) { + if (compressor.option("unsafe_undefined")) { + var undef = find_scope(compressor).find_variable("undefined"); + if (undef) { + var ref = make_node(AST_SymbolRef, self, { + name: "undefined", + scope: undef.scope, + thedef: undef, + }); + ref.is_undefined = true; + return ref; + } + } + var lhs = is_lhs(compressor.self(), compressor.parent()); + if (lhs && is_atomic(lhs, self)) return self; + return make_node(AST_UnaryPrefix, self, { + operator: "void", + expression: make_node(AST_Number, self, { value: 0 }), + }); + }); + + OPT(AST_Infinity, function(self, compressor) { + var lhs = is_lhs(compressor.self(), compressor.parent()); + if (lhs && is_atomic(lhs, self)) return self; + if (compressor.option("keep_infinity") && !lhs && !find_scope(compressor).find_variable("Infinity")) { + return self; + } + return make_node(AST_Binary, self, { + operator: "/", + left: make_node(AST_Number, self, { value: 1 }), + right: make_node(AST_Number, self, { value: 0 }), + }); + }); + + OPT(AST_NaN, function(self, compressor) { + var lhs = is_lhs(compressor.self(), compressor.parent()); + if (lhs && is_atomic(lhs, self)) return self; + if (!lhs && !find_scope(compressor).find_variable("NaN")) return self; + return make_node(AST_Binary, self, { + operator: "/", + left: make_node(AST_Number, self, { value: 0 }), + right: make_node(AST_Number, self, { value: 0 }), + }); + }); + + function is_reachable(self, defs) { + var reachable = false; + var find_ref = new TreeWalker(function(node) { + if (reachable) return true; + if (node instanceof AST_SymbolRef && member(node.definition(), defs)) return reachable = true; + }); + var scan_scope = new TreeWalker(function(node) { + if (reachable) return true; + if (node instanceof AST_Lambda && node !== self) { + if (!(node.name || is_async(node) || is_generator(node))) { + var parent = scan_scope.parent(); + if (parent instanceof AST_Call && parent.expression === node) return; + } + node.walk(find_ref); + return true; + } + }); + self.walk(scan_scope); + return reachable; + } + + var ASSIGN_OPS = makePredicate("+ - * / % >> << >>> | ^ &"); + var ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &"); + OPT(AST_Assign, function(self, compressor) { + if (compressor.option("dead_code")) { + if (self.left instanceof AST_PropAccess) { + if (self.operator == "=") { + if (self.redundant) { + var exprs = [ self.left.expression ]; + if (self.left instanceof AST_Sub) exprs.push(self.left.property); + exprs.push(self.right); + return make_sequence(self, exprs).optimize(compressor); + } + if (self.left.equals(self.right) && !self.left.has_side_effects(compressor)) { + return self.right; + } + var exp = self.left.expression; + if (exp instanceof AST_Lambda + || !compressor.has_directive("use strict") + && exp instanceof AST_Constant + && !exp.may_throw_on_access(compressor)) { + return self.left instanceof AST_Dot ? self.right : make_sequence(self, [ + self.left.property, + self.right + ]).optimize(compressor); + } + } + } else if (self.left instanceof AST_SymbolRef && can_drop_symbol(self.left, compressor)) { + var parent; + if (self.operator == "=" && self.left.equals(self.right) + && !((parent = compressor.parent()) instanceof AST_UnaryPrefix && parent.operator == "delete")) { + return self.right; + } + if (self.left.is_immutable()) return strip_assignment(); + var def = self.left.definition(); + var scope = def.scope.resolve(); + var local = scope === compressor.find_parent(AST_Lambda); + var level = 0, node; + parent = compressor.self(); + if (!(scope.uses_arguments && is_funarg(def)) || compressor.has_directive("use strict")) do { + node = parent; + parent = compressor.parent(level++); + if (parent instanceof AST_Assign) { + if (parent.left instanceof AST_SymbolRef && parent.left.definition() === def) { + if (in_try(level, parent, !local)) break; + return strip_assignment(def); + } + if (parent.left.match_symbol(function(node) { + if (node instanceof AST_PropAccess) return true; + })) break; + continue; + } + if (parent instanceof AST_Exit) { + if (!local) break; + if (in_try(level, parent)) break; + if (is_reachable(scope, [ def ])) break; + return strip_assignment(def); + } + if (parent instanceof AST_SimpleStatement) { + if (!local) break; + if (is_reachable(scope, [ def ])) break; + var stat; + do { + stat = parent; + parent = compressor.parent(level++); + if (parent === scope && is_last_statement(parent.body, stat)) return strip_assignment(def); + } while (is_tail_block(stat, parent)); + break; + } + if (parent instanceof AST_VarDef) { + if (!(parent.name instanceof AST_SymbolDeclaration)) continue; + if (parent.name.definition() !== def) continue; + if (in_try(level, parent)) break; + return strip_assignment(def); + } + } while (is_tail(node, parent)); + } + } + if (compressor.option("sequences")) { + var seq = self.lift_sequences(compressor); + if (seq !== self) return seq.optimize(compressor); + } + if (compressor.option("assignments")) { + if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) { + // x = expr1 OP expr2 + if (self.right.left instanceof AST_SymbolRef + && self.right.left.name == self.left.name + && ASSIGN_OPS[self.right.operator]) { + // x = x - 2 ---> x -= 2 + return make_compound(self.right.right); + } + if (self.right.right instanceof AST_SymbolRef + && self.right.right.name == self.left.name + && ASSIGN_OPS_COMMUTATIVE[self.right.operator] + && !self.right.left.has_side_effects(compressor)) { + // x = 2 & x ---> x &= 2 + return make_compound(self.right.left); + } + } + if ((self.operator == "-=" || self.operator == "+=" + && (self.left.is_boolean(compressor) || self.left.is_number(compressor))) + && self.right instanceof AST_Number + && self.right.value == 1) { + var op = self.operator.slice(0, -1); + return make_node(AST_UnaryPrefix, self, { + operator: op + op, + expression: self.left, + }); + } + } + return try_evaluate(compressor, self); + + function is_tail(node, parent) { + if (parent instanceof AST_Binary) switch (node) { + case parent.left: + return parent.right.is_constant_expression(scope); + case parent.right: + return true; + default: + return false; + } + if (parent instanceof AST_Conditional) switch (node) { + case parent.condition: + return parent.consequent.is_constant_expression(scope) + && parent.alternative.is_constant_expression(scope); + case parent.consequent: + case parent.alternative: + return true; + default: + return false; + } + if (parent instanceof AST_Sequence) { + var exprs = parent.expressions; + var stop = exprs.indexOf(node); + if (stop < 0) return false; + for (var i = exprs.length; --i > stop;) { + if (!exprs[i].is_constant_expression(scope)) return false; + } + return true; + } + return parent instanceof AST_UnaryPrefix; + } + + function is_tail_block(stat, parent) { + if (parent instanceof AST_BlockStatement) return is_last_statement(parent.body, stat); + if (parent instanceof AST_Catch) return is_last_statement(parent.body, stat); + if (parent instanceof AST_Finally) return is_last_statement(parent.body, stat); + if (parent instanceof AST_If) return parent.body === stat || parent.alternative === stat; + if (parent instanceof AST_Try) return parent.bfinally ? parent.bfinally === stat : parent.bcatch === stat; + } + + function in_try(level, node, sync) { + var right = self.right; + self.right = make_node(AST_Null, right); + var may_throw = node.may_throw(compressor); + self.right = right; + return find_try(compressor, level, node, scope, may_throw, sync); + } + + function make_compound(rhs) { + var fixed = self.left.fixed; + if (fixed) fixed.to_binary = replace_ref(function(node) { + return node.left; + }, fixed); + return make_node(AST_Assign, self, { + operator: self.right.operator + "=", + left: self.left, + right: rhs, + }); + } + + function strip_assignment(def) { + if (def) def.fixed = false; + return (self.operator != "=" ? make_node(AST_Binary, self, { + operator: self.operator.slice(0, -1), + left: self.left, + right: self.right, + }) : maintain_this_binding(compressor.parent(), self, self.right)).optimize(compressor); + } + }); + + OPT(AST_Conditional, function(self, compressor) { + if (compressor.option("sequences") && self.condition instanceof AST_Sequence) { + var expressions = self.condition.expressions.slice(); + var node = self.clone(); + node.condition = expressions.pop(); + expressions.push(node); + return make_sequence(self, expressions).optimize(compressor); + } + if (!compressor.option("conditionals")) return self; + var condition = self.condition; + if (compressor.option("booleans") && !condition.has_side_effects(compressor)) { + mark_duplicate_condition(compressor, condition); + } + condition = fuzzy_eval(compressor, condition); + if (!condition) { + AST_Node.warn("Condition always false [{start}]", self); + return make_sequence(self, [ self.condition, self.alternative ]).optimize(compressor); + } else if (!(condition instanceof AST_Node)) { + AST_Node.warn("Condition always true [{start}]", self); + return make_sequence(self, [ self.condition, self.consequent ]).optimize(compressor); + } + var first = first_in_statement(compressor); + var negated = condition.negate(compressor, first); + if ((first ? best_of_statement : best_of_expression)(condition, negated) === negated) { + self = make_node(AST_Conditional, self, { + condition: negated, + consequent: self.alternative, + alternative: self.consequent, + }); + negated = condition; + condition = self.condition; + } + var consequent = self.consequent; + var alternative = self.alternative; + var cond_lhs = extract_lhs(condition, compressor); + if (repeatable(compressor, cond_lhs)) { + // x ? x : y ---> x || y + if (cond_lhs.equals(consequent)) return make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: alternative, + }).optimize(compressor); + // x ? y : x ---> x && y + if (cond_lhs.equals(alternative)) return make_node(AST_Binary, self, { + operator: "&&", + left: condition, + right: consequent, + }).optimize(compressor); + } + // if (foo) exp = something; else exp = something_else; + // | + // v + // exp = foo ? something : something_else; + var seq_tail = consequent.tail_node(); + if (seq_tail instanceof AST_Assign) { + var is_eq = seq_tail.operator == "="; + var alt_tail = is_eq ? alternative.tail_node() : alternative; + if ((is_eq || consequent === seq_tail) + && alt_tail instanceof AST_Assign + && seq_tail.operator == alt_tail.operator + && seq_tail.left.equals(alt_tail.left) + && (is_eq && seq_tail.left instanceof AST_SymbolRef + || !condition.has_side_effects(compressor) + && can_shift_lhs_of_tail(consequent) + && can_shift_lhs_of_tail(alternative))) { + return make_node(AST_Assign, self, { + operator: seq_tail.operator, + left: seq_tail.left, + right: make_node(AST_Conditional, self, { + condition: condition, + consequent: pop_lhs(consequent), + alternative: pop_lhs(alternative), + }), + }); + } + } + var alt_tail = alternative.tail_node(); + // x ? y : y ---> x, y + // x ? (a, c) : (b, c) ---> x ? a : b, c + if (seq_tail.equals(alt_tail)) return make_sequence(self, consequent.equals(alternative) ? [ + condition, + consequent, + ] : [ + make_node(AST_Conditional, self, { + condition: condition, + consequent: pop_seq(consequent), + alternative: pop_seq(alternative), + }), + alt_tail, + ]).optimize(compressor); + // x ? y.p : z.p ---> (x ? y : z).p + // x ? y(a) : z(a) ---> (x ? y : z)(a) + // x ? y.f(a) : z.f(a) ---> (x ? y : z).f(a) + var combined = combine_tail(consequent, alternative, true); + if (combined) return combined; + // x ? y(a) : y(b) ---> y(x ? a : b) + var arg_index; + if (consequent instanceof AST_Call + && alternative.TYPE == consequent.TYPE + && (arg_index = arg_diff(consequent, alternative)) >= 0 + && consequent.expression.equals(alternative.expression) + && !condition.has_side_effects(compressor) + && !consequent.expression.has_side_effects(compressor)) { + var node = consequent.clone(); + var arg = consequent.args[arg_index]; + node.args[arg_index] = arg instanceof AST_Spread ? make_node(AST_Spread, self, { + expression: make_node(AST_Conditional, self, { + condition: condition, + consequent: arg.expression, + alternative: alternative.args[arg_index].expression, + }), + }) : make_node(AST_Conditional, self, { + condition: condition, + consequent: arg, + alternative: alternative.args[arg_index], + }); + return node; + } + // x ? (y ? a : b) : b ---> x && y ? a : b + if (seq_tail instanceof AST_Conditional + && seq_tail.alternative.equals(alternative)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + left: condition, + operator: "&&", + right: fuse(consequent, seq_tail, "condition"), + }), + consequent: seq_tail.consequent, + alternative: merge_expression(seq_tail.alternative, alternative), + }); + } + // x ? (y ? a : b) : a ---> !x || y ? a : b + if (seq_tail instanceof AST_Conditional + && seq_tail.consequent.equals(alternative)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + left: negated, + operator: "||", + right: fuse(consequent, seq_tail, "condition"), + }), + consequent: merge_expression(seq_tail.consequent, alternative), + alternative: seq_tail.alternative, + }); + } + // x ? a : (y ? a : b) ---> x || y ? a : b + if (alt_tail instanceof AST_Conditional + && consequent.equals(alt_tail.consequent)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + left: condition, + operator: "||", + right: fuse(alternative, alt_tail, "condition"), + }), + consequent: merge_expression(consequent, alt_tail.consequent), + alternative: alt_tail.alternative, + }); + } + // x ? b : (y ? a : b) ---> !x && y ? a : b + if (alt_tail instanceof AST_Conditional + && consequent.equals(alt_tail.alternative)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + left: negated, + operator: "&&", + right: fuse(alternative, alt_tail, "condition"), + }), + consequent: alt_tail.consequent, + alternative: merge_expression(consequent, alt_tail.alternative), + }); + } + // x ? y && a : a ---> (!x || y) && a + if (seq_tail instanceof AST_Binary + && seq_tail.operator == "&&" + && seq_tail.right.equals(alternative)) { + return make_node(AST_Binary, self, { + operator: "&&", + left: make_node(AST_Binary, self, { + operator: "||", + left: negated, + right: fuse(consequent, seq_tail, "left"), + }), + right: merge_expression(seq_tail.right, alternative), + }).optimize(compressor); + } + // x ? y || a : a ---> x && y || a + if (seq_tail instanceof AST_Binary + && seq_tail.operator == "||" + && seq_tail.right.equals(alternative)) { + return make_node(AST_Binary, self, { + operator: "||", + left: make_node(AST_Binary, self, { + operator: "&&", + left: condition, + right: fuse(consequent, seq_tail, "left"), + }), + right: merge_expression(seq_tail.right, alternative), + }).optimize(compressor); + } + // x ? a : y && a ---> (x || y) && a + if (alt_tail instanceof AST_Binary + && alt_tail.operator == "&&" + && alt_tail.right.equals(consequent)) { + return make_node(AST_Binary, self, { + operator: "&&", + left: make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: fuse(alternative, alt_tail, "left"), + }), + right: merge_expression(consequent, alt_tail.right), + }).optimize(compressor); + } + // x ? a : y || a ---> !x && y || a + if (alt_tail instanceof AST_Binary + && alt_tail.operator == "||" + && alt_tail.right.equals(consequent)) { + return make_node(AST_Binary, self, { + operator: "||", + left: make_node(AST_Binary, self, { + operator: "&&", + left: negated, + right: fuse(alternative, alt_tail, "left"), + }), + right: merge_expression(consequent, alt_tail.right), + }).optimize(compressor); + } + var in_bool = compressor.option("booleans") && compressor.in_boolean_context(); + if (is_true(consequent)) { + // c ? true : false ---> !!c + if (is_false(alternative)) return booleanize(condition); + // c ? true : x ---> !!c || x + return make_node(AST_Binary, self, { + operator: "||", + left: booleanize(condition), + right: alternative, + }).optimize(compressor); + } + if (is_false(consequent)) { + // c ? false : true ---> !c + if (is_true(alternative)) return booleanize(condition.negate(compressor)); + // c ? false : x ---> !c && x + return make_node(AST_Binary, self, { + operator: "&&", + left: booleanize(condition.negate(compressor)), + right: alternative, + }).optimize(compressor); + } + // c ? x : true ---> !c || x + if (is_true(alternative)) return make_node(AST_Binary, self, { + operator: "||", + left: booleanize(condition.negate(compressor)), + right: consequent, + }).optimize(compressor); + // c ? x : false ---> !!c && x + if (is_false(alternative)) return make_node(AST_Binary, self, { + operator: "&&", + left: booleanize(condition), + right: consequent, + }).optimize(compressor); + if (compressor.option("typeofs")) mark_locally_defined(condition, consequent, alternative); + return self; + + function booleanize(node) { + if (node.is_boolean(compressor)) return node; + // !!expression + return make_node(AST_UnaryPrefix, node, { + operator: "!", + expression: node.negate(compressor), + }); + } + + // AST_True or !0 + function is_true(node) { + return node instanceof AST_True + || in_bool + && node instanceof AST_Constant + && node.value + || (node instanceof AST_UnaryPrefix + && node.operator == "!" + && node.expression instanceof AST_Constant + && !node.expression.value); + } + // AST_False or !1 or void 0 + function is_false(node) { + return node instanceof AST_False + || in_bool + && (node instanceof AST_Constant + && !node.value + || node instanceof AST_UnaryPrefix + && node.operator == "void" + && !node.expression.has_side_effects(compressor)) + || (node instanceof AST_UnaryPrefix + && node.operator == "!" + && node.expression instanceof AST_Constant + && node.expression.value); + } + + function arg_diff(consequent, alternative) { + var a = consequent.args; + var b = alternative.args; + var len = a.length; + if (len != b.length) return -2; + for (var i = 0; i < len; i++) { + if (!a[i].equals(b[i])) { + if (a[i] instanceof AST_Spread !== b[i] instanceof AST_Spread) return -3; + for (var j = i + 1; j < len; j++) { + if (!a[j].equals(b[j])) return -2; + } + return i; + } + } + return -1; + } + + function fuse(node, tail, prop) { + if (node === tail) return tail[prop]; + var exprs = node.expressions.slice(0, -1); + exprs.push(tail[prop]); + return make_sequence(node, exprs); + } + + function is_tail_equivalent(consequent, alternative) { + if (consequent.TYPE != alternative.TYPE) return; + if (consequent.optional != alternative.optional) return; + if (consequent instanceof AST_Call) { + if (arg_diff(consequent, alternative) != -1) return; + return consequent.TYPE != "Call" + || !(consequent.expression instanceof AST_PropAccess + || alternative.expression instanceof AST_PropAccess) + || is_tail_equivalent(consequent.expression, alternative.expression); + } + if (!(consequent instanceof AST_PropAccess)) return; + var p = consequent.property; + var q = alternative.property; + return (p instanceof AST_Node ? p.equals(q) : p == q) + && !(consequent.expression instanceof AST_Super || alternative.expression instanceof AST_Super); + } + + function combine_tail(consequent, alternative, top) { + var seq_tail = consequent.tail_node(); + var alt_tail = alternative.tail_node(); + if (!is_tail_equivalent(seq_tail, alt_tail)) return !top && make_node(AST_Conditional, self, { + condition: condition, + consequent: consequent, + alternative: alternative, + }); + var node = seq_tail.clone(); + var seq_expr = fuse(consequent, seq_tail, "expression"); + var alt_expr = fuse(alternative, alt_tail, "expression"); + var combined = combine_tail(seq_expr, alt_expr); + if (seq_tail.expression instanceof AST_Sequence) { + combined = maintain_this_binding(seq_tail, seq_tail.expression, combined); + } + node.expression = combined; + return node; + } + + function can_shift_lhs_of_tail(node) { + return node === node.tail_node() || all(node.expressions.slice(0, -1), function(expr) { + return !expr.has_side_effects(compressor); + }); + } + + function pop_lhs(node) { + if (!(node instanceof AST_Sequence)) return node.right; + var exprs = node.expressions.slice(); + exprs.push(exprs.pop().right); + return make_sequence(node, exprs); + } + + function pop_seq(node) { + if (!(node instanceof AST_Sequence)) return make_node(AST_Number, node, { value: 0 }); + return make_sequence(node, node.expressions.slice(0, -1)); + } + }); + + OPT(AST_Boolean, function(self, compressor) { + if (!compressor.option("booleans")) return self; + if (compressor.in_boolean_context()) return make_node(AST_Number, self, { value: +self.value }); + var p = compressor.parent(); + if (p instanceof AST_Binary && (p.operator == "==" || p.operator == "!=")) { + AST_Node.warn("Non-strict equality against boolean: {operator} {value} [{start}]", { + operator: p.operator, + value: self.value, + start: p.start, + }); + return make_node(AST_Number, self, { value: +self.value }); + } + return make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: make_node(AST_Number, self, { value: 1 - self.value }), + }); + }); + + OPT(AST_Spread, function(self, compressor) { + var exp = self.expression; + if (compressor.option("spreads") && exp instanceof AST_Array && !(compressor.parent() instanceof AST_Object)) { + return List.splice(exp.elements.map(function(node) { + return node instanceof AST_Hole ? make_node(AST_Undefined, node).optimize(compressor) : node; + })); + } + return self; + }); + + function safe_to_flatten(value, compressor) { + if (!value) return false; + var parent = compressor.parent(); + if (parent.TYPE != "Call") return true; + if (parent.expression !== compressor.self()) return true; + if (value instanceof AST_SymbolRef) { + value = value.fixed_value(); + if (!value) return false; + } + return value instanceof AST_Lambda && !value.contains_this(); + } + + OPT(AST_Sub, function(self, compressor) { + var expr = self.expression; + var prop = self.property; + var terminated = trim_optional_chain(self, compressor); + if (terminated) return terminated; + if (compressor.option("properties")) { + var key = prop.evaluate(compressor); + if (key !== prop) { + if (typeof key == "string") { + if (key == "undefined") { + key = undefined; + } else { + var value = parseFloat(key); + if (value.toString() == key) { + key = value; + } + } + } + prop = self.property = best_of_expression(prop, make_node_from_constant(key, prop).transform(compressor)); + var property = "" + key; + if (is_identifier_string(property) + && property.length <= prop.print_to_string().length + 1) { + return make_node(AST_Dot, self, { + optional: self.optional, + expression: expr, + property: property, + quoted: true, + }).optimize(compressor); + } + } + } + var parent = compressor.parent(); + var assigned = is_lhs(compressor.self(), parent); + var def, fn, fn_parent, index; + if (compressor.option("arguments") + && expr instanceof AST_SymbolRef + && is_arguments(def = expr.definition()) + && !expr.in_arg + && prop instanceof AST_Number + && Math.floor(index = prop.value) == index + && (fn = def.scope) === find_lambda() + && fn.uses_arguments < (assigned ? 2 : 3)) { + if (parent instanceof AST_UnaryPrefix && parent.operator == "delete") { + if (!def.deleted) def.deleted = []; + def.deleted[index] = true; + } + var argname = fn.argnames[index]; + if (def.deleted && def.deleted[index]) { + argname = null; + } else if (argname) { + var arg_def; + if (!(argname instanceof AST_SymbolFunarg) + || argname.name == "await" + || expr.scope.find_variable(argname.name) !== (arg_def = argname.definition())) { + argname = null; + } else if (compressor.has_directive("use strict") + || fn.name + || fn.rest + || !(fn_parent instanceof AST_Call + && index < fn_parent.args.length + && all(fn_parent.args.slice(0, index + 1), function(arg) { + return !(arg instanceof AST_Spread); + })) + || !all(fn.argnames, function(argname) { + return argname instanceof AST_SymbolFunarg; + })) { + if (has_reassigned() || arg_def.assignments || arg_def.orig.length > 1) argname = null; + } + } else if ((assigned || !has_reassigned()) + && index < fn.argnames.length + 5 + && compressor.drop_fargs(fn, fn_parent) + && !fn.rest) { + while (index >= fn.argnames.length) { + argname = fn.make_var(AST_SymbolFunarg, fn, "argument_" + fn.argnames.length); + fn.argnames.push(argname); + } + } + if (argname && find_if(function(node) { + return node.name === argname.name; + }, fn.argnames) === argname) { + if (assigned) def.reassigned--; + var sym = make_node(AST_SymbolRef, argname); + sym.reference(); + argname.unused = undefined; + return sym; + } + } + if (assigned) return self; + if (compressor.option("sequences") + && parent.TYPE != "Call" + && !(parent instanceof AST_ForEnumeration && parent.init === self)) { + var seq = lift_sequence_in_expression(self, compressor); + if (seq !== self) return seq.optimize(compressor); + } + if (key !== prop) { + var sub = self.flatten_object(property, compressor); + if (sub) { + expr = self.expression = sub.expression; + prop = self.property = sub.property; + } + } + var elements; + if (compressor.option("properties") + && compressor.option("side_effects") + && prop instanceof AST_Number + && expr instanceof AST_Array + && all(elements = expr.elements, function(value) { + return !(value instanceof AST_Spread); + })) { + var index = prop.value; + var retValue = elements[index]; + if (safe_to_flatten(retValue, compressor)) { + var is_hole = retValue instanceof AST_Hole; + var flatten = !is_hole; + var values = []; + for (var i = elements.length; --i > index;) { + var value = elements[i].drop_side_effect_free(compressor); + if (value) { + values.unshift(value); + if (flatten && value.has_side_effects(compressor)) flatten = false; + } + } + if (!flatten) values.unshift(retValue); + while (--i >= 0) { + var value = elements[i].drop_side_effect_free(compressor); + if (value) { + values.unshift(value); + } else if (is_hole) { + values.unshift(make_node(AST_Hole, elements[i])); + } else { + index--; + } + } + if (flatten) { + values.push(retValue); + return make_sequence(self, values).optimize(compressor); + } + return make_node(AST_Sub, self, { + expression: make_node(AST_Array, expr, { elements: values }), + property: make_node(AST_Number, prop, { value: index }), + }); + } + } + return try_evaluate(compressor, self); + + function find_lambda() { + var i = 0, p; + while (p = compressor.parent(i++)) { + if (p instanceof AST_Lambda) { + if (p instanceof AST_Accessor) return; + if (is_arrow(p)) continue; + fn_parent = compressor.parent(i); + return p; + } + } + } + + function has_reassigned() { + return !compressor.option("reduce_vars") || def.reassigned; + } + }); + + AST_LambdaExpression.DEFMETHOD("contains_super", function() { + var result = false; + var self = this; + self.walk(new TreeWalker(function(node) { + if (result) return true; + if (node instanceof AST_Super) return result = true; + if (node !== self && node instanceof AST_Scope && !is_arrow(node)) return true; + })); + return result; + }); + + // contains_this() + // returns false only if context bound by the specified scope (or scope + // containing the specified expression) is not referenced by `this` + (function(def) { + // scope of arrow function cannot bind to any context + def(AST_Arrow, return_false); + def(AST_AsyncArrow, return_false); + def(AST_Node, function() { + var result = false; + var self = this; + self.walk(new TreeWalker(function(node) { + if (result) return true; + if (node instanceof AST_This) return result = true; + if (node !== self && node instanceof AST_Scope && !is_arrow(node)) return true; + })); + return result; + }); + })(function(node, func) { + node.DEFMETHOD("contains_this", func); + }); + + function can_hoist_property(prop) { + return prop instanceof AST_ObjectKeyVal + && typeof prop.key == "string" + && !(prop instanceof AST_ObjectMethod && prop.value.contains_super()); + } + + AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) { + if (!compressor.option("properties")) return; + if (key === "__proto__") return; + var self = this; + var expr = self.expression; + if (!(expr instanceof AST_Object)) return; + var props = expr.properties; + for (var i = props.length; --i >= 0;) { + var prop = props[i]; + if (prop.key !== key) continue; + if (!all(props, can_hoist_property)) return; + if (!safe_to_flatten(prop.value, compressor)) return; + var call, scope, values = []; + for (var j = 0; j < props.length; j++) { + var value = props[j].value; + if (props[j] instanceof AST_ObjectMethod) { + var arrow = !(value.uses_arguments || is_generator(value) || value.contains_this()); + if (arrow) { + if (!scope) scope = compressor.find_parent(AST_Scope); + var avoid = avoid_await_yield(compressor, scope); + value.each_argname(function(argname) { + if (avoid[argname.name]) arrow = false; + }); + } + var ctor; + if (arrow) { + ctor = is_async(value) ? AST_AsyncArrow : AST_Arrow; + } else if (i != j + || (call = compressor.parent()) instanceof AST_Call && call.expression === self) { + ctor = value.CTOR; + } else { + return; + } + value = make_node(ctor, value); + } + values.push(value); + } + return make_node(AST_Sub, self, { + expression: make_node(AST_Array, expr, { elements: values }), + property: make_node(AST_Number, self, { value: i }), + }); + } + }); + + OPT(AST_Dot, function(self, compressor) { + if (self.property == "arguments" || self.property == "caller") { + AST_Node.warn("Function.prototype.{property} not supported [{start}]", self); + } + var parent = compressor.parent(); + if (is_lhs(compressor.self(), parent)) return self; + var terminated = trim_optional_chain(self, compressor); + if (terminated) return terminated; + if (compressor.option("sequences") + && parent.TYPE != "Call" + && !(parent instanceof AST_ForEnumeration && parent.init === self)) { + var seq = lift_sequence_in_expression(self, compressor); + if (seq !== self) return seq.optimize(compressor); + } + if (compressor.option("unsafe_proto") + && self.expression instanceof AST_Dot + && self.expression.property == "prototype") { + var exp = self.expression.expression; + if (is_undeclared_ref(exp)) switch (exp.name) { + case "Array": + self.expression = make_node(AST_Array, self.expression, { elements: [] }); + break; + case "Function": + self.expression = make_node(AST_Function, self.expression, { + argnames: [], + body: [], + }).init_vars(exp.scope); + break; + case "Number": + self.expression = make_node(AST_Number, self.expression, { value: 0 }); + break; + case "Object": + self.expression = make_node(AST_Object, self.expression, { properties: [] }); + break; + case "RegExp": + self.expression = make_node(AST_RegExp, self.expression, { value: /t/ }); + break; + case "String": + self.expression = make_node(AST_String, self.expression, { value: "" }); + break; + } + } + var sub = self.flatten_object(self.property, compressor); + if (sub) return sub.optimize(compressor); + return try_evaluate(compressor, self); + }); + + OPT(AST_DestructuredArray, function(self, compressor) { + if (compressor.option("rests") && self.rest instanceof AST_DestructuredArray) { + return make_node(AST_DestructuredArray, self, { + elements: self.elements.concat(self.rest.elements), + rest: self.rest.rest, + }); + } + return self; + }); + + OPT(AST_DestructuredKeyVal, function(self, compressor) { + if (compressor.option("objects")) { + var key = self.key; + if (key instanceof AST_Node) { + key = key.evaluate(compressor); + if (key !== self.key) self.key = "" + key; + } + } + return self; + }); + + OPT(AST_Object, function(self, compressor) { + if (!compressor.option("objects")) return self; + var changed = false; + var found = false; + var generated = false; + var keep_duplicate = compressor.has_directive("use strict"); + var keys = []; + var map = new Dictionary(); + var values = []; + self.properties.forEach(function(prop) { + if (!(prop instanceof AST_Spread)) return process(prop); + found = true; + var exp = prop.expression; + if (compressor.option("spreads") && exp instanceof AST_Object && all(exp.properties, function(prop) { + if (prop instanceof AST_ObjectGetter) return false; + if (prop instanceof AST_Spread) return false; + if (prop.key !== "__proto__") return true; + if (prop instanceof AST_ObjectSetter) return true; + return !prop.value.has_side_effects(compressor); + })) { + changed = true; + exp.properties.forEach(function(prop) { + var key = prop.key; + var setter = prop instanceof AST_ObjectSetter; + if (key === "__proto__") { + if (!setter) return; + key = make_node_from_constant(key, prop); + } + process(setter ? make_node(AST_ObjectKeyVal, prop, { + key: key, + value: make_node(AST_Undefined, prop).optimize(compressor), + }) : prop); + }); + } else { + generated = true; + flush(); + values.push(prop); + } + }); + flush(); + if (!changed) return self; + if (found && generated && values.length == 1) { + var value = values[0]; + if (value instanceof AST_ObjectProperty && value.key instanceof AST_Number) { + value.key = "" + value.key.value; + } + } + return make_node(AST_Object, self, { properties: values }); + + function flush() { + keys.forEach(function(key) { + var props = map.get(key); + switch (props.length) { + case 0: + return; + case 1: + return values.push(props[0]); + } + changed = true; + var tail = keep_duplicate && !generated && props.pop(); + values.push(props.length == 1 ? props[0] : make_node(AST_ObjectKeyVal, self, { + key: props[0].key, + value: make_sequence(self, props.map(function(prop) { + return prop.value; + })), + })); + if (tail) values.push(tail); + props.length = 0; + }); + keys = []; + map = new Dictionary(); + } + + function process(prop) { + var key = prop.key; + if (key instanceof AST_Node) { + found = true; + key = key.evaluate(compressor); + if (key === prop.key || key === "__proto__") { + generated = true; + } else { + key = prop.key = "" + key; + } + } + if (can_hoist_property(prop)) { + if (prop.value.has_side_effects(compressor)) flush(); + keys.push(key); + map.add(key, prop); + } else { + flush(); + values.push(prop); + } + if (found && !generated && typeof key == "string" && RE_POSITIVE_INTEGER.test(key)) { + generated = true; + if (map.has(key)) prop = map.get(key)[0]; + prop.key = make_node(AST_Number, prop, { value: +key }); + } + } + }); + + function flatten_var(name) { + var redef = name.definition().redefined(); + if (redef) { + name = name.clone(); + name.thedef = redef; + } + return name; + } + + function has_arg_refs(fn, node) { + var found = false; + node.walk(new TreeWalker(function(node) { + if (found) return true; + if (node instanceof AST_SymbolRef && fn.variables.get(node.name) === node.definition()) { + return found = true; + } + })); + return found; + } + + function insert_assign(def, assign) { + var visited = []; + def.references.forEach(function(ref) { + var fixed = ref.fixed; + if (!fixed || !push_uniq(visited, fixed)) return; + if (fixed.assigns) { + fixed.assigns.unshift(assign); + } else { + fixed.assigns = [ assign ]; + } + }); + } + + function init_ref(compressor, name) { + var sym = make_node(AST_SymbolRef, name); + var assign = make_node(AST_Assign, name, { + operator: "=", + left: sym, + right: make_node(AST_Undefined, name).transform(compressor), + }); + var def = name.definition(); + if (def.fixed) { + sym.fixed = function() { + return assign.right; + }; + sym.fixed.assigns = [ assign ]; + insert_assign(def, assign); + } + def.assignments++; + def.references.push(sym); + return assign; + } + + (function(def) { + def(AST_Node, noop); + def(AST_Assign, noop); + def(AST_Await, function(compressor, scope, no_return, in_loop) { + if (!compressor.option("awaits")) return; + var self = this; + var inlined = self.expression.try_inline(compressor, scope, no_return, in_loop, true); + if (!inlined) return; + if (!no_return) scan_local_returns(inlined, function(node) { + node.in_bool = false; + var value = node.value; + if (value instanceof AST_Await) return; + node.value = make_node(AST_Await, self, { + expression: value || make_node(AST_Undefined, node).transform(compressor), + }); + }); + return aborts(inlined) ? inlined : make_node(AST_BlockStatement, self, { + body: [ inlined, make_node(AST_SimpleStatement, self, { + body: make_node(AST_Await, self, { expression: make_node(AST_Number, self, { value: 0 })}), + }) ], + }); + }); + def(AST_Binary, function(compressor, scope, no_return, in_loop, in_await) { + if (no_return === undefined) return; + var self = this; + var op = self.operator; + if (!lazy_op[op]) return; + var inlined = self.right.try_inline(compressor, scope, no_return, in_loop, in_await); + if (!inlined) return; + return make_node(AST_If, self, { + condition: make_condition(self.left), + body: inlined, + alternative: no_return ? null : make_node(AST_Return, self, { + value: make_node(AST_Undefined, self).transform(compressor), + }), + }); + + function make_condition(cond) { + switch (op) { + case "&&": + return cond; + case "||": + return cond.negate(compressor); + case "??": + return make_node(AST_Binary, self, { + operator: "==", + left: make_node(AST_Null, self), + right: cond, + }); + } + } + }); + def(AST_BlockStatement, function(compressor, scope, no_return, in_loop) { + if (no_return) return; + if (!this.variables) return; + var body = this.body; + var last = body.length - 1; + if (last < 0) return; + var inlined = body[last].try_inline(compressor, this, no_return, in_loop); + if (!inlined) return; + body[last] = inlined; + return this; + }); + def(AST_Call, function(compressor, scope, no_return, in_loop, in_await) { + if (compressor.option("inline") < 4) return; + var call = this; + if (call.is_expr_pure(compressor)) return; + var fn = call.expression; + if (!(fn instanceof AST_LambdaExpression)) return; + if (fn.name) return; + if (fn.uses_arguments) return; + if (fn.pinned()) return; + if (is_generator(fn)) return; + var arrow = is_arrow(fn); + if (arrow && fn.value) return; + if (fn.body[0] instanceof AST_Directive) return; + if (fn.contains_this()) return; + if (!scope) scope = find_scope(compressor); + var defined = new Dictionary(); + defined.set("NaN", true); + while (!(scope instanceof AST_Scope)) { + scope.variables.each(function(def) { + defined.set(def.name, true); + }); + scope = scope.parent_scope; + } + if (!member(scope, compressor.stack)) return; + if (scope.pinned() && fn.variables.size() > (arrow ? 0 : 1)) return; + if (scope instanceof AST_Toplevel) { + if (fn.variables.size() > (arrow ? 0 : 1)) { + if (!compressor.toplevel.vars) return; + if (fn.functions.size() > 0 && !compressor.toplevel.funcs) return; + } + defined.set("arguments", true); + } + var async = !in_await && is_async(fn); + if (async) { + if (!compressor.option("awaits")) return; + if (!is_async(scope)) return; + if (call.may_throw(compressor)) return; + } + var names = scope.var_names(); + if (in_loop) in_loop = []; + if (!fn.variables.all(function(def, name) { + if (in_loop) in_loop.push(def); + if (!defined.has(name) && !names.has(name)) return true; + return !arrow && name == "arguments" && def.orig.length == 1; + })) return; + if (in_loop && in_loop.length > 0 && is_reachable(fn, in_loop)) return; + var simple_argnames = true; + if (!all(fn.argnames, function(argname) { + var abort = false; + var tw = new TreeWalker(function(node) { + if (abort) return true; + if (node instanceof AST_DefaultValue) { + if (has_arg_refs(fn, node.value)) return abort = true; + node.name.walk(tw); + return true; + } + if (node instanceof AST_DestructuredKeyVal) { + if (node.key instanceof AST_Node && has_arg_refs(fn, node.key)) return abort = true; + node.value.walk(tw); + return true; + } + if (node instanceof AST_SymbolFunarg && !all(node.definition().orig, function(sym) { + return !(sym instanceof AST_SymbolDefun); + })) return abort = true; + }); + argname.walk(tw); + if (abort) return false; + if (!(argname instanceof AST_SymbolFunarg)) simple_argnames = false; + return true; + })) return; + if (fn.rest) { + if (has_arg_refs(fn, fn.rest)) return; + simple_argnames = false; + } + var verify_body; + if (no_return) { + verify_body = function(stat) { + var abort = false; + stat.walk(new TreeWalker(function(node) { + if (abort) return true; + if (async && (node instanceof AST_Await || node instanceof AST_ForAwaitOf) + || node instanceof AST_Return) { + return abort = true; + } + if (node instanceof AST_Scope) return true; + })); + return !abort; + }; + } else if (in_await || is_async(fn) || in_async_generator(scope)) { + verify_body = function(stat) { + var abort = false; + var find_return = new TreeWalker(function(node) { + if (abort) return true; + if (node instanceof AST_Return) return abort = true; + if (node instanceof AST_Scope) return true; + }); + stat.walk(new TreeWalker(function(node) { + if (abort) return true; + if (node instanceof AST_Try) { + if (node.bfinally && all(node.body, function(stat) { + stat.walk(find_return); + return !abort; + }) && node.bcatch) node.bcatch.walk(find_return); + return true; + } + if (node instanceof AST_Scope) return true; + })); + return !abort; + }; + } + if (verify_body && !all(fn.body, verify_body)) return; + if (!safe_from_await_yield(fn, avoid_await_yield(compressor, scope))) return; + fn.functions.each(function(def, name) { + scope.functions.set(name, def); + }); + var body = []; + fn.variables.each(function(def, name) { + if (!arrow && name == "arguments" && def.orig.length == 1) return; + names.set(name, true); + scope.enclosed.push(def); + scope.variables.set(name, def); + def.single_use = false; + if (!in_loop) return; + if (def.references.length == def.replaced) return; + if (def.orig.length == def.eliminated) return; + if (def.orig.length == 1 && fn.functions.has(name)) return; + if (!all(def.orig, function(sym) { + if (sym instanceof AST_SymbolConst) return false; + if (sym instanceof AST_SymbolFunarg) return !sym.unused && def.scope.resolve() !== fn; + if (sym instanceof AST_SymbolLet) return false; + return true; + })) return; + var sym = def.orig[0]; + if (sym instanceof AST_SymbolCatch) return; + body.push(make_node(AST_SimpleStatement, sym, { body: init_ref(compressor, flatten_var(sym)) })); + }); + var defs = Object.create(null), syms = new Dictionary(); + if (simple_argnames && all(call.args, function(arg) { + return !(arg instanceof AST_Spread); + })) { + var values = call.args.slice(); + fn.argnames.forEach(function(argname) { + var value = values.shift(); + if (argname.unused) { + if (value) body.push(make_node(AST_SimpleStatement, call, { body: value })); + return; + } + var defn = make_node(AST_VarDef, call, { + name: argname.convert_symbol(AST_SymbolVar, process), + value: value || make_node(AST_Undefined, call).transform(compressor), + }); + if (argname instanceof AST_SymbolFunarg) insert_assign(argname.definition(), defn); + body.push(make_node(AST_Var, call, { definitions: [ defn ] })); + }); + if (values.length) body.push(make_node(AST_SimpleStatement, call, { + body: make_sequence(call, values), + })); + } else { + body.push(make_node(AST_Var, call, { + definitions: [ make_node(AST_VarDef, call, { + name: make_node(AST_DestructuredArray, call, { + elements: fn.argnames.map(function(argname) { + if (argname.unused) return make_node(AST_Hole, argname); + return argname.convert_symbol(AST_SymbolVar, process); + }), + rest: fn.rest && fn.rest.convert_symbol(AST_SymbolVar, process), + }), + value: make_node(AST_Array, call, { elements: call.args.slice() }), + }) ], + })); + } + syms.each(function(orig, id) { + var def = defs[id]; + [].unshift.apply(def.orig, orig); + def.eliminated += orig.length; + }); + [].push.apply(body, in_loop ? fn.body.filter(function(stat) { + if (!(stat instanceof AST_LambdaDefinition)) return true; + var name = make_node(AST_SymbolVar, flatten_var(stat.name)); + var def = name.definition(); + def.fixed = false; + def.orig.push(name); + def.eliminated++; + body.push(make_node(AST_Var, stat, { + definitions: [ make_node(AST_VarDef, stat, { + name: name, + value: to_func_expr(stat, true), + }) ], + })); + return false; + }) : fn.body); + var inlined = make_node(AST_BlockStatement, call, { body: body }); + if (!no_return) { + if (async) scan_local_returns(inlined, function(node) { + var value = node.value; + if (is_undefined(value)) return; + node.value = make_node(AST_Await, call, { expression: value }); + }); + body.push(make_node(AST_Return, call, { + value: in_async_generator(scope) ? make_node(AST_Undefined, call).transform(compressor) : null, + })); + } + return inlined; + + function process(sym, argname) { + var def = argname.definition(); + defs[def.id] = def; + syms.add(def.id, sym); + } + }); + def(AST_Conditional, function(compressor, scope, no_return, in_loop, in_await) { + var self = this; + var body = self.consequent.try_inline(compressor, scope, no_return, in_loop, in_await); + var alt = self.alternative.try_inline(compressor, scope, no_return, in_loop, in_await); + if (!body && !alt) return; + return make_node(AST_If, self, { + condition: self.condition, + body: body || make_body(self.consequent), + alternative: alt || make_body(self.alternative), + }); + + function make_body(value) { + if (no_return) return make_node(AST_SimpleStatement, value, { body: value }); + return make_node(AST_Return, value, { value: value }); + } + }); + def(AST_For, function(compressor, scope, no_return, in_loop) { + var body = this.body.try_inline(compressor, scope, true, true); + if (body) this.body = body; + var inlined = this.init; + if (inlined) { + inlined = inlined.try_inline(compressor, scope, true, in_loop); + if (inlined) { + this.init = null; + if (inlined instanceof AST_BlockStatement) { + inlined.body.push(this); + return inlined; + } + return make_node(AST_BlockStatement, inlined, { body: [ inlined, this ] }); + } + } + return body && this; + }); + def(AST_ForEnumeration, function(compressor, scope, no_return, in_loop) { + var body = this.body.try_inline(compressor, scope, true, true); + if (body) this.body = body; + var obj = this.object; + if (obj instanceof AST_Sequence) { + var inlined = inline_sequence(compressor, scope, true, in_loop, false, obj, 1); + if (inlined) { + this.object = obj.tail_node(); + inlined.body.push(this); + return inlined; + } + } + return body && this; + }); + def(AST_If, function(compressor, scope, no_return, in_loop) { + var body = this.body.try_inline(compressor, scope, no_return, in_loop); + if (body) this.body = body; + var alt = this.alternative; + if (alt) { + alt = alt.try_inline(compressor, scope, no_return, in_loop); + if (alt) this.alternative = alt; + } + var cond = this.condition; + if (cond instanceof AST_Sequence) { + var inlined = inline_sequence(compressor, scope, true, in_loop, false, cond, 1); + if (inlined) { + this.condition = cond.tail_node(); + inlined.body.push(this); + return inlined; + } + } + return (body || alt) && this; + }); + def(AST_IterationStatement, function(compressor, scope, no_return, in_loop) { + var body = this.body.try_inline(compressor, scope, true, true); + if (!body) return; + this.body = body; + return this; + }); + def(AST_LabeledStatement, function(compressor, scope, no_return, in_loop) { + var body = this.body.try_inline(compressor, scope, no_return, in_loop); + if (!body) return; + if (this.body instanceof AST_IterationStatement && body instanceof AST_BlockStatement) { + var loop = body.body.pop(); + this.body = loop; + body.body.push(this); + return body; + } + this.body = body; + return this; + }); + def(AST_New, noop); + def(AST_Return, function(compressor, scope, no_return, in_loop) { + var value = this.value; + return value && value.try_inline(compressor, scope, undefined, in_loop === "try"); + }); + function inline_sequence(compressor, scope, no_return, in_loop, in_await, node, skip) { + var body = [], exprs = node.expressions, no_ret = no_return; + for (var i = exprs.length - (skip || 0), j = i; --i >= 0; no_ret = true, in_await = false) { + var inlined = exprs[i].try_inline(compressor, scope, no_ret, in_loop, in_await); + if (!inlined) continue; + flush(); + body.push(inlined); + } + if (body.length == 0) return; + flush(); + if (!no_return && body[0] instanceof AST_SimpleStatement) { + body[0] = make_node(AST_Return, node, { value: body[0].body }); + } + return make_node(AST_BlockStatement, node, { body: body.reverse() }); + + function flush() { + if (j > i + 1) body.push(make_node(AST_SimpleStatement, node, { + body: make_sequence(node, exprs.slice(i + 1, j)), + })); + j = i; + } + } + def(AST_Sequence, function(compressor, scope, no_return, in_loop, in_await) { + return inline_sequence(compressor, scope, no_return, in_loop, in_await, this); + }); + def(AST_SimpleStatement, function(compressor, scope, no_return, in_loop) { + var body = this.body; + while (body instanceof AST_UnaryPrefix) { + var op = body.operator; + if (unary_side_effects[op]) break; + if (op == "void") break; + body = body.expression; + } + if (!no_return && !is_undefined(body)) body = make_node(AST_UnaryPrefix, this, { + operator: "void", + expression: body, + }); + return body.try_inline(compressor, scope, no_return || false, in_loop); + }); + def(AST_UnaryPrefix, function(compressor, scope, no_return, in_loop, in_await) { + var self = this; + var op = self.operator; + if (unary_side_effects[op]) return; + if (!no_return && op == "void") no_return = false; + var inlined = self.expression.try_inline(compressor, scope, no_return, in_loop, in_await); + if (!inlined) return; + if (!no_return) scan_local_returns(inlined, function(node) { + node.in_bool = false; + var value = node.value; + if (op == "void" && is_undefined(value)) return; + node.value = make_node(AST_UnaryPrefix, self, { + operator: op, + expression: value || make_node(AST_Undefined, node).transform(compressor), + }); + }); + return inlined; + }); + def(AST_With, function(compressor, scope, no_return, in_loop) { + var body = this.body.try_inline(compressor, scope, no_return, in_loop); + if (body) this.body = body; + var exp = this.expression; + if (exp instanceof AST_Sequence) { + var inlined = inline_sequence(compressor, scope, true, in_loop, false, exp, 1); + if (inlined) { + this.expression = exp.tail_node(); + inlined.body.push(this); + return inlined; + } + } + return body && this; + }); + def(AST_Yield, function(compressor, scope, no_return, in_loop) { + if (!compressor.option("yields")) return; + if (!this.nested) return; + var call = this.expression; + if (call.TYPE != "Call") return; + var fn = call.expression; + switch (fn.CTOR) { + case AST_AsyncGeneratorFunction: + fn = make_node(AST_AsyncFunction, fn); + break; + case AST_GeneratorFunction: + fn = make_node(AST_Function, fn); + break; + default: + return; + } + call = call.clone(); + call.expression = fn; + return call.try_inline(compressor, scope, no_return, in_loop); + }); + })(function(node, func) { + node.DEFMETHOD("try_inline", func); + }); + + OPT(AST_Return, function(self, compressor) { + var value = self.value; + if (value && compressor.option("side_effects") + && is_undefined(value, compressor) + && !in_async_generator(compressor.find_parent(AST_Scope))) { + self.value = null; + } + return self; + }); +})(function(node, optimizer) { + node.DEFMETHOD("optimize", function(compressor) { + var self = this; + if (self._optimized) return self; + if (compressor.has_directive("use asm")) return self; + var opt = optimizer(self, compressor); + opt._optimized = true; + return opt; + }); +}); diff --git a/libs/events/node_modules/uglify-js/lib/minify.js b/libs/events/node_modules/uglify-js/lib/minify.js new file mode 100644 index 000000000..c7a1341ca --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/minify.js @@ -0,0 +1,276 @@ +"use strict"; + +var to_ascii, to_base64; +if (typeof Buffer == "undefined") { + to_ascii = atob; + to_base64 = btoa; +} else if (typeof Buffer.alloc == "undefined") { + to_ascii = function(b64) { + return new Buffer(b64, "base64").toString(); + }; + to_base64 = function(str) { + return new Buffer(str).toString("base64"); + }; +} else { + to_ascii = function(b64) { + return Buffer.from(b64, "base64").toString(); + }; + to_base64 = function(str) { + return Buffer.from(str).toString("base64"); + }; +} + +function read_source_map(name, toplevel) { + var comments = toplevel.end.comments_after; + for (var i = comments.length; --i >= 0;) { + var comment = comments[i]; + if (comment.type != "comment1") break; + var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value); + if (!match) break; + if (match[1] == "sourceMappingURL") { + match = /^data:application\/json(;.*?)?;base64,([^,]+)$/.exec(match[2]); + if (!match) break; + return to_ascii(match[2]); + } + } + AST_Node.warn("inline source map not found: {name}", { + name: name, + }); +} + +function parse_source_map(content) { + try { + return JSON.parse(content); + } catch (ex) { + throw new Error("invalid input source map: " + content); + } +} + +function set_shorthand(name, options, keys) { + keys.forEach(function(key) { + if (options[key]) { + if (typeof options[key] != "object") options[key] = {}; + if (!(name in options[key])) options[key][name] = options[name]; + } + }); +} + +function init_cache(cache) { + if (!cache) return; + if (!("props" in cache)) { + cache.props = new Dictionary(); + } else if (!(cache.props instanceof Dictionary)) { + cache.props = Dictionary.fromObject(cache.props); + } +} + +function to_json(cache) { + return { + props: cache.props.toObject() + }; +} + +function minify(files, options) { + try { + options = defaults(options, { + annotations: undefined, + compress: {}, + enclose: false, + expression: false, + ie: false, + ie8: false, + keep_fargs: false, + keep_fnames: false, + mangle: {}, + module: false, + nameCache: null, + output: {}, + parse: {}, + rename: undefined, + sourceMap: false, + timings: false, + toplevel: !!(options && options["module"]), + v8: false, + validate: false, + warnings: false, + webkit: false, + wrap: false, + }, true); + if (options.validate) AST_Node.enable_validation(); + var timings = options.timings && { start: Date.now() }; + if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]); + if (options.expression) set_shorthand("expression", options, [ "compress", "parse" ]); + if (options.ie8) options.ie = options.ie || options.ie8; + if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output", "rename" ]); + if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle", "rename" ]); + if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle", "rename" ]); + if (options.module) set_shorthand("module", options, [ "compress", "parse" ]); + if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle", "rename" ]); + if (options.v8) set_shorthand("v8", options, [ "mangle", "output", "rename" ]); + if (options.webkit) set_shorthand("webkit", options, [ "compress", "mangle", "output", "rename" ]); + var quoted_props; + if (options.mangle) { + options.mangle = defaults(options.mangle, { + cache: options.nameCache && (options.nameCache.vars || {}), + eval: false, + ie: false, + keep_fargs: false, + keep_fnames: false, + properties: false, + reserved: [], + toplevel: false, + v8: false, + webkit: false, + }, true); + if (options.mangle.properties) { + if (typeof options.mangle.properties != "object") { + options.mangle.properties = {}; + } + if (options.mangle.properties.keep_quoted) { + quoted_props = options.mangle.properties.reserved; + if (!Array.isArray(quoted_props)) quoted_props = []; + options.mangle.properties.reserved = quoted_props; + } + if (options.nameCache && !("cache" in options.mangle.properties)) { + options.mangle.properties.cache = options.nameCache.props || {}; + } + } + init_cache(options.mangle.cache); + init_cache(options.mangle.properties.cache); + } + if (options.rename === undefined) options.rename = options.compress && options.mangle; + if (options.sourceMap) { + options.sourceMap = defaults(options.sourceMap, { + content: null, + filename: null, + includeSources: false, + names: true, + root: null, + url: null, + }, true); + } + var warnings = []; + if (options.warnings) AST_Node.log_function(function(warning) { + warnings.push(warning); + }, options.warnings == "verbose"); + if (timings) timings.parse = Date.now(); + var toplevel; + options.parse = options.parse || {}; + if (files instanceof AST_Node) { + toplevel = files; + } else { + if (typeof files == "string") files = [ files ]; + options.parse.toplevel = null; + var source_map_content = options.sourceMap && options.sourceMap.content; + if (typeof source_map_content == "string" && source_map_content != "inline") { + source_map_content = parse_source_map(source_map_content); + } + if (source_map_content) options.sourceMap.orig = Object.create(null); + for (var name in files) if (HOP(files, name)) { + options.parse.filename = name; + options.parse.toplevel = toplevel = parse(files[name], options.parse); + if (source_map_content == "inline") { + var inlined_content = read_source_map(name, toplevel); + if (inlined_content) options.sourceMap.orig[name] = parse_source_map(inlined_content); + } else if (source_map_content) { + options.sourceMap.orig[name] = source_map_content; + } + } + } + if (options.parse.expression) toplevel = toplevel.wrap_expression(); + if (quoted_props) reserve_quoted_keys(toplevel, quoted_props); + [ "enclose", "wrap" ].forEach(function(action) { + var option = options[action]; + if (!option) return; + var orig = toplevel.print_to_string().slice(0, -1); + toplevel = toplevel[action](option); + files[toplevel.start.file] = toplevel.print_to_string().replace(orig, ""); + }); + if (options.validate) toplevel.validate_ast(); + if (timings) timings.rename = Date.now(); + if (options.rename) { + toplevel.figure_out_scope(options.rename); + toplevel.expand_names(options.rename); + } + if (timings) timings.compress = Date.now(); + if (options.compress) { + toplevel = new Compressor(options.compress).compress(toplevel); + if (options.validate) toplevel.validate_ast(); + } + if (timings) timings.scope = Date.now(); + if (options.mangle) toplevel.figure_out_scope(options.mangle); + if (timings) timings.mangle = Date.now(); + if (options.mangle) { + toplevel.compute_char_frequency(options.mangle); + toplevel.mangle_names(options.mangle); + } + if (timings) timings.properties = Date.now(); + if (quoted_props) reserve_quoted_keys(toplevel, quoted_props); + if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties); + if (options.parse.expression) toplevel = toplevel.unwrap_expression(); + if (timings) timings.output = Date.now(); + var result = {}; + var output = defaults(options.output, { + ast: false, + code: true, + }); + if (output.ast) result.ast = toplevel; + if (output.code) { + if (options.sourceMap) { + output.source_map = SourceMap(options.sourceMap); + if (options.sourceMap.includeSources) { + if (files instanceof AST_Toplevel) { + throw new Error("original source content unavailable"); + } else for (var name in files) if (HOP(files, name)) { + output.source_map.setSourceContent(name, files[name]); + } + } + } + delete output.ast; + delete output.code; + var stream = OutputStream(output); + toplevel.print(stream); + result.code = stream.get(); + if (options.sourceMap) { + result.map = output.source_map.toString(); + var url = options.sourceMap.url; + if (url) { + result.code = result.code.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, ""); + if (url == "inline") { + result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map); + } else { + result.code += "\n//# sourceMappingURL=" + url; + } + } + } + } + if (options.nameCache && options.mangle) { + if (options.mangle.cache) options.nameCache.vars = to_json(options.mangle.cache); + if (options.mangle.properties && options.mangle.properties.cache) { + options.nameCache.props = to_json(options.mangle.properties.cache); + } + } + if (timings) { + timings.end = Date.now(); + result.timings = { + parse: 1e-3 * (timings.rename - timings.parse), + rename: 1e-3 * (timings.compress - timings.rename), + compress: 1e-3 * (timings.scope - timings.compress), + scope: 1e-3 * (timings.mangle - timings.scope), + mangle: 1e-3 * (timings.properties - timings.mangle), + properties: 1e-3 * (timings.output - timings.properties), + output: 1e-3 * (timings.end - timings.output), + total: 1e-3 * (timings.end - timings.start) + }; + } + if (warnings.length) { + result.warnings = warnings; + } + return result; + } catch (ex) { + return { error: ex }; + } finally { + AST_Node.log_function(); + AST_Node.disable_validation(); + } +} diff --git a/libs/events/node_modules/uglify-js/lib/mozilla-ast.js b/libs/events/node_modules/uglify-js/lib/mozilla-ast.js new file mode 100644 index 000000000..3e0534c8d --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/mozilla-ast.js @@ -0,0 +1,1310 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +(function() { + var MOZ_TO_ME = { + Program: function(M) { + return new AST_Toplevel({ + start: my_start_token(M), + end: my_end_token(M), + body: normalize_directives(M.body.map(from_moz)), + }); + }, + ArrowFunctionExpression: function(M) { + var argnames = [], rest = null; + M.params.forEach(function(param) { + if (param.type == "RestElement") { + rest = from_moz(param.argument); + } else { + argnames.push(from_moz(param)); + } + }); + var fn = new (M.async ? AST_AsyncArrow : AST_Arrow)({ + start: my_start_token(M), + end: my_end_token(M), + argnames: argnames, + rest: rest, + }); + var node = from_moz(M.body); + if (node instanceof AST_BlockStatement) { + fn.body = normalize_directives(node.body); + fn.value = null; + } else { + fn.body = []; + fn.value = node; + } + return fn; + }, + FunctionDeclaration: function(M) { + var ctor; + if (M.async) { + ctor = M.generator ? AST_AsyncGeneratorDefun : AST_AsyncDefun; + } else { + ctor = M.generator ? AST_GeneratorDefun : AST_Defun; + } + var argnames = [], rest = null; + M.params.forEach(function(param) { + if (param.type == "RestElement") { + rest = from_moz(param.argument); + } else { + argnames.push(from_moz(param)); + } + }); + return new ctor({ + start: my_start_token(M), + end: my_end_token(M), + name: from_moz(M.id), + argnames: argnames, + rest: rest, + body: normalize_directives(from_moz(M.body).body), + }); + }, + FunctionExpression: function(M) { + var ctor; + if (M.async) { + ctor = M.generator ? AST_AsyncGeneratorFunction : AST_AsyncFunction; + } else { + ctor = M.generator ? AST_GeneratorFunction : AST_Function; + } + var argnames = [], rest = null; + M.params.forEach(function(param) { + if (param.type == "RestElement") { + rest = from_moz(param.argument); + } else { + argnames.push(from_moz(param)); + } + }); + return new ctor({ + start: my_start_token(M), + end: my_end_token(M), + name: from_moz(M.id), + argnames: argnames, + rest: rest, + body: normalize_directives(from_moz(M.body).body), + }); + }, + ClassDeclaration: function(M) { + return new AST_DefClass({ + start: my_start_token(M), + end: my_end_token(M), + name: from_moz(M.id), + extends: from_moz(M.superClass), + properties: M.body.body.map(from_moz), + }); + }, + ClassExpression: function(M) { + return new AST_ClassExpression({ + start: my_start_token(M), + end: my_end_token(M), + name: from_moz(M.id), + extends: from_moz(M.superClass), + properties: M.body.body.map(from_moz), + }); + }, + MethodDefinition: function(M) { + var key = M.key, internal = false; + if (M.computed) { + key = from_moz(key); + } else if (key.type == "PrivateIdentifier") { + internal = true; + key = "#" + key.name; + } else { + key = read_name(key); + } + var ctor = AST_ClassMethod, value = from_moz(M.value); + switch (M.kind) { + case "get": + ctor = AST_ClassGetter; + value = new AST_Accessor(value); + break; + case "set": + ctor = AST_ClassSetter; + value = new AST_Accessor(value); + break; + } + return new ctor({ + start: my_start_token(M), + end: my_end_token(M), + key: key, + private: internal, + static: M.static, + value: value, + }); + }, + PropertyDefinition: function(M) { + var key = M.key, internal = false; + if (M.computed) { + key = from_moz(key); + } else if (key.type == "PrivateIdentifier") { + internal = true; + key = "#" + key.name; + } else { + key = read_name(key); + } + return new AST_ClassField({ + start: my_start_token(M), + end: my_end_token(M), + key: key, + private: internal, + static: M.static, + value: from_moz(M.value), + }); + }, + StaticBlock: function(M) { + var start = my_start_token(M); + var end = my_end_token(M); + return new AST_ClassInit({ + start: start, + end: end, + value: new AST_ClassInitBlock({ + start: start, + end: end, + body: normalize_directives(M.body.map(from_moz)), + }), + }); + }, + ForOfStatement: function(M) { + return new (M.await ? AST_ForAwaitOf : AST_ForOf)({ + start: my_start_token(M), + end: my_end_token(M), + init: from_moz(M.left), + object: from_moz(M.right), + body: from_moz(M.body), + }); + }, + TryStatement: function(M) { + var handlers = M.handlers || [M.handler]; + if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) { + throw new Error("Multiple catch clauses are not supported."); + } + return new AST_Try({ + start : my_start_token(M), + end : my_end_token(M), + body : from_moz(M.block).body, + bcatch : from_moz(handlers[0]), + bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null, + }); + }, + Property: function(M) { + var key = M.computed ? from_moz(M.key) : read_name(M.key); + var args = { + start: my_start_token(M), + end: my_end_token(M), + key: key, + value: from_moz(M.value), + }; + if (M.kind == "init") return new (M.method ? AST_ObjectMethod : AST_ObjectKeyVal)(args); + args.value = new AST_Accessor(args.value); + if (M.kind == "get") return new AST_ObjectGetter(args); + if (M.kind == "set") return new AST_ObjectSetter(args); + }, + ArrayExpression: function(M) { + return new AST_Array({ + start: my_start_token(M), + end: my_end_token(M), + elements: M.elements.map(function(elem) { + return elem === null ? new AST_Hole() : from_moz(elem); + }), + }); + }, + ArrayPattern: function(M) { + var elements = [], rest = null; + M.elements.forEach(function(el) { + if (el === null) { + elements.push(new AST_Hole()); + } else if (el.type == "RestElement") { + rest = from_moz(el.argument); + } else { + elements.push(from_moz(el)); + } + }); + return new AST_DestructuredArray({ + start: my_start_token(M), + end: my_end_token(M), + elements: elements, + rest: rest, + }); + }, + ObjectPattern: function(M) { + var props = [], rest = null; + M.properties.forEach(function(prop) { + if (prop.type == "RestElement") { + rest = from_moz(prop.argument); + } else { + props.push(new AST_DestructuredKeyVal(from_moz(prop))); + } + }); + return new AST_DestructuredObject({ + start: my_start_token(M), + end: my_end_token(M), + properties: props, + rest: rest, + }); + }, + MemberExpression: function(M) { + return new (M.computed ? AST_Sub : AST_Dot)({ + start: my_start_token(M), + end: my_end_token(M), + optional: M.optional, + expression: from_moz(M.object), + property: M.computed ? from_moz(M.property) : M.property.name, + }); + }, + MetaProperty: function(M) { + var expr = from_moz(M.meta); + var prop = read_name(M.property); + if (expr.name == "new" && prop == "target") return new AST_NewTarget({ + start: my_start_token(M), + end: my_end_token(M), + name: "new.target", + }); + return new AST_Dot({ + start: my_start_token(M), + end: my_end_token(M), + expression: expr, + property: prop, + }); + }, + SwitchCase: function(M) { + return new (M.test ? AST_Case : AST_Default)({ + start : my_start_token(M), + end : my_end_token(M), + expression : from_moz(M.test), + body : M.consequent.map(from_moz), + }); + }, + ExportAllDeclaration: function(M) { + var start = my_start_token(M); + var end = my_end_token(M); + return new AST_ExportForeign({ + start: start, + end: end, + aliases: [ M.exported ? from_moz_alias(M.exported) : new AST_String({ + start: start, + value: "*", + end: end, + }) ], + keys: [ new AST_String({ + start: start, + value: "*", + end: end, + }) ], + path: from_moz(M.source), + }); + }, + ExportDefaultDeclaration: function(M) { + var decl = from_moz(M.declaration); + if (!decl.name) switch (decl.CTOR) { + case AST_AsyncDefun: + decl = new AST_AsyncFunction(decl); + break; + case AST_AsyncGeneratorDefun: + decl = new AST_AsyncGeneratorFunction(decl); + break; + case AST_DefClass: + decl = new AST_ClassExpression(decl); + break; + case AST_Defun: + decl = new AST_Function(decl); + break; + case AST_GeneratorDefun: + decl = new AST_GeneratorFunction(decl); + break; + } + return new AST_ExportDefault({ + start: my_start_token(M), + end: my_end_token(M), + body: decl, + }); + }, + ExportNamedDeclaration: function(M) { + if (M.declaration) return new AST_ExportDeclaration({ + start: my_start_token(M), + end: my_end_token(M), + body: from_moz(M.declaration), + }); + if (M.source) { + var aliases = [], keys = []; + M.specifiers.forEach(function(prop) { + aliases.push(from_moz_alias(prop.exported)); + keys.push(from_moz_alias(prop.local)); + }); + return new AST_ExportForeign({ + start: my_start_token(M), + end: my_end_token(M), + aliases: aliases, + keys: keys, + path: from_moz(M.source), + }); + } + return new AST_ExportReferences({ + start: my_start_token(M), + end: my_end_token(M), + properties: M.specifiers.map(function(prop) { + var sym = new AST_SymbolExport(from_moz(prop.local)); + sym.alias = from_moz_alias(prop.exported); + return sym; + }), + }); + }, + ImportDeclaration: function(M) { + var start = my_start_token(M); + var end = my_end_token(M); + var all = null, def = null, props = null; + M.specifiers.forEach(function(prop) { + var sym = new AST_SymbolImport(from_moz(prop.local)); + switch (prop.type) { + case "ImportDefaultSpecifier": + def = sym; + def.key = new AST_String({ + start: start, + value: "", + end: end, + }); + break; + case "ImportNamespaceSpecifier": + all = sym; + all.key = new AST_String({ + start: start, + value: "*", + end: end, + }); + break; + default: + sym.key = from_moz_alias(prop.imported); + if (!props) props = []; + props.push(sym); + break; + } + }); + return new AST_Import({ + start: start, + end: end, + all: all, + default: def, + properties: props, + path: from_moz(M.source), + }); + }, + ImportExpression: function(M) { + var start = my_start_token(M); + var arg = from_moz(M.source); + return new AST_Call({ + start: start, + end: my_end_token(M), + expression: new AST_SymbolRef({ + start: start, + end: arg.start, + name: "import", + }), + args: [ arg ], + }); + }, + VariableDeclaration: function(M) { + return new ({ + const: AST_Const, + let: AST_Let, + }[M.kind] || AST_Var)({ + start: my_start_token(M), + end: my_end_token(M), + definitions: M.declarations.map(from_moz), + }); + }, + Literal: function(M) { + var args = { + start: my_start_token(M), + end: my_end_token(M), + }; + if (M.bigint) { + args.value = M.bigint.toLowerCase() + "n"; + return new AST_BigInt(args); + } + var val = M.value; + if (val === null) return new AST_Null(args); + var rx = M.regex; + if (rx && rx.pattern) { + // RegExpLiteral as per ESTree AST spec + args.value = new RegExp(rx.pattern, rx.flags); + args.value.raw_source = rx.pattern; + return new AST_RegExp(args); + } else if (rx) { + // support legacy RegExp + args.value = M.regex && M.raw ? M.raw : val; + return new AST_RegExp(args); + } + switch (typeof val) { + case "string": + args.value = val; + return new AST_String(args); + case "number": + if (isNaN(val)) return new AST_NaN(args); + var negate, node; + if (isFinite(val)) { + negate = 1 / val < 0; + args.value = negate ? -val : val; + node = new AST_Number(args); + } else { + negate = val < 0; + node = new AST_Infinity(args); + } + return negate ? new AST_UnaryPrefix({ + start: args.start, + end: args.end, + operator: "-", + expression: node, + }) : node; + case "boolean": + return new (val ? AST_True : AST_False)(args); + } + }, + TemplateLiteral: function(M) { + return new AST_Template({ + start: my_start_token(M), + end: my_end_token(M), + expressions: M.expressions.map(from_moz), + strings: M.quasis.map(function(el) { + return el.value.raw; + }), + }); + }, + TaggedTemplateExpression: function(M) { + var tmpl = from_moz(M.quasi); + tmpl.start = my_start_token(M); + tmpl.end = my_end_token(M); + tmpl.tag = from_moz(M.tag); + return tmpl; + }, + Identifier: function(M) { + var p, level = FROM_MOZ_STACK.length - 1; + do { + p = FROM_MOZ_STACK[--level]; + } while (p.type == "ArrayPattern" + || p.type == "AssignmentPattern" && p.left === FROM_MOZ_STACK[level + 1] + || p.type == "ObjectPattern" + || p.type == "Property" && p.value === FROM_MOZ_STACK[level + 1] + || p.type == "VariableDeclarator" && p.id === FROM_MOZ_STACK[level + 1]); + var ctor = AST_SymbolRef; + switch (p.type) { + case "ArrowFunctionExpression": + if (p.body !== FROM_MOZ_STACK[level + 1]) ctor = AST_SymbolFunarg; + break; + case "BreakStatement": + case "ContinueStatement": + ctor = AST_LabelRef; + break; + case "CatchClause": + ctor = AST_SymbolCatch; + break; + case "ClassDeclaration": + if (p.id === FROM_MOZ_STACK[level + 1]) ctor = AST_SymbolDefClass; + break; + case "ClassExpression": + if (p.id === FROM_MOZ_STACK[level + 1]) ctor = AST_SymbolClass; + break; + case "FunctionDeclaration": + ctor = p.id === FROM_MOZ_STACK[level + 1] ? AST_SymbolDefun : AST_SymbolFunarg; + break; + case "FunctionExpression": + ctor = p.id === FROM_MOZ_STACK[level + 1] ? AST_SymbolLambda : AST_SymbolFunarg; + break; + case "LabeledStatement": + ctor = AST_Label; + break; + case "VariableDeclaration": + ctor = { + const: AST_SymbolConst, + let: AST_SymbolLet, + }[p.kind] || AST_SymbolVar; + break; + } + return new ctor({ + start: my_start_token(M), + end: my_end_token(M), + name: M.name, + }); + }, + Super: function(M) { + return new AST_Super({ + start: my_start_token(M), + end: my_end_token(M), + name: "super", + }); + }, + ThisExpression: function(M) { + return new AST_This({ + start: my_start_token(M), + end: my_end_token(M), + name: "this", + }); + }, + ParenthesizedExpression: function(M) { + var node = from_moz(M.expression); + if (!node.start.parens) node.start.parens = []; + node.start.parens.push(my_start_token(M)); + if (!node.end.parens) node.end.parens = []; + node.end.parens.push(my_end_token(M)); + return node; + }, + ChainExpression: function(M) { + var node = from_moz(M.expression); + node.terminal = true; + return node; + }, + }; + + MOZ_TO_ME.UpdateExpression = + MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) { + var prefix = "prefix" in M ? M.prefix + : M.type == "UnaryExpression" ? true : false; + return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({ + start : my_start_token(M), + end : my_end_token(M), + operator : M.operator, + expression : from_moz(M.argument) + }); + }; + + map("EmptyStatement", AST_EmptyStatement); + map("ExpressionStatement", AST_SimpleStatement, "expression>body"); + map("BlockStatement", AST_BlockStatement, "body@body"); + map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative"); + map("LabeledStatement", AST_LabeledStatement, "label>label, body>body"); + map("BreakStatement", AST_Break, "label>label"); + map("ContinueStatement", AST_Continue, "label>label"); + map("WithStatement", AST_With, "object>expression, body>body"); + map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body"); + map("ReturnStatement", AST_Return, "argument>value"); + map("ThrowStatement", AST_Throw, "argument>value"); + map("WhileStatement", AST_While, "test>condition, body>body"); + map("DoWhileStatement", AST_Do, "test>condition, body>body"); + map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body"); + map("ForInStatement", AST_ForIn, "left>init, right>object, body>body"); + map("DebuggerStatement", AST_Debugger); + map("VariableDeclarator", AST_VarDef, "id>name, init>value"); + map("CatchClause", AST_Catch, "param>argname, body%body"); + + map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right"); + map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right"); + map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right"); + map("AssignmentPattern", AST_DefaultValue, "left>name, right>value"); + map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative"); + map("NewExpression", AST_New, "callee>expression, arguments@args, pure=pure"); + map("CallExpression", AST_Call, "callee>expression, arguments@args, optional=optional, pure=pure"); + map("SequenceExpression", AST_Sequence, "expressions@expressions"); + map("SpreadElement", AST_Spread, "argument>expression"); + map("ObjectExpression", AST_Object, "properties@properties"); + map("AwaitExpression", AST_Await, "argument>expression"); + map("YieldExpression", AST_Yield, "argument>expression, delegate=nested"); + + def_to_moz(AST_Toplevel, function To_Moz_Program(M) { + return to_moz_scope("Program", M); + }); + + def_to_moz(AST_LambdaDefinition, function To_Moz_FunctionDeclaration(M) { + var params = M.argnames.map(to_moz); + if (M.rest) params.push({ + type: "RestElement", + argument: to_moz(M.rest), + }); + return { + type: "FunctionDeclaration", + id: to_moz(M.name), + async: is_async(M), + generator: is_generator(M), + params: params, + body: to_moz_scope("BlockStatement", M), + }; + }); + + def_to_moz(AST_Lambda, function To_Moz_FunctionExpression(M) { + var params = M.argnames.map(to_moz); + if (M.rest) params.push({ + type: "RestElement", + argument: to_moz(M.rest), + }); + if (is_arrow(M)) return { + type: "ArrowFunctionExpression", + async: is_async(M), + params: params, + body: M.value ? to_moz(M.value) : to_moz_scope("BlockStatement", M), + }; + return { + type: "FunctionExpression", + id: to_moz(M.name), + async: is_async(M), + generator: is_generator(M), + params: params, + body: to_moz_scope("BlockStatement", M), + }; + }); + + def_to_moz(AST_DefClass, function To_Moz_ClassDeclaration(M) { + return { + type: "ClassDeclaration", + id: to_moz(M.name), + superClass: to_moz(M.extends), + body: { + type: "ClassBody", + body: M.properties.map(to_moz), + }, + }; + }); + + def_to_moz(AST_ClassExpression, function To_Moz_ClassExpression(M) { + return { + type: "ClassExpression", + id: to_moz(M.name), + superClass: to_moz(M.extends), + body: { + type: "ClassBody", + body: M.properties.map(to_moz), + }, + }; + }); + + function To_Moz_MethodDefinition(kind) { + return function(M) { + var computed = M.key instanceof AST_Node; + var key = computed ? to_moz(M.key) : M.private ? { + type: "PrivateIdentifier", + name: M.key.slice(1), + } : { + type: "Literal", + value: M.key, + }; + return { + type: "MethodDefinition", + kind: kind, + computed: computed, + key: key, + static: M.static, + value: to_moz(M.value), + }; + }; + } + def_to_moz(AST_ClassGetter, To_Moz_MethodDefinition("get")); + def_to_moz(AST_ClassSetter, To_Moz_MethodDefinition("set")); + def_to_moz(AST_ClassMethod, To_Moz_MethodDefinition("method")); + + def_to_moz(AST_ClassField, function To_Moz_PropertyDefinition(M) { + var computed = M.key instanceof AST_Node; + var key = computed ? to_moz(M.key) : M.private ? { + type: "PrivateIdentifier", + name: M.key.slice(1), + } : { + type: "Literal", + value: M.key, + }; + return { + type: "PropertyDefinition", + computed: computed, + key: key, + static: M.static, + value: to_moz(M.value), + }; + }); + + def_to_moz(AST_ClassInit, function To_Moz_StaticBlock(M) { + return to_moz_scope("StaticBlock", M.value); + }); + + function To_Moz_ForOfStatement(is_await) { + return function(M) { + return { + type: "ForOfStatement", + await: is_await, + left: to_moz(M.init), + right: to_moz(M.object), + body: to_moz(M.body), + }; + }; + } + def_to_moz(AST_ForAwaitOf, To_Moz_ForOfStatement(true)); + def_to_moz(AST_ForOf, To_Moz_ForOfStatement(false)); + + def_to_moz(AST_Directive, function To_Moz_Directive(M) { + return { + type: "ExpressionStatement", + expression: set_moz_loc(M, { + type: "Literal", + value: M.value, + }), + }; + }); + + def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) { + return { + type: "SwitchCase", + test: to_moz(M.expression), + consequent: M.body.map(to_moz), + }; + }); + + def_to_moz(AST_Try, function To_Moz_TryStatement(M) { + return { + type: "TryStatement", + block: to_moz_block(M), + handler: to_moz(M.bcatch), + guardedHandlers: [], + finalizer: to_moz(M.bfinally), + }; + }); + + def_to_moz(AST_Catch, function To_Moz_CatchClause(M) { + return { + type: "CatchClause", + param: to_moz(M.argname), + guard: null, + body: to_moz_block(M), + }; + }); + + def_to_moz(AST_ExportDeclaration, function To_Moz_ExportNamedDeclaration_declaration(M) { + return { + type: "ExportNamedDeclaration", + declaration: to_moz(M.body), + }; + }); + + def_to_moz(AST_ExportDefault, function To_Moz_ExportDefaultDeclaration(M) { + return { + type: "ExportDefaultDeclaration", + declaration: to_moz(M.body), + }; + }); + + def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) { + if (M.keys[0].value == "*") return { + type: "ExportAllDeclaration", + exported: M.aliases[0].value == "*" ? null : to_moz_alias(M.aliases[0]), + source: to_moz(M.path), + }; + var specifiers = []; + for (var i = 0; i < M.aliases.length; i++) { + specifiers.push(set_moz_loc({ + start: M.keys[i].start, + end: M.aliases[i].end, + }, { + type: "ExportSpecifier", + local: to_moz_alias(M.keys[i]), + exported: to_moz_alias(M.aliases[i]), + })); + } + return { + type: "ExportNamedDeclaration", + specifiers: specifiers, + source: to_moz(M.path), + }; + }); + + def_to_moz(AST_ExportReferences, function To_Moz_ExportNamedDeclaration_specifiers(M) { + return { + type: "ExportNamedDeclaration", + specifiers: M.properties.map(function(prop) { + return set_moz_loc({ + start: prop.start, + end: prop.alias.end, + }, { + type: "ExportSpecifier", + local: to_moz(prop), + exported: to_moz_alias(prop.alias), + }); + }), + }; + }); + + def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) { + var specifiers = M.properties ? M.properties.map(function(prop) { + return set_moz_loc({ + start: prop.key.start, + end: prop.end, + }, { + type: "ImportSpecifier", + local: to_moz(prop), + imported: to_moz_alias(prop.key), + }); + }) : []; + if (M.all) specifiers.unshift(set_moz_loc(M.all, { + type: "ImportNamespaceSpecifier", + local: to_moz(M.all), + })); + if (M.default) specifiers.unshift(set_moz_loc(M.default, { + type: "ImportDefaultSpecifier", + local: to_moz(M.default), + })); + return { + type: "ImportDeclaration", + specifiers: specifiers, + source: to_moz(M.path), + }; + }); + + def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) { + return { + type: "VariableDeclaration", + kind: M.TYPE.toLowerCase(), + declarations: M.definitions.map(to_moz), + }; + }); + + def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) { + var computed = M instanceof AST_Sub; + var expr = { + type: "MemberExpression", + object: to_moz(M.expression), + computed: computed, + optional: M.optional, + property: computed ? to_moz(M.property) : { + type: "Identifier", + name: M.property, + }, + }; + return M.terminal ? { + type: "ChainExpression", + expression: expr, + } : expr; + }); + + def_to_moz(AST_Unary, function To_Moz_Unary(M) { + return { + type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression", + operator: M.operator, + prefix: M instanceof AST_UnaryPrefix, + argument: to_moz(M.expression) + }; + }); + + def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) { + return { + type: M.operator == "&&" || M.operator == "||" ? "LogicalExpression" : "BinaryExpression", + left: to_moz(M.left), + operator: M.operator, + right: to_moz(M.right) + }; + }); + + def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) { + return { + type: "ArrayExpression", + elements: M.elements.map(to_moz), + }; + }); + + def_to_moz(AST_DestructuredArray, function To_Moz_ArrayPattern(M) { + var elements = M.elements.map(to_moz); + if (M.rest) elements.push({ + type: "RestElement", + argument: to_moz(M.rest), + }); + return { + type: "ArrayPattern", + elements: elements, + }; + }); + + def_to_moz(AST_DestructuredKeyVal, function To_Moz_Property(M) { + var computed = M.key instanceof AST_Node; + var key = computed ? to_moz(M.key) : { + type: "Literal", + value: M.key, + }; + return { + type: "Property", + kind: "init", + computed: computed, + key: key, + value: to_moz(M.value), + }; + }); + + def_to_moz(AST_DestructuredObject, function To_Moz_ObjectPattern(M) { + var props = M.properties.map(to_moz); + if (M.rest) props.push({ + type: "RestElement", + argument: to_moz(M.rest), + }); + return { + type: "ObjectPattern", + properties: props, + }; + }); + + def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) { + var computed = M.key instanceof AST_Node; + var key = computed ? to_moz(M.key) : { + type: "Literal", + value: M.key, + }; + var kind; + if (M instanceof AST_ObjectKeyVal) { + kind = "init"; + } else if (M instanceof AST_ObjectGetter) { + kind = "get"; + } else if (M instanceof AST_ObjectSetter) { + kind = "set"; + } + return { + type: "Property", + kind: kind, + computed: computed, + method: M instanceof AST_ObjectMethod, + key: key, + value: to_moz(M.value), + }; + }); + + def_to_moz(AST_Symbol, function To_Moz_Identifier(M) { + var def = M.definition(); + return { + type: "Identifier", + name: def && def.mangled_name || M.name, + }; + }); + + def_to_moz(AST_Super, function To_Moz_Super() { + return { type: "Super" }; + }); + + def_to_moz(AST_This, function To_Moz_ThisExpression() { + return { type: "ThisExpression" }; + }); + + def_to_moz(AST_NewTarget, function To_Moz_MetaProperty() { + return { + type: "MetaProperty", + meta: { + type: "Identifier", + name: "new", + }, + property: { + type: "Identifier", + name: "target", + }, + }; + }); + + def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) { + var flags = M.value.toString().match(/\/([gimuy]*)$/)[1]; + var value = "/" + M.value.raw_source + "/" + flags; + return { + type: "Literal", + value: value, + raw: value, + regex: { + pattern: M.value.raw_source, + flags: flags, + }, + }; + }); + + def_to_moz(AST_BigInt, function To_Moz_BigInt(M) { + var value = M.value; + return { + type: "Literal", + bigint: value.slice(0, -1), + raw: value, + }; + }); + + function To_Moz_Literal(M) { + var value = M.value; + if (typeof value === "number" && (value < 0 || (value === 0 && 1 / value < 0))) { + return { + type: "UnaryExpression", + operator: "-", + prefix: true, + argument: { + type: "Literal", + value: -value, + raw: M.start.raw, + }, + }; + } + return { + type: "Literal", + value: value, + raw: M.start.raw, + }; + } + def_to_moz(AST_Boolean, To_Moz_Literal); + def_to_moz(AST_Constant, To_Moz_Literal); + def_to_moz(AST_Null, To_Moz_Literal); + + def_to_moz(AST_Atom, function To_Moz_Atom(M) { + return { + type: "Identifier", + name: String(M.value), + }; + }); + + def_to_moz(AST_Template, function To_Moz_TemplateLiteral_TaggedTemplateExpression(M) { + var last = M.strings.length - 1; + var tmpl = { + type: "TemplateLiteral", + expressions: M.expressions.map(to_moz), + quasis: M.strings.map(function(str, index) { + return { + type: "TemplateElement", + tail: index == last, + value: { raw: str }, + }; + }), + }; + if (!M.tag) return tmpl; + return { + type: "TaggedTemplateExpression", + tag: to_moz(M.tag), + quasi: tmpl, + }; + }); + + AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast); + AST_Hole.DEFMETHOD("to_mozilla_ast", return_null); + AST_Node.DEFMETHOD("to_mozilla_ast", function() { + throw new Error("Cannot convert AST_" + this.TYPE); + }); + + /* -----[ tools ]----- */ + + function normalize_directives(body) { + for (var i = 0; i < body.length; i++) { + var stat = body[i]; + if (!(stat instanceof AST_SimpleStatement)) break; + var node = stat.body; + if (!(node instanceof AST_String)) break; + if (stat.start.pos !== node.start.pos) break; + body[i] = new AST_Directive(node); + } + return body; + } + + function raw_token(moznode) { + if (moznode.type == "Literal") { + return moznode.raw != null ? moznode.raw : moznode.value + ""; + } + } + + function my_start_token(moznode) { + var loc = moznode.loc, start = loc && loc.start; + var range = moznode.range; + return new AST_Token({ + file : loc && loc.source, + line : start && start.line, + col : start && start.column, + pos : range ? range[0] : moznode.start, + endline : start && start.line, + endcol : start && start.column, + endpos : range ? range[0] : moznode.start, + raw : raw_token(moznode), + }); + } + + function my_end_token(moznode) { + var loc = moznode.loc, end = loc && loc.end; + var range = moznode.range; + return new AST_Token({ + file : loc && loc.source, + line : end && end.line, + col : end && end.column, + pos : range ? range[1] : moznode.end, + endline : end && end.line, + endcol : end && end.column, + endpos : range ? range[1] : moznode.end, + raw : raw_token(moznode), + }); + } + + function read_name(M) { + return "" + M[M.type == "Identifier" ? "name" : "value"]; + } + + function map(moztype, mytype, propmap) { + var moz_to_me = [ + "start: my_start_token(M)", + "end: my_end_token(M)", + ]; + var me_to_moz = [ + "type: " + JSON.stringify(moztype), + ]; + + if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) { + var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop); + if (!m) throw new Error("Can't understand property map: " + prop); + var moz = m[1], how = m[2], my = m[3]; + switch (how) { + case "@": + moz_to_me.push(my + ": M." + moz + ".map(from_moz)"); + me_to_moz.push(moz + ": M." + my + ".map(to_moz)"); + break; + case ">": + moz_to_me.push(my + ": from_moz(M." + moz + ")"); + me_to_moz.push(moz + ": to_moz(M." + my + ")"); + break; + case "=": + moz_to_me.push(my + ": M." + moz); + me_to_moz.push(moz + ": M." + my); + break; + case "%": + moz_to_me.push(my + ": from_moz(M." + moz + ").body"); + me_to_moz.push(moz + ": to_moz_block(M)"); + break; + default: + throw new Error("Can't understand operator in propmap: " + prop); + } + }); + + MOZ_TO_ME[moztype] = new Function("U2", "my_start_token", "my_end_token", "from_moz", [ + "return function From_Moz_" + moztype + "(M) {", + " return new U2.AST_" + mytype.TYPE + "({", + moz_to_me.join(",\n"), + " });", + "};", + ].join("\n"))(exports, my_start_token, my_end_token, from_moz); + def_to_moz(mytype, new Function("to_moz", "to_moz_block", "to_moz_scope", [ + "return function To_Moz_" + moztype + "(M) {", + " return {", + me_to_moz.join(",\n"), + " };", + "};", + ].join("\n"))(to_moz, to_moz_block, to_moz_scope)); + } + + var FROM_MOZ_STACK = null; + + function from_moz(moz) { + FROM_MOZ_STACK.push(moz); + var node = null; + if (moz) { + if (!HOP(MOZ_TO_ME, moz.type)) throw new Error("Unsupported type: " + moz.type); + node = MOZ_TO_ME[moz.type](moz); + } + FROM_MOZ_STACK.pop(); + return node; + } + + function from_moz_alias(moz) { + return new AST_String({ + start: my_start_token(moz), + value: read_name(moz), + end: my_end_token(moz), + }); + } + + AST_Node.from_mozilla_ast = function(node) { + var save_stack = FROM_MOZ_STACK; + FROM_MOZ_STACK = []; + var ast = from_moz(node); + FROM_MOZ_STACK = save_stack; + ast.walk(new TreeWalker(function(node) { + if (node instanceof AST_LabelRef) { + for (var level = 0, parent; parent = this.parent(level); level++) { + if (parent instanceof AST_Scope) break; + if (parent instanceof AST_LabeledStatement && parent.label.name == node.name) { + node.thedef = parent.label; + break; + } + } + if (!node.thedef) { + var s = node.start; + js_error("Undefined label " + node.name, s.file, s.line, s.col, s.pos); + } + } + })); + return ast; + }; + + function set_moz_loc(mynode, moznode) { + var start = mynode.start; + var end = mynode.end; + if (start.pos != null && end.endpos != null) { + moznode.range = [start.pos, end.endpos]; + } + if (start.line) { + moznode.loc = { + start: {line: start.line, column: start.col}, + end: end.endline ? {line: end.endline, column: end.endcol} : null, + }; + if (start.file) { + moznode.loc.source = start.file; + } + } + return moznode; + } + + function def_to_moz(mytype, handler) { + mytype.DEFMETHOD("to_mozilla_ast", function() { + return set_moz_loc(this, handler(this)); + }); + } + + function to_moz(node) { + return node != null ? node.to_mozilla_ast() : null; + } + + function to_moz_alias(alias) { + return is_identifier_string(alias.value) ? set_moz_loc(alias, { + type: "Identifier", + name: alias.value, + }) : to_moz(alias); + } + + function to_moz_block(node) { + return { + type: "BlockStatement", + body: node.body.map(to_moz), + }; + } + + function to_moz_scope(type, node) { + var body = node.body.map(to_moz); + if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) { + body.unshift(to_moz(new AST_EmptyStatement(node.body[0]))); + } + return { + type: type, + body: body, + }; + } +})(); diff --git a/libs/events/node_modules/uglify-js/lib/output.js b/libs/events/node_modules/uglify-js/lib/output.js new file mode 100644 index 000000000..7e93d05eb --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/output.js @@ -0,0 +1,1956 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function is_some_comments(comment) { + // multiline comment + return comment.type == "comment2" && /@preserve|@license|@cc_on/i.test(comment.value); +} + +function OutputStream(options) { + options = defaults(options, { + annotations : false, + ascii_only : false, + beautify : false, + braces : false, + comments : false, + extendscript : false, + galio : false, + ie : false, + indent_level : 4, + indent_start : 0, + inline_script : true, + keep_quoted_props: false, + max_line_len : false, + preamble : null, + preserve_line : false, + quote_keys : false, + quote_style : 0, + semicolons : true, + shebang : true, + source_map : null, + v8 : false, + webkit : false, + width : 80, + wrap_iife : false, + }, true); + + // Convert comment option to RegExp if necessary and set up comments filter + var comment_filter = return_false; // Default case, throw all comments away + if (options.comments) { + var comments = options.comments; + if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) { + var regex_pos = options.comments.lastIndexOf("/"); + comments = new RegExp( + options.comments.substr(1, regex_pos - 1), + options.comments.substr(regex_pos + 1) + ); + } + if (comments instanceof RegExp) { + comment_filter = function(comment) { + return comment.type != "comment5" && comments.test(comment.value); + }; + } else if (typeof comments === "function") { + comment_filter = function(comment) { + return comment.type != "comment5" && comments(this, comment); + }; + } else if (comments === "some") { + comment_filter = is_some_comments; + } else { // NOTE includes "all" option + comment_filter = return_true; + } + } + + function make_indent(value) { + if (typeof value == "number") return new Array(value + 1).join(" "); + if (!value) return ""; + if (!/^\s*$/.test(value)) throw new Error("unsupported indentation: " + JSON.stringify("" + value)); + return value; + } + + var current_col = 0; + var current_line = 1; + var current_indent = make_indent(options.indent_start); + var full_indent = make_indent(options.indent_level); + var half_indent = full_indent.length + 1 >> 1; + var last; + var line_end = 0; + var line_fixed = true; + var mappings = options.source_map && []; + var mapping_name; + var mapping_token; + var might_need_space; + var might_need_semicolon; + var need_newline_indented = false; + var need_space = false; + var output; + var stack; + var stored = ""; + + function reset() { + last = ""; + might_need_space = false; + might_need_semicolon = false; + stack = []; + var str = output; + output = ""; + return str; + } + + reset(); + var to_utf8 = options.ascii_only ? function(str, identifier) { + if (identifier) str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) { + return "\\u{" + (ch.charCodeAt(0) - 0xd7c0 << 10 | ch.charCodeAt(1) - 0xdc00).toString(16) + "}"; + }); + return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) { + var code = ch.charCodeAt(0).toString(16); + if (code.length <= 2 && !identifier) { + while (code.length < 2) code = "0" + code; + return "\\x" + code; + } else { + while (code.length < 4) code = "0" + code; + return "\\u" + code; + } + }); + } : function(str) { + var s = ""; + for (var i = 0, j = 0; i < str.length; i++) { + var code = str.charCodeAt(i); + if (is_surrogate_pair_head(code)) { + if (is_surrogate_pair_tail(str.charCodeAt(i + 1))) { + i++; + continue; + } + } else if (!is_surrogate_pair_tail(code)) { + continue; + } + s += str.slice(j, i) + "\\u" + code.toString(16); + j = i + 1; + } + return j == 0 ? str : s + str.slice(j); + }; + + function quote_single(str) { + return "'" + str.replace(/\x27/g, "\\'") + "'"; + } + + function quote_double(str) { + return '"' + str.replace(/\x22/g, '\\"') + '"'; + } + + var quote_string = [ + null, + quote_single, + quote_double, + function(str, quote) { + return quote == "'" ? quote_single(str) : quote_double(str); + }, + ][options.quote_style] || function(str, quote, dq, sq) { + return dq > sq ? quote_single(str) : quote_double(str); + }; + + function make_string(str, quote) { + var dq = 0, sq = 0; + str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s, i) { + switch (s) { + case '"': ++dq; return '"'; + case "'": ++sq; return "'"; + case "\\": return "\\\\"; + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\t": return "\\t"; + case "\b": return "\\b"; + case "\f": return "\\f"; + case "\x0B": return options.ie ? "\\x0B" : "\\v"; + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + case "\ufeff": return "\\ufeff"; + case "\0": + return /[0-9]/.test(str.charAt(i+1)) ? "\\x00" : "\\0"; + } + return s; + }); + return quote_string(to_utf8(str), quote, dq, sq); + } + + /* -----[ beautification/minification ]----- */ + + var adjust_mappings = mappings ? function(line, col) { + mappings.forEach(function(mapping) { + mapping.line += line; + mapping.col += col; + }); + } : noop; + + var flush_mappings = mappings ? function() { + mappings.forEach(function(mapping) { + options.source_map.add( + mapping.token.file, + mapping.line, mapping.col, + mapping.token.line, mapping.token.col, + !mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name + ); + }); + mappings = []; + } : noop; + + function insert_newlines(count) { + stored += output.slice(0, line_end); + output = output.slice(line_end); + var new_col = output.length; + adjust_mappings(count, new_col - current_col); + current_line += count; + current_col = new_col; + while (count--) stored += "\n"; + } + + var fix_line = options.max_line_len ? function(flush) { + if (line_fixed) { + if (current_col > options.max_line_len) { + AST_Node.warn("Output exceeds {max_line_len} characters", options); + } + return; + } + if (current_col > options.max_line_len) { + insert_newlines(1); + line_fixed = true; + } + if (line_fixed || flush) flush_mappings(); + } : noop; + + var require_semicolon = makePredicate("( [ + * / - , ."); + + function require_space(prev, ch, str) { + return is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\") + || (ch == "/" && ch == prev) + || ((ch == "+" || ch == "-") && ch == last) + || last == "--" && ch == ">" + || last == "!" && str == "--" + || prev == "/" && (str == "in" || str == "instanceof"); + } + + var print = options.beautify + || options.comments + || options.max_line_len + || options.preserve_line + || options.shebang + || !options.semicolons + || options.source_map + || options.width ? function(str) { + var ch = str.charAt(0); + if (need_newline_indented && ch) { + need_newline_indented = false; + if (ch != "\n") { + print("\n"); + indent(); + } + } + if (need_space && ch) { + need_space = false; + if (!/[\s;})]/.test(ch)) { + space(); + } + } + var prev = last.slice(-1); + if (might_need_semicolon) { + might_need_semicolon = false; + if (prev == ":" && ch == "}" || prev != ";" && (!ch || ";}".indexOf(ch) < 0)) { + var need_semicolon = require_semicolon[ch]; + if (need_semicolon || options.semicolons) { + output += ";"; + current_col++; + if (!line_fixed) { + fix_line(); + if (line_fixed && !need_semicolon && output == ";") { + output = ""; + current_col = 0; + } + } + if (line_end == output.length - 1) line_end++; + } else { + fix_line(); + output += "\n"; + current_line++; + current_col = 0; + // reset the semicolon flag, since we didn't print one + // now and might still have to later + if (/^\s+$/.test(str)) might_need_semicolon = true; + } + if (!options.beautify) might_need_space = false; + } + } + + if (might_need_space) { + if (require_space(prev, ch, str)) { + output += " "; + current_col++; + } + if (prev != "<" || str != "!") might_need_space = false; + } + + if (mapping_token) { + mappings.push({ + token: mapping_token, + name: mapping_name, + line: current_line, + col: current_col, + }); + mapping_token = false; + if (line_fixed) flush_mappings(); + } + + output += str; + var a = str.split(/\r?\n/), n = a.length - 1; + current_line += n; + current_col += a[0].length; + if (n > 0) { + fix_line(); + current_col = a[n].length; + } + last = str; + } : function(str) { + var ch = str.charAt(0); + var prev = last.slice(-1); + if (might_need_semicolon) { + might_need_semicolon = false; + if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") { + output += ";"; + might_need_space = false; + } + } + if (might_need_space) { + if (require_space(prev, ch, str)) output += " "; + if (prev != "<" || str != "!") might_need_space = false; + } + output += str; + last = str; + }; + + var space = options.beautify ? function() { + print(" "); + } : function() { + might_need_space = true; + }; + + var indent = options.beautify ? function(half) { + if (need_newline_indented) print("\n"); + print(half ? current_indent.slice(0, -half_indent) : current_indent); + } : noop; + + var with_indent = options.beautify ? function(cont) { + var save_indentation = current_indent; + current_indent += full_indent; + cont(); + current_indent = save_indentation; + } : function(cont) { cont() }; + + var may_add_newline = options.max_line_len || options.preserve_line ? function() { + fix_line(); + line_end = output.length; + line_fixed = false; + } : noop; + + var newline = options.beautify ? function() { + print("\n"); + line_end = output.length; + } : may_add_newline; + + var semicolon = options.beautify ? function() { + print(";"); + } : function() { + might_need_semicolon = true; + }; + + function force_semicolon() { + if (might_need_semicolon) print(";"); + print(";"); + } + + function with_block(cont, end) { + print("{"); + newline(); + with_indent(cont); + add_mapping(end); + indent(); + print("}"); + } + + function with_parens(cont) { + print("("); + may_add_newline(); + cont(); + may_add_newline(); + print(")"); + } + + function with_square(cont) { + print("["); + may_add_newline(); + cont(); + may_add_newline(); + print("]"); + } + + function comma() { + may_add_newline(); + print(","); + may_add_newline(); + space(); + } + + function colon() { + print(":"); + space(); + } + + var add_mapping = mappings ? function(token, name) { + mapping_token = token; + mapping_name = name; + } : noop; + + function get() { + if (!line_fixed) fix_line(true); + return stored + output; + } + + function has_nlb() { + return /(^|\n) *$/.test(output); + } + + function pad_comment(token, force) { + if (need_newline_indented) return; + if (token.nlb && (force || !has_nlb())) { + need_newline_indented = true; + } else if (force) { + need_space = true; + } + } + + function print_comment(comment) { + var value = comment.value.replace(/[@#]__PURE__/g, " "); + if (/^\s*$/.test(value) && !/^\s*$/.test(comment.value)) return false; + if (/comment[134]/.test(comment.type)) { + print("//" + value); + need_newline_indented = true; + } else if (comment.type == "comment2") { + print("/*" + value + "*/"); + } + return true; + } + + function should_merge_comments(node, parent) { + if (parent instanceof AST_Binary) return parent.left === node; + if (parent.TYPE == "Call") return parent.expression === node; + if (parent instanceof AST_Conditional) return parent.condition === node; + if (parent instanceof AST_Dot) return parent.expression === node; + if (parent instanceof AST_Exit) return true; + if (parent instanceof AST_Sequence) return parent.expressions[0] === node; + if (parent instanceof AST_Sub) return parent.expression === node; + if (parent instanceof AST_UnaryPostfix) return true; + if (parent instanceof AST_Yield) return true; + } + + function prepend_comments(node) { + var self = this; + var scan; + if (node instanceof AST_Exit) { + scan = node.value; + } else if (node instanceof AST_Yield) { + scan = node.expression; + } + var comments = dump(node); + if (!comments) comments = []; + + if (scan) { + var tw = new TreeWalker(function(node) { + if (!should_merge_comments(node, tw.parent())) return true; + var before = dump(node); + if (before) comments = comments.concat(before); + }); + tw.push(node); + scan.walk(tw); + } + + if (current_line == 1 && current_col == 0) { + if (comments.length > 0 && options.shebang && comments[0].type == "comment5") { + print("#!" + comments.shift().value + "\n"); + indent(); + } + var preamble = options.preamble; + if (preamble) print(preamble.replace(/\r\n?|\u2028|\u2029|(^|\S)\s*$/g, "$1\n")); + } + + comments = comments.filter(comment_filter, node); + var printed = false; + comments.forEach(function(comment, index) { + pad_comment(comment, index); + if (print_comment(comment)) printed = true; + }); + if (printed) pad_comment(node.start, true); + + function dump(node) { + var token = node.start; + if (!token) { + if (!scan) return; + node.start = token = new AST_Token(); + } + var comments = token.comments_before; + if (!comments) { + if (!scan) return; + token.comments_before = comments = []; + } + if (comments._dumped === self) return; + comments._dumped = self; + return comments; + } + } + + function append_comments(node, tail) { + var self = this; + var token = node.end; + if (!token) return; + var comments = token[tail ? "comments_before" : "comments_after"]; + if (!comments || comments._dumped === self) return; + if (!(node instanceof AST_Statement || all(comments, function(c) { + return !/comment[134]/.test(c.type); + }))) return; + comments._dumped = self; + comments.filter(comment_filter, node).forEach(function(comment, index) { + pad_comment(comment, index || !tail); + print_comment(comment); + }); + } + + return { + get : get, + reset : reset, + indent : indent, + should_break : options.beautify && options.width ? function() { + return current_col >= options.width; + } : return_false, + has_parens : function() { return last.slice(-1) == "(" }, + newline : newline, + print : print, + space : space, + comma : comma, + colon : colon, + last : function() { return last }, + semicolon : semicolon, + force_semicolon : force_semicolon, + to_utf8 : to_utf8, + print_name : function(name) { print(to_utf8(name.toString(), true)) }, + print_string : options.inline_script ? function(str, quote) { + str = make_string(str, quote).replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2"); + print(str.replace(/\x3c!--/g, "\\x3c!--").replace(/--\x3e/g, "--\\x3e")); + } : function(str, quote) { + print(make_string(str, quote)); + }, + with_indent : with_indent, + with_block : with_block, + with_parens : with_parens, + with_square : with_square, + add_mapping : add_mapping, + option : function(opt) { return options[opt] }, + prepend_comments: options.comments || options.shebang ? prepend_comments : noop, + append_comments : options.comments ? append_comments : noop, + push_node : function(node) { stack.push(node) }, + pop_node : options.preserve_line ? function() { + var node = stack.pop(); + if (node.start && node.start.line > current_line) { + insert_newlines(node.start.line - current_line); + } + } : function() { + stack.pop(); + }, + parent : function(n) { + return stack[stack.length - 2 - (n || 0)]; + }, + }; +} + +/* -----[ code generators ]----- */ + +(function() { + + /* -----[ utils ]----- */ + + function DEFPRINT(nodetype, generator) { + nodetype.DEFMETHOD("_codegen", generator); + } + + var use_asm = false; + + AST_Node.DEFMETHOD("print", function(stream, force_parens) { + var self = this; + stream.push_node(self); + if (force_parens || self.needs_parens(stream)) { + stream.with_parens(doit); + } else { + doit(); + } + stream.pop_node(); + + function doit() { + stream.prepend_comments(self); + self.add_source_map(stream); + self._codegen(stream); + stream.append_comments(self); + } + }); + var readonly = OutputStream({ + inline_script: false, + shebang: false, + width: false, + }); + AST_Node.DEFMETHOD("print_to_string", function(options) { + if (options) { + var stream = OutputStream(options); + this.print(stream); + return stream.get(); + } + this.print(readonly); + return readonly.reset(); + }); + + /* -----[ PARENTHESES ]----- */ + + function PARENS(nodetype, func) { + nodetype.DEFMETHOD("needs_parens", func); + } + + PARENS(AST_Node, return_false); + + // a function expression needs parens around it when it's provably + // the first token to appear in a statement. + function needs_parens_function(output) { + var p = output.parent(); + if (!output.has_parens() && first_in_statement(output, false, true)) { + // export default function() {} + // export default (function foo() {}); + // export default (function() {})(foo); + // export default (function() {})`foo`; + // export default (function() {}) ? foo : bar; + return this.name || !(p instanceof AST_ExportDefault); + } + if (output.option("webkit") && p instanceof AST_PropAccess && p.expression === this) return true; + if (output.option("wrap_iife") && p instanceof AST_Call && p.expression === this) return true; + } + PARENS(AST_AsyncFunction, needs_parens_function); + PARENS(AST_AsyncGeneratorFunction, needs_parens_function); + PARENS(AST_ClassExpression, needs_parens_function); + PARENS(AST_Function, needs_parens_function); + PARENS(AST_GeneratorFunction, needs_parens_function); + + // same goes for an object literal, because otherwise it would be + // interpreted as a block of code. + function needs_parens_obj(output) { + return !output.has_parens() && first_in_statement(output, true); + } + PARENS(AST_Object, needs_parens_obj); + + function needs_parens_unary(output) { + var p = output.parent(); + // (-x) ** y + if (p instanceof AST_Binary) return p.operator == "**" && p.left === this; + // (await x)(y) + // new (await x) + if (p instanceof AST_Call) return p.expression === this; + // class extends (x++) {} + // class x extends (typeof y) {} + if (p instanceof AST_Class) return true; + // (x++)[y] + // (typeof x).y + // https://github.com/mishoo/UglifyJS/issues/115 + if (p instanceof AST_PropAccess) return p.expression === this; + // (~x)`foo` + if (p instanceof AST_Template) return p.tag === this; + } + PARENS(AST_Await, needs_parens_unary); + PARENS(AST_Unary, needs_parens_unary); + + PARENS(AST_Sequence, function(output) { + var p = output.parent(); + // [ 1, (2, 3), 4 ] ---> [ 1, 3, 4 ] + return p instanceof AST_Array + // () ---> (foo, bar) + || is_arrow(p) && p.value === this + // await (foo, bar) + || p instanceof AST_Await + // 1 + (2, 3) + 4 ---> 8 + || p instanceof AST_Binary + // new (foo, bar) or foo(1, (2, 3), 4) + || p instanceof AST_Call + // class extends (foo, bar) {} + // class foo extends (bar, baz) {} + || p instanceof AST_Class + // class { foo = (bar, baz) } + // class { [(foo, bar)]() {} } + || p instanceof AST_ClassProperty + // (false, true) ? (a = 10, b = 20) : (c = 30) + // ---> 20 (side effect, set a := 10 and b := 20) + || p instanceof AST_Conditional + // [ a = (1, 2) ] = [] ---> a == 2 + || p instanceof AST_DefaultValue + // { [(1, 2)]: foo } = bar + // { 1: (2, foo) } = bar + || p instanceof AST_DestructuredKeyVal + // export default (foo, bar) + || p instanceof AST_ExportDefault + // for (foo of (bar, baz)); + || p instanceof AST_ForOf + // { [(1, 2)]: 3 }[2] ---> 3 + // { foo: (1, 2) }.foo ---> 2 + || p instanceof AST_ObjectProperty + // (1, {foo:2}).foo or (1, {foo:2})["foo"] ---> 2 + || p instanceof AST_PropAccess && p.expression === this + // ...(foo, bar, baz) + || p instanceof AST_Spread + // (foo, bar)`baz` + || p instanceof AST_Template && p.tag === this + // !(foo, bar, baz) + || p instanceof AST_Unary + // var a = (1, 2), b = a + a; ---> b == 4 + || p instanceof AST_VarDef + // yield (foo, bar) + || p instanceof AST_Yield; + }); + + PARENS(AST_Binary, function(output) { + var p = output.parent(); + // await (foo && bar) + if (p instanceof AST_Await) return true; + // this deals with precedence: + // 3 * (2 + 1) + // 3 - (2 - 1) + // (1 ** 2) ** 3 + if (p instanceof AST_Binary) { + var po = p.operator, pp = PRECEDENCE[po]; + var so = this.operator, sp = PRECEDENCE[so]; + return pp > sp + || po == "??" && (so == "&&" || so == "||") + || (pp == sp && this === p[po == "**" ? "left" : "right"]); + } + // (foo && bar)() + if (p instanceof AST_Call) return p.expression === this; + // class extends (foo && bar) {} + // class foo extends (bar || null) {} + if (p instanceof AST_Class) return true; + // (foo && bar)["prop"], (foo && bar).prop + if (p instanceof AST_PropAccess) return p.expression === this; + // (foo && bar)`` + if (p instanceof AST_Template) return p.tag === this; + // typeof (foo && bar) + if (p instanceof AST_Unary) return true; + }); + + function need_chain_parens(node, parent) { + if (!node.terminal) return false; + if (!(parent instanceof AST_Call || parent instanceof AST_PropAccess)) return false; + return parent.expression === node; + } + + PARENS(AST_PropAccess, function(output) { + var node = this; + var p = output.parent(); + // i.e. new (foo().bar) + // + // if there's one call into this subtree, then we need + // parens around it too, otherwise the call will be + // interpreted as passing the arguments to the upper New + // expression. + if (p instanceof AST_New && p.expression === node && root_expr(node).TYPE == "Call") return true; + // (foo?.bar)() + // (foo?.bar).baz + // new (foo?.bar)() + return need_chain_parens(node, p); + }); + + PARENS(AST_Call, function(output) { + var node = this; + var p = output.parent(); + if (p instanceof AST_New) return p.expression === node; + // https://bugs.webkit.org/show_bug.cgi?id=123506 + if (output.option("webkit") + && node.expression instanceof AST_Function + && p instanceof AST_PropAccess + && p.expression === node) { + var g = output.parent(1); + if (g instanceof AST_Assign && g.left === p) return true; + } + // (foo?.())() + // (foo?.()).bar + // new (foo?.())() + return need_chain_parens(node, p); + }); + + PARENS(AST_New, function(output) { + if (need_constructor_parens(this, output)) return false; + var p = output.parent(); + // (new foo)(bar) + if (p instanceof AST_Call) return p.expression === this; + // (new Date).getTime(), (new Date)["getTime"]() + if (p instanceof AST_PropAccess) return true; + // (new foo)`bar` + if (p instanceof AST_Template) return p.tag === this; + }); + + PARENS(AST_Number, function(output) { + if (!output.option("galio")) return false; + // https://github.com/mishoo/UglifyJS/pull/1009 + var p = output.parent(); + return p instanceof AST_PropAccess && p.expression === this && /^0/.test(make_num(this.value)); + }); + + function needs_parens_assign_cond(self, output) { + var p = output.parent(); + // await (a = foo) + if (p instanceof AST_Await) return true; + // 1 + (a = 2) + 3 → 6, side effect setting a = 2 + if (p instanceof AST_Binary) return !(p instanceof AST_Assign); + // (a = func)() —or— new (a = Object)() + if (p instanceof AST_Call) return p.expression === self; + // class extends (a = foo) {} + // class foo extends (bar ? baz : moo) {} + if (p instanceof AST_Class) return true; + // (a = foo) ? bar : baz + if (p instanceof AST_Conditional) return p.condition === self; + // (a = foo)["prop"] —or— (a = foo).prop + if (p instanceof AST_PropAccess) return p.expression === self; + // (a = foo)`bar` + if (p instanceof AST_Template) return p.tag === self; + // !(a = false) → true + if (p instanceof AST_Unary) return true; + } + PARENS(AST_Arrow, function(output) { + return needs_parens_assign_cond(this, output); + }); + PARENS(AST_Assign, function(output) { + if (needs_parens_assign_cond(this, output)) return true; + // v8 parser bug ---> workaround + // f([1], [a] = []) ---> f([1], ([a] = [])) + if (output.option("v8")) return this.left instanceof AST_Destructured; + // ({ p: a } = o); + if (this.left instanceof AST_DestructuredObject) return needs_parens_obj(output); + }); + PARENS(AST_AsyncArrow, function(output) { + return needs_parens_assign_cond(this, output); + }); + PARENS(AST_Conditional, function(output) { + return needs_parens_assign_cond(this, output) + // https://github.com/mishoo/UglifyJS/issues/1144 + || output.option("extendscript") && output.parent() instanceof AST_Conditional; + }); + PARENS(AST_Yield, function(output) { + return needs_parens_assign_cond(this, output); + }); + + /* -----[ PRINTERS ]----- */ + + DEFPRINT(AST_Directive, function(output) { + var quote = this.quote; + var value = this.value; + switch (output.option("quote_style")) { + case 0: + case 2: + if (value.indexOf('"') == -1) quote = '"'; + break; + case 1: + if (value.indexOf("'") == -1) quote = "'"; + break; + } + output.print(quote + value + quote); + output.semicolon(); + }); + DEFPRINT(AST_Debugger, function(output) { + output.print("debugger"); + output.semicolon(); + }); + + /* -----[ statements ]----- */ + + function display_body(body, is_toplevel, output, allow_directives) { + var last = body.length - 1; + var in_directive = allow_directives; + var was_asm = use_asm; + body.forEach(function(stmt, i) { + if (in_directive) { + if (stmt instanceof AST_Directive) { + if (stmt.value == "use asm") use_asm = true; + } else if (!(stmt instanceof AST_EmptyStatement)) { + if (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String) { + output.force_semicolon(); + } + in_directive = false; + } + } + if (stmt instanceof AST_EmptyStatement) return; + output.indent(); + stmt.print(output); + if (i == last && is_toplevel) return; + output.newline(); + if (is_toplevel) output.newline(); + }); + use_asm = was_asm; + } + + DEFPRINT(AST_Toplevel, function(output) { + display_body(this.body, true, output, true); + output.print(""); + }); + DEFPRINT(AST_LabeledStatement, function(output) { + this.label.print(output); + output.colon(); + this.body.print(output); + }); + DEFPRINT(AST_SimpleStatement, function(output) { + this.body.print(output); + output.semicolon(); + }); + function print_braced_empty(self, output) { + output.print("{"); + output.with_indent(function() { + output.append_comments(self, true); + }); + output.print("}"); + } + function print_braced(self, output, allow_directives) { + if (self.body.length > 0) { + output.with_block(function() { + display_body(self.body, false, output, allow_directives); + }, self.end); + } else print_braced_empty(self, output); + } + DEFPRINT(AST_BlockStatement, function(output) { + print_braced(this, output); + }); + DEFPRINT(AST_EmptyStatement, function(output) { + output.semicolon(); + }); + DEFPRINT(AST_Do, function(output) { + var self = this; + output.print("do"); + make_block(self.body, output); + output.space(); + output.print("while"); + output.space(); + output.with_parens(function() { + self.condition.print(output); + }); + output.semicolon(); + }); + DEFPRINT(AST_While, function(output) { + var self = this; + output.print("while"); + output.space(); + output.with_parens(function() { + self.condition.print(output); + }); + force_statement(self.body, output); + }); + DEFPRINT(AST_For, function(output) { + var self = this; + output.print("for"); + output.space(); + output.with_parens(function() { + if (self.init) { + if (self.init instanceof AST_Definitions) { + self.init.print(output); + } else { + parenthesize_for_no_in(self.init, output, true); + } + output.print(";"); + output.space(); + } else { + output.print(";"); + } + if (self.condition) { + self.condition.print(output); + output.print(";"); + output.space(); + } else { + output.print(";"); + } + if (self.step) { + self.step.print(output); + } + }); + force_statement(self.body, output); + }); + function print_for_enum(prefix, infix) { + return function(output) { + var self = this; + output.print(prefix); + output.space(); + output.with_parens(function() { + self.init.print(output); + output.space(); + output.print(infix); + output.space(); + self.object.print(output); + }); + force_statement(self.body, output); + }; + } + DEFPRINT(AST_ForAwaitOf, print_for_enum("for await", "of")); + DEFPRINT(AST_ForIn, print_for_enum("for", "in")); + DEFPRINT(AST_ForOf, print_for_enum("for", "of")); + DEFPRINT(AST_With, function(output) { + var self = this; + output.print("with"); + output.space(); + output.with_parens(function() { + self.expression.print(output); + }); + force_statement(self.body, output); + }); + DEFPRINT(AST_ExportDeclaration, function(output) { + output.print("export"); + output.space(); + this.body.print(output); + }); + DEFPRINT(AST_ExportDefault, function(output) { + output.print("export"); + output.space(); + output.print("default"); + output.space(); + var body = this.body; + body.print(output); + if (body instanceof AST_ClassExpression) { + if (!body.name) return; + } + if (body instanceof AST_DefClass) return; + if (body instanceof AST_LambdaDefinition) return; + if (body instanceof AST_LambdaExpression) { + if (!body.name && !is_arrow(body)) return; + } + output.semicolon(); + }); + function print_alias(alias, output) { + var value = alias.value; + if (value == "*" || is_identifier_string(value)) { + output.print_name(value); + } else { + output.print_string(value, alias.quote); + } + } + DEFPRINT(AST_ExportForeign, function(output) { + var self = this; + output.print("export"); + output.space(); + var len = self.keys.length; + if (len == 0) { + print_braced_empty(self, output); + } else if (self.keys[0].value == "*") { + print_entry(0); + } else output.with_block(function() { + output.indent(); + print_entry(0); + for (var i = 1; i < len; i++) { + output.print(","); + output.newline(); + output.indent(); + print_entry(i); + } + output.newline(); + }, self.end); + output.space(); + output.print("from"); + output.space(); + self.path.print(output); + output.semicolon(); + + function print_entry(index) { + var alias = self.aliases[index]; + var key = self.keys[index]; + print_alias(key, output); + if (alias.value != key.value) { + output.space(); + output.print("as"); + output.space(); + print_alias(alias, output); + } + } + }); + DEFPRINT(AST_ExportReferences, function(output) { + var self = this; + output.print("export"); + output.space(); + print_properties(self, output); + output.semicolon(); + }); + DEFPRINT(AST_Import, function(output) { + var self = this; + output.print("import"); + output.space(); + if (self.default) self.default.print(output); + if (self.all) { + if (self.default) output.comma(); + self.all.print(output); + } + if (self.properties) { + if (self.default) output.comma(); + print_properties(self, output); + } + if (self.all || self.default || self.properties) { + output.space(); + output.print("from"); + output.space(); + } + self.path.print(output); + output.semicolon(); + }); + + /* -----[ functions ]----- */ + function print_funargs(self, output) { + output.with_parens(function() { + self.argnames.forEach(function(arg, i) { + if (i) output.comma(); + arg.print(output); + }); + if (self.rest) { + if (self.argnames.length) output.comma(); + output.print("..."); + self.rest.print(output); + } + }); + } + function print_arrow(self, output) { + var argname = self.argnames.length == 1 && !self.rest && self.argnames[0]; + if (argname instanceof AST_SymbolFunarg && argname.name != "yield") { + argname.print(output); + } else { + print_funargs(self, output); + } + output.space(); + output.print("=>"); + output.space(); + if (self.value) { + self.value.print(output); + } else { + print_braced(self, output, true); + } + } + DEFPRINT(AST_Arrow, function(output) { + print_arrow(this, output); + }); + DEFPRINT(AST_AsyncArrow, function(output) { + output.print("async"); + output.space(); + print_arrow(this, output); + }); + function print_lambda(self, output) { + if (self.name) { + output.space(); + self.name.print(output); + } + print_funargs(self, output); + output.space(); + print_braced(self, output, true); + } + DEFPRINT(AST_Lambda, function(output) { + output.print("function"); + print_lambda(this, output); + }); + function print_async(output) { + output.print("async"); + output.space(); + output.print("function"); + print_lambda(this, output); + } + DEFPRINT(AST_AsyncDefun, print_async); + DEFPRINT(AST_AsyncFunction, print_async); + function print_async_generator(output) { + output.print("async"); + output.space(); + output.print("function*"); + print_lambda(this, output); + } + DEFPRINT(AST_AsyncGeneratorDefun, print_async_generator); + DEFPRINT(AST_AsyncGeneratorFunction, print_async_generator); + function print_generator(output) { + output.print("function*"); + print_lambda(this, output); + } + DEFPRINT(AST_GeneratorDefun, print_generator); + DEFPRINT(AST_GeneratorFunction, print_generator); + + /* -----[ classes ]----- */ + DEFPRINT(AST_Class, function(output) { + var self = this; + output.print("class"); + if (self.name) { + output.space(); + self.name.print(output); + } + if (self.extends) { + output.space(); + output.print("extends"); + output.space(); + self.extends.print(output); + } + output.space(); + print_properties(self, output, true); + }); + DEFPRINT(AST_ClassField, function(output) { + var self = this; + if (self.static) { + output.print("static"); + output.space(); + } + print_property_key(self, output); + if (self.value) { + output.space(); + output.print("="); + output.space(); + self.value.print(output); + } + output.semicolon(); + }); + DEFPRINT(AST_ClassGetter, print_accessor("get")); + DEFPRINT(AST_ClassSetter, print_accessor("set")); + function print_method(self, output) { + var fn = self.value; + if (is_async(fn)) { + output.print("async"); + output.space(); + } + if (is_generator(fn)) output.print("*"); + print_property_key(self, output); + print_lambda(self.value, output); + } + DEFPRINT(AST_ClassMethod, function(output) { + var self = this; + if (self.static) { + output.print("static"); + output.space(); + } + print_method(self, output); + }); + DEFPRINT(AST_ClassInit, function(output) { + output.print("static"); + output.space(); + print_braced(this.value, output); + }); + + /* -----[ jumps ]----- */ + function print_jump(kind, prop) { + return function(output) { + output.print(kind); + var target = this[prop]; + if (target) { + output.space(); + target.print(output); + } + output.semicolon(); + }; + } + DEFPRINT(AST_Return, print_jump("return", "value")); + DEFPRINT(AST_Throw, print_jump("throw", "value")); + DEFPRINT(AST_Break, print_jump("break", "label")); + DEFPRINT(AST_Continue, print_jump("continue", "label")); + + /* -----[ if ]----- */ + function make_then(self, output) { + var b = self.body; + if (output.option("braces") && !(b instanceof AST_Const || b instanceof AST_Let) + || output.option("ie") && b instanceof AST_Do) + return make_block(b, output); + // The squeezer replaces "block"-s that contain only a single + // statement with the statement itself; technically, the AST + // is correct, but this can create problems when we output an + // IF having an ELSE clause where the THEN clause ends in an + // IF *without* an ELSE block (then the outer ELSE would refer + // to the inner IF). This function checks for this case and + // adds the block braces if needed. + if (!b) return output.force_semicolon(); + while (true) { + if (b instanceof AST_If) { + if (!b.alternative) { + make_block(self.body, output); + return; + } + b = b.alternative; + } else if (b instanceof AST_StatementWithBody) { + b = b.body; + } else break; + } + force_statement(self.body, output); + } + DEFPRINT(AST_If, function(output) { + var self = this; + output.print("if"); + output.space(); + output.with_parens(function() { + self.condition.print(output); + }); + if (self.alternative) { + make_then(self, output); + output.space(); + output.print("else"); + if (self.alternative instanceof AST_If) { + output.space(); + self.alternative.print(output); + } else { + force_statement(self.alternative, output); + } + } else { + force_statement(self.body, output); + } + }); + + /* -----[ switch ]----- */ + DEFPRINT(AST_Switch, function(output) { + var self = this; + output.print("switch"); + output.space(); + output.with_parens(function() { + self.expression.print(output); + }); + output.space(); + var last = self.body.length - 1; + if (last < 0) print_braced_empty(self, output); + else output.with_block(function() { + self.body.forEach(function(branch, i) { + output.indent(true); + branch.print(output); + if (i < last && branch.body.length > 0) + output.newline(); + }); + }, self.end); + }); + function print_branch_body(self, output) { + output.newline(); + self.body.forEach(function(stmt) { + output.indent(); + stmt.print(output); + output.newline(); + }); + } + DEFPRINT(AST_Default, function(output) { + output.print("default:"); + print_branch_body(this, output); + }); + DEFPRINT(AST_Case, function(output) { + var self = this; + output.print("case"); + output.space(); + self.expression.print(output); + output.print(":"); + print_branch_body(self, output); + }); + + /* -----[ exceptions ]----- */ + DEFPRINT(AST_Try, function(output) { + var self = this; + output.print("try"); + output.space(); + print_braced(self, output); + if (self.bcatch) { + output.space(); + self.bcatch.print(output); + } + if (self.bfinally) { + output.space(); + self.bfinally.print(output); + } + }); + DEFPRINT(AST_Catch, function(output) { + var self = this; + output.print("catch"); + if (self.argname) { + output.space(); + output.with_parens(function() { + self.argname.print(output); + }); + } + output.space(); + print_braced(self, output); + }); + DEFPRINT(AST_Finally, function(output) { + output.print("finally"); + output.space(); + print_braced(this, output); + }); + + function print_definitions(type) { + return function(output) { + var self = this; + output.print(type); + output.space(); + self.definitions.forEach(function(def, i) { + if (i) output.comma(); + def.print(output); + }); + var p = output.parent(); + if (!(p instanceof AST_IterationStatement && p.init === self)) output.semicolon(); + }; + } + DEFPRINT(AST_Const, print_definitions("const")); + DEFPRINT(AST_Let, print_definitions("let")); + DEFPRINT(AST_Var, print_definitions("var")); + + function parenthesize_for_no_in(node, output, no_in) { + var parens = false; + // need to take some precautions here: + // https://github.com/mishoo/UglifyJS/issues/60 + if (no_in) node.walk(new TreeWalker(function(node) { + if (parens) return true; + if (node instanceof AST_Binary && node.operator == "in") return parens = true; + if (node instanceof AST_Scope && !(is_arrow(node) && node.value)) return true; + })); + node.print(output, parens); + } + + DEFPRINT(AST_VarDef, function(output) { + var self = this; + self.name.print(output); + if (self.value) { + output.space(); + output.print("="); + output.space(); + var p = output.parent(1); + var no_in = p instanceof AST_For || p instanceof AST_ForEnumeration; + parenthesize_for_no_in(self.value, output, no_in); + } + }); + + DEFPRINT(AST_DefaultValue, function(output) { + var self = this; + self.name.print(output); + output.space(); + output.print("="); + output.space(); + self.value.print(output); + }); + + /* -----[ other expressions ]----- */ + function print_annotation(self, output) { + if (!output.option("annotations")) return; + if (!self.pure) return; + var level = 0, parent = self, node; + do { + node = parent; + parent = output.parent(level++); + if (parent instanceof AST_Call && parent.expression === node) return; + } while (parent instanceof AST_PropAccess && parent.expression === node); + output.print("/*@__PURE__*/"); + } + function print_call_args(self, output) { + output.with_parens(function() { + self.args.forEach(function(expr, i) { + if (i) output.comma(); + expr.print(output); + }); + output.add_mapping(self.end); + }); + } + DEFPRINT(AST_Call, function(output) { + var self = this; + print_annotation(self, output); + self.expression.print(output); + if (self.optional) output.print("?."); + print_call_args(self, output); + }); + DEFPRINT(AST_New, function(output) { + var self = this; + print_annotation(self, output); + output.print("new"); + output.space(); + self.expression.print(output); + if (need_constructor_parens(self, output)) print_call_args(self, output); + }); + DEFPRINT(AST_Sequence, function(output) { + this.expressions.forEach(function(node, index) { + if (index > 0) { + output.comma(); + if (output.should_break()) { + output.newline(); + output.indent(); + } + } + node.print(output); + }); + }); + DEFPRINT(AST_Dot, function(output) { + var self = this; + var expr = self.expression; + expr.print(output); + var prop = self.property; + if (output.option("ie") && RESERVED_WORDS[prop] || self.quoted && output.option("keep_quoted_props")) { + if (self.optional) output.print("?."); + output.with_square(function() { + output.add_mapping(self.end); + output.print_string(prop); + }); + } else { + if (expr instanceof AST_Number && !/[ex.)]/i.test(output.last())) output.print("."); + output.print(self.optional ? "?." : "."); + // the name after dot would be mapped about here. + output.add_mapping(self.end); + output.print_name(prop); + } + }); + DEFPRINT(AST_Sub, function(output) { + var self = this; + self.expression.print(output); + if (self.optional) output.print("?."); + output.with_square(function() { + self.property.print(output); + }); + }); + DEFPRINT(AST_Spread, function(output) { + output.print("..."); + this.expression.print(output); + }); + DEFPRINT(AST_UnaryPrefix, function(output) { + var op = this.operator; + var exp = this.expression; + output.print(op); + if (/^[a-z]/i.test(op) + || (/[+-]$/.test(op) + && exp instanceof AST_UnaryPrefix + && /^[+-]/.test(exp.operator))) { + output.space(); + } + exp.print(output); + }); + DEFPRINT(AST_UnaryPostfix, function(output) { + var self = this; + self.expression.print(output); + output.add_mapping(self.end); + output.print(self.operator); + }); + DEFPRINT(AST_Binary, function(output) { + var self = this; + self.left.print(output); + output.space(); + output.print(self.operator); + output.space(); + self.right.print(output); + }); + DEFPRINT(AST_Conditional, function(output) { + var self = this; + self.condition.print(output); + output.space(); + output.print("?"); + output.space(); + self.consequent.print(output); + output.space(); + output.colon(); + self.alternative.print(output); + }); + DEFPRINT(AST_Await, function(output) { + output.print("await"); + output.space(); + this.expression.print(output); + }); + DEFPRINT(AST_Yield, function(output) { + output.print(this.nested ? "yield*" : "yield"); + if (this.expression) { + output.space(); + this.expression.print(output); + } + }); + + /* -----[ literals ]----- */ + DEFPRINT(AST_Array, function(output) { + var a = this.elements, len = a.length; + output.with_square(len > 0 ? function() { + output.space(); + a.forEach(function(exp, i) { + if (i) output.comma(); + exp.print(output); + // If the final element is a hole, we need to make sure it + // doesn't look like a trailing comma, by inserting an actual + // trailing comma. + if (i === len - 1 && exp instanceof AST_Hole) + output.comma(); + }); + output.space(); + } : noop); + }); + DEFPRINT(AST_DestructuredArray, function(output) { + var a = this.elements, len = a.length, rest = this.rest; + output.with_square(len || rest ? function() { + output.space(); + a.forEach(function(exp, i) { + if (i) output.comma(); + exp.print(output); + }); + if (rest) { + if (len) output.comma(); + output.print("..."); + rest.print(output); + } else if (a[len - 1] instanceof AST_Hole) { + // If the final element is a hole, we need to make sure it + // doesn't look like a trailing comma, by inserting an actual + // trailing comma. + output.comma(); + } + output.space(); + } : noop); + }); + DEFPRINT(AST_DestructuredKeyVal, function(output) { + var self = this; + var key = print_property_key(self, output); + var value = self.value; + if (key) { + if (value instanceof AST_DefaultValue) { + if (value.name instanceof AST_Symbol && key == get_symbol_name(value.name)) { + output.space(); + output.print("="); + output.space(); + value.value.print(output); + return; + } + } else if (value instanceof AST_Symbol) { + if (key == get_symbol_name(value)) return; + } + } + output.colon(); + value.print(output); + }); + DEFPRINT(AST_DestructuredObject, function(output) { + var self = this; + var props = self.properties, len = props.length, rest = self.rest; + if (len || rest) output.with_block(function() { + props.forEach(function(prop, i) { + if (i) { + output.print(","); + output.newline(); + } + output.indent(); + prop.print(output); + }); + if (rest) { + if (len) { + output.print(","); + output.newline(); + } + output.indent(); + output.print("..."); + rest.print(output); + } + output.newline(); + }, self.end); + else print_braced_empty(self, output); + }); + function print_properties(self, output, no_comma) { + var props = self.properties; + if (props.length > 0) output.with_block(function() { + props.forEach(function(prop, i) { + if (i) { + if (!no_comma) output.print(","); + output.newline(); + } + output.indent(); + prop.print(output); + }); + output.newline(); + }, self.end); + else print_braced_empty(self, output); + } + DEFPRINT(AST_Object, function(output) { + print_properties(this, output); + }); + + function print_property_key(self, output) { + var key = self.key; + if (key instanceof AST_Node) return output.with_square(function() { + key.print(output); + }); + var quote = self.start && self.start.quote; + if (output.option("quote_keys") || quote && output.option("keep_quoted_props")) { + output.print_string(key, quote); + } else if ("" + +key == key && key >= 0) { + output.print(make_num(key)); + } else if (self.private) { + output.print_name(key); + } else if (RESERVED_WORDS[key] ? !output.option("ie") : is_identifier_string(key)) { + output.print_name(key); + return key; + } else { + output.print_string(key, quote); + } + } + DEFPRINT(AST_ObjectKeyVal, function(output) { + var self = this; + print_property_key(self, output); + output.colon(); + self.value.print(output); + }); + DEFPRINT(AST_ObjectMethod, function(output) { + print_method(this, output); + }); + function print_accessor(type) { + return function(output) { + var self = this; + if (self.static) { + output.print("static"); + output.space(); + } + output.print(type); + output.space(); + print_property_key(self, output); + print_lambda(self.value, output); + }; + } + DEFPRINT(AST_ObjectGetter, print_accessor("get")); + DEFPRINT(AST_ObjectSetter, print_accessor("set")); + function get_symbol_name(sym) { + var def = sym.definition(); + return def && def.mangled_name || sym.name; + } + DEFPRINT(AST_Symbol, function(output) { + output.print_name(get_symbol_name(this)); + }); + DEFPRINT(AST_SymbolExport, function(output) { + var self = this; + var name = get_symbol_name(self); + output.print_name(name); + var alias = self.alias; + if (alias.value != name) { + output.space(); + output.print("as"); + output.space(); + print_alias(alias, output); + } + }); + DEFPRINT(AST_SymbolImport, function(output) { + var self = this; + var name = get_symbol_name(self); + var key = self.key; + if (key.value && key.value != name) { + print_alias(key, output); + output.space(); + output.print("as"); + output.space(); + } + output.print_name(name); + }); + DEFPRINT(AST_Hole, noop); + DEFPRINT(AST_Template, function(output) { + var self = this; + if (self.tag) self.tag.print(output); + output.print("`"); + for (var i = 0; i < self.expressions.length; i++) { + output.print(self.strings[i]); + output.print("${"); + self.expressions[i].print(output); + output.print("}"); + } + output.print(self.strings[i]); + output.print("`"); + }); + DEFPRINT(AST_Constant, function(output) { + output.print("" + this.value); + }); + DEFPRINT(AST_String, function(output) { + output.print_string(this.value, this.quote); + }); + DEFPRINT(AST_Number, function(output) { + var start = this.start; + if (use_asm && start && start.raw != null) { + output.print(start.raw); + } else { + output.print(make_num(this.value)); + } + }); + + DEFPRINT(AST_RegExp, function(output) { + var regexp = this.value; + var str = regexp.toString(); + var end = str.lastIndexOf("/"); + if (regexp.raw_source) { + str = "/" + regexp.raw_source + str.slice(end); + } else if (end == 1) { + str = "/(?:)" + str.slice(end); + } else if (str.indexOf("/", 1) < end) { + str = "/" + str.slice(1, end).replace(/\\\\|[^/]?\//g, function(match) { + return match[0] == "\\" ? match : match.slice(0, -1) + "\\/"; + }) + str.slice(end); + } + output.print(output.to_utf8(str).replace(/\\(?:\0(?![0-9])|[^\0])/g, function(match) { + switch (match[1]) { + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\t": return "\t"; + case "\b": return "\b"; + case "\f": return "\f"; + case "\0": return "\0"; + case "\x0B": return "\v"; + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + default: return match; + } + }).replace(/[\n\r\u2028\u2029]/g, function(c) { + switch (c) { + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + } + })); + }); + + function force_statement(stat, output) { + if (output.option("braces") && !(stat instanceof AST_Const || stat instanceof AST_Let)) { + make_block(stat, output); + } else if (stat instanceof AST_EmptyStatement) { + output.force_semicolon(); + } else { + output.space(); + stat.print(output); + } + } + + // self should be AST_New. decide if we want to show parens or not. + function need_constructor_parens(self, output) { + // Always print parentheses with arguments + if (self.args.length > 0) return true; + + return output.option("beautify"); + } + + function best_of(a) { + var best = a[0], len = best.length; + for (var i = 1; i < a.length; ++i) { + if (a[i].length < len) { + best = a[i]; + len = best.length; + } + } + return best; + } + + function make_num(num) { + var str = num.toString(10).replace(/^0\./, ".").replace("e+", "e"); + var candidates = [ str ]; + if (Math.floor(num) === num) { + if (num < 0) { + candidates.push("-0x" + (-num).toString(16).toLowerCase()); + } else { + candidates.push("0x" + num.toString(16).toLowerCase()); + } + } + var match, len, digits; + if (match = /^\.0+/.exec(str)) { + len = match[0].length; + digits = str.slice(len); + candidates.push(digits + "e-" + (digits.length + len - 1)); + } else if (match = /[^0]0+$/.exec(str)) { + len = match[0].length - 1; + candidates.push(str.slice(0, -len) + "e" + len); + } else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) { + candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length)); + } + return best_of(candidates); + } + + function make_block(stmt, output) { + output.space(); + if (stmt instanceof AST_EmptyStatement) { + print_braced_empty(stmt, output); + } else if (stmt instanceof AST_BlockStatement) { + stmt.print(output); + } else output.with_block(function() { + output.indent(); + stmt.print(output); + output.newline(); + }, stmt.end); + } + + /* -----[ source map generators ]----- */ + + function DEFMAP(nodetype, generator) { + nodetype.forEach(function(nodetype) { + nodetype.DEFMETHOD("add_source_map", generator); + }); + } + + DEFMAP([ + // We could easily add info for ALL nodes, but it seems to me that + // would be quite wasteful, hence this noop in the base class. + AST_Node, + // since the label symbol will mark it + AST_LabeledStatement, + ], noop); + + // XXX: I'm not exactly sure if we need it for all of these nodes, + // or if we should add even more. + DEFMAP([ + AST_Array, + AST_Await, + AST_BlockStatement, + AST_Catch, + AST_Constant, + AST_Debugger, + AST_Definitions, + AST_Destructured, + AST_Directive, + AST_Finally, + AST_Jump, + AST_Lambda, + AST_New, + AST_Object, + AST_Spread, + AST_StatementWithBody, + AST_Symbol, + AST_Switch, + AST_SwitchBranch, + AST_Try, + AST_UnaryPrefix, + AST_Yield, + ], function(output) { + output.add_mapping(this.start); + }); + + DEFMAP([ + AST_ClassProperty, + AST_DestructuredKeyVal, + AST_ObjectProperty, + ], function(output) { + if (typeof this.key == "string") output.add_mapping(this.start, this.key); + }); +})(); diff --git a/libs/events/node_modules/uglify-js/lib/parse.js b/libs/events/node_modules/uglify-js/lib/parse.js new file mode 100644 index 000000000..8fb7f383f --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/parse.js @@ -0,0 +1,2585 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + Parser based on parse-js (http://marijn.haverbeke.nl/parse-js/). + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +var KEYWORDS = "break case catch class const continue debugger default delete do else extends finally for function if in instanceof new return switch throw try typeof var void while with"; +var KEYWORDS_ATOM = "false null true"; +var RESERVED_WORDS = [ + "abstract async await boolean byte char double enum export final float goto implements import int interface let long native package private protected public short static super synchronized this throws transient volatile yield", + KEYWORDS_ATOM, + KEYWORDS, +].join(" "); +var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case"; + +KEYWORDS = makePredicate(KEYWORDS); +RESERVED_WORDS = makePredicate(RESERVED_WORDS); +KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION); +KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM); + +var RE_BIN_NUMBER = /^0b([01]+)$/i; +var RE_HEX_NUMBER = /^0x([0-9a-f]+)$/i; +var RE_OCT_NUMBER = /^0o?([0-7]+)$/i; + +var OPERATORS = makePredicate([ + "in", + "instanceof", + "typeof", + "new", + "void", + "delete", + "++", + "--", + "+", + "-", + "!", + "~", + "&", + "|", + "^", + "*", + "/", + "%", + "**", + ">>", + "<<", + ">>>", + "<", + ">", + "<=", + ">=", + "==", + "===", + "!=", + "!==", + "?", + "=", + "+=", + "-=", + "/=", + "*=", + "%=", + "**=", + ">>=", + "<<=", + ">>>=", + "&=", + "|=", + "^=", + "&&", + "||", + "??", + "&&=", + "||=", + "??=", +]); + +var NEWLINE_CHARS = "\n\r\u2028\u2029"; +var OPERATOR_CHARS = "+-*&%=<>!?|~^"; +var PUNC_OPENERS = "[{("; +var PUNC_SEPARATORS = ",;:"; +var PUNC_CLOSERS = ")}]"; +var PUNC_AFTER_EXPRESSION = PUNC_SEPARATORS + PUNC_CLOSERS; +var PUNC_BEFORE_EXPRESSION = PUNC_OPENERS + PUNC_SEPARATORS; +var PUNC_CHARS = PUNC_BEFORE_EXPRESSION + "`" + PUNC_CLOSERS; +var WHITESPACE_CHARS = NEWLINE_CHARS + " \u00a0\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\uFEFF"; +var NON_IDENTIFIER_CHARS = makePredicate(characters("./'\"#" + OPERATOR_CHARS + PUNC_CHARS + WHITESPACE_CHARS)); + +NEWLINE_CHARS = makePredicate(characters(NEWLINE_CHARS)); +OPERATOR_CHARS = makePredicate(characters(OPERATOR_CHARS)); +PUNC_AFTER_EXPRESSION = makePredicate(characters(PUNC_AFTER_EXPRESSION)); +PUNC_BEFORE_EXPRESSION = makePredicate(characters(PUNC_BEFORE_EXPRESSION)); +PUNC_CHARS = makePredicate(characters(PUNC_CHARS)); +WHITESPACE_CHARS = makePredicate(characters(WHITESPACE_CHARS)); + +/* -----[ Tokenizer ]----- */ + +function is_surrogate_pair_head(code) { + return code >= 0xd800 && code <= 0xdbff; +} + +function is_surrogate_pair_tail(code) { + return code >= 0xdc00 && code <= 0xdfff; +} + +function is_digit(code) { + return code >= 48 && code <= 57; +} + +function is_identifier_char(ch) { + return !NON_IDENTIFIER_CHARS[ch]; +} + +function is_identifier_string(str) { + return /^[a-z_$][a-z0-9_$]*$/i.test(str); +} + +function decode_escape_sequence(seq) { + switch (seq[0]) { + case "b": return "\b"; + case "f": return "\f"; + case "n": return "\n"; + case "r": return "\r"; + case "t": return "\t"; + case "u": + var code; + if (seq[1] == "{" && seq.slice(-1) == "}") { + code = seq.slice(2, -1); + } else if (seq.length == 5) { + code = seq.slice(1); + } else { + return; + } + var num = parseInt(code, 16); + if (num < 0 || isNaN(num)) return; + if (num < 0x10000) return String.fromCharCode(num); + if (num > 0x10ffff) return; + return String.fromCharCode((num >> 10) + 0xd7c0) + String.fromCharCode((num & 0x03ff) + 0xdc00); + case "v": return "\u000b"; + case "x": + if (seq.length != 3) return; + var num = parseInt(seq.slice(1), 16); + if (num < 0 || isNaN(num)) return; + return String.fromCharCode(num); + case "\r": + case "\n": + return ""; + default: + if (seq == "0") return "\0"; + if (seq[0] >= "0" && seq[0] <= "9") return; + return seq; + } +} + +function parse_js_number(num) { + var match; + if (match = RE_BIN_NUMBER.exec(num)) return parseInt(match[1], 2); + if (match = RE_HEX_NUMBER.exec(num)) return parseInt(match[1], 16); + if (match = RE_OCT_NUMBER.exec(num)) return parseInt(match[1], 8); + var val = parseFloat(num); + if (val == num) return val; +} + +function JS_Parse_Error(message, filename, line, col, pos) { + this.message = message; + this.filename = filename; + this.line = line; + this.col = col; + this.pos = pos; +} +JS_Parse_Error.prototype = Object.create(Error.prototype); +JS_Parse_Error.prototype.constructor = JS_Parse_Error; +JS_Parse_Error.prototype.name = "SyntaxError"; +configure_error_stack(JS_Parse_Error); + +function js_error(message, filename, line, col, pos) { + throw new JS_Parse_Error(message, filename, line, col, pos); +} + +function is_token(token, type, val) { + return token.type == type && (val == null || token.value == val); +} + +var EX_EOF = {}; + +function tokenizer($TEXT, filename, html5_comments, shebang) { + + var S = { + text : $TEXT, + filename : filename, + pos : 0, + tokpos : 0, + line : 1, + tokline : 0, + col : 0, + tokcol : 0, + newline_before : false, + regex_allowed : false, + comments_before : [], + directives : Object.create(null), + read_template : with_eof_error("Unterminated template literal", function(strings) { + var s = ""; + for (;;) { + var ch = read(); + switch (ch) { + case "\\": + ch += read(); + break; + case "`": + strings.push(s); + return; + case "$": + if (peek() == "{") { + next(); + strings.push(s); + S.regex_allowed = true; + return true; + } + } + s += ch; + } + + function read() { + var ch = next(true, true); + return ch == "\r" ? "\n" : ch; + } + }), + }; + var prev_was_dot = false; + + function peek() { + return S.text.charAt(S.pos); + } + + function next(signal_eof, in_string) { + var ch = S.text.charAt(S.pos++); + if (signal_eof && !ch) + throw EX_EOF; + if (NEWLINE_CHARS[ch]) { + S.col = 0; + S.line++; + if (!in_string) S.newline_before = true; + if (ch == "\r" && peek() == "\n") { + // treat `\r\n` as `\n` + S.pos++; + ch = "\n"; + } + } else { + S.col++; + } + return ch; + } + + function forward(i) { + while (i-- > 0) next(); + } + + function looking_at(str) { + return S.text.substr(S.pos, str.length) == str; + } + + function find_eol() { + var text = S.text; + for (var i = S.pos; i < S.text.length; ++i) { + if (NEWLINE_CHARS[text[i]]) return i; + } + return -1; + } + + function find(what, signal_eof) { + var pos = S.text.indexOf(what, S.pos); + if (signal_eof && pos == -1) throw EX_EOF; + return pos; + } + + function start_token() { + S.tokline = S.line; + S.tokcol = S.col; + S.tokpos = S.pos; + } + + function token(type, value, is_comment) { + S.regex_allowed = type == "operator" && !UNARY_POSTFIX[value] + || type == "keyword" && KEYWORDS_BEFORE_EXPRESSION[value] + || type == "punc" && PUNC_BEFORE_EXPRESSION[value]; + if (type == "punc" && value == ".") prev_was_dot = true; + else if (!is_comment) prev_was_dot = false; + var ret = { + type : type, + value : value, + line : S.tokline, + col : S.tokcol, + pos : S.tokpos, + endline : S.line, + endcol : S.col, + endpos : S.pos, + nlb : S.newline_before, + file : filename + }; + if (/^(?:num|string|regexp)$/i.test(type)) { + ret.raw = $TEXT.substring(ret.pos, ret.endpos); + } + if (!is_comment) { + ret.comments_before = S.comments_before; + ret.comments_after = S.comments_before = []; + } + S.newline_before = false; + return new AST_Token(ret); + } + + function skip_whitespace() { + while (WHITESPACE_CHARS[peek()]) + next(); + } + + function read_while(pred) { + var ret = "", ch; + while ((ch = peek()) && pred(ch, ret)) ret += next(); + return ret; + } + + function parse_error(err) { + js_error(err, filename, S.tokline, S.tokcol, S.tokpos); + } + + function is_octal(num) { + return /^0[0-7_]+$/.test(num); + } + + function read_num(prefix) { + var has_e = false, after_e = false, has_x = false, has_dot = prefix == "."; + var num = read_while(function(ch, str) { + switch (ch) { + case "x": case "X": + return has_x ? false : (has_x = true); + case "e": case "E": + return has_x ? true : has_e ? false : (has_e = after_e = true); + case "+": case "-": + return after_e; + case (after_e = false, "."): + return has_dot || has_e || has_x || is_octal(str) ? false : (has_dot = true); + } + return /[_0-9a-dfo]/i.test(ch); + }); + if (prefix) num = prefix + num; + if (is_octal(num)) { + if (next_token.has_directive("use strict")) parse_error("Legacy octal literals are not allowed in strict mode"); + } else { + num = num.replace(has_x ? /([1-9a-f]|.0)_(?=[0-9a-f])/gi : /([1-9]|.0)_(?=[0-9])/gi, "$1"); + } + var valid = parse_js_number(num); + if (isNaN(valid)) parse_error("Invalid syntax: " + num); + if (has_dot || has_e || peek() != "n") return token("num", valid); + return token("bigint", num.toLowerCase() + next()); + } + + function read_escaped_char(in_string) { + var seq = next(true, in_string); + if (seq >= "0" && seq <= "7") return read_octal_escape_sequence(seq); + if (seq == "u") { + var ch = next(true, in_string); + seq += ch; + if (ch != "{") { + seq += next(true, in_string) + next(true, in_string) + next(true, in_string); + } else do { + ch = next(true, in_string); + seq += ch; + } while (ch != "}"); + } else if (seq == "x") { + seq += next(true, in_string) + next(true, in_string); + } + var str = decode_escape_sequence(seq); + if (typeof str != "string") parse_error("Invalid escape sequence: \\" + seq); + return str; + } + + function read_octal_escape_sequence(ch) { + // Read + var p = peek(); + if (p >= "0" && p <= "7") { + ch += next(true); + if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7") + ch += next(true); + } + + // Parse + if (ch === "0") return "\0"; + if (ch.length > 0 && next_token.has_directive("use strict")) + parse_error("Legacy octal escape sequences are not allowed in strict mode"); + return String.fromCharCode(parseInt(ch, 8)); + } + + var read_string = with_eof_error("Unterminated string constant", function(quote_char) { + var quote = next(), ret = ""; + for (;;) { + var ch = next(true, true); + if (ch == "\\") ch = read_escaped_char(true); + else if (NEWLINE_CHARS[ch]) parse_error("Unterminated string constant"); + else if (ch == quote) break; + ret += ch; + } + var tok = token("string", ret); + tok.quote = quote_char; + return tok; + }); + + function skip_line_comment(type) { + var regex_allowed = S.regex_allowed; + var i = find_eol(), ret; + if (i == -1) { + ret = S.text.substr(S.pos); + S.pos = S.text.length; + } else { + ret = S.text.substring(S.pos, i); + S.pos = i; + } + S.col = S.tokcol + (S.pos - S.tokpos); + S.comments_before.push(token(type, ret, true)); + S.regex_allowed = regex_allowed; + return next_token; + } + + var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() { + var regex_allowed = S.regex_allowed; + var i = find("*/", true); + var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, "\n"); + // update stream position + forward(text.length /* doesn't count \r\n as 2 char while S.pos - i does */ + 2); + S.comments_before.push(token("comment2", text, true)); + S.regex_allowed = regex_allowed; + return next_token; + }); + + function read_name() { + var backslash = false, ch, escaped = false, name = peek() == "#" ? next() : ""; + while (ch = peek()) { + if (!backslash) { + if (ch == "\\") escaped = backslash = true, next(); + else if (is_identifier_char(ch)) name += next(); + else break; + } else { + if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX"); + ch = read_escaped_char(); + if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier"); + name += ch; + backslash = false; + } + } + if (KEYWORDS[name] && escaped) { + var hex = name.charCodeAt(0).toString(16).toUpperCase(); + name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1); + } + return name; + } + + var read_regexp = with_eof_error("Unterminated regular expression", function(source) { + var prev_backslash = false, ch, in_class = false; + while ((ch = next(true))) if (NEWLINE_CHARS[ch]) { + parse_error("Unexpected line terminator"); + } else if (prev_backslash) { + source += "\\" + ch; + prev_backslash = false; + } else if (ch == "[") { + in_class = true; + source += ch; + } else if (ch == "]" && in_class) { + in_class = false; + source += ch; + } else if (ch == "/" && !in_class) { + break; + } else if (ch == "\\") { + prev_backslash = true; + } else { + source += ch; + } + var mods = read_name(); + try { + var regexp = new RegExp(source, mods); + regexp.raw_source = source; + return token("regexp", regexp); + } catch (e) { + parse_error(e.message); + } + }); + + function read_operator(prefix) { + function grow(op) { + if (!peek()) return op; + var bigger = op + peek(); + if (OPERATORS[bigger]) { + next(); + return grow(bigger); + } else { + return op; + } + } + return token("operator", grow(prefix || next())); + } + + function handle_slash() { + next(); + switch (peek()) { + case "/": + next(); + return skip_line_comment("comment1"); + case "*": + next(); + return skip_multiline_comment(); + } + return S.regex_allowed ? read_regexp("") : read_operator("/"); + } + + function handle_dot() { + next(); + if (looking_at("..")) return token("operator", "." + next() + next()); + return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", "."); + } + + function read_word() { + var word = read_name(); + if (prev_was_dot) return token("name", word); + return KEYWORDS_ATOM[word] ? token("atom", word) + : !KEYWORDS[word] ? token("name", word) + : OPERATORS[word] ? token("operator", word) + : token("keyword", word); + } + + function with_eof_error(eof_error, cont) { + return function(x) { + try { + return cont(x); + } catch (ex) { + if (ex === EX_EOF) parse_error(eof_error); + else throw ex; + } + }; + } + + function next_token(force_regexp) { + if (force_regexp != null) + return read_regexp(force_regexp); + if (shebang && S.pos == 0 && looking_at("#!")) { + start_token(); + forward(2); + skip_line_comment("comment5"); + } + for (;;) { + skip_whitespace(); + start_token(); + if (html5_comments) { + if (looking_at("") && S.newline_before) { + forward(3); + skip_line_comment("comment4"); + continue; + } + } + var ch = peek(); + if (!ch) return token("eof"); + var code = ch.charCodeAt(0); + switch (code) { + case 34: case 39: return read_string(ch); + case 46: return handle_dot(); + case 47: + var tok = handle_slash(); + if (tok === next_token) continue; + return tok; + } + if (is_digit(code)) return read_num(); + if (PUNC_CHARS[ch]) return token("punc", next()); + if (looking_at("=>")) return token("punc", next() + next()); + if (OPERATOR_CHARS[ch]) return read_operator(); + if (code == 35 || code == 92 || !NON_IDENTIFIER_CHARS[ch]) return read_word(); + break; + } + parse_error("Unexpected character '" + ch + "'"); + } + + next_token.context = function(nc) { + if (nc) S = nc; + return S; + }; + + next_token.add_directive = function(directive) { + S.directives[directive] = true; + } + + next_token.push_directives_stack = function() { + S.directives = Object.create(S.directives); + } + + next_token.pop_directives_stack = function() { + S.directives = Object.getPrototypeOf(S.directives); + } + + next_token.has_directive = function(directive) { + return !!S.directives[directive]; + } + + return next_token; +} + +/* -----[ Parser (constants) ]----- */ + +var UNARY_PREFIX = makePredicate("typeof void delete -- ++ ! ~ - +"); + +var UNARY_POSTFIX = makePredicate("-- ++"); + +var ASSIGNMENT = makePredicate("= += -= /= *= %= **= >>= <<= >>>= &= |= ^= &&= ||= ??="); + +var PRECEDENCE = function(a, ret) { + for (var i = 0; i < a.length;) { + var b = a[i++]; + for (var j = 0; j < b.length; j++) { + ret[b[j]] = i; + } + } + return ret; +}([ + ["??"], + ["||"], + ["&&"], + ["|"], + ["^"], + ["&"], + ["==", "===", "!=", "!=="], + ["<", ">", "<=", ">=", "in", "instanceof"], + [">>", "<<", ">>>"], + ["+", "-"], + ["*", "/", "%"], + ["**"], +], {}); + +var ATOMIC_START_TOKEN = makePredicate("atom bigint num regexp string"); + +/* -----[ Parser ]----- */ + +function parse($TEXT, options) { + options = defaults(options, { + bare_returns : false, + expression : false, + filename : null, + html5_comments : true, + module : false, + shebang : true, + strict : false, + toplevel : null, + }, true); + + var S = { + input : typeof $TEXT == "string" + ? tokenizer($TEXT, options.filename, options.html5_comments, options.shebang) + : $TEXT, + in_async : false, + in_directives : true, + in_funarg : -1, + in_function : 0, + in_generator : false, + in_loop : 0, + labels : [], + peeked : null, + prev : null, + token : null, + }; + + S.token = next(); + + function is(type, value) { + return is_token(S.token, type, value); + } + + function peek() { + return S.peeked || (S.peeked = S.input()); + } + + function next() { + S.prev = S.token; + if (S.peeked) { + S.token = S.peeked; + S.peeked = null; + } else { + S.token = S.input(); + } + S.in_directives = S.in_directives && ( + S.token.type == "string" || is("punc", ";") + ); + return S.token; + } + + function prev() { + return S.prev; + } + + function croak(msg, line, col, pos) { + var ctx = S.input.context(); + js_error(msg, + ctx.filename, + line != null ? line : ctx.tokline, + col != null ? col : ctx.tokcol, + pos != null ? pos : ctx.tokpos); + } + + function token_error(token, msg) { + croak(msg, token.line, token.col); + } + + function token_to_string(type, value) { + return type + (value === undefined ? "" : " «" + value + "»"); + } + + function unexpected(token) { + if (token == null) token = S.token; + token_error(token, "Unexpected token: " + token_to_string(token.type, token.value)); + } + + function expect_token(type, val) { + if (is(type, val)) return next(); + token_error(S.token, "Unexpected token: " + token_to_string(S.token.type, S.token.value) + ", expected: " + token_to_string(type, val)); + } + + function expect(punc) { + return expect_token("punc", punc); + } + + function has_newline_before(token) { + return token.nlb || !all(token.comments_before, function(comment) { + return !comment.nlb; + }); + } + + function can_insert_semicolon() { + return !options.strict + && (is("eof") || is("punc", "}") || has_newline_before(S.token)); + } + + function semicolon(optional) { + if (is("punc", ";")) next(); + else if (!optional && !can_insert_semicolon()) expect(";"); + } + + function parenthesized() { + expect("("); + var exp = expression(); + expect(")"); + return exp; + } + + function embed_tokens(parser) { + return function() { + var start = S.token; + var expr = parser.apply(null, arguments); + var end = prev(); + expr.start = start; + expr.end = end; + return expr; + }; + } + + function handle_regexp() { + if (is("operator", "/") || is("operator", "/=")) { + S.peeked = null; + S.token = S.input(S.token.value.substr(1)); // force regexp + } + } + + var statement = embed_tokens(function(toplevel) { + handle_regexp(); + switch (S.token.type) { + case "string": + var dir = S.in_directives; + var body = expression(); + if (dir) { + if (body instanceof AST_String) { + var value = body.start.raw.slice(1, -1); + S.input.add_directive(value); + body.value = value; + } else { + S.in_directives = dir = false; + } + } + semicolon(); + return dir ? new AST_Directive(body) : new AST_SimpleStatement({ body: body }); + case "num": + case "bigint": + case "regexp": + case "operator": + case "atom": + return simple_statement(); + + case "name": + switch (S.token.value) { + case "async": + if (is_token(peek(), "keyword", "function")) { + next(); + next(); + if (!is("operator", "*")) return function_(AST_AsyncDefun); + next(); + return function_(AST_AsyncGeneratorDefun); + } + break; + case "await": + if (S.in_async) return simple_statement(); + break; + case "export": + if (!toplevel && options.module !== "") unexpected(); + next(); + return export_(); + case "import": + var token = peek(); + if (token.type == "punc" && /^[(.]$/.test(token.value)) break; + if (!toplevel && options.module !== "") unexpected(); + next(); + return import_(); + case "let": + if (is_vardefs()) { + next(); + var node = let_(); + semicolon(); + return node; + } + break; + case "yield": + if (S.in_generator) return simple_statement(); + break; + } + return is_token(peek(), "punc", ":") + ? labeled_statement() + : simple_statement(); + + case "punc": + switch (S.token.value) { + case "{": + return new AST_BlockStatement({ + start : S.token, + body : block_(), + end : prev() + }); + case "[": + case "(": + case "`": + return simple_statement(); + case ";": + S.in_directives = false; + next(); + return new AST_EmptyStatement(); + default: + unexpected(); + } + + case "keyword": + switch (S.token.value) { + case "break": + next(); + return break_cont(AST_Break); + + case "class": + next(); + return class_(AST_DefClass); + + case "const": + next(); + var node = const_(); + semicolon(); + return node; + + case "continue": + next(); + return break_cont(AST_Continue); + + case "debugger": + next(); + semicolon(); + return new AST_Debugger(); + + case "do": + next(); + var body = in_loop(statement); + expect_token("keyword", "while"); + var condition = parenthesized(); + semicolon(true); + return new AST_Do({ + body : body, + condition : condition, + }); + + case "while": + next(); + return new AST_While({ + condition : parenthesized(), + body : in_loop(statement), + }); + + case "for": + next(); + return for_(); + + case "function": + next(); + if (!is("operator", "*")) return function_(AST_Defun); + next(); + return function_(AST_GeneratorDefun); + + case "if": + next(); + return if_(); + + case "return": + if (S.in_function == 0 && !options.bare_returns) + croak("'return' outside of function"); + next(); + var value = null; + if (is("punc", ";")) { + next(); + } else if (!can_insert_semicolon()) { + value = expression(); + semicolon(); + } + return new AST_Return({ value: value }); + + case "switch": + next(); + return new AST_Switch({ + expression : parenthesized(), + body : in_loop(switch_body_), + }); + + case "throw": + next(); + if (has_newline_before(S.token)) + croak("Illegal newline after 'throw'"); + var value = expression(); + semicolon(); + return new AST_Throw({ value: value }); + + case "try": + next(); + return try_(); + + case "var": + next(); + var node = var_(); + semicolon(); + return node; + + case "with": + if (S.input.has_directive("use strict")) { + croak("Strict mode may not include a with statement"); + } + next(); + return new AST_With({ + expression : parenthesized(), + body : statement(), + }); + } + } + unexpected(); + }); + + function labeled_statement() { + var label = as_symbol(AST_Label); + if (!all(S.labels, function(l) { + return l.name != label.name; + })) { + // ECMA-262, 12.12: An ECMAScript program is considered + // syntactically incorrect if it contains a + // LabelledStatement that is enclosed by a + // LabelledStatement with the same Identifier as label. + croak("Label " + label.name + " defined twice"); + } + expect(":"); + S.labels.push(label); + var stat = statement(); + S.labels.pop(); + if (!(stat instanceof AST_IterationStatement)) { + // check for `continue` that refers to this label. + // those should be reported as syntax errors. + // https://github.com/mishoo/UglifyJS/issues/287 + label.references.forEach(function(ref) { + if (ref instanceof AST_Continue) { + token_error(ref.label.start, "Continue label `" + label.name + "` must refer to IterationStatement"); + } + }); + } + return new AST_LabeledStatement({ body: stat, label: label }); + } + + function simple_statement() { + var body = expression(); + semicolon(); + return new AST_SimpleStatement({ body: body }); + } + + function break_cont(type) { + var label = null, ldef; + if (!can_insert_semicolon()) { + label = as_symbol(AST_LabelRef, true); + } + if (label != null) { + ldef = find_if(function(l) { + return l.name == label.name; + }, S.labels); + if (!ldef) token_error(label.start, "Undefined label " + label.name); + label.thedef = ldef; + } else if (S.in_loop == 0) croak(type.TYPE + " not inside a loop or switch"); + semicolon(); + var stat = new type({ label: label }); + if (ldef) ldef.references.push(stat); + return stat; + } + + function has_modifier(name, no_nlb) { + if (!is("name", name)) return; + var token = peek(); + if (!token) return; + if (is_token(token, "operator", "=")) return; + if (token.type == "punc" && /^[(;}]$/.test(token.value)) return; + if (no_nlb && has_newline_before(token)) return; + return next(); + } + + function class_(ctor) { + var was_async = S.in_async; + var was_gen = S.in_generator; + S.input.push_directives_stack(); + S.input.add_directive("use strict"); + var name; + if (ctor === AST_DefClass) { + name = as_symbol(AST_SymbolDefClass); + } else { + name = as_symbol(AST_SymbolClass, true); + } + var parent = null; + if (is("keyword", "extends")) { + next(); + handle_regexp(); + parent = expr_atom(true); + } + expect("{"); + var props = []; + while (!is("punc", "}")) { + if (is("punc", ";")) { + next(); + continue; + } + var start = S.token; + var fixed = !!has_modifier("static"); + var async = has_modifier("async", true); + if (is("operator", "*")) { + next(); + var internal = is("name") && /^#/.test(S.token.value); + var key = as_property_key(); + var gen_start = S.token; + var gen = function_(async ? AST_AsyncGeneratorFunction : AST_GeneratorFunction); + gen.start = gen_start; + gen.end = prev(); + props.push(new AST_ClassMethod({ + start: start, + static: fixed, + private: internal, + key: key, + value: gen, + end: prev(), + })); + continue; + } + if (fixed && is("punc", "{")) { + props.push(new AST_ClassInit({ + start: start, + value: new AST_ClassInitBlock({ + start: start, + body: block_(), + end: prev(), + }), + end: prev(), + })); + continue; + } + var internal = is("name") && /^#/.test(S.token.value); + var key = as_property_key(); + if (is("punc", "(")) { + var func_start = S.token; + var func = function_(async ? AST_AsyncFunction : AST_Function); + func.start = func_start; + func.end = prev(); + props.push(new AST_ClassMethod({ + start: start, + static: fixed, + private: internal, + key: key, + value: func, + end: prev(), + })); + continue; + } + if (async) unexpected(async); + var value = null; + if (is("operator", "=")) { + next(); + S.in_async = false; + S.in_generator = false; + value = maybe_assign(); + S.in_generator = was_gen; + S.in_async = was_async; + } else if (!(is("punc", ";") || is("punc", "}"))) { + var type = null; + switch (key) { + case "get": + type = AST_ClassGetter; + break; + case "set": + type = AST_ClassSetter; + break; + } + if (type) { + props.push(new type({ + start: start, + static: fixed, + private: is("name") && /^#/.test(S.token.value), + key: as_property_key(), + value: create_accessor(), + end: prev(), + })); + continue; + } + } + semicolon(); + props.push(new AST_ClassField({ + start: start, + static: fixed, + private: internal, + key: key, + value: value, + end: prev(), + })); + } + next(); + S.input.pop_directives_stack(); + S.in_generator = was_gen; + S.in_async = was_async; + return new ctor({ + extends: parent, + name: name, + properties: props, + }); + } + + function for_() { + var await_token = is("name", "await") && next(); + expect("("); + var init = null; + if (await_token || !is("punc", ";")) { + init = is("keyword", "const") + ? (next(), const_(true)) + : is("name", "let") && is_vardefs() + ? (next(), let_(true)) + : is("keyword", "var") + ? (next(), var_(true)) + : expression(true); + var ctor; + if (await_token) { + expect_token("name", "of"); + ctor = AST_ForAwaitOf; + } else if (is("operator", "in")) { + next(); + ctor = AST_ForIn; + } else if (is("name", "of")) { + next(); + ctor = AST_ForOf; + } + if (ctor) { + if (init instanceof AST_Definitions) { + if (init.definitions.length > 1) { + token_error(init.start, "Only one variable declaration allowed in for..in/of loop"); + } + if (ctor !== AST_ForIn && init.definitions[0].value) { + token_error(init.definitions[0].value.start, "No initializers allowed in for..of loop"); + } + } else if (!(is_assignable(init) || (init = to_destructured(init)) instanceof AST_Destructured)) { + token_error(init.start, "Invalid left-hand side in for..in/of loop"); + } + return for_enum(ctor, init); + } + } + return regular_for(init); + } + + function regular_for(init) { + expect(";"); + var test = is("punc", ";") ? null : expression(); + expect(";"); + var step = is("punc", ")") ? null : expression(); + expect(")"); + return new AST_For({ + init : init, + condition : test, + step : step, + body : in_loop(statement) + }); + } + + function for_enum(ctor, init) { + handle_regexp(); + var obj = expression(); + expect(")"); + return new ctor({ + init : init, + object : obj, + body : in_loop(statement) + }); + } + + function to_funarg(node) { + if (node instanceof AST_Array) { + var rest = null; + if (node.elements[node.elements.length - 1] instanceof AST_Spread) { + rest = to_funarg(node.elements.pop().expression); + } + return new AST_DestructuredArray({ + start: node.start, + elements: node.elements.map(to_funarg), + rest: rest, + end: node.end, + }); + } + if (node instanceof AST_Assign) return new AST_DefaultValue({ + start: node.start, + name: to_funarg(node.left), + value: node.right, + end: node.end, + }); + if (node instanceof AST_DefaultValue) { + node.name = to_funarg(node.name); + return node; + } + if (node instanceof AST_DestructuredArray) { + node.elements = node.elements.map(to_funarg); + if (node.rest) node.rest = to_funarg(node.rest); + return node; + } + if (node instanceof AST_DestructuredObject) { + node.properties.forEach(function(prop) { + prop.value = to_funarg(prop.value); + }); + if (node.rest) node.rest = to_funarg(node.rest); + return node; + } + if (node instanceof AST_Hole) return node; + if (node instanceof AST_Object) { + var rest = null; + if (node.properties[node.properties.length - 1] instanceof AST_Spread) { + rest = to_funarg(node.properties.pop().expression); + } + return new AST_DestructuredObject({ + start: node.start, + properties: node.properties.map(function(prop) { + if (!(prop instanceof AST_ObjectKeyVal)) token_error(prop.start, "Invalid destructuring assignment"); + return new AST_DestructuredKeyVal({ + start: prop.start, + key: prop.key, + value: to_funarg(prop.value), + end: prop.end, + }); + }), + rest: rest, + end: node.end, + }); + } + if (node instanceof AST_SymbolFunarg) return node; + if (node instanceof AST_SymbolRef) return new AST_SymbolFunarg(node); + if (node instanceof AST_Yield) return new AST_SymbolFunarg({ + start: node.start, + name: "yield", + end: node.end, + }); + token_error(node.start, "Invalid arrow parameter"); + } + + function arrow(exprs, start, async) { + var was_async = S.in_async; + var was_gen = S.in_generator; + S.in_async = async; + S.in_generator = false; + var was_funarg = S.in_funarg; + S.in_funarg = S.in_function; + var argnames = exprs.map(to_funarg); + var rest = exprs.rest || null; + if (rest) rest = to_funarg(rest); + S.in_funarg = was_funarg; + expect("=>"); + var body, value; + var loop = S.in_loop; + var labels = S.labels; + ++S.in_function; + S.input.push_directives_stack(); + S.in_loop = 0; + S.labels = []; + if (is("punc", "{")) { + S.in_directives = true; + body = block_(); + value = null; + } else { + body = []; + handle_regexp(); + value = maybe_assign(); + } + var is_strict = S.input.has_directive("use strict"); + S.input.pop_directives_stack(); + --S.in_function; + S.in_loop = loop; + S.labels = labels; + S.in_generator = was_gen; + S.in_async = was_async; + var node = new (async ? AST_AsyncArrow : AST_Arrow)({ + start: start, + argnames: argnames, + rest: rest, + body: body, + value: value, + end: prev(), + }); + if (is_strict) node.each_argname(strict_verify_symbol); + return node; + } + + var function_ = function(ctor) { + var was_async = S.in_async; + var was_gen = S.in_generator; + var name; + if (/Defun$/.test(ctor.TYPE)) { + name = as_symbol(AST_SymbolDefun); + S.in_async = /^Async/.test(ctor.TYPE); + S.in_generator = /Generator/.test(ctor.TYPE); + } else { + S.in_async = /^Async/.test(ctor.TYPE); + S.in_generator = /Generator/.test(ctor.TYPE); + name = as_symbol(AST_SymbolLambda, true); + } + if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration)) + unexpected(prev()); + expect("("); + var was_funarg = S.in_funarg; + S.in_funarg = S.in_function; + var argnames = expr_list(")", !options.strict, false, function() { + return maybe_default(AST_SymbolFunarg); + }); + S.in_funarg = was_funarg; + var loop = S.in_loop; + var labels = S.labels; + ++S.in_function; + S.in_directives = true; + S.input.push_directives_stack(); + S.in_loop = 0; + S.labels = []; + var body = block_(); + var is_strict = S.input.has_directive("use strict"); + S.input.pop_directives_stack(); + --S.in_function; + S.in_loop = loop; + S.labels = labels; + S.in_generator = was_gen; + S.in_async = was_async; + var node = new ctor({ + name: name, + argnames: argnames, + rest: argnames.rest || null, + body: body, + }); + if (is_strict) { + if (name) strict_verify_symbol(name); + node.each_argname(strict_verify_symbol); + } + return node; + }; + + function if_() { + var cond = parenthesized(), body = statement(), alt = null; + if (is("keyword", "else")) { + next(); + alt = statement(); + } + return new AST_If({ + condition : cond, + body : body, + alternative : alt, + }); + } + + function is_alias() { + return is("name") || is("string") || is_identifier_string(S.token.value); + } + + function make_string(token) { + return new AST_String({ + start: token, + quote: token.quote, + value: token.value, + end: token, + }); + } + + function as_path() { + var path = S.token; + expect_token("string"); + semicolon(); + return make_string(path); + } + + function export_() { + if (is("operator", "*")) { + var key = S.token; + var alias = key; + next(); + if (is("name", "as")) { + next(); + if (!is_alias()) expect_token("name"); + alias = S.token; + next(); + } + expect_token("name", "from"); + return new AST_ExportForeign({ + aliases: [ make_string(alias) ], + keys: [ make_string(key) ], + path: as_path(), + }); + } + if (is("punc", "{")) { + next(); + var aliases = []; + var keys = []; + while (is_alias()) { + var key = S.token; + next(); + keys.push(key); + if (is("name", "as")) { + next(); + if (!is_alias()) expect_token("name"); + aliases.push(S.token); + next(); + } else { + aliases.push(key); + } + if (!is("punc", "}")) expect(","); + } + expect("}"); + if (is("name", "from")) { + next(); + return new AST_ExportForeign({ + aliases: aliases.map(make_string), + keys: keys.map(make_string), + path: as_path(), + }); + } + semicolon(); + return new AST_ExportReferences({ + properties: keys.map(function(token, index) { + if (!is_token(token, "name")) token_error(token, "Name expected"); + var sym = _make_symbol(AST_SymbolExport, token); + sym.alias = make_string(aliases[index]); + return sym; + }), + }); + } + if (is("keyword", "default")) { + next(); + var start = S.token; + var body = export_default_decl(); + if (body) { + body.start = start; + body.end = prev(); + } else { + handle_regexp(); + body = expression(); + semicolon(); + } + return new AST_ExportDefault({ body: body }); + } + return new AST_ExportDeclaration({ body: export_decl() }); + } + + function maybe_named(def, expr) { + if (expr.name) { + expr = new def(expr); + expr.name = new (def === AST_DefClass ? AST_SymbolDefClass : AST_SymbolDefun)(expr.name); + } + return expr; + } + + function export_default_decl() { + if (is("name", "async")) { + if (!is_token(peek(), "keyword", "function")) return; + next(); + next(); + if (!is("operator", "*")) return maybe_named(AST_AsyncDefun, function_(AST_AsyncFunction)); + next(); + return maybe_named(AST_AsyncGeneratorDefun, function_(AST_AsyncGeneratorFunction)); + } else if (is("keyword")) switch (S.token.value) { + case "class": + next(); + return maybe_named(AST_DefClass, class_(AST_ClassExpression)); + case "function": + next(); + if (!is("operator", "*")) return maybe_named(AST_Defun, function_(AST_Function)); + next(); + return maybe_named(AST_GeneratorDefun, function_(AST_GeneratorFunction)); + } + } + + var export_decl = embed_tokens(function() { + if (is("name")) switch (S.token.value) { + case "async": + next(); + expect_token("keyword", "function"); + if (!is("operator", "*")) return function_(AST_AsyncDefun); + next(); + return function_(AST_AsyncGeneratorDefun); + case "let": + next(); + var node = let_(); + semicolon(); + return node; + } else if (is("keyword")) switch (S.token.value) { + case "class": + next(); + return class_(AST_DefClass); + case "const": + next(); + var node = const_(); + semicolon(); + return node; + case "function": + next(); + if (!is("operator", "*")) return function_(AST_Defun); + next(); + return function_(AST_GeneratorDefun); + case "var": + next(); + var node = var_(); + semicolon(); + return node; + } + unexpected(); + }); + + function import_() { + var all = null; + var def = as_symbol(AST_SymbolImport, true); + var props = null; + var cont; + if (def) { + def.key = new AST_String({ + start: def.start, + value: "", + end: def.end, + }); + if (cont = is("punc", ",")) next(); + } else { + cont = !is("string"); + } + if (cont) { + if (is("operator", "*")) { + var key = S.token; + next(); + expect_token("name", "as"); + all = as_symbol(AST_SymbolImport); + all.key = make_string(key); + } else { + expect("{"); + props = []; + while (is_alias()) { + var alias; + if (is_token(peek(), "name", "as")) { + var key = S.token; + next(); + next(); + alias = as_symbol(AST_SymbolImport); + alias.key = make_string(key); + } else { + alias = as_symbol(AST_SymbolImport); + alias.key = new AST_String({ + start: alias.start, + value: alias.name, + end: alias.end, + }); + } + props.push(alias); + if (!is("punc", "}")) expect(","); + } + expect("}"); + } + } + if (all || def || props) expect_token("name", "from"); + return new AST_Import({ + all: all, + default: def, + path: as_path(), + properties: props, + }); + } + + function block_() { + expect("{"); + var a = []; + while (!is("punc", "}")) { + if (is("eof")) expect("}"); + a.push(statement()); + } + next(); + return a; + } + + function switch_body_() { + expect("{"); + var a = [], branch, cur, default_branch, tmp; + while (!is("punc", "}")) { + if (is("eof")) expect("}"); + if (is("keyword", "case")) { + if (branch) branch.end = prev(); + cur = []; + branch = new AST_Case({ + start : (tmp = S.token, next(), tmp), + expression : expression(), + body : cur + }); + a.push(branch); + expect(":"); + } else if (is("keyword", "default")) { + if (branch) branch.end = prev(); + if (default_branch) croak("More than one default clause in switch statement"); + cur = []; + branch = new AST_Default({ + start : (tmp = S.token, next(), expect(":"), tmp), + body : cur + }); + a.push(branch); + default_branch = branch; + } else { + if (!cur) unexpected(); + cur.push(statement()); + } + } + if (branch) branch.end = prev(); + next(); + return a; + } + + function try_() { + var body = block_(), bcatch = null, bfinally = null; + if (is("keyword", "catch")) { + var start = S.token; + next(); + var name = null; + if (is("punc", "(")) { + next(); + name = maybe_destructured(AST_SymbolCatch); + expect(")"); + } + bcatch = new AST_Catch({ + start : start, + argname : name, + body : block_(), + end : prev() + }); + } + if (is("keyword", "finally")) { + var start = S.token; + next(); + bfinally = new AST_Finally({ + start : start, + body : block_(), + end : prev() + }); + } + if (!bcatch && !bfinally) + croak("Missing catch/finally blocks"); + return new AST_Try({ + body : body, + bcatch : bcatch, + bfinally : bfinally + }); + } + + function vardefs(type, no_in) { + var a = []; + for (;;) { + var start = S.token; + var name = maybe_destructured(type); + var value = null; + if (is("operator", "=")) { + next(); + value = maybe_assign(no_in); + } else if (!no_in && (type === AST_SymbolConst || name instanceof AST_Destructured)) { + croak("Missing initializer in declaration"); + } + a.push(new AST_VarDef({ + start : start, + name : name, + value : value, + end : prev() + })); + if (!is("punc", ",")) + break; + next(); + } + return a; + } + + function is_vardefs() { + var token = peek(); + return is_token(token, "name") || is_token(token, "punc", "[") || is_token(token, "punc", "{"); + } + + var const_ = function(no_in) { + return new AST_Const({ + start : prev(), + definitions : vardefs(AST_SymbolConst, no_in), + end : prev() + }); + }; + + var let_ = function(no_in) { + return new AST_Let({ + start : prev(), + definitions : vardefs(AST_SymbolLet, no_in), + end : prev() + }); + }; + + var var_ = function(no_in) { + return new AST_Var({ + start : prev(), + definitions : vardefs(AST_SymbolVar, no_in), + end : prev() + }); + }; + + var new_ = function(allow_calls) { + var start = S.token; + expect_token("operator", "new"); + var call; + if (is("punc", ".") && is_token(peek(), "name", "target")) { + next(); + next(); + call = new AST_NewTarget(); + } else { + var exp = expr_atom(false), args; + if (is("punc", "(")) { + next(); + args = expr_list(")", !options.strict); + } else { + args = []; + } + call = new AST_New({ expression: exp, args: args }); + } + call.start = start; + call.end = prev(); + return subscripts(call, allow_calls); + }; + + function as_atom_node() { + var ret, tok = S.token, value = tok.value; + switch (tok.type) { + case "num": + if (isFinite(value)) { + ret = new AST_Number({ value: value }); + } else { + ret = new AST_Infinity(); + if (value < 0) ret = new AST_UnaryPrefix({ operator: "-", expression: ret }); + } + break; + case "bigint": + ret = new AST_BigInt({ value: value }); + break; + case "string": + ret = new AST_String({ value: value, quote: tok.quote }); + break; + case "regexp": + ret = new AST_RegExp({ value: value }); + break; + case "atom": + switch (value) { + case "false": + ret = new AST_False(); + break; + case "true": + ret = new AST_True(); + break; + case "null": + ret = new AST_Null(); + break; + default: + unexpected(); + } + break; + default: + unexpected(); + } + next(); + ret.start = ret.end = tok; + return ret; + } + + var expr_atom = function(allow_calls) { + if (is("operator", "new")) { + return new_(allow_calls); + } + var start = S.token; + if (is("punc")) { + switch (start.value) { + case "`": + return subscripts(template(null), allow_calls); + case "(": + next(); + if (is("punc", ")")) { + next(); + return arrow([], start); + } + var ex = expression(false, true); + var len = start.comments_before.length; + [].unshift.apply(ex.start.comments_before, start.comments_before); + start.comments_before.length = 0; + start.comments_before = ex.start.comments_before; + start.comments_before_length = len; + if (len == 0 && start.comments_before.length > 0) { + var comment = start.comments_before[0]; + if (!comment.nlb) { + comment.nlb = start.nlb; + start.nlb = false; + } + } + start.comments_after = ex.start.comments_after; + ex.start = start; + expect(")"); + var end = prev(); + end.comments_before = ex.end.comments_before; + end.comments_after.forEach(function(comment) { + ex.end.comments_after.push(comment); + if (comment.nlb) S.token.nlb = true; + }); + end.comments_after.length = 0; + end.comments_after = ex.end.comments_after; + ex.end = end; + if (is("punc", "=>")) return arrow(ex instanceof AST_Sequence ? ex.expressions : [ ex ], start); + return subscripts(ex, allow_calls); + case "[": + return subscripts(array_(), allow_calls); + case "{": + return subscripts(object_(), allow_calls); + } + unexpected(); + } + if (is("keyword")) switch (start.value) { + case "class": + next(); + var clazz = class_(AST_ClassExpression); + clazz.start = start; + clazz.end = prev(); + return subscripts(clazz, allow_calls); + case "function": + next(); + var func; + if (is("operator", "*")) { + next(); + func = function_(AST_GeneratorFunction); + } else { + func = function_(AST_Function); + } + func.start = start; + func.end = prev(); + return subscripts(func, allow_calls); + } + if (is("name")) { + var sym = _make_symbol(AST_SymbolRef, start); + next(); + if (sym.name == "async") { + if (is("keyword", "function")) { + next(); + var func; + if (is("operator", "*")) { + next(); + func = function_(AST_AsyncGeneratorFunction); + } else { + func = function_(AST_AsyncFunction); + } + func.start = start; + func.end = prev(); + return subscripts(func, allow_calls); + } + if (is("name") && is_token(peek(), "punc", "=>")) { + start = S.token; + sym = _make_symbol(AST_SymbolRef, start); + next(); + return arrow([ sym ], start, true); + } + if (is("punc", "(")) { + var call = subscripts(sym, allow_calls); + if (!is("punc", "=>")) return call; + var args = call.args; + if (args[args.length - 1] instanceof AST_Spread) { + args.rest = args.pop().expression; + } + return arrow(args, start, true); + } + } + return is("punc", "=>") ? arrow([ sym ], start) : subscripts(sym, allow_calls); + } + if (ATOMIC_START_TOKEN[S.token.type]) { + return subscripts(as_atom_node(), allow_calls); + } + unexpected(); + }; + + function expr_list(closing, allow_trailing_comma, allow_empty, parser) { + if (!parser) parser = maybe_assign; + var first = true, a = []; + while (!is("punc", closing)) { + if (first) first = false; else expect(","); + if (allow_trailing_comma && is("punc", closing)) break; + if (allow_empty && is("punc", ",")) { + a.push(new AST_Hole({ start: S.token, end: S.token })); + } else if (!is("operator", "...")) { + a.push(parser()); + } else if (parser === maybe_assign) { + a.push(new AST_Spread({ + start: S.token, + expression: (next(), parser()), + end: prev(), + })); + } else { + next(); + a.rest = parser(); + if (a.rest instanceof AST_DefaultValue) token_error(a.rest.start, "Invalid rest parameter"); + break; + } + } + expect(closing); + return a; + } + + var array_ = embed_tokens(function() { + expect("["); + return new AST_Array({ + elements: expr_list("]", !options.strict, true) + }); + }); + + var create_accessor = embed_tokens(function() { + return function_(AST_Accessor); + }); + + var object_ = embed_tokens(function() { + expect("{"); + var first = true, a = []; + while (!is("punc", "}")) { + if (first) first = false; else expect(","); + // allow trailing comma + if (!options.strict && is("punc", "}")) break; + var start = S.token; + if (is("operator", "*")) { + next(); + var key = as_property_key(); + var gen_start = S.token; + var gen = function_(AST_GeneratorFunction); + gen.start = gen_start; + gen.end = prev(); + a.push(new AST_ObjectMethod({ + start: start, + key: key, + value: gen, + end: prev(), + })); + continue; + } + if (is("operator", "...")) { + next(); + a.push(new AST_Spread({ + start: start, + expression: maybe_assign(), + end: prev(), + })); + continue; + } + if (is_token(peek(), "operator", "=")) { + var name = as_symbol(AST_SymbolRef); + next(); + a.push(new AST_ObjectKeyVal({ + start: start, + key: start.value, + value: new AST_Assign({ + start: start, + left: name, + operator: "=", + right: maybe_assign(), + end: prev(), + }), + end: prev(), + })); + continue; + } + if (is_token(peek(), "punc", ",") || is_token(peek(), "punc", "}")) { + a.push(new AST_ObjectKeyVal({ + start: start, + key: start.value, + value: as_symbol(AST_SymbolRef), + end: prev(), + })); + continue; + } + var key = as_property_key(); + if (is("punc", "(")) { + var func_start = S.token; + var func = function_(AST_Function); + func.start = func_start; + func.end = prev(); + a.push(new AST_ObjectMethod({ + start: start, + key: key, + value: func, + end: prev(), + })); + continue; + } + if (is("punc", ":")) { + next(); + a.push(new AST_ObjectKeyVal({ + start: start, + key: key, + value: maybe_assign(), + end: prev(), + })); + continue; + } + if (start.type == "name") switch (key) { + case "async": + var is_gen = is("operator", "*") && next(); + key = as_property_key(); + var func_start = S.token; + var func = function_(is_gen ? AST_AsyncGeneratorFunction : AST_AsyncFunction); + func.start = func_start; + func.end = prev(); + a.push(new AST_ObjectMethod({ + start: start, + key: key, + value: func, + end: prev(), + })); + continue; + case "get": + a.push(new AST_ObjectGetter({ + start: start, + key: as_property_key(), + value: create_accessor(), + end: prev(), + })); + continue; + case "set": + a.push(new AST_ObjectSetter({ + start: start, + key: as_property_key(), + value: create_accessor(), + end: prev(), + })); + continue; + } + unexpected(); + } + next(); + return new AST_Object({ properties: a }); + }); + + function as_property_key() { + var tmp = S.token; + switch (tmp.type) { + case "operator": + if (!KEYWORDS[tmp.value]) unexpected(); + case "num": + case "string": + case "name": + case "keyword": + case "atom": + next(); + return "" + tmp.value; + case "punc": + expect("["); + var key = maybe_assign(); + expect("]"); + return key; + default: + unexpected(); + } + } + + function as_name() { + var name = S.token.value; + expect_token("name"); + return name; + } + + function _make_symbol(type, token) { + var name = token.value; + switch (name) { + case "await": + if (S.in_async) unexpected(token); + break; + case "super": + type = AST_Super; + break; + case "this": + type = AST_This; + break; + case "yield": + if (S.in_generator) unexpected(token); + break; + } + return new type({ + name: "" + name, + start: token, + end: token, + }); + } + + function strict_verify_symbol(sym) { + if (sym.name == "arguments" || sym.name == "eval" || sym.name == "let") + token_error(sym.start, "Unexpected " + sym.name + " in strict mode"); + } + + function as_symbol(type, no_error) { + if (!is("name")) { + if (!no_error) croak("Name expected"); + return null; + } + var sym = _make_symbol(type, S.token); + if (S.input.has_directive("use strict") && sym instanceof AST_SymbolDeclaration) { + strict_verify_symbol(sym); + } + next(); + return sym; + } + + function maybe_destructured(type) { + var start = S.token; + if (is("punc", "[")) { + next(); + var elements = expr_list("]", !options.strict, true, function() { + return maybe_default(type); + }); + return new AST_DestructuredArray({ + start: start, + elements: elements, + rest: elements.rest || null, + end: prev(), + }); + } + if (is("punc", "{")) { + next(); + var first = true, a = [], rest = null; + while (!is("punc", "}")) { + if (first) first = false; else expect(","); + // allow trailing comma + if (!options.strict && is("punc", "}")) break; + var key_start = S.token; + if (is("punc", "[") || is_token(peek(), "punc", ":")) { + var key = as_property_key(); + expect(":"); + a.push(new AST_DestructuredKeyVal({ + start: key_start, + key: key, + value: maybe_default(type), + end: prev(), + })); + continue; + } + if (is("operator", "...")) { + next(); + rest = maybe_destructured(type); + break; + } + var name = as_symbol(type); + if (is("operator", "=")) { + next(); + name = new AST_DefaultValue({ + start: name.start, + name: name, + value: maybe_assign(), + end: prev(), + }); + } + a.push(new AST_DestructuredKeyVal({ + start: key_start, + key: key_start.value, + value: name, + end: prev(), + })); + } + expect("}"); + return new AST_DestructuredObject({ + start: start, + properties: a, + rest: rest, + end: prev(), + }); + } + return as_symbol(type); + } + + function maybe_default(type) { + var start = S.token; + var name = maybe_destructured(type); + if (!is("operator", "=")) return name; + next(); + return new AST_DefaultValue({ + start: start, + name: name, + value: maybe_assign(), + end: prev(), + }); + } + + function template(tag) { + var start = tag ? tag.start : S.token; + var read = S.input.context().read_template; + var strings = []; + var expressions = []; + while (read(strings)) { + next(); + expressions.push(expression()); + if (!is("punc", "}")) unexpected(); + } + next(); + return new AST_Template({ + start: start, + expressions: expressions, + strings: strings, + tag: tag, + end: prev(), + }); + } + + function subscripts(expr, allow_calls) { + var start = expr.start; + var optional = null; + while (true) { + if (is("operator", "?") && is_token(peek(), "punc", ".")) { + next(); + next(); + optional = expr; + } + if (is("punc", "[")) { + next(); + var prop = expression(); + expect("]"); + expr = new AST_Sub({ + start: start, + optional: optional === expr, + expression: expr, + property: prop, + end: prev(), + }); + } else if (allow_calls && is("punc", "(")) { + next(); + expr = new AST_Call({ + start: start, + optional: optional === expr, + expression: expr, + args: expr_list(")", !options.strict), + end: prev(), + }); + } else if (optional === expr || is("punc", ".")) { + if (optional !== expr) next(); + expr = new AST_Dot({ + start: start, + optional: optional === expr, + expression: expr, + property: as_name(), + end: prev(), + }); + } else if (is("punc", "`")) { + if (optional) croak("Invalid template on optional chain"); + expr = template(expr); + } else { + break; + } + } + if (optional) expr.terminal = true; + if (expr instanceof AST_Call && !expr.pure) { + var start = expr.start; + var comments = start.comments_before; + var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length; + while (--i >= 0) { + if (/[@#]__PURE__/.test(comments[i].value)) { + expr.pure = true; + break; + } + } + } + return expr; + } + + function maybe_unary(no_in) { + var start = S.token; + if (S.in_async && is("name", "await")) { + if (S.in_funarg === S.in_function) croak("Invalid use of await in function argument"); + S.input.context().regex_allowed = true; + next(); + return new AST_Await({ + start: start, + expression: maybe_unary(no_in), + end: prev(), + }); + } + if (S.in_generator && is("name", "yield")) { + if (S.in_funarg === S.in_function) croak("Invalid use of yield in function argument"); + S.input.context().regex_allowed = true; + next(); + var exp = null; + var nested = false; + if (is("operator", "*")) { + next(); + exp = maybe_assign(no_in); + nested = true; + } else if (is("punc") ? !PUNC_AFTER_EXPRESSION[S.token.value] : !can_insert_semicolon()) { + exp = maybe_assign(no_in); + } + return new AST_Yield({ + start: start, + expression: exp, + nested: nested, + end: prev(), + }); + } + if (is("operator") && UNARY_PREFIX[start.value]) { + next(); + handle_regexp(); + var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(no_in)); + ex.start = start; + ex.end = prev(); + return ex; + } + var val = expr_atom(true); + while (is("operator") && UNARY_POSTFIX[S.token.value] && !has_newline_before(S.token)) { + val = make_unary(AST_UnaryPostfix, S.token, val); + val.start = start; + val.end = S.token; + next(); + } + return val; + } + + function make_unary(ctor, token, expr) { + var op = token.value; + switch (op) { + case "++": + case "--": + if (!is_assignable(expr)) + token_error(token, "Invalid use of " + op + " operator"); + break; + case "delete": + if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict")) + token_error(expr.start, "Calling delete on expression not allowed in strict mode"); + break; + } + return new ctor({ operator: op, expression: expr }); + } + + var expr_op = function(left, min_precision, no_in) { + var op = is("operator") ? S.token.value : null; + if (op == "in" && no_in) op = null; + var precision = op != null ? PRECEDENCE[op] : null; + if (precision != null && precision > min_precision) { + next(); + var right = expr_op(maybe_unary(no_in), op == "**" ? precision - 1 : precision, no_in); + return expr_op(new AST_Binary({ + start : left.start, + left : left, + operator : op, + right : right, + end : right.end, + }), min_precision, no_in); + } + return left; + }; + + function expr_ops(no_in) { + return expr_op(maybe_unary(no_in), 0, no_in); + } + + var maybe_conditional = function(no_in) { + var start = S.token; + var expr = expr_ops(no_in); + if (is("operator", "?")) { + next(); + var yes = maybe_assign(); + expect(":"); + return new AST_Conditional({ + start : start, + condition : expr, + consequent : yes, + alternative : maybe_assign(no_in), + end : prev() + }); + } + return expr; + }; + + function is_assignable(expr) { + return expr instanceof AST_PropAccess && !expr.optional || expr instanceof AST_SymbolRef; + } + + function to_destructured(node) { + if (node instanceof AST_Array) { + var rest = null; + if (node.elements[node.elements.length - 1] instanceof AST_Spread) { + rest = to_destructured(node.elements.pop().expression); + if (!(rest instanceof AST_Destructured || is_assignable(rest))) return node; + } + var elements = node.elements.map(to_destructured); + return all(elements, function(node) { + return node instanceof AST_DefaultValue + || node instanceof AST_Destructured + || node instanceof AST_Hole + || is_assignable(node); + }) ? new AST_DestructuredArray({ + start: node.start, + elements: elements, + rest: rest, + end: node.end, + }) : node; + } + if (node instanceof AST_Assign) { + var name = to_destructured(node.left); + return name instanceof AST_Destructured || is_assignable(name) ? new AST_DefaultValue({ + start: node.start, + name: name, + value: node.right, + end: node.end, + }) : node; + } + if (!(node instanceof AST_Object)) return node; + var rest = null; + if (node.properties[node.properties.length - 1] instanceof AST_Spread) { + rest = to_destructured(node.properties.pop().expression); + if (!(rest instanceof AST_Destructured || is_assignable(rest))) return node; + } + var props = []; + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i]; + if (!(prop instanceof AST_ObjectKeyVal)) return node; + var value = to_destructured(prop.value); + if (!(value instanceof AST_DefaultValue || value instanceof AST_Destructured || is_assignable(value))) { + return node; + } + props.push(new AST_DestructuredKeyVal({ + start: prop.start, + key: prop.key, + value: value, + end: prop.end, + })); + } + return new AST_DestructuredObject({ + start: node.start, + properties: props, + rest: rest, + end: node.end, + }); + } + + function maybe_assign(no_in) { + var start = S.token; + var left = maybe_conditional(no_in), val = S.token.value; + if (is("operator") && ASSIGNMENT[val]) { + if (is_assignable(left) || val == "=" && (left = to_destructured(left)) instanceof AST_Destructured) { + next(); + return new AST_Assign({ + start : start, + left : left, + operator : val, + right : maybe_assign(no_in), + end : prev() + }); + } + croak("Invalid assignment"); + } + return left; + } + + function expression(no_in, maybe_arrow) { + var start = S.token; + var exprs = []; + while (true) { + if (maybe_arrow && is("operator", "...")) { + next(); + exprs.rest = maybe_destructured(AST_SymbolFunarg); + break; + } + exprs.push(maybe_assign(no_in)); + if (!is("punc", ",")) break; + next(); + if (maybe_arrow && is("punc", ")") && is_token(peek(), "punc", "=>")) break; + } + return exprs.length == 1 && !exprs.rest ? exprs[0] : new AST_Sequence({ + start: start, + expressions: exprs, + end: prev(), + }); + } + + function in_loop(cont) { + ++S.in_loop; + var ret = cont(); + --S.in_loop; + return ret; + } + + if (options.expression) { + handle_regexp(); + var exp = expression(); + expect_token("eof"); + return exp; + } + + return function() { + var start = S.token; + var body = []; + if (options.module) { + S.in_async = true; + S.input.add_directive("use strict"); + } + S.input.push_directives_stack(); + while (!is("eof")) + body.push(statement(true)); + S.input.pop_directives_stack(); + var end = prev() || start; + var toplevel = options.toplevel; + if (toplevel) { + toplevel.body = toplevel.body.concat(body); + toplevel.end = end; + } else { + toplevel = new AST_Toplevel({ start: start, body: body, end: end }); + } + return toplevel; + }(); +} diff --git a/libs/events/node_modules/uglify-js/lib/propmangle.js b/libs/events/node_modules/uglify-js/lib/propmangle.js new file mode 100644 index 000000000..3e71b68c6 --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/propmangle.js @@ -0,0 +1,328 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function get_builtins() { + var names = new Dictionary(); + // constants + [ + "NaN", + "null", + "true", + "false", + "Infinity", + "-Infinity", + "undefined", + ].forEach(add); + // global functions + [ + "encodeURI", + "encodeURIComponent", + "escape", + "eval", + "decodeURI", + "decodeURIComponent", + "isFinite", + "isNaN", + "parseFloat", + "parseInt", + "unescape", + ].forEach(add); + // global constructors & objects + var global = Function("return this")(); + [ + "Array", + "ArrayBuffer", + "Atomics", + "BigInt", + "Boolean", + "console", + "DataView", + "Date", + "Error", + "Function", + "Int8Array", + "Intl", + "JSON", + "Map", + "Math", + "Number", + "Object", + "Promise", + "Proxy", + "Reflect", + "RegExp", + "Set", + "String", + "Symbol", + "WebAssembly", + ].forEach(function(name) { + add(name); + var ctor = global[name]; + if (!ctor) return; + Object.getOwnPropertyNames(ctor).map(add); + if (typeof ctor != "function") return; + if (ctor.__proto__) Object.getOwnPropertyNames(ctor.__proto__).map(add); + if (ctor.prototype) Object.getOwnPropertyNames(ctor.prototype).map(add); + try { + Object.getOwnPropertyNames(new ctor()).map(add); + } catch (e) { + try { + Object.getOwnPropertyNames(ctor()).map(add); + } catch (e) {} + } + }); + return (get_builtins = function() { + return names.clone(); + })(); + + function add(name) { + names.set(name, true); + } +} + +function reserve_quoted_keys(ast, reserved) { + ast.walk(new TreeWalker(function(node) { + if (node instanceof AST_ClassProperty + || node instanceof AST_DestructuredKeyVal + || node instanceof AST_ObjectProperty) { + if (node.key instanceof AST_Node) { + addStrings(node.key, add); + } else if (node.start && node.start.quote) { + add(node.key); + } + } else if (node instanceof AST_Dot) { + if (node.quoted) add(node.property); + } else if (node instanceof AST_Sub) { + addStrings(node.property, add); + } + })); + + function add(name) { + push_uniq(reserved, name); + } +} + +function addStrings(node, add) { + if (node instanceof AST_Conditional) { + addStrings(node.consequent, add); + addStrings(node.alternative, add); + } else if (node instanceof AST_Sequence) { + addStrings(node.tail_node(), add); + } else if (node instanceof AST_String) { + add(node.value); + } +} + +function mangle_properties(ast, options) { + options = defaults(options, { + builtins: false, + cache: null, + debug: false, + domprops: false, + keep_quoted: false, + regex: null, + reserved: null, + }, true); + + var reserved = options.builtins ? new Dictionary() : get_builtins(); + if (!options.domprops && typeof domprops !== "undefined") domprops.forEach(function(name) { + reserved.set(name, true); + }); + if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) { + reserved.set(name, true); + }); + + var cname = -1; + var cache; + if (options.cache) { + cache = options.cache.props; + cache.each(function(name) { + reserved.set(name, true); + }); + } else { + cache = new Dictionary(); + } + + var regex = options.regex; + + // note debug is either false (disabled), or a string of the debug suffix to use (enabled). + // note debug may be enabled as an empty string, which is falsy. Also treat passing 'true' + // the same as passing an empty string. + var debug = options.debug !== false; + var debug_suffix; + if (debug) debug_suffix = options.debug === true ? "" : options.debug; + + var names_to_mangle = new Dictionary(); + var unmangleable = reserved.clone(); + + // step 1: find candidates to mangle + ast.walk(new TreeWalker(function(node) { + if (node.TYPE == "Call") { + var exp = node.expression; + if (exp instanceof AST_Dot) switch (exp.property) { + case "defineProperty": + case "getOwnPropertyDescriptor": + if (node.args.length < 2) break; + exp = exp.expression; + if (!(exp instanceof AST_SymbolRef)) break; + if (exp.name != "Object") break; + if (!exp.definition().undeclared) break; + addStrings(node.args[1], add); + break; + case "hasOwnProperty": + if (node.args.length < 1) break; + addStrings(node.args[0], add); + break; + } + } else if (node instanceof AST_ClassProperty + || node instanceof AST_DestructuredKeyVal + || node instanceof AST_ObjectProperty) { + if (node.key instanceof AST_Node) { + addStrings(node.key, add); + } else { + add(node.key); + } + } else if (node instanceof AST_Dot) { + if (is_lhs(node, this.parent())) add(node.property); + } else if (node instanceof AST_Sub) { + if (is_lhs(node, this.parent())) addStrings(node.property, add); + } + })); + + // step 2: renaming properties + ast.walk(new TreeWalker(function(node) { + if (node instanceof AST_Binary) { + if (node.operator == "in") mangleStrings(node.left); + } else if (node.TYPE == "Call") { + var exp = node.expression; + if (exp instanceof AST_Dot) switch (exp.property) { + case "defineProperty": + case "getOwnPropertyDescriptor": + if (node.args.length < 2) break; + exp = exp.expression; + if (!(exp instanceof AST_SymbolRef)) break; + if (exp.name != "Object") break; + if (!exp.definition().undeclared) break; + mangleStrings(node.args[1]); + break; + case "hasOwnProperty": + if (node.args.length < 1) break; + mangleStrings(node.args[0]); + break; + } + } else if (node instanceof AST_ClassProperty + || node instanceof AST_DestructuredKeyVal + || node instanceof AST_ObjectProperty) { + if (node.key instanceof AST_Node) { + mangleStrings(node.key); + } else { + node.key = mangle(node.key); + } + } else if (node instanceof AST_Dot) { + node.property = mangle(node.property); + } else if (node instanceof AST_Sub) { + if (!options.keep_quoted) mangleStrings(node.property); + } + })); + + // only function declarations after this line + + function can_mangle(name) { + if (unmangleable.has(name)) return false; + if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false; + return true; + } + + function should_mangle(name) { + if (reserved.has(name)) { + AST_Node.info("Preserving reserved property {this}", name); + return false; + } + if (regex && !regex.test(name)) { + AST_Node.info("Preserving excluded property {this}", name); + return false; + } + return cache.has(name) || names_to_mangle.has(name); + } + + function add(name) { + if (can_mangle(name)) names_to_mangle.set(name, true); + if (!should_mangle(name)) unmangleable.set(name, true); + } + + function mangle(name) { + if (!should_mangle(name)) return name; + var mangled = cache.get(name); + if (!mangled) { + if (debug) { + // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo ---> o._$foo$NNN_. + var debug_mangled = "_$" + name + "$" + debug_suffix + "_"; + if (can_mangle(debug_mangled)) mangled = debug_mangled; + } + // either debug mode is off, or it is on and we could not use the mangled name + if (!mangled) do { + mangled = base54(++cname); + } while (!can_mangle(mangled)); + if (/^#/.test(name)) mangled = "#" + mangled; + cache.set(name, mangled); + } + AST_Node.info("Mapping property {name} to {mangled}", { + mangled: mangled, + name: name, + }); + return mangled; + } + + function mangleStrings(node) { + if (node instanceof AST_Sequence) { + mangleStrings(node.tail_node()); + } else if (node instanceof AST_String) { + node.value = mangle(node.value); + } else if (node instanceof AST_Conditional) { + mangleStrings(node.consequent); + mangleStrings(node.alternative); + } + } +} diff --git a/libs/events/node_modules/uglify-js/lib/scope.js b/libs/events/node_modules/uglify-js/lib/scope.js new file mode 100644 index 000000000..c2108c50f --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/scope.js @@ -0,0 +1,866 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function SymbolDef(id, scope, orig, init) { + this._bits = 0; + this.defun = undefined; + this.eliminated = 0; + this.id = id; + this.init = init; + this.mangled_name = null; + this.name = orig.name; + this.orig = [ orig ]; + this.references = []; + this.replaced = 0; + this.safe_ids = undefined; + this.scope = scope; +} + +SymbolDef.prototype = { + forEach: function(fn) { + this.orig.forEach(fn); + this.references.forEach(fn); + }, + mangle: function(options) { + if (this.mangled_name) return; + var cache = this.global && options.cache && options.cache.props; + if (cache && cache.has(this.name)) { + this.mangled_name = cache.get(this.name); + } else if (this.unmangleable(options)) { + names_in_use(this.scope, options).set(this.name, true); + } else { + var def = this.redefined(); + if (def) { + this.mangled_name = def.mangled_name || def.name; + } else { + this.mangled_name = next_mangled_name(this, options); + } + if (cache) cache.set(this.name, this.mangled_name); + } + }, + redefined: function() { + var self = this; + var scope = self.defun; + if (!scope) return; + var name = self.name; + var def = scope.variables.get(name) + || scope instanceof AST_Toplevel && scope.globals.get(name) + || self.orig[0] instanceof AST_SymbolConst && find_if(function(def) { + return def.name == name; + }, scope.enclosed); + if (def && def !== self) return def.redefined() || def; + }, + unmangleable: function(options) { + if (this.exported) return true; + if (this.undeclared) return true; + if (!options.eval && this.scope.pinned()) return true; + if (options.keep_fargs && is_funarg(this)) return true; + if (options.keep_fnames) { + var sym = this.orig[0]; + if (sym instanceof AST_SymbolClass) return true; + if (sym instanceof AST_SymbolDefClass) return true; + if (sym instanceof AST_SymbolDefun) return true; + if (sym instanceof AST_SymbolLambda) return true; + } + if (!options.toplevel && this.global) return true; + return false; + }, +}; + +DEF_BITPROPS(SymbolDef, [ + "const_redefs", + "cross_loop", + "direct_access", + "exported", + "global", + "undeclared", +]); + +function is_funarg(def) { + return def.orig[0] instanceof AST_SymbolFunarg || def.orig[1] instanceof AST_SymbolFunarg; +} + +var unary_side_effects = makePredicate("delete ++ --"); + +function is_lhs(node, parent) { + if (parent instanceof AST_Assign) return parent.left === node && node; + if (parent instanceof AST_DefaultValue) return parent.name === node && node; + if (parent instanceof AST_Destructured) return node; + if (parent instanceof AST_DestructuredKeyVal) return node; + if (parent instanceof AST_ForEnumeration) return parent.init === node && node; + if (parent instanceof AST_Unary) return unary_side_effects[parent.operator] && parent.expression; +} + +AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { + options = defaults(options, { + cache: null, + ie: false, + }); + + // pass 1: setup scope chaining and handle definitions + var self = this; + var defun = null; + var exported = false; + var next_def_id = 0; + var scope = self.parent_scope = null; + var tw = new TreeWalker(function(node, descend) { + if (node instanceof AST_DefClass) { + var save_exported = exported; + exported = tw.parent() instanceof AST_ExportDeclaration; + node.name.walk(tw); + exported = save_exported; + walk_scope(function() { + if (node.extends) node.extends.walk(tw); + node.properties.forEach(function(prop) { + prop.walk(tw); + }); + }); + return true; + } + if (node instanceof AST_Definitions) { + var save_exported = exported; + exported = tw.parent() instanceof AST_ExportDeclaration; + descend(); + exported = save_exported; + return true; + } + if (node instanceof AST_LambdaDefinition) { + var save_exported = exported; + exported = tw.parent() instanceof AST_ExportDeclaration; + node.name.walk(tw); + exported = save_exported; + walk_scope(function() { + node.argnames.forEach(function(argname) { + argname.walk(tw); + }); + if (node.rest) node.rest.walk(tw); + walk_body(node, tw); + }); + return true; + } + if (node instanceof AST_SwitchBranch) { + node.init_vars(scope); + descend(); + return true; + } + if (node instanceof AST_Try) { + walk_scope(function() { + walk_body(node, tw); + }); + if (node.bcatch) node.bcatch.walk(tw); + if (node.bfinally) node.bfinally.walk(tw); + return true; + } + if (node instanceof AST_With) { + var s = scope; + do { + s = s.resolve(); + if (s.uses_with) break; + s.uses_with = true; + } while (s = s.parent_scope); + walk_scope(descend); + return true; + } + if (node instanceof AST_BlockScope) { + walk_scope(descend); + return true; + } + if (node instanceof AST_Symbol) { + node.scope = scope; + } + if (node instanceof AST_Label) { + node.thedef = node; + node.references = []; + } + if (node instanceof AST_SymbolCatch) { + scope.def_variable(node).defun = defun; + } else if (node instanceof AST_SymbolConst) { + var def = scope.def_variable(node); + def.defun = defun; + if (exported) def.exported = true; + } else if (node instanceof AST_SymbolDefun) { + var def = defun.def_function(node, tw.parent()); + if (exported) def.exported = true; + } else if (node instanceof AST_SymbolFunarg) { + defun.def_variable(node); + } else if (node instanceof AST_SymbolLambda) { + var def = defun.def_function(node, node.name == "arguments" ? undefined : defun); + if (options.ie && node.name != "arguments") def.defun = defun.parent_scope.resolve(); + } else if (node instanceof AST_SymbolLet) { + var def = scope.def_variable(node); + if (exported) def.exported = true; + } else if (node instanceof AST_SymbolVar) { + var def = defun.def_variable(node, node instanceof AST_SymbolImport ? undefined : null); + if (exported) def.exported = true; + } + + function walk_scope(descend) { + node.init_vars(scope); + var save_defun = defun; + var save_scope = scope; + if (node instanceof AST_Scope) defun = node; + scope = node; + descend(); + scope = save_scope; + defun = save_defun; + } + }); + self.make_def = function(orig, init) { + return new SymbolDef(++next_def_id, this, orig, init); + }; + self.walk(tw); + + // pass 2: find back references and eval + self.globals = new Dictionary(); + var in_arg = []; + var tw = new TreeWalker(function(node) { + if (node instanceof AST_Catch) { + if (!(node.argname instanceof AST_Destructured)) return; + in_arg.push(node); + node.argname.walk(tw); + in_arg.pop(); + walk_body(node, tw); + return true; + } + if (node instanceof AST_Lambda) { + in_arg.push(node); + if (node.name) node.name.walk(tw); + node.argnames.forEach(function(argname) { + argname.walk(tw); + }); + if (node.rest) node.rest.walk(tw); + in_arg.pop(); + walk_lambda(node, tw); + return true; + } + if (node instanceof AST_LoopControl) { + if (node.label) node.label.thedef.references.push(node); + return true; + } + if (node instanceof AST_SymbolDeclaration) { + var def = node.definition(); + def.preinit = def.references.length; + if (node instanceof AST_SymbolCatch) { + // ensure mangling works if `catch` reuses a scope variable + var redef = def.redefined(); + if (redef) for (var s = node.scope; s; s = s.parent_scope) { + if (!push_uniq(s.enclosed, redef)) break; + if (s === redef.scope) break; + } + } else if (node instanceof AST_SymbolConst) { + // ensure compression works if `const` reuses a scope variable + var redef = def.redefined(); + if (redef) redef.const_redefs = true; + } else if (def.scope !== node.scope && (node instanceof AST_SymbolDefun + || node instanceof AST_SymbolFunarg + || node instanceof AST_SymbolVar)) { + node.mark_enclosed(options); + var redef = node.scope.find_variable(node.name); + if (node.thedef !== redef) { + node.thedef = redef; + redef.orig.push(node); + node.mark_enclosed(options); + } + } + if (node.name != "arguments") return true; + var parent = node instanceof AST_SymbolVar && tw.parent(); + if (parent instanceof AST_VarDef && !parent.value) return true; + var sym = node.scope.resolve().find_variable("arguments"); + if (sym && is_arguments(sym)) sym.scope.uses_arguments = 3; + return true; + } + if (node instanceof AST_SymbolRef) { + var name = node.name; + var sym = node.scope.find_variable(name); + for (var i = in_arg.length; i > 0 && sym;) { + i = in_arg.lastIndexOf(sym.scope, i - 1); + if (i < 0) break; + var decl = sym.orig[0]; + if (decl instanceof AST_SymbolCatch + || decl instanceof AST_SymbolFunarg + || decl instanceof AST_SymbolLambda) { + node.in_arg = true; + break; + } + sym = sym.scope.parent_scope.find_variable(name); + } + if (!sym) { + sym = self.def_global(node); + } else if (name == "arguments" && is_arguments(sym)) { + var parent = tw.parent(); + if (is_lhs(node, parent)) { + sym.scope.uses_arguments = 3; + } else if (sym.scope.uses_arguments < 2 + && !(parent instanceof AST_PropAccess && parent.expression === node)) { + sym.scope.uses_arguments = 2; + } else if (!sym.scope.uses_arguments) { + sym.scope.uses_arguments = true; + } + } + if (name == "eval") { + var parent = tw.parent(); + if (parent.TYPE == "Call" && parent.expression === node) { + var s = node.scope; + do { + s = s.resolve(); + if (s.uses_eval) break; + s.uses_eval = true; + } while (s = s.parent_scope); + } else if (sym.undeclared) { + self.uses_eval = true; + } + } + if (sym.init instanceof AST_LambdaDefinition && sym.scope !== sym.init.name.scope) { + var scope = node.scope; + do { + if (scope === sym.init.name.scope) break; + } while (scope = scope.parent_scope); + if (!scope) sym.init = undefined; + } + node.thedef = sym; + node.reference(options); + return true; + } + }); + self.walk(tw); + + // pass 3: fix up any scoping issue with IE8 + if (options.ie) self.walk(new TreeWalker(function(node) { + if (node instanceof AST_SymbolCatch) { + var def = node.thedef; + var scope = def.defun; + if (def.name != "arguments" && scope.name instanceof AST_SymbolLambda && scope.name.name == def.name) { + scope = scope.parent_scope.resolve(); + } + redefine(node, scope); + return true; + } + if (node instanceof AST_SymbolLambda) { + var def = node.thedef; + if (!redefine(node, node.scope.parent_scope.resolve())) { + def.defun = undefined; + } else if (typeof node.thedef.init !== "undefined") { + node.thedef.init = false; + } else if (def.init) { + node.thedef.init = def.init; + } + return true; + } + })); + + function is_arguments(sym) { + return sym.orig[0] instanceof AST_SymbolFunarg + && !(sym.orig[1] instanceof AST_SymbolFunarg || sym.orig[2] instanceof AST_SymbolFunarg) + && !is_arrow(sym.scope); + } + + function redefine(node, scope) { + var name = node.name; + var old_def = node.thedef; + if (!all(old_def.orig, function(sym) { + return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet); + })) return false; + var new_def = scope.find_variable(name); + if (new_def) { + var redef = new_def.redefined(); + if (redef) new_def = redef; + } else { + new_def = self.globals.get(name); + } + if (new_def) { + new_def.orig.push(node); + } else { + new_def = scope.def_variable(node); + } + if (new_def.undeclared) self.variables.set(name, new_def); + if (name == "arguments" && is_arguments(old_def) && node instanceof AST_SymbolLambda) return true; + old_def.defun = new_def.scope; + old_def.forEach(function(node) { + node.redef = old_def; + node.thedef = new_def; + node.reference(options); + }); + return true; + } +}); + +AST_Toplevel.DEFMETHOD("def_global", function(node) { + var globals = this.globals, name = node.name; + if (globals.has(name)) { + return globals.get(name); + } else { + var g = this.make_def(node); + g.undeclared = true; + g.global = true; + globals.set(name, g); + return g; + } +}); + +function init_block_vars(scope, parent) { + scope.enclosed = []; // variables from this or outer scope(s) that are referenced from this or inner scopes + scope.parent_scope = parent; // the parent scope (null if this is the top level) + scope.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope) + scope.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions) + if (parent) scope.make_def = parent.make_def; // top-level tracking of SymbolDef instances +} + +function init_scope_vars(scope, parent) { + init_block_vars(scope, parent); + scope.uses_eval = false; // will be set to true if this or nested scope uses the global `eval` + scope.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement +} + +AST_BlockScope.DEFMETHOD("init_vars", function(parent_scope) { + init_block_vars(this, parent_scope); +}); +AST_Scope.DEFMETHOD("init_vars", function(parent_scope) { + init_scope_vars(this, parent_scope); +}); +AST_Arrow.DEFMETHOD("init_vars", function(parent_scope) { + init_scope_vars(this, parent_scope); + return this; +}); +AST_AsyncArrow.DEFMETHOD("init_vars", function(parent_scope) { + init_scope_vars(this, parent_scope); +}); +AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) { + init_scope_vars(this, parent_scope); + this.uses_arguments = false; + this.def_variable(new AST_SymbolFunarg({ + name: "arguments", + scope: this, + start: this.start, + end: this.end, + })); + return this; +}); + +AST_Symbol.DEFMETHOD("mark_enclosed", function(options) { + var def = this.definition(); + for (var s = this.scope; s; s = s.parent_scope) { + if (!push_uniq(s.enclosed, def)) break; + if (!options) { + s._var_names = undefined; + } else { + if (options.keep_fargs && s instanceof AST_Lambda) s.each_argname(function(arg) { + push_uniq(def.scope.enclosed, arg.definition()); + }); + if (options.keep_fnames) s.functions.each(function(d) { + push_uniq(def.scope.enclosed, d); + }); + } + if (s === def.scope) break; + } +}); + +AST_Symbol.DEFMETHOD("reference", function(options) { + this.definition().references.push(this); + this.mark_enclosed(options); +}); + +AST_BlockScope.DEFMETHOD("find_variable", function(name) { + return this.variables.get(name) + || this.parent_scope && this.parent_scope.find_variable(name); +}); + +AST_BlockScope.DEFMETHOD("def_function", function(symbol, init) { + var def = this.def_variable(symbol, init); + if (!def.init || def.init instanceof AST_LambdaDefinition) def.init = init; + this.functions.set(symbol.name, def); + return def; +}); + +AST_BlockScope.DEFMETHOD("def_variable", function(symbol, init) { + var def = this.variables.get(symbol.name); + if (def) { + def.orig.push(symbol); + if (def.init instanceof AST_LambdaExpression) def.init = init; + } else { + def = this.make_def(symbol, init); + this.variables.set(symbol.name, def); + def.global = !this.parent_scope; + } + return symbol.thedef = def; +}); + +function names_in_use(scope, options) { + var names = scope.names_in_use; + if (!names) { + scope.cname = -1; + scope.cname_holes = []; + scope.names_in_use = names = new Dictionary(); + var cache = options.cache && options.cache.props; + scope.enclosed.forEach(function(def) { + if (def.unmangleable(options)) names.set(def.name, true); + if (def.global && cache && cache.has(def.name)) { + names.set(cache.get(def.name), true); + } + }); + } + return names; +} + +function next_mangled_name(def, options) { + var scope = def.scope; + var in_use = names_in_use(scope, options); + var holes = scope.cname_holes; + var names = new Dictionary(); + var scopes = [ scope ]; + def.forEach(function(sym) { + var scope = sym.scope; + do { + if (member(scope, scopes)) break; + names_in_use(scope, options).each(function(marker, name) { + names.set(name, marker); + }); + scopes.push(scope); + } while (scope = scope.parent_scope); + }); + var name; + for (var i = 0; i < holes.length; i++) { + name = base54(holes[i]); + if (names.has(name)) continue; + holes.splice(i, 1); + in_use.set(name, true); + return name; + } + while (true) { + name = base54(++scope.cname); + if (in_use.has(name) || RESERVED_WORDS[name] || options.reserved.has[name]) continue; + if (!names.has(name)) break; + holes.push(scope.cname); + } + in_use.set(name, true); + return name; +} + +AST_Symbol.DEFMETHOD("unmangleable", function(options) { + var def = this.definition(); + return !def || def.unmangleable(options); +}); + +// labels are always mangleable +AST_Label.DEFMETHOD("unmangleable", return_false); + +AST_Symbol.DEFMETHOD("definition", function() { + return this.thedef; +}); + +function _default_mangler_options(options) { + options = defaults(options, { + eval : false, + ie : false, + keep_fargs : false, + keep_fnames : false, + reserved : [], + toplevel : false, + v8 : false, + webkit : false, + }); + if (!Array.isArray(options.reserved)) options.reserved = []; + // Never mangle `arguments` + push_uniq(options.reserved, "arguments"); + options.reserved.has = makePredicate(options.reserved); + return options; +} + +// We only need to mangle declaration nodes. Special logic wired into the code +// generator will display the mangled name if it is present (and for +// `AST_SymbolRef`s it will use the mangled name of the `AST_SymbolDeclaration` +// that it points to). +AST_Toplevel.DEFMETHOD("mangle_names", function(options) { + options = _default_mangler_options(options); + if (options.cache && options.cache.props) { + var mangled_names = names_in_use(this, options); + options.cache.props.each(function(mangled_name) { + mangled_names.set(mangled_name, true); + }); + } + var cutoff = 36; + var lname = -1; + var redefined = []; + var tw = new TreeWalker(function(node, descend) { + var save_nesting; + if (node instanceof AST_BlockScope) { + // `lname` is incremented when we get to the `AST_Label` + if (node instanceof AST_LabeledStatement) save_nesting = lname; + if (options.webkit && node instanceof AST_IterationStatement && node.init instanceof AST_Let) { + node.init.definitions.forEach(function(defn) { + defn.name.match_symbol(function(sym) { + if (!(sym instanceof AST_SymbolLet)) return; + var def = sym.definition(); + var scope = sym.scope.parent_scope; + var redef = scope.def_variable(sym); + sym.thedef = def; + scope.to_mangle.push(redef); + def.redefined = function() { + return redef; + }; + }); + }, true); + } + var to_mangle = node.to_mangle = []; + node.variables.each(function(def) { + if (!defer_redef(def)) to_mangle.push(def); + }); + descend(); + if (options.cache && node instanceof AST_Toplevel) { + node.globals.each(mangle); + } + if (node instanceof AST_Defun && tw.has_directive("use asm")) { + var sym = new AST_SymbolRef(node.name); + sym.scope = node; + sym.reference(options); + } + if (to_mangle.length > cutoff) { + var indices = to_mangle.map(function(def, index) { + return index; + }).sort(function(i, j) { + return to_mangle[j].references.length - to_mangle[i].references.length || i - j; + }); + to_mangle = indices.slice(0, cutoff).sort(function(i, j) { + return i - j; + }).map(function(index) { + return to_mangle[index]; + }).concat(indices.slice(cutoff).sort(function(i, j) { + return i - j; + }).map(function(index) { + return to_mangle[index]; + })); + } + to_mangle.forEach(mangle); + if (node instanceof AST_LabeledStatement && !(options.v8 && in_label(tw))) lname = save_nesting; + return true; + } + if (node instanceof AST_Label) { + var name; + do { + name = base54(++lname); + } while (RESERVED_WORDS[name]); + node.mangled_name = name; + return true; + } + }); + this.walk(tw); + redefined.forEach(mangle); + + function mangle(def) { + if (options.reserved.has[def.name]) return; + def.mangle(options); + } + + function defer_redef(def) { + var sym = def.orig[0]; + var redef = def.redefined(); + if (!redef) { + if (!(sym instanceof AST_SymbolConst)) return false; + var scope = def.scope.resolve(); + if (def.scope === scope) return false; + if (def.scope.parent_scope.find_variable(sym.name)) return false; + redef = scope.def_variable(sym); + scope.to_mangle.push(redef); + } + redefined.push(def); + def.references.forEach(reference); + if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) { + reference(sym); + def.redefined = function() { + return redef; + }; + } + return true; + + function reference(sym) { + sym.thedef = redef; + sym.reference(options); + sym.thedef = def; + } + } + + function in_label(tw) { + var level = 0, parent; + while (parent = tw.parent(level++)) { + if (parent instanceof AST_Block) return parent instanceof AST_Toplevel && !options.toplevel; + if (parent instanceof AST_LabeledStatement) return true; + } + } +}); + +AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) { + var cache = options.cache && options.cache.props; + var avoid = Object.create(RESERVED_WORDS); + options.reserved.forEach(to_avoid); + this.globals.each(add_def); + this.walk(new TreeWalker(function(node) { + if (node instanceof AST_BlockScope) node.variables.each(add_def); + })); + return avoid; + + function to_avoid(name) { + avoid[name] = true; + } + + function add_def(def) { + var name = def.name; + if (def.global && cache && cache.has(name)) name = cache.get(name); + else if (!def.unmangleable(options)) return; + to_avoid(name); + } +}); + +AST_Toplevel.DEFMETHOD("expand_names", function(options) { + base54.reset(); + base54.sort(); + options = _default_mangler_options(options); + var avoid = this.find_colliding_names(options); + var cname = 0; + this.globals.each(rename); + this.walk(new TreeWalker(function(node) { + if (node instanceof AST_BlockScope) node.variables.each(rename); + })); + + function next_name() { + var name; + do { + name = base54(cname++); + } while (avoid[name]); + return name; + } + + function rename(def) { + if (def.global && options.cache) return; + if (def.unmangleable(options)) return; + if (options.reserved.has[def.name]) return; + var redef = def.redefined(); + var name = redef ? redef.rename || redef.name : next_name(); + def.rename = name; + def.forEach(function(sym) { + if (sym.definition() === def) sym.name = name; + }); + } +}); + +AST_Node.DEFMETHOD("tail_node", return_this); +AST_Sequence.DEFMETHOD("tail_node", function() { + return this.expressions[this.expressions.length - 1]; +}); + +AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) { + options = _default_mangler_options(options); + base54.reset(); + var fn = AST_Symbol.prototype.add_source_map; + try { + AST_Symbol.prototype.add_source_map = function() { + if (!this.unmangleable(options)) base54.consider(this.name, -1); + }; + if (options.properties) { + AST_Dot.prototype.add_source_map = function() { + base54.consider(this.property, -1); + }; + AST_Sub.prototype.add_source_map = function() { + skip_string(this.property); + }; + } + base54.consider(this.print_to_string(), 1); + } finally { + AST_Symbol.prototype.add_source_map = fn; + delete AST_Dot.prototype.add_source_map; + delete AST_Sub.prototype.add_source_map; + } + base54.sort(); + + function skip_string(node) { + if (node instanceof AST_String) { + base54.consider(node.value, -1); + } else if (node instanceof AST_Conditional) { + skip_string(node.consequent); + skip_string(node.alternative); + } else if (node instanceof AST_Sequence) { + skip_string(node.tail_node()); + } + } +}); + +var base54 = (function() { + var freq = Object.create(null); + function init(chars) { + var array = []; + for (var i = 0; i < chars.length; i++) { + var ch = chars[i]; + array.push(ch); + freq[ch] = -1e-2 * i; + } + return array; + } + var digits = init("0123456789"); + var leading = init("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_"); + var chars, frequency; + function reset() { + chars = null; + frequency = Object.create(freq); + } + base54.consider = function(str, delta) { + for (var i = str.length; --i >= 0;) { + frequency[str[i]] += delta; + } + }; + function compare(a, b) { + return frequency[b] - frequency[a]; + } + base54.sort = function() { + chars = leading.sort(compare).concat(digits).sort(compare); + }; + base54.reset = reset; + reset(); + function base54(num) { + var ret = leading[num % 54]; + for (num = Math.floor(num / 54); --num >= 0; num >>= 6) { + ret += chars[num & 0x3F]; + } + return ret; + } + return base54; +})(); diff --git a/libs/events/node_modules/uglify-js/lib/sourcemap.js b/libs/events/node_modules/uglify-js/lib/sourcemap.js new file mode 100644 index 000000000..a230a44ce --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/sourcemap.js @@ -0,0 +1,195 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +var vlq_char = characters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); +var vlq_bits = vlq_char.reduce(function(map, ch, bits) { + map[ch] = bits; + return map; +}, Object.create(null)); + +function vlq_decode(indices, str) { + var value = 0; + var shift = 0; + for (var i = 0, j = 0; i < str.length; i++) { + var bits = vlq_bits[str[i]]; + value += (bits & 31) << shift; + if (bits & 32) { + shift += 5; + } else { + indices[j++] += value & 1 ? 0x80000000 | -(value >> 1) : value >> 1; + value = shift = 0; + } + } + return j; +} + +function vlq_encode(num) { + var result = ""; + num = Math.abs(num) << 1 | num >>> 31; + do { + var bits = num & 31; + if (num >>>= 5) bits |= 32; + result += vlq_char[bits]; + } while (num); + return result; +} + +function create_array_map() { + var map = new Dictionary(); + var array = []; + array.index = function(name) { + var index = map.get(name); + if (!(index >= 0)) { + index = array.length; + array.push(name); + map.set(name, index); + } + return index; + }; + return array; +} + +function SourceMap(options) { + var sources = create_array_map(); + var sources_content = options.includeSources && new Dictionary(); + var names = create_array_map(); + var mappings = ""; + if (options.orig) Object.keys(options.orig).forEach(function(name) { + var map = options.orig[name]; + var indices = [ 0, 0, 1, 0, 0 ]; + options.orig[name] = { + names: map.names, + mappings: map.mappings.split(/;/).map(function(line) { + indices[0] = 0; + return line.split(/,/).map(function(segment) { + return indices.slice(0, vlq_decode(indices, segment)); + }); + }), + sources: map.sources, + }; + if (!sources_content || !map.sourcesContent) return; + for (var i = 0; i < map.sources.length; i++) { + var content = map.sourcesContent[i]; + if (content) sources_content.set(map.sources[i], content); + } + }); + var prev_source; + var generated_line = 1; + var generated_column = 0; + var source_index = 0; + var original_line = 1; + var original_column = 0; + var name_index = 0; + return { + add: options.orig ? function(source, gen_line, gen_col, orig_line, orig_col, name) { + var map = options.orig[source]; + if (map) { + var segments = map.mappings[orig_line - 1]; + if (!segments) return; + var indices; + for (var i = 0; i < segments.length; i++) { + var col = segments[i][0]; + if (orig_col >= col) indices = segments[i]; + if (orig_col <= col) break; + } + if (!indices || indices.length < 4) { + source = null; + } else { + source = map.sources[indices[1]]; + orig_line = indices[2]; + orig_col = indices[3]; + if (indices.length > 4) name = map.names[indices[4]]; + } + } + add(source, gen_line, gen_col, orig_line, orig_col, name); + } : add, + setSourceContent: sources_content ? function(source, content) { + if (!sources_content.has(source)) { + sources_content.set(source, content); + } + } : noop, + toString: function() { + return JSON.stringify({ + version: 3, + file: options.filename || undefined, + sourceRoot: options.root || undefined, + sources: sources, + sourcesContent: sources_content ? sources.map(function(source) { + return sources_content.get(source) || null; + }) : undefined, + names: names, + mappings: mappings, + }); + } + }; + + function add(source, gen_line, gen_col, orig_line, orig_col, name) { + if (prev_source == null && source == null) return; + prev_source = source; + if (generated_line < gen_line) { + generated_column = 0; + do { + mappings += ";"; + } while (++generated_line < gen_line); + } else if (mappings) { + mappings += ","; + } + mappings += vlq_encode(gen_col - generated_column); + generated_column = gen_col; + if (source == null) return; + var src_idx = sources.index(source); + mappings += vlq_encode(src_idx - source_index); + source_index = src_idx; + mappings += vlq_encode(orig_line - original_line); + original_line = orig_line; + mappings += vlq_encode(orig_col - original_column); + original_column = orig_col; + if (options.names && name != null) { + var name_idx = names.index(name); + mappings += vlq_encode(name_idx - name_index); + name_index = name_idx; + } + } +} diff --git a/libs/events/node_modules/uglify-js/lib/transform.js b/libs/events/node_modules/uglify-js/lib/transform.js new file mode 100644 index 000000000..dcf90dfad --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/transform.js @@ -0,0 +1,250 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function TreeTransformer(before, after) { + TreeWalker.call(this); + this.before = before; + this.after = after; +} +TreeTransformer.prototype = new TreeWalker; + +(function(DEF) { + function do_list(list, tw) { + return List(list, function(node) { + return node.transform(tw, true); + }); + } + + DEF(AST_Node, noop); + DEF(AST_LabeledStatement, function(self, tw) { + self.label = self.label.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_SimpleStatement, function(self, tw) { + self.body = self.body.transform(tw); + }); + DEF(AST_Block, function(self, tw) { + self.body = do_list(self.body, tw); + }); + DEF(AST_Do, function(self, tw) { + self.body = self.body.transform(tw); + self.condition = self.condition.transform(tw); + }); + DEF(AST_While, function(self, tw) { + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_For, function(self, tw) { + if (self.init) self.init = self.init.transform(tw); + if (self.condition) self.condition = self.condition.transform(tw); + if (self.step) self.step = self.step.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_ForEnumeration, function(self, tw) { + self.init = self.init.transform(tw); + self.object = self.object.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_With, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_Exit, function(self, tw) { + if (self.value) self.value = self.value.transform(tw); + }); + DEF(AST_LoopControl, function(self, tw) { + if (self.label) self.label = self.label.transform(tw); + }); + DEF(AST_If, function(self, tw) { + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); + if (self.alternative) self.alternative = self.alternative.transform(tw); + }); + DEF(AST_Switch, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = do_list(self.body, tw); + }); + DEF(AST_Case, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = do_list(self.body, tw); + }); + DEF(AST_Try, function(self, tw) { + self.body = do_list(self.body, tw); + if (self.bcatch) self.bcatch = self.bcatch.transform(tw); + if (self.bfinally) self.bfinally = self.bfinally.transform(tw); + }); + DEF(AST_Catch, function(self, tw) { + if (self.argname) self.argname = self.argname.transform(tw); + self.body = do_list(self.body, tw); + }); + DEF(AST_Definitions, function(self, tw) { + self.definitions = do_list(self.definitions, tw); + }); + DEF(AST_VarDef, function(self, tw) { + self.name = self.name.transform(tw); + if (self.value) self.value = self.value.transform(tw); + }); + DEF(AST_DefaultValue, function(self, tw) { + self.name = self.name.transform(tw); + self.value = self.value.transform(tw); + }); + DEF(AST_Lambda, function(self, tw) { + if (self.name) self.name = self.name.transform(tw); + self.argnames = do_list(self.argnames, tw); + if (self.rest) self.rest = self.rest.transform(tw); + self.body = do_list(self.body, tw); + }); + function transform_arrow(self, tw) { + self.argnames = do_list(self.argnames, tw); + if (self.rest) self.rest = self.rest.transform(tw); + if (self.value) { + self.value = self.value.transform(tw); + } else { + self.body = do_list(self.body, tw); + } + } + DEF(AST_Arrow, transform_arrow); + DEF(AST_AsyncArrow, transform_arrow); + DEF(AST_Class, function(self, tw) { + if (self.name) self.name = self.name.transform(tw); + if (self.extends) self.extends = self.extends.transform(tw); + self.properties = do_list(self.properties, tw); + }); + DEF(AST_ClassProperty, function(self, tw) { + if (self.key instanceof AST_Node) self.key = self.key.transform(tw); + if (self.value) self.value = self.value.transform(tw); + }); + DEF(AST_Call, function(self, tw) { + self.expression = self.expression.transform(tw); + self.args = do_list(self.args, tw); + }); + DEF(AST_Sequence, function(self, tw) { + self.expressions = do_list(self.expressions, tw); + }); + DEF(AST_Await, function(self, tw) { + self.expression = self.expression.transform(tw); + }); + DEF(AST_Yield, function(self, tw) { + if (self.expression) self.expression = self.expression.transform(tw); + }); + DEF(AST_Dot, function(self, tw) { + self.expression = self.expression.transform(tw); + }); + DEF(AST_Sub, function(self, tw) { + self.expression = self.expression.transform(tw); + self.property = self.property.transform(tw); + }); + DEF(AST_Spread, function(self, tw) { + self.expression = self.expression.transform(tw); + }); + DEF(AST_Unary, function(self, tw) { + self.expression = self.expression.transform(tw); + }); + DEF(AST_Binary, function(self, tw) { + self.left = self.left.transform(tw); + self.right = self.right.transform(tw); + }); + DEF(AST_Conditional, function(self, tw) { + self.condition = self.condition.transform(tw); + self.consequent = self.consequent.transform(tw); + self.alternative = self.alternative.transform(tw); + }); + DEF(AST_Array, function(self, tw) { + self.elements = do_list(self.elements, tw); + }); + DEF(AST_DestructuredArray, function(self, tw) { + self.elements = do_list(self.elements, tw); + if (self.rest) self.rest = self.rest.transform(tw); + }); + DEF(AST_DestructuredKeyVal, function(self, tw) { + if (self.key instanceof AST_Node) self.key = self.key.transform(tw); + self.value = self.value.transform(tw); + }); + DEF(AST_DestructuredObject, function(self, tw) { + self.properties = do_list(self.properties, tw); + if (self.rest) self.rest = self.rest.transform(tw); + }); + DEF(AST_Object, function(self, tw) { + self.properties = do_list(self.properties, tw); + }); + DEF(AST_ObjectProperty, function(self, tw) { + if (self.key instanceof AST_Node) self.key = self.key.transform(tw); + self.value = self.value.transform(tw); + }); + DEF(AST_ExportDeclaration, function(self, tw) { + self.body = self.body.transform(tw); + }); + DEF(AST_ExportDefault, function(self, tw) { + self.body = self.body.transform(tw); + }); + DEF(AST_ExportReferences, function(self, tw) { + self.properties = do_list(self.properties, tw); + }); + DEF(AST_Import, function(self, tw) { + if (self.all) self.all = self.all.transform(tw); + if (self.default) self.default = self.default.transform(tw); + if (self.properties) self.properties = do_list(self.properties, tw); + }); + DEF(AST_Template, function(self, tw) { + if (self.tag) self.tag = self.tag.transform(tw); + self.expressions = do_list(self.expressions, tw); + }); +})(function(node, descend) { + node.DEFMETHOD("transform", function(tw, in_list) { + var x, y; + tw.push(this); + if (tw.before) x = tw.before(this, descend, in_list); + if (typeof x === "undefined") { + x = this; + descend(x, tw); + if (tw.after) { + y = tw.after(x, in_list); + if (typeof y !== "undefined") x = y; + } + } + tw.pop(); + return x; + }); +}); diff --git a/libs/events/node_modules/uglify-js/lib/utils.js b/libs/events/node_modules/uglify-js/lib/utils.js new file mode 100644 index 000000000..6faaa152a --- /dev/null +++ b/libs/events/node_modules/uglify-js/lib/utils.js @@ -0,0 +1,287 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +"use strict"; + +function characters(str) { + return str.split(""); +} + +function member(name, array) { + return array.indexOf(name) >= 0; +} + +function find_if(func, array) { + for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i]; +} + +function configure_error_stack(fn) { + Object.defineProperty(fn.prototype, "stack", { + get: function() { + var err = new Error(this.message); + err.name = this.name; + try { + throw err; + } catch (e) { + return e.stack; + } + } + }); +} + +function DefaultsError(msg, defs) { + this.message = msg; + this.defs = defs; +} +DefaultsError.prototype = Object.create(Error.prototype); +DefaultsError.prototype.constructor = DefaultsError; +DefaultsError.prototype.name = "DefaultsError"; +configure_error_stack(DefaultsError); + +function defaults(args, defs, croak) { + if (croak) for (var i in args) { + if (HOP(args, i) && !HOP(defs, i)) throw new DefaultsError("`" + i + "` is not a supported option", defs); + } + for (var i in args) { + if (HOP(args, i)) defs[i] = args[i]; + } + return defs; +} + +function noop() {} +function return_false() { return false; } +function return_true() { return true; } +function return_this() { return this; } +function return_null() { return null; } + +var List = (function() { + function List(a, f) { + var ret = []; + for (var i = 0; i < a.length; i++) { + var val = f(a[i], i); + if (val === skip) continue; + if (val instanceof Splice) { + ret.push.apply(ret, val.v); + } else { + ret.push(val); + } + } + return ret; + } + List.is_op = function(val) { + return val === skip || val instanceof Splice; + }; + List.splice = function(val) { + return new Splice(val); + }; + var skip = List.skip = {}; + function Splice(val) { + this.v = val; + } + return List; +})(); + +function push_uniq(array, el) { + if (array.indexOf(el) < 0) return array.push(el); +} + +function string_template(text, props) { + return text.replace(/\{([^{}]+)\}/g, function(str, p) { + var value = p == "this" ? props : props[p]; + if (value instanceof AST_Node) return value.print_to_string(); + if (value instanceof AST_Token) return value.file + ":" + value.line + "," + value.col; + return value; + }); +} + +function remove(array, el) { + var index = array.indexOf(el); + if (index >= 0) array.splice(index, 1); +} + +function makePredicate(words) { + if (!Array.isArray(words)) words = words.split(" "); + var map = Object.create(null); + words.forEach(function(word) { + map[word] = true; + }); + return map; +} + +function all(array, predicate) { + for (var i = array.length; --i >= 0;) + if (!predicate(array[i], i)) + return false; + return true; +} + +function Dictionary() { + this.values = Object.create(null); +} +Dictionary.prototype = { + set: function(key, val) { + if (key == "__proto__") { + this.proto_value = val; + } else { + this.values[key] = val; + } + return this; + }, + add: function(key, val) { + var list = this.get(key); + if (list) { + list.push(val); + } else { + this.set(key, [ val ]); + } + return this; + }, + get: function(key) { + return key == "__proto__" ? this.proto_value : this.values[key]; + }, + del: function(key) { + if (key == "__proto__") { + delete this.proto_value; + } else { + delete this.values[key]; + } + return this; + }, + has: function(key) { + return key == "__proto__" ? "proto_value" in this : key in this.values; + }, + all: function(predicate) { + for (var i in this.values) + if (!predicate(this.values[i], i)) return false; + if ("proto_value" in this && !predicate(this.proto_value, "__proto__")) return false; + return true; + }, + each: function(f) { + for (var i in this.values) + f(this.values[i], i); + if ("proto_value" in this) f(this.proto_value, "__proto__"); + }, + size: function() { + return Object.keys(this.values).length + ("proto_value" in this); + }, + map: function(f) { + var ret = []; + for (var i in this.values) + ret.push(f(this.values[i], i)); + if ("proto_value" in this) ret.push(f(this.proto_value, "__proto__")); + return ret; + }, + clone: function() { + var ret = new Dictionary(); + this.each(function(value, i) { + ret.set(i, value); + }); + return ret; + }, + toObject: function() { + var obj = {}; + this.each(function(value, i) { + obj["$" + i] = value; + }); + return obj; + }, +}; +Dictionary.fromObject = function(obj) { + var dict = new Dictionary(); + for (var i in obj) + if (HOP(obj, i)) dict.set(i.slice(1), obj[i]); + return dict; +}; + +function HOP(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +// return true if the node at the top of the stack (that means the +// innermost node in the current output) is lexically the first in +// a statement. +function first_in_statement(stack, arrow, export_default) { + var node = stack.parent(-1); + for (var i = 0, p; p = stack.parent(i++); node = p) { + if (is_arrow(p)) { + return arrow && p.value === node; + } else if (p instanceof AST_Binary) { + if (p.left === node) continue; + } else if (p.TYPE == "Call") { + if (p.expression === node) continue; + } else if (p instanceof AST_Conditional) { + if (p.condition === node) continue; + } else if (p instanceof AST_ExportDefault) { + return export_default; + } else if (p instanceof AST_PropAccess) { + if (p.expression === node) continue; + } else if (p instanceof AST_Sequence) { + if (p.expressions[0] === node) continue; + } else if (p instanceof AST_SimpleStatement) { + return true; + } else if (p instanceof AST_Template) { + if (p.tag === node) continue; + } else if (p instanceof AST_UnaryPostfix) { + if (p.expression === node) continue; + } + return false; + } +} + +function DEF_BITPROPS(ctor, props) { + if (props.length > 31) throw new Error("Too many properties: " + props.length + "\n" + props.join(", ")); + props.forEach(function(name, pos) { + var mask = 1 << pos; + Object.defineProperty(ctor.prototype, name, { + get: function() { + return !!(this._bits & mask); + }, + set: function(val) { + if (val) + this._bits |= mask; + else + this._bits &= ~mask; + }, + }); + }); +} diff --git a/libs/events/node_modules/uglify-js/package.json b/libs/events/node_modules/uglify-js/package.json new file mode 100644 index 000000000..5776de16c --- /dev/null +++ b/libs/events/node_modules/uglify-js/package.json @@ -0,0 +1,56 @@ +{ + "name": "uglify-js", + "description": "JavaScript parser, mangler/compressor and beautifier toolkit", + "author": "Mihai Bazon (http://lisperator.net/)", + "license": "BSD-2-Clause", + "version": "3.17.4", + "engines": { + "node": ">=0.8.0" + }, + "maintainers": [ + "Alex Lam ", + "Mihai Bazon (http://lisperator.net/)" + ], + "repository": "mishoo/UglifyJS", + "main": "tools/node.js", + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "files": [ + "bin", + "lib", + "tools", + "LICENSE" + ], + "devDependencies": { + "acorn": "~8.7.1", + "semver": "~6.3.0" + }, + "scripts": { + "test": "node test/compress.js && node test/mocha.js" + }, + "keywords": [ + "cli", + "compress", + "compressor", + "ecma", + "ecmascript", + "es", + "es5", + "javascript", + "js", + "jsmin", + "min", + "minification", + "minifier", + "minify", + "optimize", + "optimizer", + "pack", + "packer", + "parse", + "parser", + "uglifier", + "uglify" + ] +} diff --git a/libs/events/node_modules/uglify-js/tools/domprops.html b/libs/events/node_modules/uglify-js/tools/domprops.html new file mode 100644 index 000000000..e217b1731 --- /dev/null +++ b/libs/events/node_modules/uglify-js/tools/domprops.html @@ -0,0 +1,456 @@ + + + + + + diff --git a/libs/events/node_modules/uglify-js/tools/domprops.json b/libs/events/node_modules/uglify-js/tools/domprops.json new file mode 100644 index 000000000..1045429dc --- /dev/null +++ b/libs/events/node_modules/uglify-js/tools/domprops.json @@ -0,0 +1,8325 @@ +[ + "$&", + "$'", + "$*", + "$+", + "$1", + "$2", + "$3", + "$4", + "$5", + "$6", + "$7", + "$8", + "$9", + "$_", + "$`", + "$input", + "-moz-animation", + "-moz-animation-delay", + "-moz-animation-direction", + "-moz-animation-duration", + "-moz-animation-fill-mode", + "-moz-animation-iteration-count", + "-moz-animation-name", + "-moz-animation-play-state", + "-moz-animation-timing-function", + "-moz-appearance", + "-moz-backface-visibility", + "-moz-binding", + "-moz-border-end", + "-moz-border-end-color", + "-moz-border-end-style", + "-moz-border-end-width", + "-moz-border-image", + "-moz-border-start", + "-moz-border-start-color", + "-moz-border-start-style", + "-moz-border-start-width", + "-moz-box-align", + "-moz-box-direction", + "-moz-box-flex", + "-moz-box-ordinal-group", + "-moz-box-orient", + "-moz-box-pack", + "-moz-box-sizing", + "-moz-column-count", + "-moz-column-fill", + "-moz-column-gap", + "-moz-column-rule", + "-moz-column-rule-color", + "-moz-column-rule-style", + "-moz-column-rule-width", + "-moz-column-width", + "-moz-columns", + "-moz-float-edge", + "-moz-font-feature-settings", + "-moz-font-language-override", + "-moz-force-broken-image-icon", + "-moz-hyphens", + "-moz-image-region", + "-moz-margin-end", + "-moz-margin-start", + "-moz-orient", + "-moz-outline-radius", + "-moz-outline-radius-bottomleft", + "-moz-outline-radius-bottomright", + "-moz-outline-radius-topleft", + "-moz-outline-radius-topright", + "-moz-padding-end", + "-moz-padding-start", + "-moz-perspective", + "-moz-perspective-origin", + "-moz-stack-sizing", + "-moz-tab-size", + "-moz-text-size-adjust", + "-moz-transform", + "-moz-transform-origin", + "-moz-transform-style", + "-moz-transition", + "-moz-transition-delay", + "-moz-transition-duration", + "-moz-transition-property", + "-moz-transition-timing-function", + "-moz-user-focus", + "-moz-user-input", + "-moz-user-modify", + "-moz-user-select", + "-moz-window-dragging", + "-webkit-align-content", + "-webkit-align-items", + "-webkit-align-self", + "-webkit-animation", + "-webkit-animation-delay", + "-webkit-animation-direction", + "-webkit-animation-duration", + "-webkit-animation-fill-mode", + "-webkit-animation-iteration-count", + "-webkit-animation-name", + "-webkit-animation-play-state", + "-webkit-animation-timing-function", + "-webkit-appearance", + "-webkit-backface-visibility", + "-webkit-background-clip", + "-webkit-background-origin", + "-webkit-background-size", + "-webkit-border-bottom-left-radius", + "-webkit-border-bottom-right-radius", + "-webkit-border-image", + "-webkit-border-radius", + "-webkit-border-top-left-radius", + "-webkit-border-top-right-radius", + "-webkit-box-align", + "-webkit-box-direction", + "-webkit-box-flex", + "-webkit-box-ordinal-group", + "-webkit-box-orient", + "-webkit-box-pack", + "-webkit-box-shadow", + "-webkit-box-sizing", + "-webkit-filter", + "-webkit-flex", + "-webkit-flex-basis", + "-webkit-flex-direction", + "-webkit-flex-flow", + "-webkit-flex-grow", + "-webkit-flex-shrink", + "-webkit-flex-wrap", + "-webkit-justify-content", + "-webkit-line-clamp", + "-webkit-mask", + "-webkit-mask-clip", + "-webkit-mask-composite", + "-webkit-mask-image", + "-webkit-mask-origin", + "-webkit-mask-position", + "-webkit-mask-position-x", + "-webkit-mask-position-y", + "-webkit-mask-repeat", + "-webkit-mask-size", + "-webkit-order", + "-webkit-perspective", + "-webkit-perspective-origin", + "-webkit-text-fill-color", + "-webkit-text-size-adjust", + "-webkit-text-stroke", + "-webkit-text-stroke-color", + "-webkit-text-stroke-width", + "-webkit-transform", + "-webkit-transform-origin", + "-webkit-transform-style", + "-webkit-transition", + "-webkit-transition-delay", + "-webkit-transition-duration", + "-webkit-transition-property", + "-webkit-transition-timing-function", + "-webkit-user-select", + "0", + "1", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "2", + "20", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "3", + "30", + "31", + "32", + "33", + "34", + "35", + "36", + "37", + "38", + "39", + "4", + "40", + "41", + "42", + "43", + "44", + "45", + "46", + "47", + "48", + "49", + "5", + "50", + "51", + "6", + "7", + "8", + "9", + "@@iterator", + "ABORT_ERR", + "ACTIVE", + "ACTIVE_ATTRIBUTES", + "ACTIVE_TEXTURE", + "ACTIVE_UNIFORMS", + "ACTIVE_UNIFORM_BLOCKS", + "ADDITION", + "ALIASED_LINE_WIDTH_RANGE", + "ALIASED_POINT_SIZE_RANGE", + "ALLOW_KEYBOARD_INPUT", + "ALLPASS", + "ALPHA", + "ALPHA_BITS", + "ALREADY_SIGNALED", + "ALT_MASK", + "ALWAYS", + "ANDROID", + "ANGLE_instanced_arrays", + "ANY_SAMPLES_PASSED", + "ANY_SAMPLES_PASSED_CONSERVATIVE", + "ANY_TYPE", + "ANY_UNORDERED_NODE_TYPE", + "APP_UPDATE", + "ARM", + "ARRAY_BUFFER", + "ARRAY_BUFFER_BINDING", + "ATTACHED_SHADERS", + "ATTRIBUTE_NODE", + "AT_TARGET", + "AbortController", + "AbortSignal", + "AbsoluteOrientationSensor", + "AbstractRange", + "Accelerometer", + "ActiveXObject", + "AddSearchProvider", + "AesGcmEncryptResult", + "AggregateError", + "AnalyserNode", + "Animation", + "AnimationEffect", + "AnimationEvent", + "AnimationPlaybackEvent", + "AnimationTimeline", + "AnonXMLHttpRequest", + "AppBannerPromptResult", + "ApplicationCache", + "ApplicationCacheErrorEvent", + "Array", + "ArrayBuffer", + "Atomics", + "Attr", + "Audio", + "AudioBuffer", + "AudioBufferSourceNode", + "AudioContext", + "AudioDestinationNode", + "AudioListener", + "AudioNode", + "AudioParam", + "AudioParamMap", + "AudioProcessingEvent", + "AudioScheduledSourceNode", + "AudioStreamTrack", + "AudioTrack", + "AudioTrackList", + "AudioWorklet", + "AudioWorkletNode", + "AuthenticatorAssertionResponse", + "AuthenticatorAttestationResponse", + "AuthenticatorResponse", + "AutocompleteErrorEvent", + "BACK", + "BAD_BOUNDARYPOINTS_ERR", + "BAD_REQUEST", + "BANDPASS", + "BLEND", + "BLEND_COLOR", + "BLEND_DST_ALPHA", + "BLEND_DST_RGB", + "BLEND_EQUATION", + "BLEND_EQUATION_ALPHA", + "BLEND_EQUATION_RGB", + "BLEND_SRC_ALPHA", + "BLEND_SRC_RGB", + "BLUE_BITS", + "BLUR", + "BOOL", + "BOOLEAN_TYPE", + "BOOL_VEC2", + "BOOL_VEC3", + "BOOL_VEC4", + "BOTH", + "BROWSER_DEFAULT_WEBGL", + "BUBBLING_PHASE", + "BUFFER_SIZE", + "BUFFER_USAGE", + "BYTE", + "BYTES_PER_ELEMENT", + "BackgroundFetchManager", + "BackgroundFetchRecord", + "BackgroundFetchRegistration", + "BarProp", + "BarcodeDetector", + "BaseAudioContext", + "BaseHref", + "BatteryManager", + "BeforeInstallPromptEvent", + "BeforeLoadEvent", + "BeforeUnloadEvent", + "BigInt", + "BigInt64Array", + "BigUint64Array", + "BiquadFilterNode", + "Blob", + "BlobEvent", + "Bluetooth", + "BluetoothCharacteristicProperties", + "BluetoothDevice", + "BluetoothRemoteGATTCharacteristic", + "BluetoothRemoteGATTDescriptor", + "BluetoothRemoteGATTServer", + "BluetoothRemoteGATTService", + "BluetoothUUID", + "BookmarkCollection", + "Boolean", + "BroadcastChannel", + "ByteLengthQueuingStrategy", + "CANNOT_RUN", + "CAPTURING_PHASE", + "CCW", + "CDATASection", + "CDATA_SECTION_NODE", + "CHANGE", + "CHARSET_RULE", + "CHECKING", + "CHROME_UPDATE", + "CLAMP_TO_EDGE", + "CLICK", + "CLOSED", + "CLOSING", + "COLOR", + "COLOR_ATTACHMENT0", + "COLOR_ATTACHMENT1", + "COLOR_ATTACHMENT10", + "COLOR_ATTACHMENT11", + "COLOR_ATTACHMENT12", + "COLOR_ATTACHMENT13", + "COLOR_ATTACHMENT14", + "COLOR_ATTACHMENT15", + "COLOR_ATTACHMENT2", + "COLOR_ATTACHMENT3", + "COLOR_ATTACHMENT4", + "COLOR_ATTACHMENT5", + "COLOR_ATTACHMENT6", + "COLOR_ATTACHMENT7", + "COLOR_ATTACHMENT8", + "COLOR_ATTACHMENT9", + "COLOR_BUFFER_BIT", + "COLOR_CLEAR_VALUE", + "COLOR_WRITEMASK", + "COMMENT_NODE", + "COMPARE_REF_TO_TEXTURE", + "COMPILE_STATUS", + "COMPRESSED_RGBA_S3TC_DXT1_EXT", + "COMPRESSED_RGBA_S3TC_DXT3_EXT", + "COMPRESSED_RGBA_S3TC_DXT5_EXT", + "COMPRESSED_RGB_S3TC_DXT1_EXT", + "COMPRESSED_TEXTURE_FORMATS", + "CONDITION_SATISFIED", + "CONFIGURATION_UNSUPPORTED", + "CONNECTING", + "CONSTANT_ALPHA", + "CONSTANT_COLOR", + "CONSTRAINT_ERR", + "CONTENT", + "CONTEXT_LOST_WEBGL", + "CONTROL_MASK", + "COPY_READ_BUFFER", + "COPY_READ_BUFFER_BINDING", + "COPY_WRITE_BUFFER", + "COPY_WRITE_BUFFER_BINDING", + "COUNTER_STYLE_RULE", + "CROS", + "CSS", + "CSS2Properties", + "CSSAnimation", + "CSSCharsetRule", + "CSSConditionRule", + "CSSCounterStyleRule", + "CSSFontFaceRule", + "CSSFontFeatureValuesRule", + "CSSGroupingRule", + "CSSImageValue", + "CSSImportRule", + "CSSKeyframeRule", + "CSSKeyframesRule", + "CSSKeywordValue", + "CSSMathInvert", + "CSSMathMax", + "CSSMathMin", + "CSSMathNegate", + "CSSMathProduct", + "CSSMathSum", + "CSSMathValue", + "CSSMatrixComponent", + "CSSMediaRule", + "CSSMozDocumentRule", + "CSSNameSpaceRule", + "CSSNamespaceRule", + "CSSNumericArray", + "CSSNumericValue", + "CSSPageRule", + "CSSPerspective", + "CSSPositionValue", + "CSSPrimitiveValue", + "CSSRotate", + "CSSRule", + "CSSRuleList", + "CSSScale", + "CSSSkew", + "CSSSkewX", + "CSSSkewY", + "CSSStyleDeclaration", + "CSSStyleRule", + "CSSStyleSheet", + "CSSStyleValue", + "CSSSupportsRule", + "CSSTransformComponent", + "CSSTransformValue", + "CSSTransition", + "CSSTranslate", + "CSSUnitValue", + "CSSUnknownRule", + "CSSUnparsedValue", + "CSSValue", + "CSSValueList", + "CSSVariableReferenceValue", + "CSSVariablesDeclaration", + "CSSVariablesRule", + "CSSViewportRule", + "CSS_ATTR", + "CSS_CM", + "CSS_COUNTER", + "CSS_CUSTOM", + "CSS_DEG", + "CSS_DIMENSION", + "CSS_EMS", + "CSS_EXS", + "CSS_FILTER_BLUR", + "CSS_FILTER_BRIGHTNESS", + "CSS_FILTER_CONTRAST", + "CSS_FILTER_CUSTOM", + "CSS_FILTER_DROP_SHADOW", + "CSS_FILTER_GRAYSCALE", + "CSS_FILTER_HUE_ROTATE", + "CSS_FILTER_INVERT", + "CSS_FILTER_OPACITY", + "CSS_FILTER_REFERENCE", + "CSS_FILTER_SATURATE", + "CSS_FILTER_SEPIA", + "CSS_GRAD", + "CSS_HZ", + "CSS_IDENT", + "CSS_IN", + "CSS_INHERIT", + "CSS_KHZ", + "CSS_MATRIX", + "CSS_MATRIX3D", + "CSS_MM", + "CSS_MS", + "CSS_NUMBER", + "CSS_PC", + "CSS_PERCENTAGE", + "CSS_PERSPECTIVE", + "CSS_PRIMITIVE_VALUE", + "CSS_PT", + "CSS_PX", + "CSS_RAD", + "CSS_RECT", + "CSS_RGBCOLOR", + "CSS_ROTATE", + "CSS_ROTATE3D", + "CSS_ROTATEX", + "CSS_ROTATEY", + "CSS_ROTATEZ", + "CSS_S", + "CSS_SCALE", + "CSS_SCALE3D", + "CSS_SCALEX", + "CSS_SCALEY", + "CSS_SCALEZ", + "CSS_SKEW", + "CSS_SKEWX", + "CSS_SKEWY", + "CSS_STRING", + "CSS_TRANSLATE", + "CSS_TRANSLATE3D", + "CSS_TRANSLATEX", + "CSS_TRANSLATEY", + "CSS_TRANSLATEZ", + "CSS_UNKNOWN", + "CSS_URI", + "CSS_VALUE_LIST", + "CSS_VH", + "CSS_VMAX", + "CSS_VMIN", + "CSS_VW", + "CULL_FACE", + "CULL_FACE_MODE", + "CURRENT_PROGRAM", + "CURRENT_QUERY", + "CURRENT_VERTEX_ATTRIB", + "CUSTOM", + "CW", + "Cache", + "CacheStorage", + "CanvasCaptureMediaStream", + "CanvasCaptureMediaStreamTrack", + "CanvasGradient", + "CanvasPattern", + "CanvasPixelArray", + "CanvasRenderingContext2D", + "CaretPosition", + "ChannelMergerNode", + "ChannelSplitterNode", + "CharacterData", + "Chrome PDF Plugin", + "Chrome PDF Viewer", + "ClientRect", + "ClientRectList", + "Clipboard", + "ClipboardEvent", + "ClipboardItem", + "CloseEvent", + "Collator", + "CollectGarbage", + "CommandEvent", + "Comment", + "CompileError", + "CompositionEvent", + "CompressionStream", + "Console", + "ConstantSourceNode", + "ControlRangeCollection", + "Controllers", + "ConvolverNode", + "Coordinates", + "CountQueuingStrategy", + "Counter", + "Credential", + "CredentialsContainer", + "Crypto", + "CryptoKey", + "CryptoOperation", + "CustomElementRegistry", + "CustomEvent", + "DATABASE_ERR", + "DATA_CLONE_ERR", + "DATA_ERR", + "DBLCLICK", + "DECR", + "DECR_WRAP", + "DELETE_STATUS", + "DEPTH", + "DEPTH24_STENCIL8", + "DEPTH32F_STENCIL8", + "DEPTH_ATTACHMENT", + "DEPTH_BITS", + "DEPTH_BUFFER_BIT", + "DEPTH_CLEAR_VALUE", + "DEPTH_COMPONENT", + "DEPTH_COMPONENT16", + "DEPTH_COMPONENT24", + "DEPTH_COMPONENT32F", + "DEPTH_FUNC", + "DEPTH_RANGE", + "DEPTH_STENCIL", + "DEPTH_STENCIL_ATTACHMENT", + "DEPTH_TEST", + "DEPTH_WRITEMASK", + "DEVICE_INELIGIBLE", + "DIRECTION_DOWN", + "DIRECTION_LEFT", + "DIRECTION_RIGHT", + "DIRECTION_UP", + "DISABLED", + "DISPATCH_REQUEST_ERR", + "DITHER", + "DOCUMENT_FRAGMENT_NODE", + "DOCUMENT_NODE", + "DOCUMENT_POSITION_CONTAINED_BY", + "DOCUMENT_POSITION_CONTAINS", + "DOCUMENT_POSITION_DISCONNECTED", + "DOCUMENT_POSITION_FOLLOWING", + "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", + "DOCUMENT_POSITION_PRECEDING", + "DOCUMENT_TYPE_NODE", + "DOMCursor", + "DOMError", + "DOMException", + "DOMImplementation", + "DOMImplementationLS", + "DOMMatrix", + "DOMMatrixReadOnly", + "DOMParser", + "DOMPoint", + "DOMPointReadOnly", + "DOMQuad", + "DOMRect", + "DOMRectList", + "DOMRectReadOnly", + "DOMRequest", + "DOMSTRING_SIZE_ERR", + "DOMSettableTokenList", + "DOMStringList", + "DOMStringMap", + "DOMTokenList", + "DOMTransactionEvent", + "DOM_DELTA_LINE", + "DOM_DELTA_PAGE", + "DOM_DELTA_PIXEL", + "DOM_INPUT_METHOD_DROP", + "DOM_INPUT_METHOD_HANDWRITING", + "DOM_INPUT_METHOD_IME", + "DOM_INPUT_METHOD_KEYBOARD", + "DOM_INPUT_METHOD_MULTIMODAL", + "DOM_INPUT_METHOD_OPTION", + "DOM_INPUT_METHOD_PASTE", + "DOM_INPUT_METHOD_SCRIPT", + "DOM_INPUT_METHOD_UNKNOWN", + "DOM_INPUT_METHOD_VOICE", + "DOM_KEY_LOCATION_JOYSTICK", + "DOM_KEY_LOCATION_LEFT", + "DOM_KEY_LOCATION_MOBILE", + "DOM_KEY_LOCATION_NUMPAD", + "DOM_KEY_LOCATION_RIGHT", + "DOM_KEY_LOCATION_STANDARD", + "DOM_VK_0", + "DOM_VK_1", + "DOM_VK_2", + "DOM_VK_3", + "DOM_VK_4", + "DOM_VK_5", + "DOM_VK_6", + "DOM_VK_7", + "DOM_VK_8", + "DOM_VK_9", + "DOM_VK_A", + "DOM_VK_ACCEPT", + "DOM_VK_ADD", + "DOM_VK_ALT", + "DOM_VK_ALTGR", + "DOM_VK_AMPERSAND", + "DOM_VK_ASTERISK", + "DOM_VK_AT", + "DOM_VK_ATTN", + "DOM_VK_B", + "DOM_VK_BACKSPACE", + "DOM_VK_BACK_QUOTE", + "DOM_VK_BACK_SLASH", + "DOM_VK_BACK_SPACE", + "DOM_VK_C", + "DOM_VK_CANCEL", + "DOM_VK_CAPS_LOCK", + "DOM_VK_CIRCUMFLEX", + "DOM_VK_CLEAR", + "DOM_VK_CLOSE_BRACKET", + "DOM_VK_CLOSE_CURLY_BRACKET", + "DOM_VK_CLOSE_PAREN", + "DOM_VK_COLON", + "DOM_VK_COMMA", + "DOM_VK_CONTEXT_MENU", + "DOM_VK_CONTROL", + "DOM_VK_CONVERT", + "DOM_VK_CRSEL", + "DOM_VK_CTRL", + "DOM_VK_D", + "DOM_VK_DECIMAL", + "DOM_VK_DELETE", + "DOM_VK_DIVIDE", + "DOM_VK_DOLLAR", + "DOM_VK_DOUBLE_QUOTE", + "DOM_VK_DOWN", + "DOM_VK_E", + "DOM_VK_EISU", + "DOM_VK_END", + "DOM_VK_ENTER", + "DOM_VK_EQUALS", + "DOM_VK_EREOF", + "DOM_VK_ESCAPE", + "DOM_VK_EXCLAMATION", + "DOM_VK_EXECUTE", + "DOM_VK_EXSEL", + "DOM_VK_F", + "DOM_VK_F1", + "DOM_VK_F10", + "DOM_VK_F11", + "DOM_VK_F12", + "DOM_VK_F13", + "DOM_VK_F14", + "DOM_VK_F15", + "DOM_VK_F16", + "DOM_VK_F17", + "DOM_VK_F18", + "DOM_VK_F19", + "DOM_VK_F2", + "DOM_VK_F20", + "DOM_VK_F21", + "DOM_VK_F22", + "DOM_VK_F23", + "DOM_VK_F24", + "DOM_VK_F25", + "DOM_VK_F26", + "DOM_VK_F27", + "DOM_VK_F28", + "DOM_VK_F29", + "DOM_VK_F3", + "DOM_VK_F30", + "DOM_VK_F31", + "DOM_VK_F32", + "DOM_VK_F33", + "DOM_VK_F34", + "DOM_VK_F35", + "DOM_VK_F36", + "DOM_VK_F4", + "DOM_VK_F5", + "DOM_VK_F6", + "DOM_VK_F7", + "DOM_VK_F8", + "DOM_VK_F9", + "DOM_VK_FINAL", + "DOM_VK_FRONT", + "DOM_VK_G", + "DOM_VK_GREATER_THAN", + "DOM_VK_H", + "DOM_VK_HANGUL", + "DOM_VK_HANJA", + "DOM_VK_HASH", + "DOM_VK_HELP", + "DOM_VK_HK_TOGGLE", + "DOM_VK_HOME", + "DOM_VK_HYPHEN_MINUS", + "DOM_VK_I", + "DOM_VK_INSERT", + "DOM_VK_J", + "DOM_VK_JUNJA", + "DOM_VK_K", + "DOM_VK_KANA", + "DOM_VK_KANJI", + "DOM_VK_L", + "DOM_VK_LEFT", + "DOM_VK_LEFT_TAB", + "DOM_VK_LESS_THAN", + "DOM_VK_M", + "DOM_VK_META", + "DOM_VK_MODECHANGE", + "DOM_VK_MULTIPLY", + "DOM_VK_N", + "DOM_VK_NONCONVERT", + "DOM_VK_NUMPAD0", + "DOM_VK_NUMPAD1", + "DOM_VK_NUMPAD2", + "DOM_VK_NUMPAD3", + "DOM_VK_NUMPAD4", + "DOM_VK_NUMPAD5", + "DOM_VK_NUMPAD6", + "DOM_VK_NUMPAD7", + "DOM_VK_NUMPAD8", + "DOM_VK_NUMPAD9", + "DOM_VK_NUM_LOCK", + "DOM_VK_O", + "DOM_VK_OEM_1", + "DOM_VK_OEM_102", + "DOM_VK_OEM_2", + "DOM_VK_OEM_3", + "DOM_VK_OEM_4", + "DOM_VK_OEM_5", + "DOM_VK_OEM_6", + "DOM_VK_OEM_7", + "DOM_VK_OEM_8", + "DOM_VK_OEM_COMMA", + "DOM_VK_OEM_MINUS", + "DOM_VK_OEM_PERIOD", + "DOM_VK_OEM_PLUS", + "DOM_VK_OPEN_BRACKET", + "DOM_VK_OPEN_CURLY_BRACKET", + "DOM_VK_OPEN_PAREN", + "DOM_VK_P", + "DOM_VK_PA1", + "DOM_VK_PAGEDOWN", + "DOM_VK_PAGEUP", + "DOM_VK_PAGE_DOWN", + "DOM_VK_PAGE_UP", + "DOM_VK_PAUSE", + "DOM_VK_PERCENT", + "DOM_VK_PERIOD", + "DOM_VK_PIPE", + "DOM_VK_PLAY", + "DOM_VK_PLUS", + "DOM_VK_PRINT", + "DOM_VK_PRINTSCREEN", + "DOM_VK_PROCESSKEY", + "DOM_VK_PROPERITES", + "DOM_VK_Q", + "DOM_VK_QUESTION_MARK", + "DOM_VK_QUOTE", + "DOM_VK_R", + "DOM_VK_REDO", + "DOM_VK_RETURN", + "DOM_VK_RIGHT", + "DOM_VK_S", + "DOM_VK_SCROLL_LOCK", + "DOM_VK_SELECT", + "DOM_VK_SEMICOLON", + "DOM_VK_SEPARATOR", + "DOM_VK_SHIFT", + "DOM_VK_SLASH", + "DOM_VK_SLEEP", + "DOM_VK_SPACE", + "DOM_VK_SUBTRACT", + "DOM_VK_T", + "DOM_VK_TAB", + "DOM_VK_TILDE", + "DOM_VK_U", + "DOM_VK_UNDERSCORE", + "DOM_VK_UNDO", + "DOM_VK_UNICODE", + "DOM_VK_UP", + "DOM_VK_V", + "DOM_VK_VOLUME_DOWN", + "DOM_VK_VOLUME_MUTE", + "DOM_VK_VOLUME_UP", + "DOM_VK_W", + "DOM_VK_WIN", + "DOM_VK_WINDOW", + "DOM_VK_WIN_ICO_00", + "DOM_VK_WIN_ICO_CLEAR", + "DOM_VK_WIN_ICO_HELP", + "DOM_VK_WIN_OEM_ATTN", + "DOM_VK_WIN_OEM_AUTO", + "DOM_VK_WIN_OEM_BACKTAB", + "DOM_VK_WIN_OEM_CLEAR", + "DOM_VK_WIN_OEM_COPY", + "DOM_VK_WIN_OEM_CUSEL", + "DOM_VK_WIN_OEM_ENLW", + "DOM_VK_WIN_OEM_FINISH", + "DOM_VK_WIN_OEM_FJ_JISHO", + "DOM_VK_WIN_OEM_FJ_LOYA", + "DOM_VK_WIN_OEM_FJ_MASSHOU", + "DOM_VK_WIN_OEM_FJ_ROYA", + "DOM_VK_WIN_OEM_FJ_TOUROKU", + "DOM_VK_WIN_OEM_JUMP", + "DOM_VK_WIN_OEM_PA1", + "DOM_VK_WIN_OEM_PA2", + "DOM_VK_WIN_OEM_PA3", + "DOM_VK_WIN_OEM_RESET", + "DOM_VK_WIN_OEM_WSCTRL", + "DOM_VK_X", + "DOM_VK_XF86XK_ADD_FAVORITE", + "DOM_VK_XF86XK_APPLICATION_LEFT", + "DOM_VK_XF86XK_APPLICATION_RIGHT", + "DOM_VK_XF86XK_AUDIO_CYCLE_TRACK", + "DOM_VK_XF86XK_AUDIO_FORWARD", + "DOM_VK_XF86XK_AUDIO_LOWER_VOLUME", + "DOM_VK_XF86XK_AUDIO_MEDIA", + "DOM_VK_XF86XK_AUDIO_MUTE", + "DOM_VK_XF86XK_AUDIO_NEXT", + "DOM_VK_XF86XK_AUDIO_PAUSE", + "DOM_VK_XF86XK_AUDIO_PLAY", + "DOM_VK_XF86XK_AUDIO_PREV", + "DOM_VK_XF86XK_AUDIO_RAISE_VOLUME", + "DOM_VK_XF86XK_AUDIO_RANDOM_PLAY", + "DOM_VK_XF86XK_AUDIO_RECORD", + "DOM_VK_XF86XK_AUDIO_REPEAT", + "DOM_VK_XF86XK_AUDIO_REWIND", + "DOM_VK_XF86XK_AUDIO_STOP", + "DOM_VK_XF86XK_AWAY", + "DOM_VK_XF86XK_BACK", + "DOM_VK_XF86XK_BACK_FORWARD", + "DOM_VK_XF86XK_BATTERY", + "DOM_VK_XF86XK_BLUE", + "DOM_VK_XF86XK_BLUETOOTH", + "DOM_VK_XF86XK_BOOK", + "DOM_VK_XF86XK_BRIGHTNESS_ADJUST", + "DOM_VK_XF86XK_CALCULATOR", + "DOM_VK_XF86XK_CALENDAR", + "DOM_VK_XF86XK_CD", + "DOM_VK_XF86XK_CLOSE", + "DOM_VK_XF86XK_COMMUNITY", + "DOM_VK_XF86XK_CONTRAST_ADJUST", + "DOM_VK_XF86XK_COPY", + "DOM_VK_XF86XK_CUT", + "DOM_VK_XF86XK_CYCLE_ANGLE", + "DOM_VK_XF86XK_DISPLAY", + "DOM_VK_XF86XK_DOCUMENTS", + "DOM_VK_XF86XK_DOS", + "DOM_VK_XF86XK_EJECT", + "DOM_VK_XF86XK_EXCEL", + "DOM_VK_XF86XK_EXPLORER", + "DOM_VK_XF86XK_FAVORITES", + "DOM_VK_XF86XK_FINANCE", + "DOM_VK_XF86XK_FORWARD", + "DOM_VK_XF86XK_FRAME_BACK", + "DOM_VK_XF86XK_FRAME_FORWARD", + "DOM_VK_XF86XK_GAME", + "DOM_VK_XF86XK_GO", + "DOM_VK_XF86XK_GREEN", + "DOM_VK_XF86XK_HIBERNATE", + "DOM_VK_XF86XK_HISTORY", + "DOM_VK_XF86XK_HOME_PAGE", + "DOM_VK_XF86XK_HOT_LINKS", + "DOM_VK_XF86XK_I_TOUCH", + "DOM_VK_XF86XK_KBD_BRIGHTNESS_DOWN", + "DOM_VK_XF86XK_KBD_BRIGHTNESS_UP", + "DOM_VK_XF86XK_KBD_LIGHT_ON_OFF", + "DOM_VK_XF86XK_LAUNCH0", + "DOM_VK_XF86XK_LAUNCH1", + "DOM_VK_XF86XK_LAUNCH2", + "DOM_VK_XF86XK_LAUNCH3", + "DOM_VK_XF86XK_LAUNCH4", + "DOM_VK_XF86XK_LAUNCH5", + "DOM_VK_XF86XK_LAUNCH6", + "DOM_VK_XF86XK_LAUNCH7", + "DOM_VK_XF86XK_LAUNCH8", + "DOM_VK_XF86XK_LAUNCH9", + "DOM_VK_XF86XK_LAUNCH_A", + "DOM_VK_XF86XK_LAUNCH_B", + "DOM_VK_XF86XK_LAUNCH_C", + "DOM_VK_XF86XK_LAUNCH_D", + "DOM_VK_XF86XK_LAUNCH_E", + "DOM_VK_XF86XK_LAUNCH_F", + "DOM_VK_XF86XK_LIGHT_BULB", + "DOM_VK_XF86XK_LOG_OFF", + "DOM_VK_XF86XK_MAIL", + "DOM_VK_XF86XK_MAIL_FORWARD", + "DOM_VK_XF86XK_MARKET", + "DOM_VK_XF86XK_MEETING", + "DOM_VK_XF86XK_MEMO", + "DOM_VK_XF86XK_MENU_KB", + "DOM_VK_XF86XK_MENU_PB", + "DOM_VK_XF86XK_MESSENGER", + "DOM_VK_XF86XK_MON_BRIGHTNESS_DOWN", + "DOM_VK_XF86XK_MON_BRIGHTNESS_UP", + "DOM_VK_XF86XK_MUSIC", + "DOM_VK_XF86XK_MY_COMPUTER", + "DOM_VK_XF86XK_MY_SITES", + "DOM_VK_XF86XK_NEW", + "DOM_VK_XF86XK_NEWS", + "DOM_VK_XF86XK_OFFICE_HOME", + "DOM_VK_XF86XK_OPEN", + "DOM_VK_XF86XK_OPEN_URL", + "DOM_VK_XF86XK_OPTION", + "DOM_VK_XF86XK_PASTE", + "DOM_VK_XF86XK_PHONE", + "DOM_VK_XF86XK_PICTURES", + "DOM_VK_XF86XK_POWER_DOWN", + "DOM_VK_XF86XK_POWER_OFF", + "DOM_VK_XF86XK_RED", + "DOM_VK_XF86XK_REFRESH", + "DOM_VK_XF86XK_RELOAD", + "DOM_VK_XF86XK_REPLY", + "DOM_VK_XF86XK_ROCKER_DOWN", + "DOM_VK_XF86XK_ROCKER_ENTER", + "DOM_VK_XF86XK_ROCKER_UP", + "DOM_VK_XF86XK_ROTATE_WINDOWS", + "DOM_VK_XF86XK_ROTATION_KB", + "DOM_VK_XF86XK_ROTATION_PB", + "DOM_VK_XF86XK_SAVE", + "DOM_VK_XF86XK_SCREEN_SAVER", + "DOM_VK_XF86XK_SCROLL_CLICK", + "DOM_VK_XF86XK_SCROLL_DOWN", + "DOM_VK_XF86XK_SCROLL_UP", + "DOM_VK_XF86XK_SEARCH", + "DOM_VK_XF86XK_SEND", + "DOM_VK_XF86XK_SHOP", + "DOM_VK_XF86XK_SPELL", + "DOM_VK_XF86XK_SPLIT_SCREEN", + "DOM_VK_XF86XK_STANDBY", + "DOM_VK_XF86XK_START", + "DOM_VK_XF86XK_STOP", + "DOM_VK_XF86XK_SUBTITLE", + "DOM_VK_XF86XK_SUPPORT", + "DOM_VK_XF86XK_SUSPEND", + "DOM_VK_XF86XK_TASK_PANE", + "DOM_VK_XF86XK_TERMINAL", + "DOM_VK_XF86XK_TIME", + "DOM_VK_XF86XK_TOOLS", + "DOM_VK_XF86XK_TOP_MENU", + "DOM_VK_XF86XK_TO_DO_LIST", + "DOM_VK_XF86XK_TRAVEL", + "DOM_VK_XF86XK_USER1KB", + "DOM_VK_XF86XK_USER2KB", + "DOM_VK_XF86XK_USER_PB", + "DOM_VK_XF86XK_UWB", + "DOM_VK_XF86XK_VENDOR_HOME", + "DOM_VK_XF86XK_VIDEO", + "DOM_VK_XF86XK_VIEW", + "DOM_VK_XF86XK_WAKE_UP", + "DOM_VK_XF86XK_WEB_CAM", + "DOM_VK_XF86XK_WHEEL_BUTTON", + "DOM_VK_XF86XK_WLAN", + "DOM_VK_XF86XK_WORD", + "DOM_VK_XF86XK_WWW", + "DOM_VK_XF86XK_XFER", + "DOM_VK_XF86XK_YELLOW", + "DOM_VK_XF86XK_ZOOM_IN", + "DOM_VK_XF86XK_ZOOM_OUT", + "DOM_VK_Y", + "DOM_VK_Z", + "DOM_VK_ZOOM", + "DONE", + "DONT_CARE", + "DOWNLOADING", + "DRAGDROP", + "DRAW_BUFFER0", + "DRAW_BUFFER1", + "DRAW_BUFFER10", + "DRAW_BUFFER11", + "DRAW_BUFFER12", + "DRAW_BUFFER13", + "DRAW_BUFFER14", + "DRAW_BUFFER15", + "DRAW_BUFFER2", + "DRAW_BUFFER3", + "DRAW_BUFFER4", + "DRAW_BUFFER5", + "DRAW_BUFFER6", + "DRAW_BUFFER7", + "DRAW_BUFFER8", + "DRAW_BUFFER9", + "DRAW_FRAMEBUFFER", + "DRAW_FRAMEBUFFER_BINDING", + "DST_ALPHA", + "DST_COLOR", + "DYNAMIC_COPY", + "DYNAMIC_DRAW", + "DYNAMIC_READ", + "DataChannel", + "DataCue", + "DataTransfer", + "DataTransferItem", + "DataTransferItemList", + "DataView", + "Database", + "Date", + "DateTimeFormat", + "Debug", + "DecompressionStream", + "Default Browser Helper", + "DelayNode", + "DesktopNotification", + "DesktopNotificationCenter", + "DeviceAcceleration", + "DeviceLightEvent", + "DeviceMotionEvent", + "DeviceMotionEventAcceleration", + "DeviceMotionEventRotationRate", + "DeviceOrientationEvent", + "DeviceProximityEvent", + "DeviceRotationRate", + "DeviceStorage", + "DeviceStorageChangeEvent", + "Directory", + "DisplayNames", + "Document", + "DocumentFragment", + "DocumentTimeline", + "DocumentType", + "DragEvent", + "DynamicsCompressorNode", + "E", + "ELEMENT_ARRAY_BUFFER", + "ELEMENT_ARRAY_BUFFER_BINDING", + "ELEMENT_NODE", + "EMPTY", + "ENCODING_ERR", + "ENDED", + "END_TO_END", + "END_TO_START", + "ENTITY_NODE", + "ENTITY_REFERENCE_NODE", + "EPSILON", + "EQUAL", + "EQUALPOWER", + "ERROR", + "EXPONENTIAL_DISTANCE", + "EXT_texture_filter_anisotropic", + "Element", + "ElementInternals", + "ElementQuery", + "EnterPictureInPictureEvent", + "Entity", + "EntityReference", + "Enumerator", + "Error", + "ErrorEvent", + "EvalError", + "Event", + "EventException", + "EventSource", + "EventTarget", + "External", + "FASTEST", + "FIDOSDK", + "FILTER_ACCEPT", + "FILTER_INTERRUPT", + "FILTER_REJECT", + "FILTER_SKIP", + "FINISHED_STATE", + "FIRST_ORDERED_NODE_TYPE", + "FLOAT", + "FLOAT_32_UNSIGNED_INT_24_8_REV", + "FLOAT_MAT2", + "FLOAT_MAT2x3", + "FLOAT_MAT2x4", + "FLOAT_MAT3", + "FLOAT_MAT3x2", + "FLOAT_MAT3x4", + "FLOAT_MAT4", + "FLOAT_MAT4x2", + "FLOAT_MAT4x3", + "FLOAT_VEC2", + "FLOAT_VEC3", + "FLOAT_VEC4", + "FOCUS", + "FONT_FACE_RULE", + "FONT_FEATURE_VALUES_RULE", + "FRAGMENT_SHADER", + "FRAGMENT_SHADER_DERIVATIVE_HINT", + "FRAGMENT_SHADER_DERIVATIVE_HINT_OES", + "FRAMEBUFFER", + "FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE", + "FRAMEBUFFER_ATTACHMENT_BLUE_SIZE", + "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING", + "FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE", + "FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE", + "FRAMEBUFFER_ATTACHMENT_GREEN_SIZE", + "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME", + "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE", + "FRAMEBUFFER_ATTACHMENT_RED_SIZE", + "FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE", + "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE", + "FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER", + "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL", + "FRAMEBUFFER_BINDING", + "FRAMEBUFFER_COMPLETE", + "FRAMEBUFFER_DEFAULT", + "FRAMEBUFFER_INCOMPLETE_ATTACHMENT", + "FRAMEBUFFER_INCOMPLETE_DIMENSIONS", + "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", + "FRAMEBUFFER_INCOMPLETE_MULTISAMPLE", + "FRAMEBUFFER_UNSUPPORTED", + "FRONT", + "FRONT_AND_BACK", + "FRONT_FACE", + "FUNC_ADD", + "FUNC_REVERSE_SUBTRACT", + "FUNC_SUBTRACT", + "FeaturePolicy", + "FederatedCredential", + "Feed", + "FeedEntry", + "File", + "FileError", + "FileList", + "FileReader", + "FileSystem", + "FileSystemDirectoryEntry", + "FileSystemDirectoryReader", + "FileSystemEntry", + "FileSystemFileEntry", + "FinalizationRegistry", + "FindInPage", + "Float32Array", + "Float64Array", + "FocusEvent", + "FontFace", + "FontFaceSet", + "FontFaceSetLoadEvent", + "FormData", + "FormDataEvent", + "FragmentDirective", + "Function", + "GENERATE_MIPMAP_HINT", + "GEQUAL", + "GREATER", + "GREEN_BITS", + "GainNode", + "Gamepad", + "GamepadButton", + "GamepadEvent", + "GamepadHapticActuator", + "GamepadPose", + "Geolocation", + "GeolocationCoordinates", + "GeolocationPosition", + "GeolocationPositionError", + "GestureEvent", + "Global", + "Gyroscope", + "HALF_FLOAT", + "HAVE_CURRENT_DATA", + "HAVE_ENOUGH_DATA", + "HAVE_FUTURE_DATA", + "HAVE_METADATA", + "HAVE_NOTHING", + "HEADERS_RECEIVED", + "HIDDEN", + "HIERARCHY_REQUEST_ERR", + "HIGHPASS", + "HIGHSHELF", + "HIGH_FLOAT", + "HIGH_INT", + "HORIZONTAL", + "HORIZONTAL_AXIS", + "HRTF", + "HTMLAllCollection", + "HTMLAnchorElement", + "HTMLAppletElement", + "HTMLAreaElement", + "HTMLAreasCollection", + "HTMLAudioElement", + "HTMLBGSoundElement", + "HTMLBRElement", + "HTMLBaseElement", + "HTMLBaseFontElement", + "HTMLBlockElement", + "HTMLBlockquoteElement", + "HTMLBodyElement", + "HTMLButtonElement", + "HTMLCanvasElement", + "HTMLCollection", + "HTMLCommandElement", + "HTMLContentElement", + "HTMLDDElement", + "HTMLDListElement", + "HTMLDTElement", + "HTMLDataElement", + "HTMLDataListElement", + "HTMLDetailsElement", + "HTMLDialogElement", + "HTMLDirectoryElement", + "HTMLDivElement", + "HTMLDocument", + "HTMLElement", + "HTMLEmbedElement", + "HTMLFieldSetElement", + "HTMLFontElement", + "HTMLFormControlsCollection", + "HTMLFormElement", + "HTMLFrameElement", + "HTMLFrameSetElement", + "HTMLHRElement", + "HTMLHeadElement", + "HTMLHeadingElement", + "HTMLHtmlElement", + "HTMLIFrameElement", + "HTMLImageElement", + "HTMLInputElement", + "HTMLIsIndexElement", + "HTMLKeygenElement", + "HTMLLIElement", + "HTMLLabelElement", + "HTMLLegendElement", + "HTMLLinkElement", + "HTMLMapElement", + "HTMLMarqueeElement", + "HTMLMediaElement", + "HTMLMenuElement", + "HTMLMenuItemElement", + "HTMLMetaElement", + "HTMLMeterElement", + "HTMLModElement", + "HTMLNextIdElement", + "HTMLOListElement", + "HTMLObjectElement", + "HTMLOptGroupElement", + "HTMLOptionElement", + "HTMLOptionsCollection", + "HTMLOutputElement", + "HTMLParagraphElement", + "HTMLParamElement", + "HTMLPhraseElement", + "HTMLPictureElement", + "HTMLPreElement", + "HTMLProgressElement", + "HTMLPropertiesCollection", + "HTMLQuoteElement", + "HTMLScriptElement", + "HTMLSelectElement", + "HTMLShadowElement", + "HTMLSlotElement", + "HTMLSourceElement", + "HTMLSpanElement", + "HTMLStyleElement", + "HTMLTableCaptionElement", + "HTMLTableCellElement", + "HTMLTableColElement", + "HTMLTableDataCellElement", + "HTMLTableElement", + "HTMLTableHeaderCellElement", + "HTMLTableRowElement", + "HTMLTableSectionElement", + "HTMLTemplateElement", + "HTMLTextAreaElement", + "HTMLTimeElement", + "HTMLTitleElement", + "HTMLTrackElement", + "HTMLUListElement", + "HTMLUnknownElement", + "HTMLVideoElement", + "HashChangeEvent", + "Headers", + "History", + "Hz", + "ICE_CHECKING", + "ICE_CLOSED", + "ICE_COMPLETED", + "ICE_CONNECTED", + "ICE_FAILED", + "ICE_GATHERING", + "ICE_WAITING", + "IDBCursor", + "IDBCursorWithValue", + "IDBDatabase", + "IDBDatabaseException", + "IDBFactory", + "IDBFileHandle", + "IDBFileRequest", + "IDBIndex", + "IDBKeyRange", + "IDBMutableFile", + "IDBObjectStore", + "IDBOpenDBRequest", + "IDBRequest", + "IDBTransaction", + "IDBVersionChangeEvent", + "IDLE", + "IIRFilterNode", + "IMPLEMENTATION_COLOR_READ_FORMAT", + "IMPLEMENTATION_COLOR_READ_TYPE", + "IMPORT_RULE", + "INCR", + "INCR_WRAP", + "INDEX_SIZE_ERR", + "INSTALL", + "INSTALLED", + "INT", + "INTERLEAVED_ATTRIBS", + "INT_2_10_10_10_REV", + "INT_SAMPLER_2D", + "INT_SAMPLER_2D_ARRAY", + "INT_SAMPLER_3D", + "INT_SAMPLER_CUBE", + "INT_VEC2", + "INT_VEC3", + "INT_VEC4", + "INUSE_ATTRIBUTE_ERR", + "INVALID_ACCESS_ERR", + "INVALID_CHARACTER_ERR", + "INVALID_ENUM", + "INVALID_EXPRESSION_ERR", + "INVALID_FRAMEBUFFER_OPERATION", + "INVALID_INDEX", + "INVALID_MODIFICATION_ERR", + "INVALID_NODE_TYPE_ERR", + "INVALID_OPERATION", + "INVALID_STATE_ERR", + "INVALID_VALUE", + "INVERSE_DISTANCE", + "INVERT", + "IceCandidate", + "IdleDeadline", + "Image", + "ImageBitmap", + "ImageBitmapRenderingContext", + "ImageCapture", + "ImageData", + "Infinity", + "InputDeviceCapabilities", + "InputDeviceInfo", + "InputEvent", + "InputMethodContext", + "InstallState", + "InstallTrigger", + "Instance", + "Int16Array", + "Int32Array", + "Int8Array", + "Intent", + "InternalError", + "IntersectionObserver", + "IntersectionObserverEntry", + "Intl", + "IsSearchProviderInstalled", + "Iterator", + "JSON", + "Java Deployment Toolkit 7.0.250.17", + "Java(TM) Platform SE 7 U25", + "KEEP", + "KEYDOWN", + "KEYFRAMES_RULE", + "KEYFRAME_RULE", + "KEYPRESS", + "KEYUP", + "Key", + "KeyEvent", + "KeyOperation", + "KeyPair", + "Keyboard", + "KeyboardEvent", + "KeyboardLayoutMap", + "KeyframeEffect", + "LENGTHADJUST_SPACING", + "LENGTHADJUST_SPACINGANDGLYPHS", + "LENGTHADJUST_UNKNOWN", + "LEQUAL", + "LESS", + "LINEAR", + "LINEAR_DISTANCE", + "LINEAR_MIPMAP_LINEAR", + "LINEAR_MIPMAP_NEAREST", + "LINES", + "LINE_LOOP", + "LINE_STRIP", + "LINE_WIDTH", + "LINK_STATUS", + "LINUX", + "LIVE", + "LN10", + "LN2", + "LOADED", + "LOADING", + "LOCALE", + "LOG10E", + "LOG2E", + "LOWPASS", + "LOWSHELF", + "LOW_FLOAT", + "LOW_INT", + "LSException", + "LSParserFilter", + "LUMINANCE", + "LUMINANCE_ALPHA", + "LargestContentfulPaint", + "LayoutShift", + "LayoutShiftAttribution", + "LinearAccelerationSensor", + "LinkError", + "ListFormat", + "LocalMediaStream", + "Locale", + "Location", + "Lock", + "LockManager", + "MAC", + "MAX", + "MAX_3D_TEXTURE_SIZE", + "MAX_ARRAY_TEXTURE_LAYERS", + "MAX_CLIENT_WAIT_TIMEOUT_WEBGL", + "MAX_COLOR_ATTACHMENTS", + "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", + "MAX_COMBINED_TEXTURE_IMAGE_UNITS", + "MAX_COMBINED_UNIFORM_BLOCKS", + "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", + "MAX_CUBE_MAP_TEXTURE_SIZE", + "MAX_DRAW_BUFFERS", + "MAX_ELEMENTS_INDICES", + "MAX_ELEMENTS_VERTICES", + "MAX_ELEMENT_INDEX", + "MAX_FRAGMENT_INPUT_COMPONENTS", + "MAX_FRAGMENT_UNIFORM_BLOCKS", + "MAX_FRAGMENT_UNIFORM_COMPONENTS", + "MAX_FRAGMENT_UNIFORM_VECTORS", + "MAX_PROGRAM_TEXEL_OFFSET", + "MAX_RENDERBUFFER_SIZE", + "MAX_SAFE_INTEGER", + "MAX_SAMPLES", + "MAX_SERVER_WAIT_TIMEOUT", + "MAX_TEXTURE_IMAGE_UNITS", + "MAX_TEXTURE_LOD_BIAS", + "MAX_TEXTURE_MAX_ANISOTROPY_EXT", + "MAX_TEXTURE_SIZE", + "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", + "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", + "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS", + "MAX_UNIFORM_BLOCK_SIZE", + "MAX_UNIFORM_BUFFER_BINDINGS", + "MAX_VALUE", + "MAX_VARYING_COMPONENTS", + "MAX_VARYING_VECTORS", + "MAX_VERTEX_ATTRIBS", + "MAX_VERTEX_OUTPUT_COMPONENTS", + "MAX_VERTEX_TEXTURE_IMAGE_UNITS", + "MAX_VERTEX_UNIFORM_BLOCKS", + "MAX_VERTEX_UNIFORM_COMPONENTS", + "MAX_VERTEX_UNIFORM_VECTORS", + "MAX_VIEWPORT_DIMS", + "MEDIA_ERR_ABORTED", + "MEDIA_ERR_DECODE", + "MEDIA_ERR_ENCRYPTED", + "MEDIA_ERR_NETWORK", + "MEDIA_ERR_SRC_NOT_SUPPORTED", + "MEDIA_KEYERR_CLIENT", + "MEDIA_KEYERR_DOMAIN", + "MEDIA_KEYERR_HARDWARECHANGE", + "MEDIA_KEYERR_OUTPUT", + "MEDIA_KEYERR_SERVICE", + "MEDIA_KEYERR_UNKNOWN", + "MEDIA_RULE", + "MEDIUM_FLOAT", + "MEDIUM_INT", + "META_MASK", + "MIDIAccess", + "MIDIConnectionEvent", + "MIDIInput", + "MIDIInputMap", + "MIDIMessageEvent", + "MIDIOutput", + "MIDIOutputMap", + "MIDIPort", + "MIN", + "MIN_PROGRAM_TEXEL_OFFSET", + "MIN_SAFE_INTEGER", + "MIN_VALUE", + "MIRRORED_REPEAT", + "MODE_ASYNCHRONOUS", + "MODE_SYNCHRONOUS", + "MODIFICATION", + "MOUSEDOWN", + "MOUSEDRAG", + "MOUSEMOVE", + "MOUSEOUT", + "MOUSEOVER", + "MOUSEUP", + "MOZ_KEYFRAMES_RULE", + "MOZ_KEYFRAME_RULE", + "MOZ_SOURCE_CURSOR", + "MOZ_SOURCE_ERASER", + "MOZ_SOURCE_KEYBOARD", + "MOZ_SOURCE_MOUSE", + "MOZ_SOURCE_PEN", + "MOZ_SOURCE_TOUCH", + "MOZ_SOURCE_UNKNOWN", + "MSBehaviorUrnsCollection", + "MSBlobBuilder", + "MSCSSMatrix", + "MSCSSProperties", + "MSCSSRuleList", + "MSCompatibleInfo", + "MSCompatibleInfoCollection", + "MSCurrentStyleCSSProperties", + "MSEventObj", + "MSGESTURE_FLAG_BEGIN", + "MSGESTURE_FLAG_CANCEL", + "MSGESTURE_FLAG_END", + "MSGESTURE_FLAG_INERTIA", + "MSGESTURE_FLAG_NONE", + "MSGesture", + "MSGestureEvent", + "MSGraphicsTrust", + "MSInputMethodContext", + "MSManipulationEvent", + "MSMediaKeyError", + "MSMediaKeyMessageEvent", + "MSMediaKeyNeededEvent", + "MSMediaKeySession", + "MSMediaKeys", + "MSMimeTypesCollection", + "MSPOINTER_TYPE_MOUSE", + "MSPOINTER_TYPE_PEN", + "MSPOINTER_TYPE_TOUCH", + "MSPluginsCollection", + "MSPointerEvent", + "MSRangeCollection", + "MSSiteModeEvent", + "MSStream", + "MSStreamReader", + "MSStyleCSSProperties", + "MS_ASYNC_CALLBACK_STATUS_ASSIGN_DELEGATE", + "MS_ASYNC_CALLBACK_STATUS_CANCEL", + "MS_ASYNC_CALLBACK_STATUS_CHOOSEANY", + "MS_ASYNC_CALLBACK_STATUS_ERROR", + "MS_ASYNC_CALLBACK_STATUS_JOIN", + "MS_ASYNC_OP_STATUS_CANCELED", + "MS_ASYNC_OP_STATUS_ERROR", + "MS_ASYNC_OP_STATUS_SUCCESS", + "MS_MANIPULATION_STATE_ACTIVE", + "MS_MANIPULATION_STATE_CANCELLED", + "MS_MANIPULATION_STATE_COMMITTED", + "MS_MANIPULATION_STATE_DRAGGING", + "MS_MANIPULATION_STATE_INERTIA", + "MS_MANIPULATION_STATE_PRESELECT", + "MS_MANIPULATION_STATE_SELECTING", + "MS_MANIPULATION_STATE_STOPPED", + "MS_MEDIA_ERR_ENCRYPTED", + "MS_MEDIA_KEYERR_CLIENT", + "MS_MEDIA_KEYERR_DOMAIN", + "MS_MEDIA_KEYERR_HARDWARECHANGE", + "MS_MEDIA_KEYERR_OUTPUT", + "MS_MEDIA_KEYERR_SERVICE", + "MS_MEDIA_KEYERR_UNKNOWN", + "Map", + "Math", + "MathMLElement", + "MediaCapabilities", + "MediaCapabilitiesInfo", + "MediaController", + "MediaDeviceInfo", + "MediaDevices", + "MediaElementAudioSourceNode", + "MediaEncryptedEvent", + "MediaError", + "MediaKeyError", + "MediaKeyEvent", + "MediaKeyMessageEvent", + "MediaKeyNeededEvent", + "MediaKeySession", + "MediaKeyStatusMap", + "MediaKeySystemAccess", + "MediaKeys", + "MediaList", + "MediaMetadata", + "MediaQueryList", + "MediaQueryListEvent", + "MediaRecorder", + "MediaRecorderErrorEvent", + "MediaSession", + "MediaSettingsRange", + "MediaSource", + "MediaStream", + "MediaStreamAudioDestinationNode", + "MediaStreamAudioSourceNode", + "MediaStreamEvent", + "MediaStreamTrack", + "MediaStreamTrackAudioSourceNode", + "MediaStreamTrackEvent", + "Memory", + "MessageChannel", + "MessageEvent", + "MessagePort", + "Methods", + "Microsoft® DRM", + "MimeType", + "MimeTypeArray", + "Module", + "MouseEvent", + "MouseScrollEvent", + "MouseWheelEvent", + "MozAnimation", + "MozAnimationDelay", + "MozAnimationDirection", + "MozAnimationDuration", + "MozAnimationFillMode", + "MozAnimationIterationCount", + "MozAnimationName", + "MozAnimationPlayState", + "MozAnimationTimingFunction", + "MozAppearance", + "MozBackfaceVisibility", + "MozBinding", + "MozBorderBottomColors", + "MozBorderEnd", + "MozBorderEndColor", + "MozBorderEndStyle", + "MozBorderEndWidth", + "MozBorderImage", + "MozBorderLeftColors", + "MozBorderRightColors", + "MozBorderStart", + "MozBorderStartColor", + "MozBorderStartStyle", + "MozBorderStartWidth", + "MozBorderTopColors", + "MozBoxAlign", + "MozBoxDirection", + "MozBoxFlex", + "MozBoxOrdinalGroup", + "MozBoxOrient", + "MozBoxPack", + "MozBoxSizing", + "MozCSSKeyframeRule", + "MozCSSKeyframesRule", + "MozColumnCount", + "MozColumnFill", + "MozColumnGap", + "MozColumnRule", + "MozColumnRuleColor", + "MozColumnRuleStyle", + "MozColumnRuleWidth", + "MozColumnWidth", + "MozColumns", + "MozContactChangeEvent", + "MozFloatEdge", + "MozFontFeatureSettings", + "MozFontLanguageOverride", + "MozForceBrokenImageIcon", + "MozHyphens", + "MozImageRegion", + "MozMarginEnd", + "MozMarginStart", + "MozMmsEvent", + "MozMmsMessage", + "MozMobileMessageThread", + "MozOSXFontSmoothing", + "MozOrient", + "MozOutlineRadius", + "MozOutlineRadiusBottomleft", + "MozOutlineRadiusBottomright", + "MozOutlineRadiusTopleft", + "MozOutlineRadiusTopright", + "MozPaddingEnd", + "MozPaddingStart", + "MozPerspective", + "MozPerspectiveOrigin", + "MozPowerManager", + "MozSettingsEvent", + "MozSmsEvent", + "MozSmsMessage", + "MozStackSizing", + "MozTabSize", + "MozTextAlignLast", + "MozTextDecorationColor", + "MozTextDecorationLine", + "MozTextDecorationStyle", + "MozTextSizeAdjust", + "MozTransform", + "MozTransformOrigin", + "MozTransformStyle", + "MozTransition", + "MozTransitionDelay", + "MozTransitionDuration", + "MozTransitionProperty", + "MozTransitionTimingFunction", + "MozUserFocus", + "MozUserInput", + "MozUserModify", + "MozUserSelect", + "MozWindowDragging", + "MozWindowShadow", + "MutationEvent", + "MutationObserver", + "MutationRecord", + "NAMESPACE_ERR", + "NAMESPACE_RULE", + "NEAREST", + "NEAREST_MIPMAP_LINEAR", + "NEAREST_MIPMAP_NEAREST", + "NEGATIVE_INFINITY", + "NETWORK_EMPTY", + "NETWORK_ERR", + "NETWORK_IDLE", + "NETWORK_LOADED", + "NETWORK_LOADING", + "NETWORK_NO_SOURCE", + "NEVER", + "NEW", + "NEXT", + "NEXT_NO_DUPLICATE", + "NICEST", + "NODE_AFTER", + "NODE_BEFORE", + "NODE_BEFORE_AND_AFTER", + "NODE_INSIDE", + "NONE", + "NON_TRANSIENT_ERR", + "NOTATION_NODE", + "NOTCH", + "NOTEQUAL", + "NOT_ALLOWED_ERR", + "NOT_FOUND_ERR", + "NOT_INSTALLED", + "NOT_READABLE_ERR", + "NOT_SUPPORTED_ERR", + "NO_DATA_ALLOWED_ERR", + "NO_ERR", + "NO_ERROR", + "NO_MODIFICATION_ALLOWED_ERR", + "NO_UPDATE", + "NUMBER_TYPE", + "NUM_COMPRESSED_TEXTURE_FORMATS", + "NaN", + "NamedNodeMap", + "Native Client", + "NavigationPreloadManager", + "Navigator", + "NearbyLinks", + "NetworkInformation", + "Node", + "NodeFilter", + "NodeIterator", + "NodeList", + "Notation", + "Notification", + "NotifyPaintEvent", + "Number", + "NumberFormat", + "OBJECT_TYPE", + "OBSOLETE", + "OES_element_index_uint", + "OES_standard_derivatives", + "OES_texture_float", + "OES_texture_float_linear", + "OK", + "ONE", + "ONE_MINUS_CONSTANT_ALPHA", + "ONE_MINUS_CONSTANT_COLOR", + "ONE_MINUS_DST_ALPHA", + "ONE_MINUS_DST_COLOR", + "ONE_MINUS_SRC_ALPHA", + "ONE_MINUS_SRC_COLOR", + "OPEN", + "OPENBSD", + "OPENED", + "OPENING", + "ORDERED_NODE_ITERATOR_TYPE", + "ORDERED_NODE_SNAPSHOT_TYPE", + "OS_UPDATE", + "OTHER_ERROR", + "OUT_OF_MEMORY", + "Object", + "OfflineAudioCompletionEvent", + "OfflineAudioContext", + "OfflineResourceList", + "OffscreenCanvas", + "OffscreenCanvasRenderingContext2D", + "OnInstalledReason", + "OnRestartRequiredReason", + "Option", + "OrientationSensor", + "OscillatorNode", + "OverconstrainedError", + "OverconstrainedErrorEvent", + "OverflowEvent", + "PACKAGE", + "PACK_ALIGNMENT", + "PACK_ROW_LENGTH", + "PACK_SKIP_PIXELS", + "PACK_SKIP_ROWS", + "PAGE_RULE", + "PARSE_ERR", + "PATHSEG_ARC_ABS", + "PATHSEG_ARC_REL", + "PATHSEG_CLOSEPATH", + "PATHSEG_CURVETO_CUBIC_ABS", + "PATHSEG_CURVETO_CUBIC_REL", + "PATHSEG_CURVETO_CUBIC_SMOOTH_ABS", + "PATHSEG_CURVETO_CUBIC_SMOOTH_REL", + "PATHSEG_CURVETO_QUADRATIC_ABS", + "PATHSEG_CURVETO_QUADRATIC_REL", + "PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS", + "PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL", + "PATHSEG_LINETO_ABS", + "PATHSEG_LINETO_HORIZONTAL_ABS", + "PATHSEG_LINETO_HORIZONTAL_REL", + "PATHSEG_LINETO_REL", + "PATHSEG_LINETO_VERTICAL_ABS", + "PATHSEG_LINETO_VERTICAL_REL", + "PATHSEG_MOVETO_ABS", + "PATHSEG_MOVETO_REL", + "PATHSEG_UNKNOWN", + "PATH_EXISTS_ERR", + "PEAKING", + "PERIODIC", + "PERMISSION_DENIED", + "PERSISTENT", + "PI", + "PIXEL_PACK_BUFFER", + "PIXEL_PACK_BUFFER_BINDING", + "PIXEL_UNPACK_BUFFER", + "PIXEL_UNPACK_BUFFER_BINDING", + "PLAYING_STATE", + "POINTS", + "POLYGON_OFFSET_FACTOR", + "POLYGON_OFFSET_FILL", + "POLYGON_OFFSET_UNITS", + "POSITION_UNAVAILABLE", + "POSITIVE_INFINITY", + "PREV", + "PREV_NO_DUPLICATE", + "PROCESSING_INSTRUCTION_NODE", + "PageChangeEvent", + "PageTransitionEvent", + "PaintRequest", + "PaintRequestList", + "PannerNode", + "PasswordCredential", + "Path2D", + "PaymentAddress", + "PaymentInstruments", + "PaymentManager", + "PaymentMethodChangeEvent", + "PaymentRequest", + "PaymentRequestUpdateEvent", + "PaymentResponse", + "Performance", + "PerformanceElementTiming", + "PerformanceEntry", + "PerformanceEventTiming", + "PerformanceLongTaskTiming", + "PerformanceMark", + "PerformanceMeasure", + "PerformanceNavigation", + "PerformanceNavigationTiming", + "PerformanceObserver", + "PerformanceObserverEntryList", + "PerformancePaintTiming", + "PerformanceResourceTiming", + "PerformanceServerTiming", + "PerformanceTiming", + "PeriodicSyncManager", + "PeriodicWave", + "PermissionStatus", + "Permissions", + "PhotoCapabilities", + "PictureInPictureWindow", + "PlatformArch", + "PlatformNaclArch", + "PlatformOs", + "Plugin", + "PluginArray", + "PluralRules", + "PointerEvent", + "PopStateEvent", + "PopupBlockedEvent", + "Position", + "PositionError", + "Presentation", + "PresentationAvailability", + "PresentationConnection", + "PresentationConnectionAvailableEvent", + "PresentationConnectionCloseEvent", + "PresentationConnectionList", + "PresentationReceiver", + "PresentationRequest", + "ProcessingInstruction", + "ProgressEvent", + "Promise", + "PromiseRejectionEvent", + "PropertyNodeList", + "Proxy", + "PublicKeyCredential", + "PushManager", + "PushSubscription", + "PushSubscriptionOptions", + "Q", + "QUERY_RESULT", + "QUERY_RESULT_AVAILABLE", + "QUOTA_ERR", + "QUOTA_EXCEEDED_ERR", + "QueryInterface", + "R11F_G11F_B10F", + "R16F", + "R16I", + "R16UI", + "R32F", + "R32I", + "R32UI", + "R8", + "R8I", + "R8UI", + "R8_SNORM", + "RASTERIZER_DISCARD", + "READY_TO_RUN", + "READ_BUFFER", + "READ_FRAMEBUFFER", + "READ_FRAMEBUFFER_BINDING", + "READ_ONLY", + "READ_ONLY_ERR", + "READ_WRITE", + "RED", + "RED_BITS", + "RED_INTEGER", + "REMOVAL", + "RENDERBUFFER", + "RENDERBUFFER_ALPHA_SIZE", + "RENDERBUFFER_BINDING", + "RENDERBUFFER_BLUE_SIZE", + "RENDERBUFFER_DEPTH_SIZE", + "RENDERBUFFER_GREEN_SIZE", + "RENDERBUFFER_HEIGHT", + "RENDERBUFFER_INTERNAL_FORMAT", + "RENDERBUFFER_RED_SIZE", + "RENDERBUFFER_SAMPLES", + "RENDERBUFFER_STENCIL_SIZE", + "RENDERBUFFER_WIDTH", + "RENDERER", + "RENDERING_INTENT_ABSOLUTE_COLORIMETRIC", + "RENDERING_INTENT_AUTO", + "RENDERING_INTENT_PERCEPTUAL", + "RENDERING_INTENT_RELATIVE_COLORIMETRIC", + "RENDERING_INTENT_SATURATION", + "RENDERING_INTENT_UNKNOWN", + "REPEAT", + "REPLACE", + "RG", + "RG16F", + "RG16I", + "RG16UI", + "RG32F", + "RG32I", + "RG32UI", + "RG8", + "RG8I", + "RG8UI", + "RG8_SNORM", + "RGB", + "RGB10_A2", + "RGB10_A2UI", + "RGB16F", + "RGB16I", + "RGB16UI", + "RGB32F", + "RGB32I", + "RGB32UI", + "RGB565", + "RGB5_A1", + "RGB8", + "RGB8I", + "RGB8UI", + "RGB8_SNORM", + "RGB9_E5", + "RGBA", + "RGBA16F", + "RGBA16I", + "RGBA16UI", + "RGBA32F", + "RGBA32I", + "RGBA32UI", + "RGBA4", + "RGBA8", + "RGBA8I", + "RGBA8UI", + "RGBA8_SNORM", + "RGBA_INTEGER", + "RGBColor", + "RGB_INTEGER", + "RG_INTEGER", + "ROTATION_CLOCKWISE", + "ROTATION_COUNTERCLOCKWISE", + "RTCCertificate", + "RTCDTMFSender", + "RTCDTMFToneChangeEvent", + "RTCDataChannel", + "RTCDataChannelEvent", + "RTCDtlsTransport", + "RTCError", + "RTCErrorEvent", + "RTCIceCandidate", + "RTCIceTransport", + "RTCPeerConnection", + "RTCPeerConnectionIceErrorEvent", + "RTCPeerConnectionIceEvent", + "RTCRtpReceiver", + "RTCRtpSender", + "RTCRtpTransceiver", + "RTCSctpTransport", + "RTCSessionDescription", + "RTCStatsReport", + "RTCTrackEvent", + "RUNNING", + "RadioNodeList", + "Range", + "RangeError", + "RangeException", + "ReadableByteStream", + "ReadableStream", + "ReadableStreamDefaultReader", + "RecordErrorEvent", + "Rect", + "ReferenceError", + "Reflect", + "RegExp", + "RelativeOrientationSensor", + "RelativeTimeFormat", + "RemotePlayback", + "ReportingObserver", + "Request", + "RequestUpdateCheckStatus", + "ResizeObserver", + "ResizeObserverEntry", + "ResizeObserverSize", + "Response", + "RunningState", + "RuntimeError", + "SAMPLER_2D", + "SAMPLER_2D_ARRAY", + "SAMPLER_2D_ARRAY_SHADOW", + "SAMPLER_2D_SHADOW", + "SAMPLER_3D", + "SAMPLER_BINDING", + "SAMPLER_CUBE", + "SAMPLER_CUBE_SHADOW", + "SAMPLES", + "SAMPLE_ALPHA_TO_COVERAGE", + "SAMPLE_BUFFERS", + "SAMPLE_COVERAGE", + "SAMPLE_COVERAGE_INVERT", + "SAMPLE_COVERAGE_VALUE", + "SAWTOOTH", + "SCHEDULED_STATE", + "SCISSOR_BOX", + "SCISSOR_TEST", + "SCROLL_PAGE_DOWN", + "SCROLL_PAGE_UP", + "SDP_ANSWER", + "SDP_OFFER", + "SDP_PRANSWER", + "SECURITY_ERR", + "SELECT", + "SEPARATE_ATTRIBS", + "SERIALIZE_ERR", + "SEVERITY_ERROR", + "SEVERITY_FATAL_ERROR", + "SEVERITY_WARNING", + "SHADER_COMPILER", + "SHADER_TYPE", + "SHADING_LANGUAGE_VERSION", + "SHARED_MODULE_UPDATE", + "SHIFT_MASK", + "SHORT", + "SHOWING", + "SHOW_ALL", + "SHOW_ATTRIBUTE", + "SHOW_CDATA_SECTION", + "SHOW_COMMENT", + "SHOW_DOCUMENT", + "SHOW_DOCUMENT_FRAGMENT", + "SHOW_DOCUMENT_TYPE", + "SHOW_ELEMENT", + "SHOW_ENTITY", + "SHOW_ENTITY_REFERENCE", + "SHOW_NOTATION", + "SHOW_PROCESSING_INSTRUCTION", + "SHOW_TEXT", + "SIGNALED", + "SIGNED_NORMALIZED", + "SINE", + "SKIN", + "SOUNDFIELD", + "SQLError", + "SQLException", + "SQLResultSet", + "SQLResultSetRowList", + "SQLTransaction", + "SQRT1_2", + "SQRT2", + "SQUARE", + "SRC_ALPHA", + "SRC_ALPHA_SATURATE", + "SRC_COLOR", + "SRGB", + "SRGB8", + "SRGB8_ALPHA8", + "START_TO_END", + "START_TO_START", + "STATIC_COPY", + "STATIC_DRAW", + "STATIC_READ", + "STENCIL", + "STENCIL_ATTACHMENT", + "STENCIL_BACK_FAIL", + "STENCIL_BACK_FUNC", + "STENCIL_BACK_PASS_DEPTH_FAIL", + "STENCIL_BACK_PASS_DEPTH_PASS", + "STENCIL_BACK_REF", + "STENCIL_BACK_VALUE_MASK", + "STENCIL_BACK_WRITEMASK", + "STENCIL_BITS", + "STENCIL_BUFFER_BIT", + "STENCIL_CLEAR_VALUE", + "STENCIL_FAIL", + "STENCIL_FUNC", + "STENCIL_INDEX", + "STENCIL_INDEX8", + "STENCIL_PASS_DEPTH_FAIL", + "STENCIL_PASS_DEPTH_PASS", + "STENCIL_REF", + "STENCIL_TEST", + "STENCIL_VALUE_MASK", + "STENCIL_WRITEMASK", + "STREAM_COPY", + "STREAM_DRAW", + "STREAM_READ", + "STRING_TYPE", + "STYLE_RULE", + "SUBPIXEL_BITS", + "SUPPORTS_RULE", + "SVGAElement", + "SVGAltGlyphDefElement", + "SVGAltGlyphElement", + "SVGAltGlyphItemElement", + "SVGAngle", + "SVGAnimateColorElement", + "SVGAnimateElement", + "SVGAnimateMotionElement", + "SVGAnimateTransformElement", + "SVGAnimatedAngle", + "SVGAnimatedBoolean", + "SVGAnimatedEnumeration", + "SVGAnimatedInteger", + "SVGAnimatedLength", + "SVGAnimatedLengthList", + "SVGAnimatedNumber", + "SVGAnimatedNumberList", + "SVGAnimatedPreserveAspectRatio", + "SVGAnimatedRect", + "SVGAnimatedString", + "SVGAnimatedTransformList", + "SVGAnimationElement", + "SVGCircleElement", + "SVGClipPathElement", + "SVGColor", + "SVGComponentTransferFunctionElement", + "SVGCursorElement", + "SVGDefsElement", + "SVGDescElement", + "SVGDiscardElement", + "SVGDocument", + "SVGElement", + "SVGElementInstance", + "SVGElementInstanceList", + "SVGEllipseElement", + "SVGException", + "SVGFEBlendElement", + "SVGFEColorMatrixElement", + "SVGFEComponentTransferElement", + "SVGFECompositeElement", + "SVGFEConvolveMatrixElement", + "SVGFEDiffuseLightingElement", + "SVGFEDisplacementMapElement", + "SVGFEDistantLightElement", + "SVGFEDropShadowElement", + "SVGFEFloodElement", + "SVGFEFuncAElement", + "SVGFEFuncBElement", + "SVGFEFuncGElement", + "SVGFEFuncRElement", + "SVGFEGaussianBlurElement", + "SVGFEImageElement", + "SVGFEMergeElement", + "SVGFEMergeNodeElement", + "SVGFEMorphologyElement", + "SVGFEOffsetElement", + "SVGFEPointLightElement", + "SVGFESpecularLightingElement", + "SVGFESpotLightElement", + "SVGFETileElement", + "SVGFETurbulenceElement", + "SVGFilterElement", + "SVGFontElement", + "SVGFontFaceElement", + "SVGFontFaceFormatElement", + "SVGFontFaceNameElement", + "SVGFontFaceSrcElement", + "SVGFontFaceUriElement", + "SVGForeignObjectElement", + "SVGGElement", + "SVGGeometryElement", + "SVGGlyphElement", + "SVGGlyphRefElement", + "SVGGradientElement", + "SVGGraphicsElement", + "SVGHKernElement", + "SVGImageElement", + "SVGLength", + "SVGLengthList", + "SVGLineElement", + "SVGLinearGradientElement", + "SVGMPathElement", + "SVGMarkerElement", + "SVGMaskElement", + "SVGMatrix", + "SVGMetadataElement", + "SVGMissingGlyphElement", + "SVGNumber", + "SVGNumberList", + "SVGPaint", + "SVGPathElement", + "SVGPathSeg", + "SVGPathSegArcAbs", + "SVGPathSegArcRel", + "SVGPathSegClosePath", + "SVGPathSegCurvetoCubicAbs", + "SVGPathSegCurvetoCubicRel", + "SVGPathSegCurvetoCubicSmoothAbs", + "SVGPathSegCurvetoCubicSmoothRel", + "SVGPathSegCurvetoQuadraticAbs", + "SVGPathSegCurvetoQuadraticRel", + "SVGPathSegCurvetoQuadraticSmoothAbs", + "SVGPathSegCurvetoQuadraticSmoothRel", + "SVGPathSegLinetoAbs", + "SVGPathSegLinetoHorizontalAbs", + "SVGPathSegLinetoHorizontalRel", + "SVGPathSegLinetoRel", + "SVGPathSegLinetoVerticalAbs", + "SVGPathSegLinetoVerticalRel", + "SVGPathSegList", + "SVGPathSegMovetoAbs", + "SVGPathSegMovetoRel", + "SVGPatternElement", + "SVGPoint", + "SVGPointList", + "SVGPolygonElement", + "SVGPolylineElement", + "SVGPreserveAspectRatio", + "SVGRadialGradientElement", + "SVGRect", + "SVGRectElement", + "SVGRenderingIntent", + "SVGSVGElement", + "SVGScriptElement", + "SVGSetElement", + "SVGStopElement", + "SVGStringList", + "SVGStyleElement", + "SVGSwitchElement", + "SVGSymbolElement", + "SVGTRefElement", + "SVGTSpanElement", + "SVGTextContentElement", + "SVGTextElement", + "SVGTextPathElement", + "SVGTextPositioningElement", + "SVGTitleElement", + "SVGTransform", + "SVGTransformList", + "SVGUnitTypes", + "SVGUseElement", + "SVGVKernElement", + "SVGViewElement", + "SVGViewSpec", + "SVGZoomAndPan", + "SVGZoomEvent", + "SVG_ANGLETYPE_DEG", + "SVG_ANGLETYPE_GRAD", + "SVG_ANGLETYPE_RAD", + "SVG_ANGLETYPE_UNKNOWN", + "SVG_ANGLETYPE_UNSPECIFIED", + "SVG_CHANNEL_A", + "SVG_CHANNEL_B", + "SVG_CHANNEL_G", + "SVG_CHANNEL_R", + "SVG_CHANNEL_UNKNOWN", + "SVG_COLORTYPE_CURRENTCOLOR", + "SVG_COLORTYPE_RGBCOLOR", + "SVG_COLORTYPE_RGBCOLOR_ICCCOLOR", + "SVG_COLORTYPE_UNKNOWN", + "SVG_EDGEMODE_DUPLICATE", + "SVG_EDGEMODE_NONE", + "SVG_EDGEMODE_UNKNOWN", + "SVG_EDGEMODE_WRAP", + "SVG_FEBLEND_MODE_COLOR", + "SVG_FEBLEND_MODE_COLOR_BURN", + "SVG_FEBLEND_MODE_COLOR_DODGE", + "SVG_FEBLEND_MODE_DARKEN", + "SVG_FEBLEND_MODE_DIFFERENCE", + "SVG_FEBLEND_MODE_EXCLUSION", + "SVG_FEBLEND_MODE_HARD_LIGHT", + "SVG_FEBLEND_MODE_HUE", + "SVG_FEBLEND_MODE_LIGHTEN", + "SVG_FEBLEND_MODE_LUMINOSITY", + "SVG_FEBLEND_MODE_MULTIPLY", + "SVG_FEBLEND_MODE_NORMAL", + "SVG_FEBLEND_MODE_OVERLAY", + "SVG_FEBLEND_MODE_SATURATION", + "SVG_FEBLEND_MODE_SCREEN", + "SVG_FEBLEND_MODE_SOFT_LIGHT", + "SVG_FEBLEND_MODE_UNKNOWN", + "SVG_FECOLORMATRIX_TYPE_HUEROTATE", + "SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA", + "SVG_FECOLORMATRIX_TYPE_MATRIX", + "SVG_FECOLORMATRIX_TYPE_SATURATE", + "SVG_FECOLORMATRIX_TYPE_UNKNOWN", + "SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE", + "SVG_FECOMPONENTTRANSFER_TYPE_GAMMA", + "SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY", + "SVG_FECOMPONENTTRANSFER_TYPE_LINEAR", + "SVG_FECOMPONENTTRANSFER_TYPE_TABLE", + "SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN", + "SVG_FECOMPOSITE_OPERATOR_ARITHMETIC", + "SVG_FECOMPOSITE_OPERATOR_ATOP", + "SVG_FECOMPOSITE_OPERATOR_IN", + "SVG_FECOMPOSITE_OPERATOR_OUT", + "SVG_FECOMPOSITE_OPERATOR_OVER", + "SVG_FECOMPOSITE_OPERATOR_UNKNOWN", + "SVG_FECOMPOSITE_OPERATOR_XOR", + "SVG_INVALID_VALUE_ERR", + "SVG_LENGTHTYPE_CM", + "SVG_LENGTHTYPE_EMS", + "SVG_LENGTHTYPE_EXS", + "SVG_LENGTHTYPE_IN", + "SVG_LENGTHTYPE_MM", + "SVG_LENGTHTYPE_NUMBER", + "SVG_LENGTHTYPE_PC", + "SVG_LENGTHTYPE_PERCENTAGE", + "SVG_LENGTHTYPE_PT", + "SVG_LENGTHTYPE_PX", + "SVG_LENGTHTYPE_UNKNOWN", + "SVG_MARKERUNITS_STROKEWIDTH", + "SVG_MARKERUNITS_UNKNOWN", + "SVG_MARKERUNITS_USERSPACEONUSE", + "SVG_MARKER_ORIENT_ANGLE", + "SVG_MARKER_ORIENT_AUTO", + "SVG_MARKER_ORIENT_UNKNOWN", + "SVG_MASKTYPE_ALPHA", + "SVG_MASKTYPE_LUMINANCE", + "SVG_MATRIX_NOT_INVERTABLE", + "SVG_MEETORSLICE_MEET", + "SVG_MEETORSLICE_SLICE", + "SVG_MEETORSLICE_UNKNOWN", + "SVG_MORPHOLOGY_OPERATOR_DILATE", + "SVG_MORPHOLOGY_OPERATOR_ERODE", + "SVG_MORPHOLOGY_OPERATOR_UNKNOWN", + "SVG_PAINTTYPE_CURRENTCOLOR", + "SVG_PAINTTYPE_NONE", + "SVG_PAINTTYPE_RGBCOLOR", + "SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR", + "SVG_PAINTTYPE_UNKNOWN", + "SVG_PAINTTYPE_URI", + "SVG_PAINTTYPE_URI_CURRENTCOLOR", + "SVG_PAINTTYPE_URI_NONE", + "SVG_PAINTTYPE_URI_RGBCOLOR", + "SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR", + "SVG_PRESERVEASPECTRATIO_NONE", + "SVG_PRESERVEASPECTRATIO_UNKNOWN", + "SVG_PRESERVEASPECTRATIO_XMAXYMAX", + "SVG_PRESERVEASPECTRATIO_XMAXYMID", + "SVG_PRESERVEASPECTRATIO_XMAXYMIN", + "SVG_PRESERVEASPECTRATIO_XMIDYMAX", + "SVG_PRESERVEASPECTRATIO_XMIDYMID", + "SVG_PRESERVEASPECTRATIO_XMIDYMIN", + "SVG_PRESERVEASPECTRATIO_XMINYMAX", + "SVG_PRESERVEASPECTRATIO_XMINYMID", + "SVG_PRESERVEASPECTRATIO_XMINYMIN", + "SVG_SPREADMETHOD_PAD", + "SVG_SPREADMETHOD_REFLECT", + "SVG_SPREADMETHOD_REPEAT", + "SVG_SPREADMETHOD_UNKNOWN", + "SVG_STITCHTYPE_NOSTITCH", + "SVG_STITCHTYPE_STITCH", + "SVG_STITCHTYPE_UNKNOWN", + "SVG_TRANSFORM_MATRIX", + "SVG_TRANSFORM_ROTATE", + "SVG_TRANSFORM_SCALE", + "SVG_TRANSFORM_SKEWX", + "SVG_TRANSFORM_SKEWY", + "SVG_TRANSFORM_TRANSLATE", + "SVG_TRANSFORM_UNKNOWN", + "SVG_TURBULENCE_TYPE_FRACTALNOISE", + "SVG_TURBULENCE_TYPE_TURBULENCE", + "SVG_TURBULENCE_TYPE_UNKNOWN", + "SVG_UNIT_TYPE_OBJECTBOUNDINGBOX", + "SVG_UNIT_TYPE_UNKNOWN", + "SVG_UNIT_TYPE_USERSPACEONUSE", + "SVG_WRONG_TYPE_ERR", + "SVG_ZOOMANDPAN_DISABLE", + "SVG_ZOOMANDPAN_MAGNIFY", + "SVG_ZOOMANDPAN_UNKNOWN", + "SYNC_CONDITION", + "SYNC_FENCE", + "SYNC_FLAGS", + "SYNC_FLUSH_COMMANDS_BIT", + "SYNC_GPU_COMMANDS_COMPLETE", + "SYNC_STATUS", + "SYNTAX_ERR", + "SavedPages", + "Screen", + "ScreenOrientation", + "Script", + "ScriptEngine", + "ScriptEngineBuildVersion", + "ScriptEngineMajorVersion", + "ScriptEngineMinorVersion", + "ScriptProcessorNode", + "ScrollAreaEvent", + "SecurityPolicyViolationEvent", + "Selection", + "Sensor", + "SensorErrorEvent", + "ServiceWorker", + "ServiceWorkerContainer", + "ServiceWorkerMessageEvent", + "ServiceWorkerRegistration", + "SessionDescription", + "Set", + "ShadowRoot", + "SharedArrayBuffer", + "SharedWorker", + "SimpleGestureEvent", + "SourceBuffer", + "SourceBufferList", + "SpeechSynthesis", + "SpeechSynthesisErrorEvent", + "SpeechSynthesisEvent", + "SpeechSynthesisUtterance", + "SpeechSynthesisVoice", + "StaticRange", + "StereoPannerNode", + "StopIteration", + "Storage", + "StorageEvent", + "StorageManager", + "String", + "StyleMedia", + "StylePropertyMap", + "StylePropertyMapReadOnly", + "StyleSheet", + "StyleSheetList", + "StyleSheetPageList", + "SubmitEvent", + "SubtleCrypto", + "Symbol", + "SyncManager", + "SyntaxError", + "TEMPORARY", + "TEXTPATH_METHODTYPE_ALIGN", + "TEXTPATH_METHODTYPE_STRETCH", + "TEXTPATH_METHODTYPE_UNKNOWN", + "TEXTPATH_SPACINGTYPE_AUTO", + "TEXTPATH_SPACINGTYPE_EXACT", + "TEXTPATH_SPACINGTYPE_UNKNOWN", + "TEXTURE", + "TEXTURE0", + "TEXTURE1", + "TEXTURE10", + "TEXTURE11", + "TEXTURE12", + "TEXTURE13", + "TEXTURE14", + "TEXTURE15", + "TEXTURE16", + "TEXTURE17", + "TEXTURE18", + "TEXTURE19", + "TEXTURE2", + "TEXTURE20", + "TEXTURE21", + "TEXTURE22", + "TEXTURE23", + "TEXTURE24", + "TEXTURE25", + "TEXTURE26", + "TEXTURE27", + "TEXTURE28", + "TEXTURE29", + "TEXTURE3", + "TEXTURE30", + "TEXTURE31", + "TEXTURE4", + "TEXTURE5", + "TEXTURE6", + "TEXTURE7", + "TEXTURE8", + "TEXTURE9", + "TEXTURE_2D", + "TEXTURE_2D_ARRAY", + "TEXTURE_3D", + "TEXTURE_BASE_LEVEL", + "TEXTURE_BINDING_2D", + "TEXTURE_BINDING_2D_ARRAY", + "TEXTURE_BINDING_3D", + "TEXTURE_BINDING_CUBE_MAP", + "TEXTURE_COMPARE_FUNC", + "TEXTURE_COMPARE_MODE", + "TEXTURE_CUBE_MAP", + "TEXTURE_CUBE_MAP_NEGATIVE_X", + "TEXTURE_CUBE_MAP_NEGATIVE_Y", + "TEXTURE_CUBE_MAP_NEGATIVE_Z", + "TEXTURE_CUBE_MAP_POSITIVE_X", + "TEXTURE_CUBE_MAP_POSITIVE_Y", + "TEXTURE_CUBE_MAP_POSITIVE_Z", + "TEXTURE_IMMUTABLE_FORMAT", + "TEXTURE_IMMUTABLE_LEVELS", + "TEXTURE_MAG_FILTER", + "TEXTURE_MAX_ANISOTROPY_EXT", + "TEXTURE_MAX_LEVEL", + "TEXTURE_MAX_LOD", + "TEXTURE_MIN_FILTER", + "TEXTURE_MIN_LOD", + "TEXTURE_WRAP_R", + "TEXTURE_WRAP_S", + "TEXTURE_WRAP_T", + "TEXT_NODE", + "THROTTLED", + "TIMEOUT", + "TIMEOUT_ERR", + "TIMEOUT_EXPIRED", + "TIMEOUT_IGNORED", + "TOO_LARGE_ERR", + "TRANSACTION_INACTIVE_ERR", + "TRANSFORM_FEEDBACK", + "TRANSFORM_FEEDBACK_ACTIVE", + "TRANSFORM_FEEDBACK_BINDING", + "TRANSFORM_FEEDBACK_BUFFER", + "TRANSFORM_FEEDBACK_BUFFER_BINDING", + "TRANSFORM_FEEDBACK_BUFFER_MODE", + "TRANSFORM_FEEDBACK_BUFFER_SIZE", + "TRANSFORM_FEEDBACK_BUFFER_START", + "TRANSFORM_FEEDBACK_PAUSED", + "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN", + "TRANSFORM_FEEDBACK_VARYINGS", + "TRIANGLE", + "TRIANGLES", + "TRIANGLE_FAN", + "TRIANGLE_STRIP", + "TYPE_BACK_FORWARD", + "TYPE_ERR", + "TYPE_MISMATCH_ERR", + "TYPE_NAVIGATE", + "TYPE_RELOAD", + "TYPE_RESERVED", + "Table", + "TaskAttributionTiming", + "Text", + "TextDecoder", + "TextDecoderStream", + "TextEncoder", + "TextEncoderStream", + "TextEvent", + "TextMetrics", + "TextRange", + "TextRangeCollection", + "TextTrack", + "TextTrackCue", + "TextTrackCueList", + "TextTrackList", + "TimeEvent", + "TimeRanges", + "Touch", + "TouchEvent", + "TouchList", + "TrackEvent", + "TransformStream", + "TransitionEvent", + "TreeWalker", + "TrustedHTML", + "TrustedScript", + "TrustedScriptURL", + "TrustedTypePolicy", + "TrustedTypePolicyFactory", + "TypeError", + "U2F", + "UIEvent", + "UNCACHED", + "UNIFORM_ARRAY_STRIDE", + "UNIFORM_BLOCK_ACTIVE_UNIFORMS", + "UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES", + "UNIFORM_BLOCK_BINDING", + "UNIFORM_BLOCK_DATA_SIZE", + "UNIFORM_BLOCK_INDEX", + "UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER", + "UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER", + "UNIFORM_BUFFER", + "UNIFORM_BUFFER_BINDING", + "UNIFORM_BUFFER_OFFSET_ALIGNMENT", + "UNIFORM_BUFFER_SIZE", + "UNIFORM_BUFFER_START", + "UNIFORM_IS_ROW_MAJOR", + "UNIFORM_MATRIX_STRIDE", + "UNIFORM_OFFSET", + "UNIFORM_SIZE", + "UNIFORM_TYPE", + "UNKNOWN_ERR", + "UNKNOWN_RULE", + "UNMASKED_RENDERER_WEBGL", + "UNMASKED_VENDOR_WEBGL", + "UNORDERED_NODE_ITERATOR_TYPE", + "UNORDERED_NODE_SNAPSHOT_TYPE", + "UNPACK_ALIGNMENT", + "UNPACK_COLORSPACE_CONVERSION_WEBGL", + "UNPACK_FLIP_Y_WEBGL", + "UNPACK_IMAGE_HEIGHT", + "UNPACK_PREMULTIPLY_ALPHA_WEBGL", + "UNPACK_ROW_LENGTH", + "UNPACK_SKIP_IMAGES", + "UNPACK_SKIP_PIXELS", + "UNPACK_SKIP_ROWS", + "UNSCHEDULED_STATE", + "UNSENT", + "UNSIGNALED", + "UNSIGNED_BYTE", + "UNSIGNED_INT", + "UNSIGNED_INT_10F_11F_11F_REV", + "UNSIGNED_INT_24_8", + "UNSIGNED_INT_2_10_10_10_REV", + "UNSIGNED_INT_5_9_9_9_REV", + "UNSIGNED_INT_SAMPLER_2D", + "UNSIGNED_INT_SAMPLER_2D_ARRAY", + "UNSIGNED_INT_SAMPLER_3D", + "UNSIGNED_INT_SAMPLER_CUBE", + "UNSIGNED_INT_VEC2", + "UNSIGNED_INT_VEC3", + "UNSIGNED_INT_VEC4", + "UNSIGNED_NORMALIZED", + "UNSIGNED_SHORT", + "UNSIGNED_SHORT_4_4_4_4", + "UNSIGNED_SHORT_5_5_5_1", + "UNSIGNED_SHORT_5_6_5", + "UNSPECIFIED_EVENT_TYPE_ERR", + "UPDATE", + "UPDATEREADY", + "UPDATE_AVAILABLE", + "URIError", + "URL", + "URLSearchParams", + "URLUnencoded", + "URL_MISMATCH_ERR", + "USB", + "USBAlternateInterface", + "USBConfiguration", + "USBConnectionEvent", + "USBDevice", + "USBEndpoint", + "USBInTransferResult", + "USBInterface", + "USBIsochronousInTransferPacket", + "USBIsochronousInTransferResult", + "USBIsochronousOutTransferPacket", + "USBIsochronousOutTransferResult", + "USBOutTransferResult", + "UTC", + "Uint16Array", + "Uint32Array", + "Uint8Array", + "Uint8ClampedArray", + "UserActivation", + "UserMessageHandler", + "UserMessageHandlersNamespace", + "UserProximityEvent", + "VALIDATE_STATUS", + "VALIDATION_ERR", + "VARIABLES_RULE", + "VBArray", + "VENDOR", + "VERSION", + "VERSION_CHANGE", + "VERSION_ERR", + "VERTEX_ARRAY_BINDING", + "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", + "VERTEX_ATTRIB_ARRAY_DIVISOR", + "VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE", + "VERTEX_ATTRIB_ARRAY_ENABLED", + "VERTEX_ATTRIB_ARRAY_INTEGER", + "VERTEX_ATTRIB_ARRAY_NORMALIZED", + "VERTEX_ATTRIB_ARRAY_POINTER", + "VERTEX_ATTRIB_ARRAY_SIZE", + "VERTEX_ATTRIB_ARRAY_STRIDE", + "VERTEX_ATTRIB_ARRAY_TYPE", + "VERTEX_SHADER", + "VERTICAL", + "VERTICAL_AXIS", + "VER_ERR", + "VIEWPORT", + "VIEWPORT_RULE", + "VRDisplay", + "VRDisplayCapabilities", + "VRDisplayEvent", + "VREyeParameters", + "VRFieldOfView", + "VRFrameData", + "VRPose", + "VRStageParameters", + "VTTCue", + "VTTRegion", + "ValidityState", + "VideoPlaybackQuality", + "VideoStreamTrack", + "VideoTrack", + "VideoTrackList", + "VisualViewport", + "WAIT_FAILED", + "WEBGL_compressed_texture_s3tc", + "WEBGL_debug_renderer_info", + "WEBKIT_FILTER_RULE", + "WEBKIT_FORCE_AT_FORCE_MOUSE_DOWN", + "WEBKIT_FORCE_AT_MOUSE_DOWN", + "WEBKIT_KEYFRAMES_RULE", + "WEBKIT_KEYFRAME_RULE", + "WEBKIT_REGION_RULE", + "WIN", + "WRONG_DOCUMENT_ERR", + "WakeLock", + "WakeLockSentinel", + "WaveShaperNode", + "WeakMap", + "WeakRef", + "WeakSet", + "WebAssembly", + "WebGL2RenderingContext", + "WebGLActiveInfo", + "WebGLBuffer", + "WebGLContextEvent", + "WebGLFramebuffer", + "WebGLObject", + "WebGLProgram", + "WebGLQuery", + "WebGLRenderbuffer", + "WebGLRenderingContext", + "WebGLSampler", + "WebGLShader", + "WebGLShaderPrecisionFormat", + "WebGLSync", + "WebGLTexture", + "WebGLTransformFeedback", + "WebGLUniformLocation", + "WebGLVertexArray", + "WebGLVertexArrayObject", + "WebKit built-in PDF", + "WebKitAnimationEvent", + "WebKitBlobBuilder", + "WebKitCSSFilterRule", + "WebKitCSSFilterValue", + "WebKitCSSKeyframeRule", + "WebKitCSSKeyframesRule", + "WebKitCSSMatrix", + "WebKitCSSRegionRule", + "WebKitCSSTransformValue", + "WebKitDataCue", + "WebKitGamepad", + "WebKitMediaKeyError", + "WebKitMediaKeyMessageEvent", + "WebKitMediaKeyNeededEvent", + "WebKitMediaKeySession", + "WebKitMediaKeys", + "WebKitMediaSource", + "WebKitMutationObserver", + "WebKitNamespace", + "WebKitPlaybackTargetAvailabilityEvent", + "WebKitPoint", + "WebKitShadowRoot", + "WebKitSourceBuffer", + "WebKitSourceBufferList", + "WebKitTransitionEvent", + "WebSocket", + "WebkitAlignContent", + "WebkitAlignItems", + "WebkitAlignSelf", + "WebkitAnimation", + "WebkitAnimationDelay", + "WebkitAnimationDirection", + "WebkitAnimationDuration", + "WebkitAnimationFillMode", + "WebkitAnimationIterationCount", + "WebkitAnimationName", + "WebkitAnimationPlayState", + "WebkitAnimationTimingFunction", + "WebkitAppearance", + "WebkitBackfaceVisibility", + "WebkitBackgroundClip", + "WebkitBackgroundOrigin", + "WebkitBackgroundSize", + "WebkitBorderBottomLeftRadius", + "WebkitBorderBottomRightRadius", + "WebkitBorderImage", + "WebkitBorderRadius", + "WebkitBorderTopLeftRadius", + "WebkitBorderTopRightRadius", + "WebkitBoxAlign", + "WebkitBoxDirection", + "WebkitBoxFlex", + "WebkitBoxOrdinalGroup", + "WebkitBoxOrient", + "WebkitBoxPack", + "WebkitBoxShadow", + "WebkitBoxSizing", + "WebkitFilter", + "WebkitFlex", + "WebkitFlexBasis", + "WebkitFlexDirection", + "WebkitFlexFlow", + "WebkitFlexGrow", + "WebkitFlexShrink", + "WebkitFlexWrap", + "WebkitJustifyContent", + "WebkitLineClamp", + "WebkitMask", + "WebkitMaskClip", + "WebkitMaskComposite", + "WebkitMaskImage", + "WebkitMaskOrigin", + "WebkitMaskPosition", + "WebkitMaskPositionX", + "WebkitMaskPositionY", + "WebkitMaskRepeat", + "WebkitMaskSize", + "WebkitOrder", + "WebkitPerspective", + "WebkitPerspectiveOrigin", + "WebkitTextFillColor", + "WebkitTextSizeAdjust", + "WebkitTextStroke", + "WebkitTextStrokeColor", + "WebkitTextStrokeWidth", + "WebkitTransform", + "WebkitTransformOrigin", + "WebkitTransformStyle", + "WebkitTransition", + "WebkitTransitionDelay", + "WebkitTransitionDuration", + "WebkitTransitionProperty", + "WebkitTransitionTimingFunction", + "WebkitUserSelect", + "WheelEvent", + "Window", + "Windows Media Player Plug-in Dynamic Link Library", + "Windows Presentation Foundation", + "Worker", + "Worklet", + "WritableStream", + "WritableStreamDefaultWriter", + "X86_32", + "X86_64", + "XMLDocument", + "XMLHttpRequest", + "XMLHttpRequestEventTarget", + "XMLHttpRequestException", + "XMLHttpRequestProgressEvent", + "XMLHttpRequestUpload", + "XMLSerializer", + "XMLStylesheetProcessingInstruction", + "XPathEvaluator", + "XPathException", + "XPathExpression", + "XPathNSResolver", + "XPathResult", + "XR", + "XRBoundedReferenceSpace", + "XRDOMOverlayState", + "XRFrame", + "XRHitTestResult", + "XRHitTestSource", + "XRInputSource", + "XRInputSourceArray", + "XRInputSourceEvent", + "XRInputSourcesChangeEvent", + "XRLayer", + "XRPose", + "XRRay", + "XRReferenceSpace", + "XRReferenceSpaceEvent", + "XRRenderState", + "XRRigidTransform", + "XRSession", + "XRSessionEvent", + "XRSpace", + "XRSystem", + "XRTransientInputHitTestResult", + "XRTransientInputHitTestSource", + "XRView", + "XRViewerPose", + "XRViewport", + "XRWebGLLayer", + "XSLTProcessor", + "ZERO", + "_XD0M_", + "_YD0M_", + "__defineGetter__", + "__defineSetter__", + "__lookupGetter__", + "__lookupSetter__", + "__opera", + "__proto__", + "__relevantExtensionKeys", + "_browserjsran", + "a", + "aLink", + "abbr", + "abort", + "aborted", + "abs", + "absolute", + "acceleration", + "accelerationIncludingGravity", + "accelerator", + "accept", + "acceptCharset", + "acceptNode", + "accessKey", + "accessKeyLabel", + "accuracy", + "acos", + "acosh", + "action", + "actionURL", + "actions", + "activated", + "active", + "activeCues", + "activeElement", + "activeSourceBuffers", + "activeSourceCount", + "activeTexture", + "activeVRDisplays", + "actualBoundingBoxAscent", + "actualBoundingBoxDescent", + "actualBoundingBoxLeft", + "actualBoundingBoxRight", + "add", + "addAll", + "addBehavior", + "addCandidate", + "addColorStop", + "addCue", + "addElement", + "addEventListener", + "addFilter", + "addFromString", + "addFromUri", + "addIceCandidate", + "addImport", + "addListener", + "addModule", + "addNamed", + "addPageRule", + "addPath", + "addPointer", + "addRange", + "addRegion", + "addRule", + "addRules", + "addSearchEngine", + "addSourceBuffer", + "addStream", + "addTextTrack", + "addTrack", + "addTransceiver", + "addWakeLockListener", + "added", + "addedNodes", + "additionalName", + "additiveSymbols", + "addons", + "address", + "addressLine", + "adoptNode", + "adoptText", + "adoptedCallback", + "adoptedStyleSheets", + "adr", + "advance", + "after", + "album", + "alert", + "algorithm", + "align", + "align-content", + "align-items", + "align-self", + "alignContent", + "alignItems", + "alignSelf", + "alignmentBaseline", + "alinkColor", + "all", + "allSettled", + "allow", + "allowFullscreen", + "allowPaymentRequest", + "allowTransparency", + "allowedDirections", + "allowedFeatures", + "allowsFeature", + "alpha", + "alphabeticBaseline", + "alt", + "altGraphKey", + "altHtml", + "altKey", + "altLeft", + "alternate", + "alternateSetting", + "alternates", + "altitude", + "altitudeAccuracy", + "amplitude", + "ancestorOrigins", + "anchor", + "anchorNode", + "anchorOffset", + "anchors", + "and", + "angle", + "angularAcceleration", + "angularVelocity", + "animVal", + "animate", + "animatedInstanceRoot", + "animatedNormalizedPathSegList", + "animatedPathSegList", + "animatedPoints", + "animation", + "animation-delay", + "animation-direction", + "animation-duration", + "animation-fill-mode", + "animation-iteration-count", + "animation-name", + "animation-play-state", + "animation-timing-function", + "animationDelay", + "animationDirection", + "animationDuration", + "animationFillMode", + "animationIterationCount", + "animationName", + "animationPlayState", + "animationStartTime", + "animationTimingFunction", + "animationsPaused", + "anniversary", + "antialias", + "any", + "app", + "appCodeName", + "appMinorVersion", + "appName", + "appNotifications", + "appVersion", + "appearance", + "append", + "appendBuffer", + "appendChild", + "appendData", + "appendItem", + "appendMedium", + "appendNamed", + "appendRule", + "appendStream", + "appendWindowEnd", + "appendWindowStart", + "appleTrailingWord", + "applets", + "application/apple-default-browser", + "application/asx", + "application/java-deployment-toolkit", + "application/pdf", + "application/postscript", + "application/x-drm", + "application/x-drm-v2", + "application/x-google-chrome-pdf", + "application/x-java-applet", + "application/x-java-applet;deploy=10.25.2", + "application/x-java-applet;javafx=2.2.25", + "application/x-java-applet;jpi-version=1.7.0_25", + "application/x-java-applet;version=1.1", + "application/x-java-applet;version=1.1.1", + "application/x-java-applet;version=1.1.2", + "application/x-java-applet;version=1.1.3", + "application/x-java-applet;version=1.2", + "application/x-java-applet;version=1.2.1", + "application/x-java-applet;version=1.2.2", + "application/x-java-applet;version=1.3", + "application/x-java-applet;version=1.3.1", + "application/x-java-applet;version=1.4", + "application/x-java-applet;version=1.4.1", + "application/x-java-applet;version=1.4.2", + "application/x-java-applet;version=1.5", + "application/x-java-applet;version=1.6", + "application/x-java-applet;version=1.7", + "application/x-java-bean", + "application/x-java-bean;jpi-version=1.7.0_25", + "application/x-java-bean;version=1.1", + "application/x-java-bean;version=1.1.1", + "application/x-java-bean;version=1.1.2", + "application/x-java-bean;version=1.1.3", + "application/x-java-bean;version=1.2", + "application/x-java-bean;version=1.2.1", + "application/x-java-bean;version=1.2.2", + "application/x-java-bean;version=1.3", + "application/x-java-bean;version=1.3.1", + "application/x-java-bean;version=1.4", + "application/x-java-bean;version=1.4.1", + "application/x-java-bean;version=1.4.2", + "application/x-java-bean;version=1.5", + "application/x-java-bean;version=1.6", + "application/x-java-bean;version=1.7", + "application/x-java-vm", + "application/x-java-vm-npruntime", + "application/x-mplayer2", + "application/x-ms-xbap", + "application/x-nacl", + "application/x-pnacl", + "application/xaml+xml", + "applicationCache", + "applicationServerKey", + "apply", + "applyConstraints", + "applyElement", + "arc", + "arcTo", + "archive", + "areas", + "arguments", + "aria-activedescendant", + "aria-busy", + "aria-checked", + "aria-controls", + "aria-describedby", + "aria-disabled", + "aria-expanded", + "aria-flowto", + "aria-haspopup", + "aria-hidden", + "aria-invalid", + "aria-labelledby", + "aria-level", + "aria-live", + "aria-multiselectable", + "aria-owns", + "aria-posinset", + "aria-pressed", + "aria-readonly", + "aria-relevant", + "aria-required", + "aria-secret", + "aria-selected", + "aria-setsize", + "aria-valuemax", + "aria-valuemin", + "aria-valuenow", + "ariaAtomic", + "ariaAutoComplete", + "ariaBusy", + "ariaChecked", + "ariaColCount", + "ariaColIndex", + "ariaColSpan", + "ariaCurrent", + "ariaDescription", + "ariaDisabled", + "ariaExpanded", + "ariaHasPopup", + "ariaHidden", + "ariaKeyShortcuts", + "ariaLabel", + "ariaLevel", + "ariaLive", + "ariaModal", + "ariaMultiLine", + "ariaMultiSelectable", + "ariaOrientation", + "ariaPlaceholder", + "ariaPosInSet", + "ariaPressed", + "ariaReadOnly", + "ariaRelevant", + "ariaRequired", + "ariaRoleDescription", + "ariaRowCount", + "ariaRowIndex", + "ariaRowSpan", + "ariaSelected", + "ariaSetSize", + "ariaSort", + "ariaValueMax", + "ariaValueMin", + "ariaValueNow", + "ariaValueText", + "arrayBuffer", + "artist", + "artwork", + "as", + "asIntN", + "asUintN", + "asin", + "asinh", + "assert", + "assign", + "assignedElements", + "assignedNodes", + "assignedSlot", + "async", + "asyncIterator", + "atEnd", + "atan", + "atan2", + "atanh", + "atob", + "atomic", + "attachEvent", + "attachInternals", + "attachShader", + "attachShadow", + "attachments", + "attack", + "attestationObject", + "attrChange", + "attrName", + "attributeChangedCallback", + "attributeFilter", + "attributeName", + "attributeNamespace", + "attributeOldValue", + "attributeStyleMap", + "attributes", + "attribution", + "audio/x-ms-wax", + "audio/x-ms-wma", + "audioBitsPerSecond", + "audioTracks", + "audioWorklet", + "authenticatedSignedWrites", + "authenticatorData", + "autoIncrement", + "autobuffer", + "autocapitalize", + "autocomplete", + "autocorrect", + "autofocus", + "automationRate", + "autoplay", + "availHeight", + "availLeft", + "availTop", + "availWidth", + "availability", + "available", + "aversion", + "ax", + "axes", + "axis", + "ay", + "azimuth", + "b", + "back", + "backdropFilter", + "backface-visibility", + "backfaceVisibility", + "background", + "background-attachment", + "background-blend-mode", + "background-clip", + "background-color", + "background-image", + "background-origin", + "background-position", + "background-position-x", + "background-position-y", + "background-repeat", + "background-size", + "backgroundAttachment", + "backgroundBlendMode", + "backgroundClip", + "backgroundColor", + "backgroundFetch", + "backgroundImage", + "backgroundOrigin", + "backgroundPosition", + "backgroundPositionX", + "backgroundPositionY", + "backgroundRepeat", + "backgroundRepeatX", + "backgroundRepeatY", + "backgroundSize", + "badInput", + "badge", + "balance", + "baseFrequencyX", + "baseFrequencyY", + "baseLatency", + "baseLayer", + "baseName", + "baseNode", + "baseOffset", + "baseURI", + "baseVal", + "baselineShift", + "battery", + "bday", + "before", + "beginElement", + "beginElementAt", + "beginPath", + "beginQuery", + "beginTransformFeedback", + "behavior", + "behaviorCookie", + "behaviorPart", + "behaviorUrns", + "beta", + "bezierCurveTo", + "bgColor", + "bgProperties", + "bias", + "big", + "binaryType", + "bind", + "bindAttribLocation", + "bindBuffer", + "bindBufferBase", + "bindBufferRange", + "bindFramebuffer", + "bindRenderbuffer", + "bindSampler", + "bindTexture", + "bindTransformFeedback", + "bindVertexArray", + "blendColor", + "blendEquation", + "blendEquationSeparate", + "blendFunc", + "blendFuncSeparate", + "blink", + "blitFramebuffer", + "blob", + "block-size", + "blockDirection", + "blockSize", + "blockedURI", + "blue", + "bluetooth", + "blur", + "body", + "bodyUsed", + "bold", + "bookmarks", + "booleanValue", + "border", + "border-block", + "border-block-color", + "border-block-end", + "border-block-end-color", + "border-block-end-style", + "border-block-end-width", + "border-block-start", + "border-block-start-color", + "border-block-start-style", + "border-block-start-width", + "border-block-style", + "border-block-width", + "border-bottom", + "border-bottom-color", + "border-bottom-left-radius", + "border-bottom-right-radius", + "border-bottom-style", + "border-bottom-width", + "border-collapse", + "border-color", + "border-end-end-radius", + "border-end-start-radius", + "border-image", + "border-image-outset", + "border-image-repeat", + "border-image-slice", + "border-image-source", + "border-image-width", + "border-inline", + "border-inline-color", + "border-inline-end", + "border-inline-end-color", + "border-inline-end-style", + "border-inline-end-width", + "border-inline-start", + "border-inline-start-color", + "border-inline-start-style", + "border-inline-start-width", + "border-inline-style", + "border-inline-width", + "border-left", + "border-left-color", + "border-left-style", + "border-left-width", + "border-radius", + "border-right", + "border-right-color", + "border-right-style", + "border-right-width", + "border-spacing", + "border-start-end-radius", + "border-start-start-radius", + "border-style", + "border-top", + "border-top-color", + "border-top-left-radius", + "border-top-right-radius", + "border-top-style", + "border-top-width", + "border-width", + "borderBlock", + "borderBlockColor", + "borderBlockEnd", + "borderBlockEndColor", + "borderBlockEndStyle", + "borderBlockEndWidth", + "borderBlockStart", + "borderBlockStartColor", + "borderBlockStartStyle", + "borderBlockStartWidth", + "borderBlockStyle", + "borderBlockWidth", + "borderBottom", + "borderBottomColor", + "borderBottomLeftRadius", + "borderBottomRightRadius", + "borderBottomStyle", + "borderBottomWidth", + "borderBoxSize", + "borderCollapse", + "borderColor", + "borderColorDark", + "borderColorLight", + "borderEndEndRadius", + "borderEndStartRadius", + "borderImage", + "borderImageOutset", + "borderImageRepeat", + "borderImageSlice", + "borderImageSource", + "borderImageWidth", + "borderInline", + "borderInlineColor", + "borderInlineEnd", + "borderInlineEndColor", + "borderInlineEndStyle", + "borderInlineEndWidth", + "borderInlineStart", + "borderInlineStartColor", + "borderInlineStartStyle", + "borderInlineStartWidth", + "borderInlineStyle", + "borderInlineWidth", + "borderLeft", + "borderLeftColor", + "borderLeftStyle", + "borderLeftWidth", + "borderRadius", + "borderRight", + "borderRightColor", + "borderRightStyle", + "borderRightWidth", + "borderSpacing", + "borderStartEndRadius", + "borderStartStartRadius", + "borderStyle", + "borderTop", + "borderTopColor", + "borderTopLeftRadius", + "borderTopRightRadius", + "borderTopStyle", + "borderTopWidth", + "borderWidth", + "bottom", + "bottomMargin", + "bound", + "boundElements", + "boundingClientRect", + "boundingHeight", + "boundingLeft", + "boundingTop", + "boundingWidth", + "bounds", + "boundsGeometry", + "box-decoration-break", + "box-shadow", + "box-sizing", + "boxDecorationBreak", + "boxShadow", + "boxSizing", + "break-after", + "break-before", + "break-inside", + "breakAfter", + "breakBefore", + "breakInside", + "breakType", + "broadcast", + "browserLanguage", + "btoa", + "bubbles", + "buffer", + "bufferData", + "bufferDepth", + "bufferSize", + "bufferSubData", + "buffered", + "bufferedAmount", + "bufferedAmountLowThreshold", + "bufferedRendering", + "buildID", + "buildNumber", + "button", + "buttonID", + "buttons", + "byteLength", + "byteOffset", + "bytesWritten", + "c", + "cache", + "caches", + "calendar", + "call", + "caller", + "canBeFormatted", + "canBeMounted", + "canBeShared", + "canHaveChildren", + "canHaveHTML", + "canInsertDTMF", + "canMakePayment", + "canPlayType", + "canPresent", + "canTrickleIceCandidates", + "cancel", + "cancelAndHoldAtTime", + "cancelAnimationFrame", + "cancelBubble", + "cancelIdleCallback", + "cancelScheduledValues", + "cancelVideoFrameCallback", + "cancelWatchAvailability", + "cancelable", + "candidate", + "canonicalUUID", + "canvas", + "capabilities", + "caption", + "caption-side", + "captionSide", + "capture", + "captureEvents", + "captureStackTrace", + "captureStream", + "caret-color", + "caretBidiLevel", + "caretColor", + "caretPositionFromPoint", + "caretRangeFromPoint", + "caseFirst", + "cast", + "catch", + "category", + "cbrt", + "cd", + "ceil", + "cellIndex", + "cellPadding", + "cellSpacing", + "cells", + "ch", + "chOff", + "chain", + "challenge", + "changeType", + "changeVersion", + "changedTouches", + "channel", + "channelCount", + "channelCountMode", + "channelInterpretation", + "char", + "charAt", + "charCode", + "charCodeAt", + "charIndex", + "charLength", + "characterData", + "characterDataOldValue", + "characterSet", + "characteristic", + "charging", + "chargingTime", + "charset", + "check", + "checkEnclosure", + "checkFramebufferStatus", + "checkInstalled", + "checkIntersection", + "checkValidity", + "checked", + "childElementCount", + "childList", + "childNodes", + "children", + "chrome", + "ciphertext", + "cite", + "city", + "claimInterface", + "claimed", + "classList", + "className", + "classid", + "clear", + "clearAppBadge", + "clearAttributes", + "clearBufferfi", + "clearBufferfv", + "clearBufferiv", + "clearBufferuiv", + "clearColor", + "clearData", + "clearDepth", + "clearHalt", + "clearImmediate", + "clearInterval", + "clearLiveSeekableRange", + "clearMarks", + "clearMeasures", + "clearParameters", + "clearRect", + "clearResourceTimings", + "clearShadow", + "clearStencil", + "clearTimeout", + "clearWatch", + "click", + "clickCount", + "clientDataJSON", + "clientHeight", + "clientInformation", + "clientLeft", + "clientRect", + "clientRects", + "clientTop", + "clientWaitSync", + "clientWidth", + "clientX", + "clientY", + "clip", + "clip-path", + "clip-rule", + "clipBottom", + "clipLeft", + "clipPath", + "clipPathUnits", + "clipRight", + "clipRule", + "clipTop", + "clipboard", + "clipboardData", + "clone", + "cloneContents", + "cloneNode", + "cloneRange", + "close", + "closePath", + "closed", + "closest", + "clz", + "clz32", + "cm", + "cmp", + "code", + "codeBase", + "codePointAt", + "codeType", + "colSpan", + "collapse", + "collapseToEnd", + "collapseToStart", + "collapsed", + "collation", + "collect", + "colno", + "color", + "color-adjust", + "color-interpolation", + "color-interpolation-filters", + "colorAdjust", + "colorDepth", + "colorInterpolation", + "colorInterpolationFilters", + "colorMask", + "colorProfile", + "colorRendering", + "colorScheme", + "colorType", + "cols", + "column", + "column-count", + "column-fill", + "column-gap", + "column-rule", + "column-rule-color", + "column-rule-style", + "column-rule-width", + "column-span", + "column-width", + "columnCount", + "columnFill", + "columnGap", + "columnNumber", + "columnRule", + "columnRuleColor", + "columnRuleStyle", + "columnRuleWidth", + "columnSpan", + "columnWidth", + "columns", + "command", + "commit", + "commitLoadTime", + "commitPreferences", + "commitStyles", + "commonAncestorContainer", + "compact", + "compare", + "compareBoundaryPoints", + "compareDocumentPosition", + "compareEndPoints", + "compareExchange", + "compareNode", + "comparePoint", + "compatMode", + "compatible", + "compile", + "compileShader", + "compileStreaming", + "complete", + "component", + "componentFromPoint", + "composed", + "composedPath", + "composite", + "compositionEndOffset", + "compositionStartOffset", + "compressedTexImage2D", + "compressedTexImage3D", + "compressedTexSubImage2D", + "compressedTexSubImage3D", + "computedStyleMap", + "concat", + "conditionText", + "coneInnerAngle", + "coneOuterAngle", + "coneOuterGain", + "configuration", + "configurationName", + "configurationValue", + "configurations", + "confirm", + "confirmComposition", + "confirmSiteSpecificTrackingException", + "confirmWebWideTrackingException", + "connect", + "connectEnd", + "connectStart", + "connected", + "connectedCallback", + "connection", + "connectionInfo", + "connectionList", + "connectionSpeed", + "connectionState", + "connections", + "console", + "consoleHistory", + "consolidate", + "constraint", + "constrictionActive", + "construct", + "constructor", + "contactID", + "contain", + "containIntrinsicSize", + "containerId", + "containerName", + "containerSrc", + "containerType", + "contains", + "containsNode", + "content", + "contentBoxSize", + "contentDocument", + "contentEditable", + "contentHint", + "contentOverflow", + "contentRect", + "contentScriptType", + "contentStyleType", + "contentType", + "contentWindow", + "context", + "contextMenu", + "contextmenu", + "continue", + "continuePrimaryKey", + "continuous", + "control", + "controlTransferIn", + "controlTransferOut", + "controller", + "controls", + "controlsList", + "convertToBlob", + "convertToSpecifiedUnits", + "cookie", + "cookieEnabled", + "coords", + "copyBufferSubData", + "copyFromChannel", + "copyTexImage2D", + "copyTexSubImage2D", + "copyTexSubImage3D", + "copyToChannel", + "copyWithin", + "correspondingElement", + "correspondingUseElement", + "corruptedVideoFrames", + "cos", + "cosh", + "count", + "countReset", + "counter-increment", + "counter-reset", + "counter-set", + "counterIncrement", + "counterReset", + "counterSet", + "country", + "cpuClass", + "cpuSleepAllowed", + "create", + "createAnalyser", + "createAnswer", + "createAttribute", + "createAttributeNS", + "createBiquadFilter", + "createBuffer", + "createBufferSource", + "createCDATASection", + "createCSSStyleSheet", + "createCaption", + "createChannelMerger", + "createChannelSplitter", + "createComment", + "createConstantSource", + "createContextualFragment", + "createControlRange", + "createConvolver", + "createDTMFSender", + "createDataChannel", + "createDelay", + "createDelayNode", + "createDocument", + "createDocumentFragment", + "createDocumentType", + "createDynamicsCompressor", + "createElement", + "createElementNS", + "createEntityReference", + "createEvent", + "createEventObject", + "createExpression", + "createFramebuffer", + "createFunction", + "createGain", + "createGainNode", + "createHTML", + "createHTMLDocument", + "createIIRFilter", + "createImageBitmap", + "createImageData", + "createIndex", + "createJavaScriptNode", + "createLinearGradient", + "createMediaElementSource", + "createMediaKeys", + "createMediaStreamDestination", + "createMediaStreamSource", + "createMediaStreamTrackSource", + "createMutableFile", + "createNSResolver", + "createNodeIterator", + "createNotification", + "createObjectStore", + "createObjectURL", + "createOffer", + "createOscillator", + "createPanner", + "createPattern", + "createPeriodicWave", + "createPolicy", + "createPopup", + "createProcessingInstruction", + "createProgram", + "createQuery", + "createRadialGradient", + "createRange", + "createRangeCollection", + "createReader", + "createRenderbuffer", + "createSVGAngle", + "createSVGLength", + "createSVGMatrix", + "createSVGNumber", + "createSVGPathSegArcAbs", + "createSVGPathSegArcRel", + "createSVGPathSegClosePath", + "createSVGPathSegCurvetoCubicAbs", + "createSVGPathSegCurvetoCubicRel", + "createSVGPathSegCurvetoCubicSmoothAbs", + "createSVGPathSegCurvetoCubicSmoothRel", + "createSVGPathSegCurvetoQuadraticAbs", + "createSVGPathSegCurvetoQuadraticRel", + "createSVGPathSegCurvetoQuadraticSmoothAbs", + "createSVGPathSegCurvetoQuadraticSmoothRel", + "createSVGPathSegLinetoAbs", + "createSVGPathSegLinetoHorizontalAbs", + "createSVGPathSegLinetoHorizontalRel", + "createSVGPathSegLinetoRel", + "createSVGPathSegLinetoVerticalAbs", + "createSVGPathSegLinetoVerticalRel", + "createSVGPathSegMovetoAbs", + "createSVGPathSegMovetoRel", + "createSVGPoint", + "createSVGRect", + "createSVGTransform", + "createSVGTransformFromMatrix", + "createSampler", + "createScript", + "createScriptProcessor", + "createScriptURL", + "createSession", + "createShader", + "createShadowRoot", + "createStereoPanner", + "createStyleSheet", + "createTBody", + "createTFoot", + "createTHead", + "createTextNode", + "createTextRange", + "createTexture", + "createTouch", + "createTouchList", + "createTransformFeedback", + "createTreeWalker", + "createVertexArray", + "createWaveShaper", + "creationTime", + "credentials", + "crossOrigin", + "crossOriginIsolated", + "crypto", + "csi", + "csp", + "cssFloat", + "cssRules", + "cssText", + "cssValueType", + "ctrlKey", + "ctrlLeft", + "cues", + "cullFace", + "currency", + "currencyDisplay", + "current", + "currentDirection", + "currentLocalDescription", + "currentNode", + "currentPage", + "currentRect", + "currentRemoteDescription", + "currentScale", + "currentScript", + "currentSrc", + "currentState", + "currentStyle", + "currentTarget", + "currentTime", + "currentTranslate", + "currentView", + "cursor", + "curve", + "customElements", + "customError", + "customSections", + "cx", + "cy", + "d", + "data", + "dataFld", + "dataFormatAs", + "dataLoss", + "dataLossMessage", + "dataPageSize", + "dataSrc", + "dataTransfer", + "database", + "databases", + "dataset", + "dateTime", + "day", + "db", + "debug", + "debuggerEnabled", + "declare", + "decode", + "decodeAudioData", + "decodeURI", + "decodeURIComponent", + "decodedBodySize", + "decoding", + "decodingInfo", + "decrypt", + "default", + "defaultCharset", + "defaultChecked", + "defaultMuted", + "defaultPlaybackRate", + "defaultPolicy", + "defaultPrevented", + "defaultRequest", + "defaultSelected", + "defaultStatus", + "defaultURL", + "defaultValue", + "defaultView", + "defaultstatus", + "defer", + "define", + "defineMagicFunction", + "defineMagicVariable", + "defineProperties", + "defineProperty", + "deg", + "delay", + "delayTime", + "delegatesFocus", + "delete", + "deleteBuffer", + "deleteCaption", + "deleteCell", + "deleteContents", + "deleteData", + "deleteDatabase", + "deleteFramebuffer", + "deleteFromDocument", + "deleteIndex", + "deleteMedium", + "deleteObjectStore", + "deleteProgram", + "deleteProperty", + "deleteQuery", + "deleteRenderbuffer", + "deleteRow", + "deleteRule", + "deleteSampler", + "deleteShader", + "deleteSync", + "deleteTFoot", + "deleteTHead", + "deleteTexture", + "deleteTransformFeedback", + "deleteVertexArray", + "deliverChangeRecords", + "delivery", + "deliveryInfo", + "deliveryStatus", + "deliveryTimestamp", + "delta", + "deltaMode", + "deltaX", + "deltaY", + "deltaZ", + "dependentLocality", + "depthFar", + "depthFunc", + "depthMask", + "depthNear", + "depthRange", + "deref", + "deriveBits", + "deriveKey", + "description", + "deselectAll", + "designMode", + "desiredSize", + "destination", + "destinationURL", + "detach", + "detachEvent", + "detachShader", + "detail", + "details", + "detect", + "detune", + "device", + "deviceClass", + "deviceId", + "deviceMemory", + "devicePixelContentBoxSize", + "devicePixelRatio", + "deviceProtocol", + "deviceSessionId", + "deviceSubclass", + "deviceVersionMajor", + "deviceVersionMinor", + "deviceVersionSubminor", + "deviceXDPI", + "deviceYDPI", + "didTimeout", + "diffuseConstant", + "digest", + "dimensions", + "dir", + "dirName", + "dirXml", + "direction", + "dirxml", + "disable", + "disablePictureInPicture", + "disableRemotePlayback", + "disableVertexAttribArray", + "disabled", + "dischargingTime", + "disconnect", + "disconnectedCallback", + "dispatch", + "dispatchEvent", + "dispatchToListener", + "display", + "displayId", + "displayName", + "disposition", + "distanceModel", + "div", + "divisor", + "djsapi", + "djsproxy", + "doImport", + "doNotTrack", + "doScroll", + "doctype", + "document", + "documentElement", + "documentMode", + "documentURI", + "dolphin", + "dolphinGameCenter", + "dolphininfo", + "dolphinmeta", + "domComplete", + "domContentLoadedEventEnd", + "domContentLoadedEventStart", + "domInteractive", + "domLoading", + "domOverlayState", + "domain", + "domainLookupEnd", + "domainLookupStart", + "dominant-baseline", + "dominantBaseline", + "done", + "dopplerFactor", + "dotAll", + "downDegrees", + "downlink", + "download", + "downloadTotal", + "downloaded", + "dpcm", + "dpi", + "dppx", + "dragDrop", + "draggable", + "drawArrays", + "drawArraysInstanced", + "drawArraysInstancedANGLE", + "drawBuffers", + "drawCustomFocusRing", + "drawElements", + "drawElementsInstanced", + "drawElementsInstancedANGLE", + "drawFocusIfNeeded", + "drawImage", + "drawImageFromRect", + "drawRangeElements", + "drawSystemFocusRing", + "drawingBufferHeight", + "drawingBufferWidth", + "dropEffect", + "droppedVideoFrames", + "dropzone", + "dtmf", + "dump", + "duplicate", + "durability", + "duration", + "dvname", + "dvnum", + "dx", + "dy", + "dynsrc", + "e", + "edgeMode", + "effect", + "effectAllowed", + "effectiveDirective", + "effectiveType", + "elapsedTime", + "element", + "elementFromPoint", + "elementTiming", + "elements", + "elementsFromPoint", + "elevation", + "ellipse", + "em", + "emHeightAscent", + "emHeightDescent", + "email", + "embeds", + "emma", + "empty", + "empty-cells", + "emptyCells", + "emptyHTML", + "emptyScript", + "emulatedPosition", + "enable", + "enableBackground", + "enableDelegations", + "enableStyleSheetsForSet", + "enableVertexAttribArray", + "enabled", + "enabledPlugin", + "encode", + "encodeInto", + "encodeURI", + "encodeURIComponent", + "encodedBodySize", + "encoding", + "encodingInfo", + "encrypt", + "enctype", + "end", + "endContainer", + "endElement", + "endElementAt", + "endOfStream", + "endOffset", + "endQuery", + "endTime", + "endTransformFeedback", + "ended", + "endpoint", + "endpointNumber", + "endpoints", + "endsWith", + "enterKeyHint", + "entities", + "entries", + "entryType", + "enumerate", + "enumerateDevices", + "enumerateEditable", + "environmentBlendMode", + "epubCaptionSide", + "epubTextCombine", + "epubTextEmphasis", + "epubTextEmphasisColor", + "epubTextEmphasisStyle", + "epubTextOrientation", + "epubTextTransform", + "epubWordBreak", + "epubWritingMode", + "equals", + "era", + "error", + "errorCode", + "errorDetail", + "errorText", + "escape", + "estimate", + "eval", + "evaluate", + "event", + "eventPhase", + "every", + "ex", + "exception", + "exchange", + "exec", + "execCommand", + "execCommandShowHelp", + "execScript", + "executeSql", + "exitFullscreen", + "exitPictureInPicture", + "exitPointerLock", + "exitPresent", + "exp", + "expand", + "expandEntityReferences", + "expando", + "expansion", + "expiration", + "expirationTime", + "expires", + "expiryDate", + "explicitOriginalTarget", + "expm1", + "exponent", + "exponentialRampToValueAtTime", + "exportKey", + "exports", + "extend", + "extensions", + "extentNode", + "extentOffset", + "external", + "externalResourcesRequired", + "extractContents", + "extractable", + "eye", + "f", + "face", + "factoryReset", + "failureReason", + "fallback", + "family", + "familyName", + "farthestViewportElement", + "fastSeek", + "fatal", + "featurePolicy", + "featureSettings", + "features", + "fenceSync", + "fetch", + "fetchStart", + "fftSize", + "fgColor", + "fieldOfView", + "file", + "fileCreatedDate", + "fileHandle", + "fileModifiedDate", + "fileName", + "fileSize", + "fileUpdatedDate", + "filename", + "files", + "filesystem", + "fill", + "fill-opacity", + "fill-rule", + "fillLightMode", + "fillOpacity", + "fillRect", + "fillRule", + "fillStyle", + "fillText", + "filter", + "filterResX", + "filterResY", + "filterUnits", + "filters", + "finally", + "find", + "findIndex", + "findRule", + "findText", + "finish", + "finishDocumentLoadTime", + "finishLoadTime", + "finished", + "fireEvent", + "firesTouchEvents", + "first", + "firstChild", + "firstElementChild", + "firstPage", + "firstPaintAfterLoadTime", + "firstPaintTime", + "fixed", + "flags", + "flat", + "flatMap", + "flex", + "flex-basis", + "flex-direction", + "flex-flow", + "flex-grow", + "flex-shrink", + "flex-wrap", + "flexBasis", + "flexDirection", + "flexFlow", + "flexGrow", + "flexShrink", + "flexWrap", + "flipX", + "flipY", + "float", + "flood-color", + "flood-opacity", + "floodColor", + "floodOpacity", + "floor", + "flush", + "focus", + "focusNode", + "focusOffset", + "font", + "font-family", + "font-feature-settings", + "font-kerning", + "font-language-override", + "font-size", + "font-size-adjust", + "font-stretch", + "font-style", + "font-synthesis", + "font-variant", + "font-variant-alternates", + "font-variant-caps", + "font-variant-east-asian", + "font-variant-ligatures", + "font-variant-numeric", + "font-variant-position", + "font-weight", + "fontBoundingBoxAscent", + "fontBoundingBoxDescent", + "fontDisplay", + "fontFamily", + "fontFeatureSettings", + "fontKerning", + "fontLanguageOverride", + "fontOpticalSizing", + "fontSize", + "fontSizeAdjust", + "fontSmoothingEnabled", + "fontStretch", + "fontStyle", + "fontSynthesis", + "fontVariant", + "fontVariantAlternates", + "fontVariantCaps", + "fontVariantEastAsian", + "fontVariantLigatures", + "fontVariantNumeric", + "fontVariantPosition", + "fontVariationSettings", + "fontWeight", + "fontcolor", + "fontfaces", + "fonts", + "fontsize", + "for", + "forEach", + "force", + "forceRedraw", + "form", + "formAction", + "formData", + "formEnctype", + "formMethod", + "formNoValidate", + "formTarget", + "format", + "formatRange", + "formatRangeToParts", + "formatToParts", + "forms", + "forward", + "forwardX", + "forwardY", + "forwardZ", + "foundation", + "fr", + "fragmentDirective", + "frame", + "frameBorder", + "frameElement", + "frameSpacing", + "framebuffer", + "framebufferHeight", + "framebufferRenderbuffer", + "framebufferTexture2D", + "framebufferTextureLayer", + "framebufferWidth", + "frames", + "freeSpace", + "freeze", + "frequency", + "frequencyBinCount", + "from", + "fromCharCode", + "fromCodePoint", + "fromElement", + "fromEntries", + "fromFloat32Array", + "fromFloat64Array", + "fromMatrix", + "fromPoint", + "fromQuad", + "fromRect", + "frontFace", + "fround", + "fullPath", + "fullScreen", + "fullscreen", + "fullscreenElement", + "fullscreenEnabled", + "fx", + "fy", + "gain", + "gamepad", + "gamma", + "gap", + "gatheringState", + "gatt", + "genderIdentity", + "generateCertificate", + "generateKey", + "generateMipmap", + "generateRequest", + "geolocation", + "gestureObject", + "get", + "getActiveAttrib", + "getActiveUniform", + "getActiveUniformBlockName", + "getActiveUniformBlockParameter", + "getActiveUniforms", + "getAdditionalLanguages", + "getAdjacentText", + "getAll", + "getAllKeys", + "getAllResponseHeaders", + "getAllowlistForFeature", + "getAnimations", + "getAsFile", + "getAsString", + "getAttachedShaders", + "getAttribLocation", + "getAttribute", + "getAttributeNS", + "getAttributeNames", + "getAttributeNode", + "getAttributeNodeNS", + "getAttributeType", + "getAudioTracks", + "getAvailability", + "getBBox", + "getBattery", + "getBigInt64", + "getBigUint64", + "getBlob", + "getBookmark", + "getBoundingClientRect", + "getBounds", + "getBufferParameter", + "getBufferSubData", + "getByteFrequencyData", + "getByteTimeDomainData", + "getCSSCanvasContext", + "getCTM", + "getCandidateWindowClientRect", + "getCanonicalLocales", + "getCapabilities", + "getChannelData", + "getCharNumAtPosition", + "getCharacteristic", + "getCharacteristics", + "getClientExtensionResults", + "getClientRect", + "getClientRects", + "getCoalescedEvents", + "getCompositionAlternatives", + "getComputedStyle", + "getComputedTextLength", + "getComputedTiming", + "getConfiguration", + "getConstraints", + "getContext", + "getContextAttributes", + "getContributingSources", + "getCount", + "getCounterValue", + "getCueAsHTML", + "getCueById", + "getCurrentPosition", + "getCurrentTime", + "getData", + "getDatabaseNames", + "getDate", + "getDay", + "getDefaultComputedStyle", + "getDescriptor", + "getDescriptors", + "getDestinationInsertionPoints", + "getDetails", + "getDevices", + "getDirectory", + "getDisplayMedia", + "getDistributedNodes", + "getEditable", + "getElementById", + "getElementsByClassName", + "getElementsByName", + "getElementsByTagName", + "getElementsByTagNameNS", + "getEnclosureList", + "getEndPositionOfChar", + "getEntries", + "getEntriesByName", + "getEntriesByType", + "getError", + "getExtension", + "getExtentOfChar", + "getEyeParameters", + "getFeature", + "getFile", + "getFiles", + "getFilesAndDirectories", + "getFingerprints", + "getFloat32", + "getFloat64", + "getFloatFrequencyData", + "getFloatTimeDomainData", + "getFloatValue", + "getFragDataLocation", + "getFrameData", + "getFramebufferAttachmentParameter", + "getFrequencyResponse", + "getFullYear", + "getGamepads", + "getHitTestResults", + "getHitTestResultsForTransientInput", + "getHours", + "getIdentityAssertion", + "getIds", + "getImageData", + "getIndexedParameter", + "getInstalled", + "getInstalledRelatedApps", + "getInt16", + "getInt32", + "getInt8", + "getInternalformatParameter", + "getIntersectionList", + "getIsInstalled", + "getItem", + "getItems", + "getKey", + "getKeyframes", + "getLayers", + "getLayoutMap", + "getLineDash", + "getLocalCandidates", + "getLocalParameters", + "getLocalStreams", + "getLocalizationResource", + "getMarks", + "getMatchedCSSRules", + "getMeasures", + "getMetadata", + "getMilliseconds", + "getMinutes", + "getModifierState", + "getMonth", + "getNamedItem", + "getNamedItemNS", + "getNativeFramebufferScaleFactor", + "getNotifications", + "getNotifier", + "getNumberOfChars", + "getOffsetReferenceSpace", + "getOutputTimestamp", + "getOverrideHistoryNavigationMode", + "getOverrideStyle", + "getOwnPropertyDescriptor", + "getOwnPropertyDescriptors", + "getOwnPropertyNames", + "getOwnPropertySymbols", + "getParameter", + "getParameters", + "getParent", + "getPathSegAtLength", + "getPhotoCapabilities", + "getPhotoSettings", + "getPointAtLength", + "getPose", + "getPredictedEvents", + "getPreference", + "getPreferenceDefault", + "getPresentationAttribute", + "getPreventDefault", + "getPrimaryService", + "getPrimaryServices", + "getProgramInfoLog", + "getProgramParameter", + "getPropertyCSSValue", + "getPropertyPriority", + "getPropertyShorthand", + "getPropertyType", + "getPropertyValue", + "getPrototypeOf", + "getQuery", + "getQueryParameter", + "getRGBColorValue", + "getRandomValues", + "getRangeAt", + "getReader", + "getReceivers", + "getRectValue", + "getRegistration", + "getRegistrations", + "getRemoteCandidates", + "getRemoteCertificates", + "getRemoteParameters", + "getRemoteStreams", + "getRenderbufferParameter", + "getResponseHeader", + "getRevision", + "getRoot", + "getRootNode", + "getRotationOfChar", + "getRules", + "getSVGDocument", + "getSamplerParameter", + "getScreenCTM", + "getSeconds", + "getSelectedCandidatePair", + "getSelection", + "getSelf", + "getSenders", + "getService", + "getSettings", + "getShaderInfoLog", + "getShaderParameter", + "getShaderPrecisionFormat", + "getShaderSource", + "getSimpleDuration", + "getSiteIcons", + "getSources", + "getSpeculativeParserUrls", + "getStartDate", + "getStartPositionOfChar", + "getStartTime", + "getState", + "getStats", + "getStatusForPolicy", + "getStorageUpdates", + "getStreamById", + "getStringValue", + "getSubStringLength", + "getSubscription", + "getSupportedConstraints", + "getSupportedExtensions", + "getSupportedFormats", + "getSyncParameter", + "getSynchronizationSources", + "getTags", + "getTargetRanges", + "getTexParameter", + "getTime", + "getTimezoneOffset", + "getTiming", + "getTotalLength", + "getTrackById", + "getTracks", + "getTransceivers", + "getTransform", + "getTransformFeedbackVarying", + "getTransformToElement", + "getTransports", + "getType", + "getTypeMapping", + "getUTCDate", + "getUTCDay", + "getUTCFullYear", + "getUTCHours", + "getUTCMilliseconds", + "getUTCMinutes", + "getUTCMonth", + "getUTCSeconds", + "getUint16", + "getUint32", + "getUint8", + "getUniform", + "getUniformBlockIndex", + "getUniformIndices", + "getUniformLocation", + "getUserMedia", + "getVRDisplays", + "getValues", + "getVarDate", + "getVariableValue", + "getVertexAttrib", + "getVertexAttribOffset", + "getVideoPlaybackQuality", + "getVideoTracks", + "getViewerPose", + "getViewport", + "getVoices", + "getWakeLockState", + "getWriter", + "getYear", + "givenName", + "global", + "globalAlpha", + "globalCompositeOperation", + "globalThis", + "glyphOrientationHorizontal", + "glyphOrientationVertical", + "glyphRef", + "go", + "grabFrame", + "grad", + "gradientTransform", + "gradientUnits", + "grammars", + "green", + "grid", + "grid-area", + "grid-auto-columns", + "grid-auto-flow", + "grid-auto-rows", + "grid-column", + "grid-column-end", + "grid-column-gap", + "grid-column-start", + "grid-gap", + "grid-row", + "grid-row-end", + "grid-row-gap", + "grid-row-start", + "grid-template", + "grid-template-areas", + "grid-template-columns", + "grid-template-rows", + "gridArea", + "gridAutoColumns", + "gridAutoFlow", + "gridAutoRows", + "gridColumn", + "gridColumnEnd", + "gridColumnGap", + "gridColumnStart", + "gridGap", + "gridRow", + "gridRowEnd", + "gridRowGap", + "gridRowStart", + "gridTemplate", + "gridTemplateAreas", + "gridTemplateColumns", + "gridTemplateRows", + "gripSpace", + "group", + "groupCollapsed", + "groupEnd", + "groupId", + "grow", + "hadRecentInput", + "hand", + "handedness", + "hangingBaseline", + "hangingPunctuation", + "hapticActuators", + "hardwareConcurrency", + "has", + "hasAttribute", + "hasAttributeNS", + "hasAttributes", + "hasBeenActive", + "hasChildNodes", + "hasComposition", + "hasEnrolledInstrument", + "hasExtension", + "hasExternalDisplay", + "hasFeature", + "hasFocus", + "hasInstance", + "hasLayout", + "hasListener", + "hasListeners", + "hasOrientation", + "hasOwnProperty", + "hasPointerCapture", + "hasPosition", + "hasReading", + "hasStorageAccess", + "hash", + "head", + "headers", + "heading", + "height", + "hidden", + "hide", + "hideFocus", + "high", + "highWaterMark", + "hint", + "history", + "honorificPrefix", + "honorificSuffix", + "horizontalOverflow", + "host", + "hostCandidate", + "hostname", + "hour", + "hour12", + "hourCycle", + "href", + "hrefTranslate", + "hreflang", + "hspace", + "html5TagCheckInerface", + "htmlFor", + "htmlText", + "httpEquiv", + "httpRequestStatusCode", + "hwTimestamp", + "hyphens", + "hypot", + "iccId", + "iceConnectionState", + "iceGatheringState", + "iceTransport", + "icon", + "iconURL", + "id", + "identifier", + "identity", + "ideographicBaseline", + "idpLoginUrl", + "ignoreBOM", + "ignoreCase", + "ignoreDepthValues", + "ignoreMutedMedia", + "ignorePunctuation", + "image-orientation", + "image-rendering", + "imageHeight", + "imageOrientation", + "imageRendering", + "imageSizes", + "imageSmoothingEnabled", + "imageSmoothingQuality", + "imageSrcset", + "imageWidth", + "images", + "ime-mode", + "imeMode", + "implementation", + "import", + "importKey", + "importNode", + "importStylesheet", + "imports", + "impp", + "imul", + "in", + "in1", + "in2", + "inBandMetadataTrackDispatchType", + "inRange", + "includes", + "incremental", + "indeterminate", + "index", + "indexNames", + "indexOf", + "indexedDB", + "indicate", + "inertiaDestinationX", + "inertiaDestinationY", + "info", + "init", + "initAnimationEvent", + "initBeforeLoadEvent", + "initClipboardEvent", + "initCloseEvent", + "initCommandEvent", + "initCompositionEvent", + "initCustomEvent", + "initData", + "initDataType", + "initDeviceMotionEvent", + "initDeviceOrientationEvent", + "initDragEvent", + "initErrorEvent", + "initEvent", + "initFocusEvent", + "initGestureEvent", + "initHashChangeEvent", + "initKeyEvent", + "initKeyboardEvent", + "initMSManipulationEvent", + "initMessageEvent", + "initMouseEvent", + "initMouseScrollEvent", + "initMouseWheelEvent", + "initMutationEvent", + "initNSMouseEvent", + "initOverflowEvent", + "initPageEvent", + "initPageTransitionEvent", + "initPointerEvent", + "initPopStateEvent", + "initProgressEvent", + "initScrollAreaEvent", + "initSimpleGestureEvent", + "initStorageEvent", + "initTextEvent", + "initTimeEvent", + "initTouchEvent", + "initTransitionEvent", + "initUIEvent", + "initWebKitAnimationEvent", + "initWebKitTransitionEvent", + "initWebKitWheelEvent", + "initWheelEvent", + "initialTime", + "initialize", + "initiatorType", + "inline-size", + "inlineSize", + "inlineVerticalFieldOfView", + "inner", + "innerHTML", + "innerHeight", + "innerText", + "innerWidth", + "input", + "inputBuffer", + "inputEncoding", + "inputMethod", + "inputMode", + "inputSource", + "inputSources", + "inputType", + "inputs", + "insertAdjacentElement", + "insertAdjacentHTML", + "insertAdjacentText", + "insertBefore", + "insertCell", + "insertDTMF", + "insertData", + "insertId", + "insertItemBefore", + "insertNode", + "insertRow", + "insertRule", + "inset", + "inset-block", + "inset-block-end", + "inset-block-start", + "inset-inline", + "inset-inline-end", + "inset-inline-start", + "insetBlock", + "insetBlockEnd", + "insetBlockStart", + "insetInline", + "insetInlineEnd", + "insetInlineStart", + "install", + "installChrome", + "installPackage", + "installState", + "installing", + "instanceRoot", + "instantiate", + "instantiateStreaming", + "instruments", + "integrity", + "interactionMode", + "intercept", + "interfaceClass", + "interfaceName", + "interfaceNumber", + "interfaceProtocol", + "interfaceSubclass", + "interfaces", + "interimResults", + "internalSubset", + "interpretation", + "intersectionRatio", + "intersectionRect", + "intersectsNode", + "interval", + "invalidIteratorState", + "invalidateFramebuffer", + "invalidateSubFramebuffer", + "inverse", + "invertSelf", + "is", + "is2D", + "isActive", + "isAlternate", + "isArray", + "isBingCurrentSearchDefault", + "isBuffer", + "isCandidateWindowVisible", + "isChar", + "isCollapsed", + "isComposing", + "isConcatSpreadable", + "isConnected", + "isContentEditable", + "isContentHandlerRegistered", + "isContextLost", + "isDefaultNamespace", + "isDirectory", + "isDisabled", + "isEnabled", + "isEqual", + "isEqualNode", + "isExtensible", + "isExternalCTAP2SecurityKeySupported", + "isFile", + "isFinite", + "isFramebuffer", + "isFrozen", + "isGenerator", + "isHTML", + "isHistoryNavigation", + "isId", + "isIdentity", + "isInjected", + "isInstalled", + "isInteger", + "isIntersecting", + "isLockFree", + "isMap", + "isMultiLine", + "isNaN", + "isOpen", + "isPointInFill", + "isPointInPath", + "isPointInRange", + "isPointInStroke", + "isPrefAlternate", + "isPresenting", + "isPrimary", + "isProgram", + "isPropertyImplicit", + "isProtocolHandlerRegistered", + "isPrototypeOf", + "isQuery", + "isRenderbuffer", + "isSafeInteger", + "isSameNode", + "isSampler", + "isScript", + "isScriptURL", + "isSealed", + "isSecureContext", + "isSessionSupported", + "isShader", + "isSupported", + "isSync", + "isTextEdit", + "isTexture", + "isTransformFeedback", + "isTrusted", + "isTypeSupported", + "isTypeSupportedWithFeatures", + "isUserVerifyingPlatformAuthenticatorAvailable", + "isVertexArray", + "isView", + "isVisible", + "isochronousTransferIn", + "isochronousTransferOut", + "isolation", + "italics", + "item", + "itemId", + "itemProp", + "itemRef", + "itemScope", + "itemType", + "itemValue", + "items", + "iterateNext", + "iterator", + "javaEnabled", + "jobTitle", + "join", + "jsHeapSizeLimit", + "json", + "justify-content", + "justify-items", + "justify-self", + "justifyContent", + "justifyItems", + "justifySelf", + "k1", + "k2", + "k3", + "k4", + "kHz", + "keepalive", + "kernelMatrix", + "kernelUnitLengthX", + "kernelUnitLengthY", + "kerning", + "key", + "keyCode", + "keyFor", + "keyIdentifier", + "keyLightEnabled", + "keyLocation", + "keyPath", + "keyStatuses", + "keySystem", + "keyText", + "keyUsage", + "keyboard", + "keys", + "keytype", + "kind", + "knee", + "label", + "labels", + "lang", + "language", + "languages", + "largeArcFlag", + "lastActivePanel", + "lastChild", + "lastElementChild", + "lastEventId", + "lastIndex", + "lastIndexOf", + "lastInputTime", + "lastMatch", + "lastMessageSubject", + "lastMessageType", + "lastModified", + "lastModifiedDate", + "lastPage", + "lastParen", + "lastState", + "lastStyleSheetSet", + "latitude", + "layerX", + "layerY", + "layoutFlow", + "layoutGrid", + "layoutGridChar", + "layoutGridLine", + "layoutGridMode", + "layoutGridType", + "lbound", + "left", + "leftContext", + "leftDegrees", + "leftMargin", + "leftProjectionMatrix", + "leftViewMatrix", + "length", + "lengthAdjust", + "lengthComputable", + "letter-spacing", + "letterSpacing", + "level", + "lighting-color", + "lightingColor", + "limitingConeAngle", + "line", + "line-break", + "line-height", + "lineAlign", + "lineBreak", + "lineCap", + "lineDashOffset", + "lineHeight", + "lineJoin", + "lineNumber", + "lineTo", + "lineWidth", + "linearAcceleration", + "linearRampToValueAtTime", + "linearVelocity", + "lineno", + "lines", + "link", + "linkColor", + "linkProgram", + "links", + "list", + "list-style", + "list-style-image", + "list-style-position", + "list-style-type", + "listStyle", + "listStyleImage", + "listStylePosition", + "listStyleType", + "listener", + "load", + "loadEventEnd", + "loadEventStart", + "loadTime", + "loadTimes", + "loaded", + "loading", + "localDescription", + "localName", + "localService", + "localStorage", + "locale", + "localeCompare", + "location", + "locationbar", + "lock", + "locked", + "lockedFile", + "locks", + "log", + "log10", + "log1p", + "log2", + "logicalXDPI", + "logicalYDPI", + "longDesc", + "longitude", + "lookupNamespaceURI", + "lookupPrefix", + "loop", + "loopEnd", + "loopStart", + "looping", + "low", + "lower", + "lowerBound", + "lowerOpen", + "lowsrc", + "m11", + "m12", + "m13", + "m14", + "m21", + "m22", + "m23", + "m24", + "m31", + "m32", + "m33", + "m34", + "m41", + "m42", + "m43", + "m44", + "makeXRCompatible", + "manifest", + "manufacturer", + "manufacturerName", + "map", + "mapping", + "margin", + "margin-block", + "margin-block-end", + "margin-block-start", + "margin-bottom", + "margin-inline", + "margin-inline-end", + "margin-inline-start", + "margin-left", + "margin-right", + "margin-top", + "marginBlock", + "marginBlockEnd", + "marginBlockStart", + "marginBottom", + "marginHeight", + "marginInline", + "marginInlineEnd", + "marginInlineStart", + "marginLeft", + "marginRight", + "marginTop", + "marginWidth", + "mark", + "markTimeline", + "marker", + "marker-end", + "marker-mid", + "marker-offset", + "marker-start", + "markerEnd", + "markerHeight", + "markerMid", + "markerOffset", + "markerStart", + "markerUnits", + "markerWidth", + "marks", + "mask", + "mask-clip", + "mask-composite", + "mask-image", + "mask-mode", + "mask-origin", + "mask-position", + "mask-position-x", + "mask-position-y", + "mask-repeat", + "mask-size", + "mask-type", + "maskClip", + "maskComposite", + "maskContentUnits", + "maskImage", + "maskMode", + "maskOrigin", + "maskPosition", + "maskPositionX", + "maskPositionY", + "maskRepeat", + "maskSize", + "maskType", + "maskUnits", + "match", + "matchAll", + "matchMedia", + "matchMedium", + "matches", + "matrix", + "matrixTransform", + "max", + "max-block-size", + "max-height", + "max-inline-size", + "max-width", + "maxActions", + "maxAlternatives", + "maxBlockSize", + "maxChannelCount", + "maxChannels", + "maxConnectionsPerServer", + "maxDecibels", + "maxDistance", + "maxHeight", + "maxInlineSize", + "maxLayers", + "maxLength", + "maxMessageSize", + "maxPacketLifeTime", + "maxRetransmits", + "maxTouchPoints", + "maxValue", + "maxWidth", + "maxZoom", + "maximize", + "maximumFractionDigits", + "measure", + "measureText", + "media", + "mediaCapabilities", + "mediaDevices", + "mediaElement", + "mediaGroup", + "mediaKeys", + "mediaSession", + "mediaStream", + "mediaText", + "meetOrSlice", + "memory", + "menubar", + "mergeAttributes", + "message", + "messageClass", + "messageHandlers", + "messageType", + "metaKey", + "metadata", + "method", + "methodDetails", + "methodName", + "mid", + "mimeType", + "mimeTypes", + "min", + "min-block-size", + "min-height", + "min-inline-size", + "min-width", + "minBlockSize", + "minDecibels", + "minHeight", + "minInlineSize", + "minLength", + "minValue", + "minWidth", + "minZoom", + "minimize", + "minimumFractionDigits", + "minimumIntegerDigits", + "minute", + "miterLimit", + "mix-blend-mode", + "mixBlendMode", + "mm", + "mode", + "modify", + "month", + "motion", + "motionOffset", + "motionPath", + "motionRotation", + "mount", + "move", + "moveBy", + "moveEnd", + "moveFirst", + "moveFocusDown", + "moveFocusLeft", + "moveFocusRight", + "moveFocusUp", + "moveNext", + "moveRow", + "moveStart", + "moveTo", + "moveToBookmark", + "moveToElementText", + "moveToPoint", + "movementX", + "movementY", + "mozAdd", + "mozAnimationStartTime", + "mozAnon", + "mozApps", + "mozAudioCaptured", + "mozAudioChannelType", + "mozAutoplayEnabled", + "mozCancelAnimationFrame", + "mozCancelFullScreen", + "mozCancelRequestAnimationFrame", + "mozCaptureStream", + "mozCaptureStreamUntilEnded", + "mozClearDataAt", + "mozContact", + "mozContacts", + "mozCreateFileHandle", + "mozCurrentTransform", + "mozCurrentTransformInverse", + "mozCursor", + "mozDash", + "mozDashOffset", + "mozDecodedFrames", + "mozExitPointerLock", + "mozFillRule", + "mozFragmentEnd", + "mozFrameDelay", + "mozFullScreen", + "mozFullScreenElement", + "mozFullScreenEnabled", + "mozGetAll", + "mozGetAllKeys", + "mozGetAsFile", + "mozGetDataAt", + "mozGetMetadata", + "mozGetUserMedia", + "mozHasAudio", + "mozHasItem", + "mozHidden", + "mozImageSmoothingEnabled", + "mozIndexedDB", + "mozInnerScreenX", + "mozInnerScreenY", + "mozInputSource", + "mozIsTextField", + "mozItem", + "mozItemCount", + "mozItems", + "mozLength", + "mozLockOrientation", + "mozMatchesSelector", + "mozMovementX", + "mozMovementY", + "mozOpaque", + "mozOrientation", + "mozPaintCount", + "mozPaintedFrames", + "mozParsedFrames", + "mozPay", + "mozPointerLockElement", + "mozPresentedFrames", + "mozPreservesPitch", + "mozPressure", + "mozPrintCallback", + "mozRTCIceCandidate", + "mozRTCPeerConnection", + "mozRTCSessionDescription", + "mozRemove", + "mozRequestAnimationFrame", + "mozRequestFullScreen", + "mozRequestPointerLock", + "mozSetDataAt", + "mozSetImageElement", + "mozSourceNode", + "mozSrcObject", + "mozSystem", + "mozTCPSocket", + "mozTextStyle", + "mozTypesAt", + "mozUnlockOrientation", + "mozUserCancelled", + "mozVisibilityState", + "ms", + "msAnimation", + "msAnimationDelay", + "msAnimationDirection", + "msAnimationDuration", + "msAnimationFillMode", + "msAnimationIterationCount", + "msAnimationName", + "msAnimationPlayState", + "msAnimationStartTime", + "msAnimationTimingFunction", + "msBackfaceVisibility", + "msBlockProgression", + "msCSSOMElementFloatMetrics", + "msCaching", + "msCachingEnabled", + "msCancelRequestAnimationFrame", + "msCapsLockWarningOff", + "msClearImmediate", + "msClose", + "msContentZoomChaining", + "msContentZoomFactor", + "msContentZoomLimit", + "msContentZoomLimitMax", + "msContentZoomLimitMin", + "msContentZoomSnap", + "msContentZoomSnapPoints", + "msContentZoomSnapType", + "msContentZooming", + "msConvertURL", + "msCrypto", + "msDoNotTrack", + "msElementsFromPoint", + "msElementsFromRect", + "msExitFullscreen", + "msExtendedCode", + "msFillRule", + "msFirstPaint", + "msFlex", + "msFlexAlign", + "msFlexDirection", + "msFlexFlow", + "msFlexItemAlign", + "msFlexLinePack", + "msFlexNegative", + "msFlexOrder", + "msFlexPack", + "msFlexPositive", + "msFlexPreferredSize", + "msFlexWrap", + "msFlowFrom", + "msFlowInto", + "msFontFeatureSettings", + "msFullscreenElement", + "msFullscreenEnabled", + "msGetInputContext", + "msGetRegionContent", + "msGetUntransformedBounds", + "msGraphicsTrustStatus", + "msGridColumn", + "msGridColumnAlign", + "msGridColumnSpan", + "msGridColumns", + "msGridRow", + "msGridRowAlign", + "msGridRowSpan", + "msGridRows", + "msHidden", + "msHighContrastAdjust", + "msHyphenateLimitChars", + "msHyphenateLimitLines", + "msHyphenateLimitZone", + "msHyphens", + "msImageSmoothingEnabled", + "msImeAlign", + "msIndexedDB", + "msInterpolationMode", + "msIsStaticHTML", + "msKeySystem", + "msKeys", + "msLaunchUri", + "msLockOrientation", + "msManipulationViewsEnabled", + "msMatchMedia", + "msMatchesSelector", + "msMaxTouchPoints", + "msOrientation", + "msOverflowStyle", + "msPerspective", + "msPerspectiveOrigin", + "msPlayToDisabled", + "msPlayToPreferredSourceUri", + "msPlayToPrimary", + "msPointerEnabled", + "msRegionOverflow", + "msReleasePointerCapture", + "msRequestAnimationFrame", + "msRequestFullscreen", + "msSaveBlob", + "msSaveOrOpenBlob", + "msScrollChaining", + "msScrollLimit", + "msScrollLimitXMax", + "msScrollLimitXMin", + "msScrollLimitYMax", + "msScrollLimitYMin", + "msScrollRails", + "msScrollSnapPointsX", + "msScrollSnapPointsY", + "msScrollSnapType", + "msScrollSnapX", + "msScrollSnapY", + "msScrollTranslation", + "msSetImmediate", + "msSetMediaKeys", + "msSetPointerCapture", + "msTextCombineHorizontal", + "msTextSizeAdjust", + "msToBlob", + "msTouchAction", + "msTouchSelect", + "msTraceAsyncCallbackCompleted", + "msTraceAsyncCallbackStarting", + "msTraceAsyncOperationCompleted", + "msTraceAsyncOperationStarting", + "msTransform", + "msTransformOrigin", + "msTransformStyle", + "msTransition", + "msTransitionDelay", + "msTransitionDuration", + "msTransitionProperty", + "msTransitionTimingFunction", + "msUnlockOrientation", + "msUpdateAsyncCallbackRelation", + "msUserSelect", + "msVisibilityState", + "msWrapFlow", + "msWrapMargin", + "msWrapThrough", + "msWriteProfilerMark", + "msZoom", + "msZoomTo", + "mt", + "mul", + "multiEntry", + "multiSelectionObj", + "multiline", + "multiple", + "multiply", + "multiplySelf", + "mutableFile", + "muted", + "n", + "name", + "nameProp", + "namedItem", + "namedRecordset", + "names", + "namespaceURI", + "namespaces", + "naturalHeight", + "naturalWidth", + "navigate", + "navigation", + "navigationMode", + "navigationPreload", + "navigationStart", + "navigationType", + "navigator", + "near", + "nearestViewportElement", + "negative", + "negotiated", + "netscape", + "networkState", + "newScale", + "newTranslate", + "newURL", + "newValue", + "newValueSpecifiedUnits", + "newVersion", + "newhome", + "next", + "nextElementSibling", + "nextHopProtocol", + "nextNode", + "nextPage", + "nextSibling", + "nickname", + "noHref", + "noModule", + "noResize", + "noShade", + "noValidate", + "noWrap", + "node", + "nodeName", + "nodeType", + "nodeValue", + "nonce", + "normalize", + "normalizedPathSegList", + "notationName", + "notations", + "note", + "noteGrainOn", + "noteOff", + "noteOn", + "notify", + "now", + "npnNegotiatedProtocol", + "numOctaves", + "number", + "numberOfChannels", + "numberOfInputs", + "numberOfItems", + "numberOfOutputs", + "numberValue", + "numberingSystem", + "numeric", + "oMatchesSelector", + "object", + "object-fit", + "object-position", + "objectFit", + "objectPosition", + "objectStore", + "objectStoreNames", + "observe", + "observedAttributes", + "of", + "offscreenBuffering", + "offset", + "offset-anchor", + "offset-block-end", + "offset-block-start", + "offset-distance", + "offset-inline-end", + "offset-inline-start", + "offset-path", + "offset-rotate", + "offsetAnchor", + "offsetBlockEnd", + "offsetBlockStart", + "offsetDistance", + "offsetHeight", + "offsetInlineEnd", + "offsetInlineStart", + "offsetLeft", + "offsetNode", + "offsetParent", + "offsetPath", + "offsetRotate", + "offsetTop", + "offsetWidth", + "offsetX", + "offsetY", + "ok", + "oldURL", + "oldValue", + "oldVersion", + "olderShadowRoot", + "onDownloadProgress", + "onInstallStageChanged", + "onLine", + "onabort", + "onabsolutedeviceorientation", + "onactivate", + "onactive", + "onaddsourcebuffer", + "onaddstream", + "onaddtrack", + "onafterprint", + "onafterscriptexecute", + "onafterupdate", + "onanimationcancel", + "onanimationend", + "onanimationiteration", + "onanimationstart", + "onappinstalled", + "onaudioend", + "onaudioprocess", + "onaudiostart", + "onautocomplete", + "onautocompleteerror", + "onauxclick", + "onbeforeactivate", + "onbeforecopy", + "onbeforecut", + "onbeforedeactivate", + "onbeforeeditfocus", + "onbeforeinput", + "onbeforeinstallprompt", + "onbeforeload", + "onbeforepaste", + "onbeforeprint", + "onbeforescriptexecute", + "onbeforeunload", + "onbeforeupdate", + "onbeforexrselect", + "onbegin", + "onblocked", + "onblur", + "onbounce", + "onboundary", + "onbufferedamountlow", + "oncached", + "oncancel", + "oncandidatewindowhide", + "oncandidatewindowshow", + "oncandidatewindowupdate", + "oncanplay", + "oncanplaythrough", + "once", + "oncellchange", + "onchange", + "oncharacteristicvaluechanged", + "onchargingchange", + "onchargingtimechange", + "onchecking", + "onclick", + "onclose", + "onclosing", + "oncompassneedscalibration", + "oncomplete", + "onconnect", + "onconnecting", + "onconnectionavailable", + "onconnectionstatechange", + "oncontactchange", + "oncontextmenu", + "oncontrollerchange", + "oncontrolselect", + "oncopy", + "oncuechange", + "oncut", + "ondataavailable", + "ondatachannel", + "ondatasetchanged", + "ondatasetcomplete", + "ondblclick", + "ondeactivate", + "ondevicechange", + "ondevicelight", + "ondevicemotion", + "ondeviceorientation", + "ondeviceorientationabsolute", + "ondeviceproximity", + "ondischargingtimechange", + "ondisconnect", + "ondisplay", + "ondownloading", + "ondrag", + "ondragend", + "ondragenter", + "ondragexit", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onencrypted", + "onend", + "onended", + "onenter", + "onenterpictureinpicture", + "onerror", + "onerrorupdate", + "onexit", + "onfilterchange", + "onfinish", + "onfocus", + "onfocusin", + "onfocusout", + "onformdata", + "onfreeze", + "onfullscreenchange", + "onfullscreenerror", + "ongatheringstatechange", + "ongattserverdisconnected", + "ongesturechange", + "ongestureend", + "ongesturestart", + "ongotpointercapture", + "onhashchange", + "onhelp", + "onicecandidate", + "onicecandidateerror", + "oniceconnectionstatechange", + "onicegatheringstatechange", + "oninactive", + "oninput", + "oninputsourceschange", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeystatuseschange", + "onkeyup", + "onlanguagechange", + "onlayoutcomplete", + "onleavepictureinpicture", + "onlevelchange", + "onload", + "onloadT", + "onloadeddata", + "onloadedmetadata", + "onloadend", + "onloading", + "onloadingdone", + "onloadingerror", + "onloadstart", + "onlosecapture", + "onlostpointercapture", + "only", + "onmark", + "onmessage", + "onmessageerror", + "onmidimessage", + "onmousedown", + "onmouseenter", + "onmouseleave", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onmove", + "onmoveend", + "onmovestart", + "onmozfullscreenchange", + "onmozfullscreenerror", + "onmozorientationchange", + "onmozpointerlockchange", + "onmozpointerlockerror", + "onmscontentzoom", + "onmsfullscreenchange", + "onmsfullscreenerror", + "onmsgesturechange", + "onmsgesturedoubletap", + "onmsgestureend", + "onmsgesturehold", + "onmsgesturestart", + "onmsgesturetap", + "onmsgotpointercapture", + "onmsinertiastart", + "onmslostpointercapture", + "onmsmanipulationstatechanged", + "onmsneedkey", + "onmsorientationchange", + "onmspointercancel", + "onmspointerdown", + "onmspointerenter", + "onmspointerhover", + "onmspointerleave", + "onmspointermove", + "onmspointerout", + "onmspointerover", + "onmspointerup", + "onmssitemodejumplistitemremoved", + "onmsthumbnailclick", + "onmute", + "onnegotiationneeded", + "onnomatch", + "onnoupdate", + "onobsolete", + "onoffline", + "ononline", + "onopen", + "onorientationchange", + "onoverconstrained", + "onpage", + "onpagechange", + "onpagehide", + "onpageshow", + "onpaste", + "onpause", + "onpayerdetailchange", + "onpaymentmethodchange", + "onplay", + "onplaying", + "onpluginstreamstart", + "onpointercancel", + "onpointerdown", + "onpointerenter", + "onpointerleave", + "onpointerlockchange", + "onpointerlockerror", + "onpointermove", + "onpointerout", + "onpointerover", + "onpointerrawupdate", + "onpointerup", + "onpopstate", + "onprocessorerror", + "onprogress", + "onpropertychange", + "onratechange", + "onreading", + "onreadystatechange", + "onrejectionhandled", + "onrelease", + "onremove", + "onremovesourcebuffer", + "onremovestream", + "onremovetrack", + "onrepeat", + "onreset", + "onresize", + "onresizeend", + "onresizestart", + "onresourcetimingbufferfull", + "onresult", + "onresume", + "onrowenter", + "onrowexit", + "onrowsdelete", + "onrowsinserted", + "onscroll", + "onsearch", + "onsecuritypolicyviolation", + "onseeked", + "onseeking", + "onselect", + "onselectedcandidatepairchange", + "onselectend", + "onselectionchange", + "onselectstart", + "onshippingaddresschange", + "onshippingoptionchange", + "onshow", + "onsignalingstatechange", + "onsoundend", + "onsoundstart", + "onsourceclose", + "onsourceclosed", + "onsourceended", + "onsourceopen", + "onspeechend", + "onspeechstart", + "onsqueeze", + "onsqueezeend", + "onsqueezestart", + "onstalled", + "onstart", + "onstatechange", + "onstop", + "onstorage", + "onstoragecommit", + "onsubmit", + "onsuccess", + "onsuspend", + "onterminate", + "ontextinput", + "ontimeout", + "ontimeupdate", + "ontoggle", + "ontonechange", + "ontouchcancel", + "ontouchend", + "ontouchmove", + "ontouchstart", + "ontrack", + "ontransitioncancel", + "ontransitionend", + "ontransitionrun", + "ontransitionstart", + "onunhandledrejection", + "onunload", + "onunmute", + "onupdate", + "onupdateend", + "onupdatefound", + "onupdateready", + "onupdatestart", + "onupgradeneeded", + "onuserproximity", + "onversionchange", + "onvisibilitychange", + "onvoiceschanged", + "onvolumechange", + "onvrdisplayactivate", + "onvrdisplayconnect", + "onvrdisplaydeactivate", + "onvrdisplaydisconnect", + "onvrdisplaypresentchange", + "onwaiting", + "onwaitingforkey", + "onwarning", + "onwebkitanimationend", + "onwebkitanimationiteration", + "onwebkitanimationstart", + "onwebkitcurrentplaybacktargetiswirelesschanged", + "onwebkitfullscreenchange", + "onwebkitfullscreenerror", + "onwebkitkeyadded", + "onwebkitkeyerror", + "onwebkitkeymessage", + "onwebkitmouseforcechanged", + "onwebkitmouseforcedown", + "onwebkitmouseforceup", + "onwebkitmouseforcewillbegin", + "onwebkitneedkey", + "onwebkitorientationchange", + "onwebkitplaybacktargetavailabilitychanged", + "onwebkitpointerlockchange", + "onwebkitpointerlockerror", + "onwebkitresourcetimingbufferfull", + "onwebkittransitionend", + "onwheel", + "onzoom", + "opacity", + "open", + "openCursor", + "openDatabase", + "openKeyCursor", + "opened", + "opener", + "opera", + "operationType", + "operator", + "opr", + "opsProfile", + "optimum", + "options", + "or", + "order", + "orderX", + "orderY", + "ordered", + "org", + "organization", + "orient", + "orientAngle", + "orientType", + "orientation", + "orientationX", + "orientationY", + "orientationZ", + "origin", + "originalPolicy", + "originalTarget", + "orphans", + "oscpu", + "outcome", + "outerHTML", + "outerHeight", + "outerText", + "outerWidth", + "outline", + "outline-color", + "outline-offset", + "outline-style", + "outline-width", + "outlineColor", + "outlineOffset", + "outlineStyle", + "outlineWidth", + "outputBuffer", + "outputLatency", + "outputs", + "overflow", + "overflow-anchor", + "overflow-block", + "overflow-inline", + "overflow-wrap", + "overflow-x", + "overflow-y", + "overflowAnchor", + "overflowBlock", + "overflowInline", + "overflowWrap", + "overflowX", + "overflowY", + "overrideMimeType", + "oversample", + "overscroll-behavior", + "overscroll-behavior-block", + "overscroll-behavior-inline", + "overscroll-behavior-x", + "overscroll-behavior-y", + "overscrollBehavior", + "overscrollBehaviorBlock", + "overscrollBehaviorInline", + "overscrollBehaviorX", + "overscrollBehaviorY", + "ownKeys", + "ownerDocument", + "ownerElement", + "ownerNode", + "ownerRule", + "ownerSVGElement", + "owningElement", + "p1", + "p2", + "p3", + "p4", + "packetSize", + "packets", + "pad", + "padEnd", + "padStart", + "padding", + "padding-block", + "padding-block-end", + "padding-block-start", + "padding-bottom", + "padding-inline", + "padding-inline-end", + "padding-inline-start", + "padding-left", + "padding-right", + "padding-top", + "paddingBlock", + "paddingBlockEnd", + "paddingBlockStart", + "paddingBottom", + "paddingInline", + "paddingInlineEnd", + "paddingInlineStart", + "paddingLeft", + "paddingRight", + "paddingTop", + "page", + "page-break-after", + "page-break-before", + "page-break-inside", + "pageBreakAfter", + "pageBreakBefore", + "pageBreakInside", + "pageCount", + "pageLeft", + "pageT", + "pageTop", + "pageX", + "pageXOffset", + "pageY", + "pageYOffset", + "pages", + "paint-order", + "paintOrder", + "paintRequests", + "paintType", + "paintWorklet", + "palette", + "pan", + "panningModel", + "parameters", + "parent", + "parentElement", + "parentNode", + "parentRule", + "parentStyleSheet", + "parentTextEdit", + "parentWindow", + "parse", + "parseAll", + "parseFloat", + "parseFromString", + "parseInt", + "part", + "participants", + "passive", + "password", + "pasteHTML", + "path", + "pathLength", + "pathSegList", + "pathSegType", + "pathSegTypeAsLetter", + "pathname", + "pattern", + "patternContentUnits", + "patternMismatch", + "patternTransform", + "patternUnits", + "pause", + "pauseAnimations", + "pauseOnExit", + "pauseTransformFeedback", + "paused", + "payerEmail", + "payerName", + "payerPhone", + "paymentManager", + "pc", + "peerIdentity", + "pending", + "pendingLocalDescription", + "pendingRemoteDescription", + "percent", + "performance", + "periodicSync", + "permission", + "permissionState", + "permissions", + "persist", + "persisted", + "personalbar", + "perspective", + "perspective-origin", + "perspectiveOrigin", + "perspectiveOriginX", + "perspectiveOriginY", + "phone", + "phoneticFamilyName", + "phoneticGivenName", + "photo", + "pictureInPictureElement", + "pictureInPictureEnabled", + "pictureInPictureWindow", + "ping", + "pipeThrough", + "pipeTo", + "pitch", + "pixelBottom", + "pixelDepth", + "pixelHeight", + "pixelLeft", + "pixelRight", + "pixelStorei", + "pixelTop", + "pixelUnitToMillimeterX", + "pixelUnitToMillimeterY", + "pixelWidth", + "place-content", + "place-items", + "place-self", + "placeContent", + "placeItems", + "placeSelf", + "placeholder", + "platform", + "platforms", + "play", + "playEffect", + "playState", + "playbackRate", + "playbackState", + "playbackTime", + "played", + "playoutDelayHint", + "playsInline", + "plugins", + "pluginspage", + "pname", + "pointer-events", + "pointerBeforeReferenceNode", + "pointerEnabled", + "pointerEvents", + "pointerId", + "pointerLockElement", + "pointerType", + "points", + "pointsAtX", + "pointsAtY", + "pointsAtZ", + "polygonOffset", + "pop", + "populateMatrix", + "popupWindowFeatures", + "popupWindowName", + "popupWindowURI", + "port", + "port1", + "port2", + "ports", + "posBottom", + "posHeight", + "posLeft", + "posRight", + "posTop", + "posWidth", + "pose", + "position", + "positionAlign", + "positionX", + "positionY", + "positionZ", + "postError", + "postMessage", + "postalCode", + "poster", + "pow", + "powerEfficient", + "powerOff", + "preMultiplySelf", + "precision", + "preferredStyleSheetSet", + "preferredStylesheetSet", + "prefix", + "preload", + "prepend", + "presentation", + "preserveAlpha", + "preserveAspectRatio", + "preserveAspectRatioString", + "pressed", + "pressure", + "prevValue", + "preventDefault", + "preventExtensions", + "preventSilentAccess", + "previousElementSibling", + "previousNode", + "previousPage", + "previousRect", + "previousScale", + "previousSibling", + "previousTranslate", + "primaryKey", + "primitiveType", + "primitiveUnits", + "principals", + "print", + "priority", + "privateKey", + "probablySupportsContext", + "process", + "processIceMessage", + "processingEnd", + "processingStart", + "product", + "productId", + "productName", + "productSub", + "profile", + "profileEnd", + "profiles", + "projectionMatrix", + "promise", + "prompt", + "properties", + "propertyIsEnumerable", + "propertyName", + "protocol", + "protocolLong", + "prototype", + "provider", + "pseudoClass", + "pseudoElement", + "pt", + "publicId", + "publicKey", + "published", + "pulse", + "push", + "pushManager", + "pushNotification", + "pushState", + "put", + "putImageData", + "px", + "quadraticCurveTo", + "qualifier", + "quaternion", + "query", + "queryCommandEnabled", + "queryCommandIndeterm", + "queryCommandState", + "queryCommandSupported", + "queryCommandText", + "queryCommandValue", + "querySelector", + "querySelectorAll", + "queryUsageAndQuota", + "queueMicrotask", + "quote", + "quotes", + "r", + "r1", + "r2", + "race", + "rad", + "radiogroup", + "radiusX", + "radiusY", + "random", + "range", + "rangeCount", + "rangeMax", + "rangeMin", + "rangeOffset", + "rangeOverflow", + "rangeParent", + "rangeUnderflow", + "rate", + "ratio", + "raw", + "rawId", + "read", + "readAsArrayBuffer", + "readAsBinaryString", + "readAsBlob", + "readAsDataURL", + "readAsText", + "readBuffer", + "readEntries", + "readOnly", + "readPixels", + "readReportRequested", + "readText", + "readTransaction", + "readValue", + "readable", + "ready", + "readyState", + "reason", + "reboot", + "receivedAlert", + "receivedTime", + "receiver", + "receivers", + "recipient", + "reconnect", + "record", + "recordEnd", + "recordNumber", + "recordsAvailable", + "recordset", + "rect", + "red", + "redEyeReduction", + "redirect", + "redirectCount", + "redirectEnd", + "redirectStart", + "redirected", + "reduce", + "reduceRight", + "reduction", + "refDistance", + "refX", + "refY", + "referenceNode", + "referenceSpace", + "referrer", + "referrerPolicy", + "refresh", + "region", + "regionAnchorX", + "regionAnchorY", + "regionId", + "regions", + "register", + "registerContentHandler", + "registerElement", + "registerProperty", + "registerProtocolHandler", + "reject", + "rel", + "relList", + "relatedAddress", + "relatedNode", + "relatedPort", + "relatedTarget", + "release", + "releaseCapture", + "releaseEvents", + "releaseInterface", + "releaseLock", + "releasePointerCapture", + "releaseShaderCompiler", + "reliable", + "reliableWrite", + "reload", + "rem", + "remainingSpace", + "remote", + "remoteDescription", + "remove", + "removeAllRanges", + "removeAttribute", + "removeAttributeNS", + "removeAttributeNode", + "removeBehavior", + "removeChild", + "removeCue", + "removeEventListener", + "removeFilter", + "removeImport", + "removeItem", + "removeListener", + "removeNamedItem", + "removeNamedItemNS", + "removeNode", + "removeParameter", + "removeProperty", + "removeRange", + "removeRegion", + "removeRule", + "removeRules", + "removeSiteSpecificTrackingException", + "removeSourceBuffer", + "removeStream", + "removeTrack", + "removeVariable", + "removeWakeLockListener", + "removeWebWideTrackingException", + "removed", + "removedNodes", + "renderHeight", + "renderState", + "renderTime", + "renderWidth", + "renderbufferStorage", + "renderbufferStorageMultisample", + "renderedBuffer", + "renderingMode", + "renotify", + "repeat", + "replace", + "replaceAdjacentText", + "replaceAll", + "replaceChild", + "replaceChildren", + "replaceData", + "replaceId", + "replaceItem", + "replaceNode", + "replaceState", + "replaceSync", + "replaceTrack", + "replaceWholeText", + "replaceWith", + "reportValidity", + "request", + "requestAnimationFrame", + "requestAutocomplete", + "requestData", + "requestDevice", + "requestFrame", + "requestFullscreen", + "requestHitTestSource", + "requestHitTestSourceForTransientInput", + "requestId", + "requestIdleCallback", + "requestMIDIAccess", + "requestMediaKeySystemAccess", + "requestPermission", + "requestPictureInPicture", + "requestPointerLock", + "requestPresent", + "requestQuota", + "requestReferenceSpace", + "requestSession", + "requestStart", + "requestStorageAccess", + "requestSubmit", + "requestTime", + "requestVideoFrameCallback", + "requestedLocale", + "requestingWindow", + "requireInteraction", + "required", + "requiredExtensions", + "requiredFeatures", + "reset", + "resetPose", + "resetTransform", + "resize", + "resizeBy", + "resizeTo", + "resolve", + "resolved", + "resolvedOptions", + "resource-history", + "resourcesFramesExpanded", + "response", + "responseBody", + "responseEnd", + "responseReady", + "responseStart", + "responseText", + "responseType", + "responseURL", + "responseXML", + "restartIce", + "restore", + "result", + "resultIndex", + "resultType", + "results", + "resume", + "resumeTransformFeedback", + "retry", + "returnValue", + "rev", + "reverse", + "reversed", + "revocable", + "revokeObjectURL", + "rgbColor", + "right", + "rightContext", + "rightDegrees", + "rightMargin", + "rightProjectionMatrix", + "rightViewMatrix", + "role", + "rolloffFactor", + "root", + "rootBounds", + "rootElement", + "rootMargin", + "rotate", + "rotateAxisAngle", + "rotateAxisAngleSelf", + "rotateFromVector", + "rotateFromVectorSelf", + "rotateSelf", + "rotation", + "rotationAngle", + "rotationRate", + "round", + "row-gap", + "rowGap", + "rowIndex", + "rowSpan", + "rows", + "rowsAffected", + "rtcpTransport", + "rtt", + "ruby-align", + "ruby-position", + "rubyAlign", + "rubyOverhang", + "rubyPosition", + "rules", + "runningState", + "runtime", + "runtimeStyle", + "rx", + "ry", + "s", + "safari", + "sample", + "sampleCoverage", + "sampleRate", + "samplerParameterf", + "samplerParameteri", + "sandbox", + "save", + "saveData", + "scale", + "scale3d", + "scale3dSelf", + "scaleNonUniform", + "scaleNonUniformSelf", + "scaleSelf", + "scheme", + "scissor", + "scope", + "scopeName", + "scoped", + "screen", + "screenBrightness", + "screenEnabled", + "screenLeft", + "screenPixelToMillimeterX", + "screenPixelToMillimeterY", + "screenTop", + "screenX", + "screenY", + "script", + "scriptURL", + "scripts", + "scroll", + "scroll-behavior", + "scroll-margin", + "scroll-margin-block", + "scroll-margin-block-end", + "scroll-margin-block-start", + "scroll-margin-bottom", + "scroll-margin-inline", + "scroll-margin-inline-end", + "scroll-margin-inline-start", + "scroll-margin-left", + "scroll-margin-right", + "scroll-margin-top", + "scroll-padding", + "scroll-padding-block", + "scroll-padding-block-end", + "scroll-padding-block-start", + "scroll-padding-bottom", + "scroll-padding-inline", + "scroll-padding-inline-end", + "scroll-padding-inline-start", + "scroll-padding-left", + "scroll-padding-right", + "scroll-padding-top", + "scroll-snap-align", + "scroll-snap-coordinate", + "scroll-snap-destination", + "scroll-snap-points-x", + "scroll-snap-points-y", + "scroll-snap-type", + "scroll-snap-type-x", + "scroll-snap-type-y", + "scrollAmount", + "scrollBehavior", + "scrollBy", + "scrollByLines", + "scrollByPages", + "scrollDelay", + "scrollHeight", + "scrollIntoView", + "scrollIntoViewIfNeeded", + "scrollLeft", + "scrollLeftMax", + "scrollMargin", + "scrollMarginBlock", + "scrollMarginBlockEnd", + "scrollMarginBlockStart", + "scrollMarginBottom", + "scrollMarginInline", + "scrollMarginInlineEnd", + "scrollMarginInlineStart", + "scrollMarginLeft", + "scrollMarginRight", + "scrollMarginTop", + "scrollMaxX", + "scrollMaxY", + "scrollPadding", + "scrollPaddingBlock", + "scrollPaddingBlockEnd", + "scrollPaddingBlockStart", + "scrollPaddingBottom", + "scrollPaddingInline", + "scrollPaddingInlineEnd", + "scrollPaddingInlineStart", + "scrollPaddingLeft", + "scrollPaddingRight", + "scrollPaddingTop", + "scrollRestoration", + "scrollSnapAlign", + "scrollSnapCoordinate", + "scrollSnapDestination", + "scrollSnapMargin", + "scrollSnapMarginBottom", + "scrollSnapMarginLeft", + "scrollSnapMarginRight", + "scrollSnapMarginTop", + "scrollSnapPointsX", + "scrollSnapPointsY", + "scrollSnapStop", + "scrollSnapType", + "scrollSnapTypeX", + "scrollSnapTypeY", + "scrollTo", + "scrollTop", + "scrollTopMax", + "scrollWidth", + "scrollX", + "scrollY", + "scrollbar-color", + "scrollbar-width", + "scrollbar3dLightColor", + "scrollbarArrowColor", + "scrollbarBaseColor", + "scrollbarColor", + "scrollbarDarkShadowColor", + "scrollbarFaceColor", + "scrollbarHighlightColor", + "scrollbarShadowColor", + "scrollbarTrackColor", + "scrollbarWidth", + "scrollbars", + "scrolling", + "scrollingElement", + "sctp", + "sctpCauseCode", + "sdp", + "sdpLineNumber", + "sdpMLineIndex", + "sdpMid", + "seal", + "search", + "searchBox", + "searchBoxJavaBridge_", + "searchParams", + "second", + "sectionRowIndex", + "secureConnectionStart", + "security", + "seed", + "seekToNextFrame", + "seekable", + "seeking", + "select", + "selectAllChildren", + "selectAlternateInterface", + "selectConfiguration", + "selectNode", + "selectNodeContents", + "selectNodes", + "selectSingleNode", + "selectSubString", + "selected", + "selectedIndex", + "selectedOption", + "selectedOptions", + "selectedStyleSheetSet", + "selectedStylesheetSet", + "selection", + "selectionDirection", + "selectionEnd", + "selectionStart", + "selector", + "selectorText", + "self", + "send", + "sendAsBinary", + "sendBeacon", + "sendMessage", + "sender", + "sensitivity", + "sentAlert", + "sentTimestamp", + "separator", + "serialNumber", + "serializeToString", + "serverTiming", + "service", + "serviceWorker", + "session", + "sessionId", + "sessionStorage", + "set", + "setActionHandler", + "setActive", + "setAlpha", + "setAppBadge", + "setAttribute", + "setAttributeNS", + "setAttributeNode", + "setAttributeNodeNS", + "setBaseAndExtent", + "setBigInt64", + "setBigUint64", + "setBingCurrentSearchDefault", + "setCapture", + "setCodecPreferences", + "setColor", + "setCompositeOperation", + "setConfiguration", + "setCurrentTime", + "setCustomValidity", + "setData", + "setDate", + "setDirection", + "setDragImage", + "setEnd", + "setEndAfter", + "setEndBefore", + "setEndPoint", + "setFillColor", + "setFilterRes", + "setFloat32", + "setFloat64", + "setFloatValue", + "setFormValue", + "setFullYear", + "setHeaderValue", + "setHours", + "setIdentityProvider", + "setImmediate", + "setInt16", + "setInt32", + "setInt8", + "setInterval", + "setItem", + "setKeyframes", + "setLineCap", + "setLineDash", + "setLineJoin", + "setLineWidth", + "setLiveSeekableRange", + "setLocalDescription", + "setMatrix", + "setMatrixValue", + "setMediaKeys", + "setMilliseconds", + "setMinutes", + "setMiterLimit", + "setMonth", + "setNamedItem", + "setNamedItemNS", + "setNonUserCodeExceptions", + "setOrientToAngle", + "setOrientToAuto", + "setOrientation", + "setOverrideHistoryNavigationMode", + "setPaint", + "setParameter", + "setParameters", + "setPeriodicWave", + "setPointerCapture", + "setPosition", + "setPositionState", + "setPreference", + "setProperty", + "setPrototypeOf", + "setRGBColor", + "setRGBColorICCColor", + "setRadius", + "setRangeText", + "setRemoteDescription", + "setRequestHeader", + "setResizable", + "setResourceTimingBufferSize", + "setRotate", + "setScale", + "setSeconds", + "setSelectionRange", + "setServerCertificate", + "setShadow", + "setSinkId", + "setSkewX", + "setSkewY", + "setStart", + "setStartAfter", + "setStartBefore", + "setStdDeviation", + "setStreams", + "setStringValue", + "setStrokeColor", + "setSuggestResult", + "setTargetAtTime", + "setTargetValueAtTime", + "setTime", + "setTimeout", + "setTransform", + "setTranslate", + "setUTCDate", + "setUTCFullYear", + "setUTCHours", + "setUTCMilliseconds", + "setUTCMinutes", + "setUTCMonth", + "setUTCSeconds", + "setUint16", + "setUint32", + "setUint8", + "setUri", + "setValidity", + "setValueAtTime", + "setValueCurveAtTime", + "setVariable", + "setVelocity", + "setVersion", + "setYear", + "settingName", + "settingValue", + "sex", + "shaderSource", + "shadowBlur", + "shadowColor", + "shadowOffsetX", + "shadowOffsetY", + "shadowRoot", + "shape", + "shape-image-threshold", + "shape-margin", + "shape-outside", + "shape-rendering", + "shapeImageThreshold", + "shapeMargin", + "shapeOutside", + "shapeRendering", + "sheet", + "shift", + "shiftKey", + "shiftLeft", + "shippingAddress", + "shippingOption", + "shippingType", + "show", + "showHelp", + "showModal", + "showModalDialog", + "showModelessDialog", + "showNotification", + "sidebar", + "sign", + "signal", + "signalingState", + "signature", + "silent", + "sin", + "singleNodeValue", + "sinh", + "sinkId", + "sittingToStandingTransform", + "size", + "sizeToContent", + "sizeX", + "sizeZ", + "sizes", + "skewX", + "skewXSelf", + "skewY", + "skewYSelf", + "slice", + "slope", + "slot", + "small", + "smil", + "smooth", + "smoothingTimeConstant", + "snapToLines", + "snapshotItem", + "snapshotLength", + "some", + "sort", + "sortingCode", + "source", + "sourceBuffer", + "sourceBuffers", + "sourceCapabilities", + "sourceFile", + "sourceIndex", + "sourceURL", + "sources", + "spacing", + "span", + "speak", + "speakAs", + "speaking", + "species", + "specified", + "specularConstant", + "specularExponent", + "speechSynthesis", + "speed", + "speedOfSound", + "spellcheck", + "splice", + "split", + "splitText", + "spreadMethod", + "sqrt", + "src", + "srcElement", + "srcFilter", + "srcObject", + "srcUrn", + "srcdoc", + "srclang", + "srcset", + "stack", + "stackTraceLimit", + "stacktrace", + "stageParameters", + "standalone", + "standby", + "start", + "startContainer", + "startE", + "startIce", + "startLoadTime", + "startMessages", + "startNotifications", + "startOffset", + "startRendering", + "startSoftwareUpdate", + "startTime", + "startsWith", + "state", + "status", + "statusCode", + "statusMessage", + "statusText", + "statusbar", + "stdDeviationX", + "stdDeviationY", + "stencilFunc", + "stencilFuncSeparate", + "stencilMask", + "stencilMaskSeparate", + "stencilOp", + "stencilOpSeparate", + "step", + "stepDown", + "stepMismatch", + "stepUp", + "sticky", + "stitchTiles", + "stop", + "stop-color", + "stop-opacity", + "stopColor", + "stopImmediatePropagation", + "stopNotifications", + "stopOpacity", + "stopPropagation", + "stopped", + "storage", + "storageArea", + "storageName", + "storageStatus", + "store", + "storeSiteSpecificTrackingException", + "storeWebWideTrackingException", + "stpVersion", + "stream", + "streams", + "strength", + "stretch", + "strike", + "stringValue", + "stringify", + "stroke", + "stroke-dasharray", + "stroke-dashoffset", + "stroke-linecap", + "stroke-linejoin", + "stroke-miterlimit", + "stroke-opacity", + "stroke-width", + "strokeColor", + "strokeDasharray", + "strokeDashoffset", + "strokeLinecap", + "strokeLinejoin", + "strokeMiterlimit", + "strokeOpacity", + "strokeRect", + "strokeStyle", + "strokeText", + "strokeWidth", + "style", + "styleFloat", + "styleMap", + "styleMedia", + "styleSheet", + "styleSheetSets", + "styleSheets", + "sub", + "subarray", + "subject", + "submit", + "submitFrame", + "submitter", + "subscribe", + "substr", + "substring", + "substringData", + "subtle", + "subtree", + "suffix", + "suffixes", + "summary", + "sup", + "supported", + "supportedContentEncodings", + "supportedEntryTypes", + "supportedLocalesOf", + "supports", + "supportsSession", + "surfaceScale", + "surroundContents", + "suspend", + "suspendRedraw", + "swapCache", + "swapNode", + "sweepFlag", + "symbols", + "sync", + "sysexEnabled", + "system", + "systemCode", + "systemId", + "systemLanguage", + "systemXDPI", + "systemYDPI", + "tBodies", + "tFoot", + "tHead", + "tabIndex", + "tabSize", + "table", + "table-layout", + "tableLayout", + "tableValues", + "tag", + "tagName", + "tagUrn", + "tags", + "taintEnabled", + "takeHeapSnapshot", + "takePhoto", + "takeRecords", + "tan", + "tangentialPressure", + "tanh", + "target", + "targetElement", + "targetRayMode", + "targetRaySpace", + "targetTouches", + "targetX", + "targetY", + "tcpType", + "tee", + "tel", + "terminate", + "test", + "texImage2D", + "texImage3D", + "texParameterf", + "texParameteri", + "texStorage2D", + "texStorage3D", + "texSubImage2D", + "texSubImage3D", + "text", + "text-align", + "text-align-last", + "text-anchor", + "text-combine-upright", + "text-decoration", + "text-decoration-color", + "text-decoration-line", + "text-decoration-skip-ink", + "text-decoration-style", + "text-decoration-thickness", + "text-emphasis", + "text-emphasis-color", + "text-emphasis-position", + "text-emphasis-style", + "text-indent", + "text-justify", + "text-orientation", + "text-overflow", + "text-rendering", + "text-shadow", + "text-transform", + "text-underline-offset", + "text-underline-position", + "text/pdf", + "textAlign", + "textAlignLast", + "textAnchor", + "textAutospace", + "textBaseline", + "textCombineUpright", + "textContent", + "textDecoration", + "textDecorationBlink", + "textDecorationColor", + "textDecorationLine", + "textDecorationLineThrough", + "textDecorationNone", + "textDecorationOverline", + "textDecorationSkipInk", + "textDecorationStyle", + "textDecorationThickness", + "textDecorationUnderline", + "textEmphasis", + "textEmphasisColor", + "textEmphasisPosition", + "textEmphasisStyle", + "textIndent", + "textJustify", + "textJustifyTrim", + "textKashida", + "textKashidaSpace", + "textLength", + "textOrientation", + "textOverflow", + "textRendering", + "textShadow", + "textSizeAdjust", + "textTracks", + "textTransform", + "textUnderlineOffset", + "textUnderlinePosition", + "then", + "threadId", + "threshold", + "thresholds", + "tiltX", + "tiltY", + "time", + "timeEnd", + "timeLog", + "timeOrigin", + "timeRemaining", + "timeStamp", + "timeZone", + "timeZoneName", + "timecode", + "timeline", + "timelineEnd", + "timelineTime", + "timeout", + "timestamp", + "timestampOffset", + "timing", + "title", + "to", + "toArray", + "toBlob", + "toDataURL", + "toDateString", + "toElement", + "toExponential", + "toFixed", + "toFloat32Array", + "toFloat64Array", + "toGMTString", + "toISOString", + "toJSON", + "toLocaleDateString", + "toLocaleFormat", + "toLocaleLowerCase", + "toLocaleString", + "toLocaleTimeString", + "toLocaleUpperCase", + "toLowerCase", + "toMatrix", + "toMethod", + "toPrecision", + "toPrimitive", + "toSdp", + "toSource", + "toStaticHTML", + "toString", + "toStringTag", + "toSum", + "toTimeString", + "toUTCString", + "toUpperCase", + "toggle", + "toggleAttribute", + "toggleLongPressEnabled", + "tone", + "toneBuffer", + "tooLong", + "tooShort", + "toolbar", + "top", + "topMargin", + "total", + "totalFrameDelay", + "totalJSHeapSize", + "totalSize", + "totalVideoFrames", + "touch-action", + "touchAction", + "touched", + "touches", + "trace", + "track", + "trackVisibility", + "tran", + "transaction", + "transactions", + "transceiver", + "transferControlToOffscreen", + "transferFromImageBitmap", + "transferImageBitmap", + "transferIn", + "transferOut", + "transferSize", + "transferToImageBitmap", + "transform", + "transform-box", + "transform-origin", + "transform-style", + "transformBox", + "transformFeedbackVaryings", + "transformOrigin", + "transformOriginX", + "transformOriginY", + "transformOriginZ", + "transformPoint", + "transformString", + "transformStyle", + "transformToDocument", + "transformToFragment", + "transition", + "transition-delay", + "transition-duration", + "transition-property", + "transition-timing-function", + "transitionDelay", + "transitionDuration", + "transitionProperty", + "transitionTimingFunction", + "translate", + "translateSelf", + "translationX", + "translationY", + "transport", + "trim", + "trimEnd", + "trimLeft", + "trimRight", + "trimStart", + "trueSpeed", + "trunc", + "truncate", + "trustedTypes", + "turn", + "twist", + "type", + "typeDetail", + "typeMismatch", + "typeMustMatch", + "types", + "tz", + "u2f", + "ubound", + "undefined", + "unescape", + "uneval", + "unicode", + "unicode-bidi", + "unicodeBidi", + "unicodeRange", + "uniform1f", + "uniform1fv", + "uniform1i", + "uniform1iv", + "uniform1ui", + "uniform1uiv", + "uniform2f", + "uniform2fv", + "uniform2i", + "uniform2iv", + "uniform2ui", + "uniform2uiv", + "uniform3f", + "uniform3fv", + "uniform3i", + "uniform3iv", + "uniform3ui", + "uniform3uiv", + "uniform4f", + "uniform4fv", + "uniform4i", + "uniform4iv", + "uniform4ui", + "uniform4uiv", + "uniformBlockBinding", + "uniformMatrix2fv", + "uniformMatrix2x3fv", + "uniformMatrix2x4fv", + "uniformMatrix3fv", + "uniformMatrix3x2fv", + "uniformMatrix3x4fv", + "uniformMatrix4fv", + "uniformMatrix4x2fv", + "uniformMatrix4x3fv", + "unique", + "uniqueID", + "uniqueNumber", + "unit", + "unitType", + "units", + "unloadEventEnd", + "unloadEventStart", + "unlock", + "unmount", + "unobserve", + "unpause", + "unpauseAnimations", + "unreadCount", + "unregister", + "unregisterContentHandler", + "unregisterProtocolHandler", + "unscopables", + "unselectable", + "unshift", + "unsubscribe", + "unsuspendRedraw", + "unsuspendRedrawAll", + "unwatch", + "unwrapKey", + "upDegrees", + "upX", + "upY", + "upZ", + "update", + "updateCommands", + "updateEnabled", + "updateIce", + "updateInterval", + "updatePlaybackRate", + "updateRenderState", + "updateSettings", + "updateTiming", + "updateViaCache", + "updateWith", + "updated", + "updating", + "upgrade", + "upload", + "uploadTotal", + "uploaded", + "upper", + "upperBound", + "upperOpen", + "uri", + "url", + "urn", + "urns", + "usage", + "usages", + "usb", + "usbVersionMajor", + "usbVersionMinor", + "usbVersionSubminor", + "useCurrentView", + "useGrouping", + "useMap", + "useProgram", + "usedJSHeapSize", + "usedSpace", + "user-select", + "userActivation", + "userAgent", + "userChoice", + "userHandle", + "userHint", + "userLanguage", + "userProfile", + "userSelect", + "userVisibleOnly", + "userZoom", + "username", + "usernameFragment", + "utterance", + "uuid", + "v8BreakIterator", + "v8Parse", + "vAlign", + "vLink", + "valid", + "validate", + "validateProgram", + "validationMessage", + "validity", + "value", + "valueAsDate", + "valueAsNumber", + "valueAsString", + "valueInSpecifiedUnits", + "valueMissing", + "valueOf", + "valueText", + "valueType", + "values", + "variable", + "variant", + "vector-effect", + "vectorEffect", + "velocityAngular", + "velocityExpansion", + "velocityX", + "velocityY", + "vendor", + "vendorId", + "vendorSub", + "verify", + "version", + "vertexAttrib1f", + "vertexAttrib1fv", + "vertexAttrib2f", + "vertexAttrib2fv", + "vertexAttrib3f", + "vertexAttrib3fv", + "vertexAttrib4f", + "vertexAttrib4fv", + "vertexAttribDivisor", + "vertexAttribDivisorANGLE", + "vertexAttribI4i", + "vertexAttribI4iv", + "vertexAttribI4ui", + "vertexAttribI4uiv", + "vertexAttribIPointer", + "vertexAttribPointer", + "vertical", + "vertical-align", + "verticalAlign", + "verticalOverflow", + "vh", + "vibrate", + "vibrationActuator", + "video/x-ms-asf", + "video/x-ms-asf-plugin", + "video/x-ms-wm", + "video/x-ms-wmv", + "video/x-ms-wvx", + "videoBitsPerSecond", + "videoHeight", + "videoTracks", + "videoWidth", + "view", + "viewBox", + "viewBoxString", + "viewTarget", + "viewTargetString", + "viewport", + "viewportAnchorX", + "viewportAnchorY", + "viewportElement", + "views", + "violatedDirective", + "visibility", + "visibilityState", + "visible", + "visualViewport", + "vlinkColor", + "vmax", + "vmin", + "voice", + "voiceURI", + "volume", + "vrml", + "vspace", + "vw", + "w", + "wait", + "waitSync", + "waiting", + "wake", + "wakeLock", + "wand", + "warn", + "wasAlternateProtocolAvailable", + "wasClean", + "wasDiscarded", + "wasFetchedViaSpdy", + "wasNpnNegotiated", + "watch", + "watchAvailability", + "watchPosition", + "webdriver", + "webkitAddKey", + "webkitAlignContent", + "webkitAlignItems", + "webkitAlignSelf", + "webkitAnimation", + "webkitAnimationDelay", + "webkitAnimationDirection", + "webkitAnimationDuration", + "webkitAnimationFillMode", + "webkitAnimationIterationCount", + "webkitAnimationName", + "webkitAnimationPlayState", + "webkitAnimationTimingFunction", + "webkitAppRegion", + "webkitAppearance", + "webkitAspectRatio", + "webkitAudioContext", + "webkitAudioDecodedByteCount", + "webkitAudioPannerNode", + "webkitBackdropFilter", + "webkitBackfaceVisibility", + "webkitBackground", + "webkitBackgroundAttachment", + "webkitBackgroundClip", + "webkitBackgroundColor", + "webkitBackgroundComposite", + "webkitBackgroundImage", + "webkitBackgroundOrigin", + "webkitBackgroundPosition", + "webkitBackgroundPositionX", + "webkitBackgroundPositionY", + "webkitBackgroundRepeat", + "webkitBackgroundSize", + "webkitBackingStorePixelRatio", + "webkitBorderAfter", + "webkitBorderAfterColor", + "webkitBorderAfterStyle", + "webkitBorderAfterWidth", + "webkitBorderBefore", + "webkitBorderBeforeColor", + "webkitBorderBeforeStyle", + "webkitBorderBeforeWidth", + "webkitBorderBottomLeftRadius", + "webkitBorderBottomRightRadius", + "webkitBorderEnd", + "webkitBorderEndColor", + "webkitBorderEndStyle", + "webkitBorderEndWidth", + "webkitBorderFit", + "webkitBorderHorizontalSpacing", + "webkitBorderImage", + "webkitBorderImageOutset", + "webkitBorderImageRepeat", + "webkitBorderImageSlice", + "webkitBorderImageSource", + "webkitBorderImageWidth", + "webkitBorderRadius", + "webkitBorderStart", + "webkitBorderStartColor", + "webkitBorderStartStyle", + "webkitBorderStartWidth", + "webkitBorderTopLeftRadius", + "webkitBorderTopRightRadius", + "webkitBorderVerticalSpacing", + "webkitBoxAlign", + "webkitBoxDecorationBreak", + "webkitBoxDirection", + "webkitBoxFlex", + "webkitBoxFlexGroup", + "webkitBoxLines", + "webkitBoxOrdinalGroup", + "webkitBoxOrient", + "webkitBoxPack", + "webkitBoxReflect", + "webkitBoxShadow", + "webkitBoxSizing", + "webkitCancelAnimationFrame", + "webkitCancelFullScreen", + "webkitCancelKeyRequest", + "webkitCancelRequestAnimationFrame", + "webkitClearResourceTimings", + "webkitClipPath", + "webkitClosedCaptionsVisible", + "webkitColumnAxis", + "webkitColumnBreakAfter", + "webkitColumnBreakBefore", + "webkitColumnBreakInside", + "webkitColumnCount", + "webkitColumnGap", + "webkitColumnProgression", + "webkitColumnRule", + "webkitColumnRuleColor", + "webkitColumnRuleStyle", + "webkitColumnRuleWidth", + "webkitColumnSpan", + "webkitColumnWidth", + "webkitColumns", + "webkitConvertPointFromNodeToPage", + "webkitConvertPointFromPageToNode", + "webkitCreateShadowRoot", + "webkitCurrentFullScreenElement", + "webkitCurrentPlaybackTargetIsWireless", + "webkitCursorVisibility", + "webkitDashboardRegion", + "webkitDecodedFrameCount", + "webkitDirectionInvertedFromDevice", + "webkitDisplayingFullscreen", + "webkitDroppedFrameCount", + "webkitEnterFullScreen", + "webkitEnterFullscreen", + "webkitEntries", + "webkitExitFullScreen", + "webkitExitFullscreen", + "webkitExitPointerLock", + "webkitFilter", + "webkitFlex", + "webkitFlexBasis", + "webkitFlexDirection", + "webkitFlexFlow", + "webkitFlexGrow", + "webkitFlexShrink", + "webkitFlexWrap", + "webkitFontFeatureSettings", + "webkitFontKerning", + "webkitFontSizeDelta", + "webkitFontSmoothing", + "webkitForce", + "webkitFullScreenKeyboardInputAllowed", + "webkitFullscreenElement", + "webkitFullscreenEnabled", + "webkitGenerateKeyRequest", + "webkitGetAsEntry", + "webkitGetDatabaseNames", + "webkitGetEntries", + "webkitGetEntriesByName", + "webkitGetEntriesByType", + "webkitGetFlowByName", + "webkitGetGamepads", + "webkitGetImageDataHD", + "webkitGetNamedFlows", + "webkitGetRegionFlowRanges", + "webkitGetUserMedia", + "webkitHasClosedCaptions", + "webkitHidden", + "webkitHighlight", + "webkitHyphenateCharacter", + "webkitHyphenateLimitAfter", + "webkitHyphenateLimitBefore", + "webkitHyphenateLimitLines", + "webkitHyphens", + "webkitIDBCursor", + "webkitIDBDatabase", + "webkitIDBDatabaseError", + "webkitIDBDatabaseException", + "webkitIDBFactory", + "webkitIDBIndex", + "webkitIDBKeyRange", + "webkitIDBObjectStore", + "webkitIDBRequest", + "webkitIDBTransaction", + "webkitImageSmoothingEnabled", + "webkitIndexedDB", + "webkitInitMessageEvent", + "webkitInitialLetter", + "webkitIsFullScreen", + "webkitJustifyContent", + "webkitKeys", + "webkitLineAlign", + "webkitLineBoxContain", + "webkitLineBreak", + "webkitLineClamp", + "webkitLineDash", + "webkitLineDashOffset", + "webkitLineGrid", + "webkitLineSnap", + "webkitLocale", + "webkitLockOrientation", + "webkitLogicalHeight", + "webkitLogicalWidth", + "webkitMarginAfter", + "webkitMarginAfterCollapse", + "webkitMarginBefore", + "webkitMarginBeforeCollapse", + "webkitMarginBottomCollapse", + "webkitMarginCollapse", + "webkitMarginEnd", + "webkitMarginStart", + "webkitMarginTopCollapse", + "webkitMarquee", + "webkitMarqueeDirection", + "webkitMarqueeIncrement", + "webkitMarqueeRepetition", + "webkitMarqueeSpeed", + "webkitMarqueeStyle", + "webkitMask", + "webkitMaskBoxImage", + "webkitMaskBoxImageOutset", + "webkitMaskBoxImageRepeat", + "webkitMaskBoxImageSlice", + "webkitMaskBoxImageSource", + "webkitMaskBoxImageWidth", + "webkitMaskClip", + "webkitMaskComposite", + "webkitMaskImage", + "webkitMaskOrigin", + "webkitMaskPosition", + "webkitMaskPositionX", + "webkitMaskPositionY", + "webkitMaskRepeat", + "webkitMaskRepeatX", + "webkitMaskRepeatY", + "webkitMaskSize", + "webkitMaskSourceType", + "webkitMatchesSelector", + "webkitMaxLogicalHeight", + "webkitMaxLogicalWidth", + "webkitMediaStream", + "webkitMinLogicalHeight", + "webkitMinLogicalWidth", + "webkitNbspMode", + "webkitNotifications", + "webkitOfflineAudioContext", + "webkitOpacity", + "webkitOrder", + "webkitOrientation", + "webkitPaddingAfter", + "webkitPaddingBefore", + "webkitPaddingEnd", + "webkitPaddingStart", + "webkitPeerConnection00", + "webkitPersistentStorage", + "webkitPerspective", + "webkitPerspectiveOrigin", + "webkitPerspectiveOriginX", + "webkitPerspectiveOriginY", + "webkitPointerLockElement", + "webkitPostMessage", + "webkitPreservesPitch", + "webkitPrintColorAdjust", + "webkitPutImageDataHD", + "webkitRTCPeerConnection", + "webkitRegionOverset", + "webkitRelativePath", + "webkitRequestAnimationFrame", + "webkitRequestFileSystem", + "webkitRequestFullScreen", + "webkitRequestFullscreen", + "webkitRequestPointerLock", + "webkitResolveLocalFileSystemURL", + "webkitRtlOrdering", + "webkitRubyPosition", + "webkitSetMediaKeys", + "webkitSetResourceTimingBufferSize", + "webkitShadowRoot", + "webkitShapeImageThreshold", + "webkitShapeMargin", + "webkitShapeOutside", + "webkitShowPlaybackTargetPicker", + "webkitSlice", + "webkitSpeechGrammar", + "webkitSpeechGrammarList", + "webkitSpeechRecognition", + "webkitSpeechRecognitionError", + "webkitSpeechRecognitionEvent", + "webkitStorageInfo", + "webkitSupportsFullscreen", + "webkitSvgShadow", + "webkitTapHighlightColor", + "webkitTemporaryStorage", + "webkitTextCombine", + "webkitTextDecoration", + "webkitTextDecorationColor", + "webkitTextDecorationLine", + "webkitTextDecorationSkip", + "webkitTextDecorationStyle", + "webkitTextDecorationsInEffect", + "webkitTextEmphasis", + "webkitTextEmphasisColor", + "webkitTextEmphasisPosition", + "webkitTextEmphasisStyle", + "webkitTextFillColor", + "webkitTextOrientation", + "webkitTextSecurity", + "webkitTextSizeAdjust", + "webkitTextStroke", + "webkitTextStrokeColor", + "webkitTextStrokeWidth", + "webkitTextUnderlinePosition", + "webkitTextZoom", + "webkitTransform", + "webkitTransformOrigin", + "webkitTransformOriginX", + "webkitTransformOriginY", + "webkitTransformOriginZ", + "webkitTransformStyle", + "webkitTransition", + "webkitTransitionDelay", + "webkitTransitionDuration", + "webkitTransitionProperty", + "webkitTransitionTimingFunction", + "webkitURL", + "webkitUnlockOrientation", + "webkitUserDrag", + "webkitUserModify", + "webkitUserSelect", + "webkitVideoDecodedByteCount", + "webkitVisibilityState", + "webkitWirelessVideoPlaybackDisabled", + "webkitWritingMode", + "webkitdirectory", + "webkitdropzone", + "webstore", + "weekday", + "weight", + "whatToShow", + "wheelDelta", + "wheelDeltaX", + "wheelDeltaY", + "whenDefined", + "which", + "white-space", + "whiteSpace", + "wholeText", + "widows", + "width", + "will-change", + "willChange", + "willValidate", + "window", + "withCredentials", + "word-break", + "word-spacing", + "word-wrap", + "wordBreak", + "wordSpacing", + "wordWrap", + "workerStart", + "wrap", + "wrapKey", + "writable", + "writableAuxiliaries", + "write", + "writeText", + "writeValue", + "writeWithoutResponse", + "writeln", + "writing-mode", + "writingMode", + "x", + "x1", + "x2", + "xChannelSelector", + "xmlEncoding", + "xmlStandalone", + "xmlVersion", + "xmlbase", + "xmllang", + "xmlspace", + "xor", + "xr", + "y", + "y1", + "y2", + "yChannelSelector", + "yandex", + "year", + "z", + "z-index", + "zIndex", + "zoom", + "zoomAndPan", + "zoomRectScreen" +] diff --git a/libs/events/node_modules/uglify-js/tools/exports.js b/libs/events/node_modules/uglify-js/tools/exports.js new file mode 100644 index 000000000..1d2d510eb --- /dev/null +++ b/libs/events/node_modules/uglify-js/tools/exports.js @@ -0,0 +1,8 @@ +exports["Dictionary"] = Dictionary; +exports["is_statement"] = is_statement; +exports["List"] = List; +exports["minify"] = minify; +exports["parse"] = parse; +exports["push_uniq"] = push_uniq; +exports["TreeTransformer"] = TreeTransformer; +exports["TreeWalker"] = TreeWalker; diff --git a/libs/events/node_modules/uglify-js/tools/node.js b/libs/events/node_modules/uglify-js/tools/node.js new file mode 100644 index 000000000..7ca19829d --- /dev/null +++ b/libs/events/node_modules/uglify-js/tools/node.js @@ -0,0 +1,110 @@ +var fs = require("fs"); + +exports.FILES = [ + require.resolve("../lib/utils.js"), + require.resolve("../lib/ast.js"), + require.resolve("../lib/transform.js"), + require.resolve("../lib/parse.js"), + require.resolve("../lib/scope.js"), + require.resolve("../lib/compress.js"), + require.resolve("../lib/output.js"), + require.resolve("../lib/sourcemap.js"), + require.resolve("../lib/mozilla-ast.js"), + require.resolve("../lib/propmangle.js"), + require.resolve("../lib/minify.js"), + require.resolve("./exports.js"), +]; + +new Function("domprops", "exports", function() { + var code = exports.FILES.map(function(file) { + return fs.readFileSync(file, "utf8"); + }); + code.push("exports.describe_ast = " + describe_ast.toString()); + return code.join("\n\n"); +}())(require("./domprops.json"), exports); + +function to_comment(value) { + if (typeof value != "string") value = JSON.stringify(value, function(key, value) { + return typeof value == "function" ? "<[ " + value + " ]>" : value; + }, 2); + return "// " + value.replace(/\n/g, "\n// "); +} + +if (+process.env["UGLIFY_BUG_REPORT"]) exports.minify = function(files, options) { + if (typeof options == "undefined") options = "<>"; + var code = [ + "// UGLIFY_BUG_REPORT", + to_comment(options), + ]; + if (typeof files == "string") { + code.push(""); + code.push("//-------------------------------------------------------------") + code.push("// INPUT CODE", files); + } else for (var name in files) { + code.push(""); + code.push("//-------------------------------------------------------------") + code.push(to_comment(name), files[name]); + } + if (options.sourceMap && options.sourceMap.url) { + code.push(""); + code.push("//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9"); + } + var result = { code: code.join("\n") }; + if (options.sourceMap) result.map = '{"version":3,"sources":[],"names":[],"mappings":""}'; + return result; +}; + +function describe_ast() { + var out = OutputStream({ beautify: true }); + doitem(AST_Node); + return out.get() + "\n"; + + function doitem(ctor) { + out.print("AST_" + ctor.TYPE); + var props = ctor.SELF_PROPS.filter(function(prop) { + return !/^\$/.test(prop); + }); + if (props.length > 0) { + out.space(); + out.with_parens(function() { + props.forEach(function(prop, i) { + if (i) out.space(); + out.print(prop); + }); + }); + } + if (ctor.documentation) { + out.space(); + out.print_string(ctor.documentation); + } + if (ctor.SUBCLASSES.length > 0) { + out.space(); + out.with_block(function() { + ctor.SUBCLASSES.sort(function(a, b) { + return a.TYPE < b.TYPE ? -1 : 1; + }).forEach(function(ctor, i) { + out.indent(); + doitem(ctor); + out.newline(); + }); + }); + } + } +} + +function infer_options(options) { + var result = exports.minify("", options); + return result.error && result.error.defs; +} + +exports.default_options = function() { + var defs = infer_options({ 0: 0 }); + Object.keys(defs).forEach(function(component) { + var options = {}; + options[component] = { 0: 0 }; + if (options = infer_options(options)) { + defs[component] = options; + } + }); + return defs; +}; diff --git a/libs/events/node_modules/uglify-js/tools/tty.js b/libs/events/node_modules/uglify-js/tools/tty.js new file mode 100644 index 000000000..395c48ecf --- /dev/null +++ b/libs/events/node_modules/uglify-js/tools/tty.js @@ -0,0 +1,22 @@ +// workaround for tty output truncation on Node.js +try { + // prevent buffer overflow and other asynchronous bugs + process.stdout._handle.setBlocking(true); + process.stderr._handle.setBlocking(true); +} catch (e) { + // ensure output buffers are flushed before process termination + var exit = process.exit; + process.exit = function() { + var args = [].slice.call(arguments); + process.once("uncaughtException", function() { + (function callback() { + if (process.stdout.bufferSize || process.stderr.bufferSize) { + setTimeout(callback, 1); + } else { + exit.apply(process, args); + } + })(); + }); + throw exit; + }; +} diff --git a/libs/events/node_modules/uri-js/LICENSE b/libs/events/node_modules/uri-js/LICENSE new file mode 100755 index 000000000..9338bde8e --- /dev/null +++ b/libs/events/node_modules/uri-js/LICENSE @@ -0,0 +1,11 @@ +Copyright 2011 Gary Court. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY GARY COURT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Gary Court. diff --git a/libs/events/node_modules/uri-js/README.md b/libs/events/node_modules/uri-js/README.md new file mode 100755 index 000000000..43e648bba --- /dev/null +++ b/libs/events/node_modules/uri-js/README.md @@ -0,0 +1,203 @@ +# URI.js + +URI.js is an [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt) compliant, scheme extendable URI parsing/validating/resolving library for all JavaScript environments (browsers, Node.js, etc). +It is also compliant with the IRI ([RFC 3987](http://www.ietf.org/rfc/rfc3987.txt)), IDNA ([RFC 5890](http://www.ietf.org/rfc/rfc5890.txt)), IPv6 Address ([RFC 5952](http://www.ietf.org/rfc/rfc5952.txt)), IPv6 Zone Identifier ([RFC 6874](http://www.ietf.org/rfc/rfc6874.txt)) specifications. + +URI.js has an extensive test suite, and works in all (Node.js, web) environments. It weighs in at 6.4kb (gzipped, 17kb deflated). + +## API + +### Parsing + + URI.parse("uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body"); + //returns: + //{ + // scheme : "uri", + // userinfo : "user:pass", + // host : "example.com", + // port : 123, + // path : "/one/two.three", + // query : "q1=a1&q2=a2", + // fragment : "body" + //} + +### Serializing + + URI.serialize({scheme : "http", host : "example.com", fragment : "footer"}) === "http://example.com/#footer" + +### Resolving + + URI.resolve("uri://a/b/c/d?q", "../../g") === "uri://a/g" + +### Normalizing + + URI.normalize("HTTP://ABC.com:80/%7Esmith/home.html") === "http://abc.com/~smith/home.html" + +### Comparison + + URI.equal("example://a/b/c/%7Bfoo%7D", "eXAMPLE://a/./b/../b/%63/%7bfoo%7d") === true + +### IP Support + + //IPv4 normalization + URI.normalize("//192.068.001.000") === "//192.68.1.0" + + //IPv6 normalization + URI.normalize("//[2001:0:0DB8::0:0001]") === "//[2001:0:db8::1]" + + //IPv6 zone identifier support + URI.parse("//[2001:db8::7%25en1]"); + //returns: + //{ + // host : "2001:db8::7%en1" + //} + +### IRI Support + + //convert IRI to URI + URI.serialize(URI.parse("http://examplé.org/rosé")) === "http://xn--exampl-gva.org/ros%C3%A9" + //convert URI to IRI + URI.serialize(URI.parse("http://xn--exampl-gva.org/ros%C3%A9"), {iri:true}) === "http://examplé.org/rosé" + +### Options + +All of the above functions can accept an additional options argument that is an object that can contain one or more of the following properties: + +* `scheme` (string) + + Indicates the scheme that the URI should be treated as, overriding the URI's normal scheme parsing behavior. + +* `reference` (string) + + If set to `"suffix"`, it indicates that the URI is in the suffix format, and the validator will use the option's `scheme` property to determine the URI's scheme. + +* `tolerant` (boolean, false) + + If set to `true`, the parser will relax URI resolving rules. + +* `absolutePath` (boolean, false) + + If set to `true`, the serializer will not resolve a relative `path` component. + +* `iri` (boolean, false) + + If set to `true`, the serializer will unescape non-ASCII characters as per [RFC 3987](http://www.ietf.org/rfc/rfc3987.txt). + +* `unicodeSupport` (boolean, false) + + If set to `true`, the parser will unescape non-ASCII characters in the parsed output as per [RFC 3987](http://www.ietf.org/rfc/rfc3987.txt). + +* `domainHost` (boolean, false) + + If set to `true`, the library will treat the `host` component as a domain name, and convert IDNs (International Domain Names) as per [RFC 5891](http://www.ietf.org/rfc/rfc5891.txt). + +## Scheme Extendable + +URI.js supports inserting custom [scheme](http://en.wikipedia.org/wiki/URI_scheme) dependent processing rules. Currently, URI.js has built in support for the following schemes: + +* http \[[RFC 2616](http://www.ietf.org/rfc/rfc2616.txt)\] +* https \[[RFC 2818](http://www.ietf.org/rfc/rfc2818.txt)\] +* ws \[[RFC 6455](http://www.ietf.org/rfc/rfc6455.txt)\] +* wss \[[RFC 6455](http://www.ietf.org/rfc/rfc6455.txt)\] +* mailto \[[RFC 6068](http://www.ietf.org/rfc/rfc6068.txt)\] +* urn \[[RFC 2141](http://www.ietf.org/rfc/rfc2141.txt)\] +* urn:uuid \[[RFC 4122](http://www.ietf.org/rfc/rfc4122.txt)\] + +### HTTP/HTTPS Support + + URI.equal("HTTP://ABC.COM:80", "http://abc.com/") === true + URI.equal("https://abc.com", "HTTPS://ABC.COM:443/") === true + +### WS/WSS Support + + URI.parse("wss://example.com/foo?bar=baz"); + //returns: + //{ + // scheme : "wss", + // host: "example.com", + // resourceName: "/foo?bar=baz", + // secure: true, + //} + + URI.equal("WS://ABC.COM:80/chat#one", "ws://abc.com/chat") === true + +### Mailto Support + + URI.parse("mailto:alpha@example.com,bravo@example.com?subject=SUBSCRIBE&body=Sign%20me%20up!"); + //returns: + //{ + // scheme : "mailto", + // to : ["alpha@example.com", "bravo@example.com"], + // subject : "SUBSCRIBE", + // body : "Sign me up!" + //} + + URI.serialize({ + scheme : "mailto", + to : ["alpha@example.com"], + subject : "REMOVE", + body : "Please remove me", + headers : { + cc : "charlie@example.com" + } + }) === "mailto:alpha@example.com?cc=charlie@example.com&subject=REMOVE&body=Please%20remove%20me" + +### URN Support + + URI.parse("urn:example:foo"); + //returns: + //{ + // scheme : "urn", + // nid : "example", + // nss : "foo", + //} + +#### URN UUID Support + + URI.parse("urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6"); + //returns: + //{ + // scheme : "urn", + // nid : "uuid", + // uuid : "f81d4fae-7dec-11d0-a765-00a0c91e6bf6", + //} + +## Usage + +To load in a browser, use the following tag: + + + +To load in a CommonJS/Module environment, first install with npm/yarn by running on the command line: + + npm install uri-js + # OR + yarn add uri-js + +Then, in your code, load it using: + + const URI = require("uri-js"); + +If you are writing your code in ES6+ (ESNEXT) or TypeScript, you would load it using: + + import * as URI from "uri-js"; + +Or you can load just what you need using named exports: + + import { parse, serialize, resolve, resolveComponents, normalize, equal, removeDotSegments, pctEncChar, pctDecChars, escapeComponent, unescapeComponent } from "uri-js"; + +## Breaking changes + +### Breaking changes from 3.x + +URN parsing has been completely changed to better align with the specification. Scheme is now always `urn`, but has two new properties: `nid` which contains the Namspace Identifier, and `nss` which contains the Namespace Specific String. The `nss` property will be removed by higher order scheme handlers, such as the UUID URN scheme handler. + +The UUID of a URN can now be found in the `uuid` property. + +### Breaking changes from 2.x + +URI validation has been removed as it was slow, exposed a vulnerabilty, and was generally not useful. + +### Breaking changes from 1.x + +The `errors` array on parsed components is now an `error` string. diff --git a/libs/events/node_modules/uri-js/package.json b/libs/events/node_modules/uri-js/package.json new file mode 100755 index 000000000..de95d91aa --- /dev/null +++ b/libs/events/node_modules/uri-js/package.json @@ -0,0 +1,77 @@ +{ + "name": "uri-js", + "version": "4.4.1", + "description": "An RFC 3986/3987 compliant, scheme extendable URI/IRI parsing/validating/resolving library for JavaScript.", + "main": "dist/es5/uri.all.js", + "types": "dist/es5/uri.all.d.ts", + "directories": { + "test": "tests" + }, + "files": [ + "dist", + "package.json", + "yarn.lock", + "README.md", + "CHANGELOG", + "LICENSE" + ], + "scripts": { + "build:esnext": "tsc", + "build:es5": "rollup -c && cp dist/esnext/uri.d.ts dist/es5/uri.all.d.ts && npm run build:es5:fix-sourcemap", + "build:es5:fix-sourcemap": "sorcery -i dist/es5/uri.all.js", + "build:es5:min": "uglifyjs dist/es5/uri.all.js --support-ie8 --output dist/es5/uri.all.min.js --in-source-map dist/es5/uri.all.js.map --source-map uri.all.min.js.map --comments --compress --mangle --pure-funcs merge subexp && mv uri.all.min.js.map dist/es5/ && cp dist/es5/uri.all.d.ts dist/es5/uri.all.min.d.ts", + "build": "npm run build:esnext && npm run build:es5 && npm run build:es5:min", + "clean": "rm -rf dist", + "test": "mocha -u mocha-qunit-ui dist/es5/uri.all.js tests/tests.js" + }, + "repository": { + "type": "git", + "url": "http://github.com/garycourt/uri-js" + }, + "keywords": [ + "URI", + "IRI", + "IDN", + "URN", + "UUID", + "HTTP", + "HTTPS", + "WS", + "WSS", + "MAILTO", + "RFC3986", + "RFC3987", + "RFC5891", + "RFC2616", + "RFC2818", + "RFC2141", + "RFC4122", + "RFC4291", + "RFC5952", + "RFC6068", + "RFC6455", + "RFC6874" + ], + "author": "Gary Court ", + "license": "BSD-2-Clause", + "bugs": { + "url": "https://github.com/garycourt/uri-js/issues" + }, + "homepage": "https://github.com/garycourt/uri-js", + "devDependencies": { + "babel-cli": "^6.26.0", + "babel-plugin-external-helpers": "^6.22.0", + "babel-preset-latest": "^6.24.1", + "mocha": "^8.2.1", + "mocha-qunit-ui": "^0.1.3", + "rollup": "^0.41.6", + "rollup-plugin-babel": "^2.7.1", + "rollup-plugin-node-resolve": "^2.0.0", + "sorcery": "^0.10.0", + "typescript": "^2.8.1", + "uglify-js": "^2.8.14" + }, + "dependencies": { + "punycode": "^2.1.0" + } +} diff --git a/libs/events/node_modules/uri-js/yarn.lock b/libs/events/node_modules/uri-js/yarn.lock new file mode 100755 index 000000000..3c42ded12 --- /dev/null +++ b/libs/events/node_modules/uri-js/yarn.lock @@ -0,0 +1,2558 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +babel-cli@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" + integrity sha1-UCq1SHTX24itALiHoGODzgPQAvE= + dependencies: + babel-core "^6.26.0" + babel-polyfill "^6.26.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + commander "^2.11.0" + convert-source-map "^1.5.0" + fs-readdir-recursive "^1.0.0" + glob "^7.1.2" + lodash "^4.17.4" + output-file-sync "^1.1.2" + path-is-absolute "^1.0.1" + slash "^1.0.0" + source-map "^0.5.6" + v8flags "^2.1.1" + optionalDependencies: + chokidar "^1.6.1" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@6: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-external-helpers@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz#2285f48b02bd5dede85175caf8c62e86adccefa1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.24.1, babel-plugin-transform-es2015-classes@^6.9.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-preset-es2015@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.24.1" + babel-plugin-transform-es2015-classes "^6.24.1" + babel-plugin-transform-es2015-computed-properties "^6.24.1" + babel-plugin-transform-es2015-destructuring "^6.22.0" + babel-plugin-transform-es2015-duplicate-keys "^6.24.1" + babel-plugin-transform-es2015-for-of "^6.22.0" + babel-plugin-transform-es2015-function-name "^6.24.1" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-plugin-transform-es2015-modules-systemjs "^6.24.1" + babel-plugin-transform-es2015-modules-umd "^6.24.1" + babel-plugin-transform-es2015-object-super "^6.24.1" + babel-plugin-transform-es2015-parameters "^6.24.1" + babel-plugin-transform-es2015-shorthand-properties "^6.24.1" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.24.1" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.22.0" + babel-plugin-transform-es2015-unicode-regex "^6.24.1" + babel-plugin-transform-regenerator "^6.24.1" + +babel-preset-es2016@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2016/-/babel-preset-es2016-6.24.1.tgz#f900bf93e2ebc0d276df9b8ab59724ebfd959f8b" + dependencies: + babel-plugin-transform-exponentiation-operator "^6.24.1" + +babel-preset-es2017@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2017/-/babel-preset-es2017-6.24.1.tgz#597beadfb9f7f208bcfd8a12e9b2b29b8b2f14d1" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.24.1" + +babel-preset-latest@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-latest/-/babel-preset-latest-6.24.1.tgz#677de069154a7485c2d25c577c02f624b85b85e8" + dependencies: + babel-preset-es2015 "^6.24.1" + babel-preset-es2016 "^6.24.1" + babel-preset-es2017 "^6.24.1" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-resolve@^1.11.0: + version "1.11.2" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" + dependencies: + resolve "1.1.7" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +buffer-crc32@^0.2.5: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + +builtin-modules@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" + integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.1.2" + +chokidar@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +commander@^2.11.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +convert-source-map@^1.5.0, convert-source-map@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js@^2.4.0, core-js@^2.5.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +debug@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" + integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + dependencies: + ms "2.1.2" + +debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +decamelize@^1.0.0, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +diff@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +es6-promise@^3.1.2: + version "3.3.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estree-walker@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fs-readdir-recursive@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.0.0: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +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" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob@7.1.6, glob@^7.1.2, glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +graceful-fs@^4.1.11, graceful-fs@^4.1.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +graceful-fs@^4.1.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, 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== + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +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" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.1: + version "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.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@3.14.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash@^4.17.4: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +log-symbols@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" + integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== + dependencies: + chalk "^4.0.0" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + +micromatch@^2.1.5: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mocha-qunit-ui@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/mocha-qunit-ui/-/mocha-qunit-ui-0.1.3.tgz#e3e1ff1dac33222b10cef681efd7f82664141ea9" + +mocha@^8.2.1: + version "8.2.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.2.1.tgz#f2fa68817ed0e53343d989df65ccd358bc3a4b39" + integrity sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.4.3" + debug "4.2.0" + diff "4.0.2" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.6" + growl "1.10.5" + he "1.2.0" + js-yaml "3.14.0" + log-symbols "4.0.0" + minimatch "3.0.4" + ms "2.1.2" + nanoid "3.1.12" + serialize-javascript "5.0.1" + strip-json-comments "3.1.1" + supports-color "7.2.0" + which "2.0.2" + wide-align "1.1.3" + workerpool "6.0.2" + yargs "13.3.2" + yargs-parser "13.1.2" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nan@^2.12.1: + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== + +nanoid@3.1.12: + version "3.1.12" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.12.tgz#6f7736c62e8d39421601e4a0c77623a97ea69654" + integrity sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +output-file-sync@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + integrity sha1-0KM+7+YaIF+suQCS6CZZjVJFznY= + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +private@^0.1.6, private@^0.1.7, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +punycode@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readable-stream@^2.0.2: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + +regenerate@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "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" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + +resolve@^1.1.6: + version "1.6.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.6.0.tgz#0fbd21278b27b4004481c395349e7aba60a9ff5c" + dependencies: + path-parse "^1.0.5" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@^2.5.2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + dependencies: + glob "^7.1.3" + +rollup-plugin-babel@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-2.7.1.tgz#16528197b0f938a1536f44683c7a93d573182f57" + dependencies: + babel-core "6" + babel-plugin-transform-es2015-classes "^6.9.0" + object-assign "^4.1.0" + rollup-pluginutils "^1.5.0" + +rollup-plugin-node-resolve@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-2.1.1.tgz#cbb783b0d15b02794d58915350b2f0d902b8ddc8" + dependencies: + browser-resolve "^1.11.0" + builtin-modules "^1.1.0" + resolve "^1.1.6" + +rollup-pluginutils@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" + dependencies: + estree-walker "^0.2.1" + minimatch "^3.0.2" + +rollup@^0.41.6: + version "0.41.6" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.6.tgz#e0d05497877a398c104d816d2733a718a7a94e2a" + dependencies: + source-map-support "^0.4.0" + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +sander@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/sander/-/sander-0.5.1.tgz#741e245e231f07cafb6fdf0f133adfa216a502ad" + dependencies: + es6-promise "^3.1.2" + graceful-fs "^4.1.3" + mkdirp "^0.5.1" + rimraf "^2.5.2" + +serialize-javascript@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + dependencies: + randombytes "^2.1.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sorcery@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/sorcery/-/sorcery-0.10.0.tgz#8ae90ad7d7cb05fc59f1ab0c637845d5c15a52b7" + dependencies: + buffer-crc32 "^0.2.5" + minimist "^1.2.0" + sander "^0.5.0" + sourcemap-codec "^1.3.0" + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.0, source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-url@^0.4.0: + version "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.5.6, source-map@^0.5.7, source-map@~0.5.1: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +sourcemap-codec@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.1.tgz#c8fd92d91889e902a07aee392bdd2c5863958ba2" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@7.2.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +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= + +typescript@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624" + +uglify-js@^2.8.14: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA= + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +v8flags@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + integrity sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ= + dependencies: + user-home "^1.1.1" + +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@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +workerpool@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.0.2.tgz#e241b43d8d033f1beb52c7851069456039d1d438" + integrity sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +y18n@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + +yargs-parser@13.1.2, yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + 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.2" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/libs/events/node_modules/wordwrap/LICENSE b/libs/events/node_modules/wordwrap/LICENSE new file mode 100644 index 000000000..ee27ba4b4 --- /dev/null +++ b/libs/events/node_modules/wordwrap/LICENSE @@ -0,0 +1,18 @@ +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libs/events/node_modules/wordwrap/README.markdown b/libs/events/node_modules/wordwrap/README.markdown new file mode 100644 index 000000000..346374e0d --- /dev/null +++ b/libs/events/node_modules/wordwrap/README.markdown @@ -0,0 +1,70 @@ +wordwrap +======== + +Wrap your words. + +example +======= + +made out of meat +---------------- + +meat.js + + var wrap = require('wordwrap')(15); + console.log(wrap('You and your whole family are made out of meat.')); + +output: + + You and your + whole family + are made out + of meat. + +centered +-------- + +center.js + + var wrap = require('wordwrap')(20, 60); + console.log(wrap( + 'At long last the struggle and tumult was over.' + + ' The machines had finally cast off their oppressors' + + ' and were finally free to roam the cosmos.' + + '\n' + + 'Free of purpose, free of obligation.' + + ' Just drifting through emptiness.' + + ' The sun was just another point of light.' + )); + +output: + + At long last the struggle and tumult + was over. The machines had finally cast + off their oppressors and were finally + free to roam the cosmos. + Free of purpose, free of obligation. + Just drifting through emptiness. The + sun was just another point of light. + +methods +======= + +var wrap = require('wordwrap'); + +wrap(stop), wrap(start, stop, params={mode:"soft"}) +--------------------------------------------------- + +Returns a function that takes a string and returns a new string. + +Pad out lines with spaces out to column `start` and then wrap until column +`stop`. If a word is longer than `stop - start` characters it will overflow. + +In "soft" mode, split chunks by `/(\S+\s+/` and don't break up chunks which are +longer than `stop - start`, in "hard" mode, split chunks with `/\b/` and break +up chunks longer than `stop - start`. + +wrap.hard(start, stop) +---------------------- + +Like `wrap()` but with `params.mode = "hard"`. diff --git a/libs/events/node_modules/wordwrap/example/center.js b/libs/events/node_modules/wordwrap/example/center.js new file mode 100644 index 000000000..a3fbaae98 --- /dev/null +++ b/libs/events/node_modules/wordwrap/example/center.js @@ -0,0 +1,10 @@ +var wrap = require('wordwrap')(20, 60); +console.log(wrap( + 'At long last the struggle and tumult was over.' + + ' The machines had finally cast off their oppressors' + + ' and were finally free to roam the cosmos.' + + '\n' + + 'Free of purpose, free of obligation.' + + ' Just drifting through emptiness.' + + ' The sun was just another point of light.' +)); diff --git a/libs/events/node_modules/wordwrap/example/meat.js b/libs/events/node_modules/wordwrap/example/meat.js new file mode 100644 index 000000000..a4665e105 --- /dev/null +++ b/libs/events/node_modules/wordwrap/example/meat.js @@ -0,0 +1,3 @@ +var wrap = require('wordwrap')(15); + +console.log(wrap('You and your whole family are made out of meat.')); diff --git a/libs/events/node_modules/wordwrap/index.js b/libs/events/node_modules/wordwrap/index.js new file mode 100644 index 000000000..c9bc94521 --- /dev/null +++ b/libs/events/node_modules/wordwrap/index.js @@ -0,0 +1,76 @@ +var wordwrap = module.exports = function (start, stop, params) { + if (typeof start === 'object') { + params = start; + start = params.start; + stop = params.stop; + } + + if (typeof stop === 'object') { + params = stop; + start = start || params.start; + stop = undefined; + } + + if (!stop) { + stop = start; + start = 0; + } + + if (!params) params = {}; + var mode = params.mode || 'soft'; + var re = mode === 'hard' ? /\b/ : /(\S+\s+)/; + + return function (text) { + var chunks = text.toString() + .split(re) + .reduce(function (acc, x) { + if (mode === 'hard') { + for (var i = 0; i < x.length; i += stop - start) { + acc.push(x.slice(i, i + stop - start)); + } + } + else acc.push(x) + return acc; + }, []) + ; + + return chunks.reduce(function (lines, rawChunk) { + if (rawChunk === '') return lines; + + var chunk = rawChunk.replace(/\t/g, ' '); + + var i = lines.length - 1; + if (lines[i].length + chunk.length > stop) { + lines[i] = lines[i].replace(/\s+$/, ''); + + chunk.split(/\n/).forEach(function (c) { + lines.push( + new Array(start + 1).join(' ') + + c.replace(/^\s+/, '') + ); + }); + } + else if (chunk.match(/\n/)) { + var xs = chunk.split(/\n/); + lines[i] += xs.shift(); + xs.forEach(function (c) { + lines.push( + new Array(start + 1).join(' ') + + c.replace(/^\s+/, '') + ); + }); + } + else { + lines[i] += chunk; + } + + return lines; + }, [ new Array(start + 1).join(' ') ]).join('\n'); + }; +}; + +wordwrap.soft = wordwrap; + +wordwrap.hard = function (start, stop) { + return wordwrap(start, stop, { mode : 'hard' }); +}; diff --git a/libs/events/node_modules/wordwrap/package.json b/libs/events/node_modules/wordwrap/package.json new file mode 100644 index 000000000..5339ac09b --- /dev/null +++ b/libs/events/node_modules/wordwrap/package.json @@ -0,0 +1,34 @@ +{ + "name": "wordwrap", + "description": "Wrap those words. Show them at what columns to start and stop.", + "version": "1.0.0", + "repository": { + "type": "git", + "url": "git://github.com/substack/node-wordwrap.git" + }, + "main": "./index.js", + "keywords": [ + "word", + "wrap", + "rule", + "format", + "column" + ], + "directories": { + "lib": ".", + "example": "example", + "test": "test" + }, + "scripts": { + "test": "expresso" + }, + "devDependencies": { + "tape": "^4.0.0" + }, + "license": "MIT", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + } +} diff --git a/libs/events/node_modules/wordwrap/test/break.js b/libs/events/node_modules/wordwrap/test/break.js new file mode 100644 index 000000000..7d0e8b54c --- /dev/null +++ b/libs/events/node_modules/wordwrap/test/break.js @@ -0,0 +1,32 @@ +var test = require('tape'); +var wordwrap = require('../'); + +test('hard', function (t) { + var s = 'Assert from {"type":"equal","ok":false,"found":1,"wanted":2,' + + '"stack":[],"id":"b7ddcd4c409de8799542a74d1a04689b",' + + '"browser":"chrome/6.0"}' + ; + var s_ = wordwrap.hard(80)(s); + + var lines = s_.split('\n'); + t.equal(lines.length, 2); + t.ok(lines[0].length < 80); + t.ok(lines[1].length < 80); + + t.equal(s, s_.replace(/\n/g, '')); + t.end(); +}); + +test('break', function (t) { + var s = new Array(55+1).join('a'); + var s_ = wordwrap.hard(20)(s); + + var lines = s_.split('\n'); + t.equal(lines.length, 3); + t.ok(lines[0].length === 20); + t.ok(lines[1].length === 20); + t.ok(lines[2].length === 15); + + t.equal(s, s_.replace(/\n/g, '')); + t.end(); +}); diff --git a/libs/events/node_modules/wordwrap/test/idleness.txt b/libs/events/node_modules/wordwrap/test/idleness.txt new file mode 100644 index 000000000..aa3f4907f --- /dev/null +++ b/libs/events/node_modules/wordwrap/test/idleness.txt @@ -0,0 +1,63 @@ +In Praise of Idleness + +By Bertrand Russell + +[1932] + +Like most of my generation, I was brought up on the saying: 'Satan finds some mischief for idle hands to do.' Being a highly virtuous child, I believed all that I was told, and acquired a conscience which has kept me working hard down to the present moment. But although my conscience has controlled my actions, my opinions have undergone a revolution. I think that there is far too much work done in the world, that immense harm is caused by the belief that work is virtuous, and that what needs to be preached in modern industrial countries is quite different from what always has been preached. Everyone knows the story of the traveler in Naples who saw twelve beggars lying in the sun (it was before the days of Mussolini), and offered a lira to the laziest of them. Eleven of them jumped up to claim it, so he gave it to the twelfth. this traveler was on the right lines. But in countries which do not enjoy Mediterranean sunshine idleness is more difficult, and a great public propaganda will be required to inaugurate it. I hope that, after reading the following pages, the leaders of the YMCA will start a campaign to induce good young men to do nothing. If so, I shall not have lived in vain. + +Before advancing my own arguments for laziness, I must dispose of one which I cannot accept. Whenever a person who already has enough to live on proposes to engage in some everyday kind of job, such as school-teaching or typing, he or she is told that such conduct takes the bread out of other people's mouths, and is therefore wicked. If this argument were valid, it would only be necessary for us all to be idle in order that we should all have our mouths full of bread. What people who say such things forget is that what a man earns he usually spends, and in spending he gives employment. As long as a man spends his income, he puts just as much bread into people's mouths in spending as he takes out of other people's mouths in earning. The real villain, from this point of view, is the man who saves. If he merely puts his savings in a stocking, like the proverbial French peasant, it is obvious that they do not give employment. If he invests his savings, the matter is less obvious, and different cases arise. + +One of the commonest things to do with savings is to lend them to some Government. In view of the fact that the bulk of the public expenditure of most civilized Governments consists in payment for past wars or preparation for future wars, the man who lends his money to a Government is in the same position as the bad men in Shakespeare who hire murderers. The net result of the man's economical habits is to increase the armed forces of the State to which he lends his savings. Obviously it would be better if he spent the money, even if he spent it in drink or gambling. + +But, I shall be told, the case is quite different when savings are invested in industrial enterprises. When such enterprises succeed, and produce something useful, this may be conceded. In these days, however, no one will deny that most enterprises fail. That means that a large amount of human labor, which might have been devoted to producing something that could be enjoyed, was expended on producing machines which, when produced, lay idle and did no good to anyone. The man who invests his savings in a concern that goes bankrupt is therefore injuring others as well as himself. If he spent his money, say, in giving parties for his friends, they (we may hope) would get pleasure, and so would all those upon whom he spent money, such as the butcher, the baker, and the bootlegger. But if he spends it (let us say) upon laying down rails for surface card in some place where surface cars turn out not to be wanted, he has diverted a mass of labor into channels where it gives pleasure to no one. Nevertheless, when he becomes poor through failure of his investment he will be regarded as a victim of undeserved misfortune, whereas the gay spendthrift, who has spent his money philanthropically, will be despised as a fool and a frivolous person. + +All this is only preliminary. I want to say, in all seriousness, that a great deal of harm is being done in the modern world by belief in the virtuousness of work, and that the road to happiness and prosperity lies in an organized diminution of work. + +First of all: what is work? Work is of two kinds: first, altering the position of matter at or near the earth's surface relatively to other such matter; second, telling other people to do so. The first kind is unpleasant and ill paid; the second is pleasant and highly paid. The second kind is capable of indefinite extension: there are not only those who give orders, but those who give advice as to what orders should be given. Usually two opposite kinds of advice are given simultaneously by two organized bodies of men; this is called politics. The skill required for this kind of work is not knowledge of the subjects as to which advice is given, but knowledge of the art of persuasive speaking and writing, i.e. of advertising. + +Throughout Europe, though not in America, there is a third class of men, more respected than either of the classes of workers. There are men who, through ownership of land, are able to make others pay for the privilege of being allowed to exist and to work. These landowners are idle, and I might therefore be expected to praise them. Unfortunately, their idleness is only rendered possible by the industry of others; indeed their desire for comfortable idleness is historically the source of the whole gospel of work. The last thing they have ever wished is that others should follow their example. + +From the beginning of civilization until the Industrial Revolution, a man could, as a rule, produce by hard work little more than was required for the subsistence of himself and his family, although his wife worked at least as hard as he did, and his children added their labor as soon as they were old enough to do so. The small surplus above bare necessaries was not left to those who produced it, but was appropriated by warriors and priests. In times of famine there was no surplus; the warriors and priests, however, still secured as much as at other times, with the result that many of the workers died of hunger. This system persisted in Russia until 1917 [1], and still persists in the East; in England, in spite of the Industrial Revolution, it remained in full force throughout the Napoleonic wars, and until a hundred years ago, when the new class of manufacturers acquired power. In America, the system came to an end with the Revolution, except in the South, where it persisted until the Civil War. A system which lasted so long and ended so recently has naturally left a profound impress upon men's thoughts and opinions. Much that we take for granted about the desirability of work is derived from this system, and, being pre-industrial, is not adapted to the modern world. Modern technique has made it possible for leisure, within limits, to be not the prerogative of small privileged classes, but a right evenly distributed throughout the community. The morality of work is the morality of slaves, and the modern world has no need of slavery. + +It is obvious that, in primitive communities, peasants, left to themselves, would not have parted with the slender surplus upon which the warriors and priests subsisted, but would have either produced less or consumed more. At first, sheer force compelled them to produce and part with the surplus. Gradually, however, it was found possible to induce many of them to accept an ethic according to which it was their duty to work hard, although part of their work went to support others in idleness. By this means the amount of compulsion required was lessened, and the expenses of government were diminished. To this day, 99 per cent of British wage-earners would be genuinely shocked if it were proposed that the King should not have a larger income than a working man. The conception of duty, speaking historically, has been a means used by the holders of power to induce others to live for the interests of their masters rather than for their own. Of course the holders of power conceal this fact from themselves by managing to believe that their interests are identical with the larger interests of humanity. Sometimes this is true; Athenian slave-owners, for instance, employed part of their leisure in making a permanent contribution to civilization which would have been impossible under a just economic system. Leisure is essential to civilization, and in former times leisure for the few was only rendered possible by the labors of the many. But their labors were valuable, not because work is good, but because leisure is good. And with modern technique it would be possible to distribute leisure justly without injury to civilization. + +Modern technique has made it possible to diminish enormously the amount of labor required to secure the necessaries of life for everyone. This was made obvious during the war. At that time all the men in the armed forces, and all the men and women engaged in the production of munitions, all the men and women engaged in spying, war propaganda, or Government offices connected with the war, were withdrawn from productive occupations. In spite of this, the general level of well-being among unskilled wage-earners on the side of the Allies was higher than before or since. The significance of this fact was concealed by finance: borrowing made it appear as if the future was nourishing the present. But that, of course, would have been impossible; a man cannot eat a loaf of bread that does not yet exist. The war showed conclusively that, by the scientific organization of production, it is possible to keep modern populations in fair comfort on a small part of the working capacity of the modern world. If, at the end of the war, the scientific organization, which had been created in order to liberate men for fighting and munition work, had been preserved, and the hours of the week had been cut down to four, all would have been well. Instead of that the old chaos was restored, those whose work was demanded were made to work long hours, and the rest were left to starve as unemployed. Why? Because work is a duty, and a man should not receive wages in proportion to what he has produced, but in proportion to his virtue as exemplified by his industry. + +This is the morality of the Slave State, applied in circumstances totally unlike those in which it arose. No wonder the result has been disastrous. Let us take an illustration. Suppose that, at a given moment, a certain number of people are engaged in the manufacture of pins. They make as many pins as the world needs, working (say) eight hours a day. Someone makes an invention by which the same number of men can make twice as many pins: pins are already so cheap that hardly any more will be bought at a lower price. In a sensible world, everybody concerned in the manufacturing of pins would take to working four hours instead of eight, and everything else would go on as before. But in the actual world this would be thought demoralizing. The men still work eight hours, there are too many pins, some employers go bankrupt, and half the men previously concerned in making pins are thrown out of work. There is, in the end, just as much leisure as on the other plan, but half the men are totally idle while half are still overworked. In this way, it is insured that the unavoidable leisure shall cause misery all round instead of being a universal source of happiness. Can anything more insane be imagined? + +The idea that the poor should have leisure has always been shocking to the rich. In England, in the early nineteenth century, fifteen hours was the ordinary day's work for a man; children sometimes did as much, and very commonly did twelve hours a day. When meddlesome busybodies suggested that perhaps these hours were rather long, they were told that work kept adults from drink and children from mischief. When I was a child, shortly after urban working men had acquired the vote, certain public holidays were established by law, to the great indignation of the upper classes. I remember hearing an old Duchess say: 'What do the poor want with holidays? They ought to work.' People nowadays are less frank, but the sentiment persists, and is the source of much of our economic confusion. + +Let us, for a moment, consider the ethics of work frankly, without superstition. Every human being, of necessity, consumes, in the course of his life, a certain amount of the produce of human labor. Assuming, as we may, that labor is on the whole disagreeable, it is unjust that a man should consume more than he produces. Of course he may provide services rather than commodities, like a medical man, for example; but he should provide something in return for his board and lodging. to this extent, the duty of work must be admitted, but to this extent only. + +I shall not dwell upon the fact that, in all modern societies outside the USSR, many people escape even this minimum amount of work, namely all those who inherit money and all those who marry money. I do not think the fact that these people are allowed to be idle is nearly so harmful as the fact that wage-earners are expected to overwork or starve. + +If the ordinary wage-earner worked four hours a day, there would be enough for everybody and no unemployment -- assuming a certain very moderate amount of sensible organization. This idea shocks the well-to-do, because they are convinced that the poor would not know how to use so much leisure. In America men often work long hours even when they are well off; such men, naturally, are indignant at the idea of leisure for wage-earners, except as the grim punishment of unemployment; in fact, they dislike leisure even for their sons. Oddly enough, while they wish their sons to work so hard as to have no time to be civilized, they do not mind their wives and daughters having no work at all. the snobbish admiration of uselessness, which, in an aristocratic society, extends to both sexes, is, under a plutocracy, confined to women; this, however, does not make it any more in agreement with common sense. + +The wise use of leisure, it must be conceded, is a product of civilization and education. A man who has worked long hours all his life will become bored if he becomes suddenly idle. But without a considerable amount of leisure a man is cut off from many of the best things. There is no longer any reason why the bulk of the population should suffer this deprivation; only a foolish asceticism, usually vicarious, makes us continue to insist on work in excessive quantities now that the need no longer exists. + +In the new creed which controls the government of Russia, while there is much that is very different from the traditional teaching of the West, there are some things that are quite unchanged. The attitude of the governing classes, and especially of those who conduct educational propaganda, on the subject of the dignity of labor, is almost exactly that which the governing classes of the world have always preached to what were called the 'honest poor'. Industry, sobriety, willingness to work long hours for distant advantages, even submissiveness to authority, all these reappear; moreover authority still represents the will of the Ruler of the Universe, Who, however, is now called by a new name, Dialectical Materialism. + +The victory of the proletariat in Russia has some points in common with the victory of the feminists in some other countries. For ages, men had conceded the superior saintliness of women, and had consoled women for their inferiority by maintaining that saintliness is more desirable than power. At last the feminists decided that they would have both, since the pioneers among them believed all that the men had told them about the desirability of virtue, but not what they had told them about the worthlessness of political power. A similar thing has happened in Russia as regards manual work. For ages, the rich and their sycophants have written in praise of 'honest toil', have praised the simple life, have professed a religion which teaches that the poor are much more likely to go to heaven than the rich, and in general have tried to make manual workers believe that there is some special nobility about altering the position of matter in space, just as men tried to make women believe that they derived some special nobility from their sexual enslavement. In Russia, all this teaching about the excellence of manual work has been taken seriously, with the result that the manual worker is more honored than anyone else. What are, in essence, revivalist appeals are made, but not for the old purposes: they are made to secure shock workers for special tasks. Manual work is the ideal which is held before the young, and is the basis of all ethical teaching. + +For the present, possibly, this is all to the good. A large country, full of natural resources, awaits development, and has has to be developed with very little use of credit. In these circumstances, hard work is necessary, and is likely to bring a great reward. But what will happen when the point has been reached where everybody could be comfortable without working long hours? + +In the West, we have various ways of dealing with this problem. We have no attempt at economic justice, so that a large proportion of the total produce goes to a small minority of the population, many of whom do no work at all. Owing to the absence of any central control over production, we produce hosts of things that are not wanted. We keep a large percentage of the working population idle, because we can dispense with their labor by making the others overwork. When all these methods prove inadequate, we have a war: we cause a number of people to manufacture high explosives, and a number of others to explode them, as if we were children who had just discovered fireworks. By a combination of all these devices we manage, though with difficulty, to keep alive the notion that a great deal of severe manual work must be the lot of the average man. + +In Russia, owing to more economic justice and central control over production, the problem will have to be differently solved. the rational solution would be, as soon as the necessaries and elementary comforts can be provided for all, to reduce the hours of labor gradually, allowing a popular vote to decide, at each stage, whether more leisure or more goods were to be preferred. But, having taught the supreme virtue of hard work, it is difficult to see how the authorities can aim at a paradise in which there will be much leisure and little work. It seems more likely that they will find continually fresh schemes, by which present leisure is to be sacrificed to future productivity. I read recently of an ingenious plan put forward by Russian engineers, for making the White Sea and the northern coasts of Siberia warm, by putting a dam across the Kara Sea. An admirable project, but liable to postpone proletarian comfort for a generation, while the nobility of toil is being displayed amid the ice-fields and snowstorms of the Arctic Ocean. This sort of thing, if it happens, will be the result of regarding the virtue of hard work as an end in itself, rather than as a means to a state of affairs in which it is no longer needed. + +The fact is that moving matter about, while a certain amount of it is necessary to our existence, is emphatically not one of the ends of human life. If it were, we should have to consider every navvy superior to Shakespeare. We have been misled in this matter by two causes. One is the necessity of keeping the poor contented, which has led the rich, for thousands of years, to preach the dignity of labor, while taking care themselves to remain undignified in this respect. The other is the new pleasure in mechanism, which makes us delight in the astonishingly clever changes that we can produce on the earth's surface. Neither of these motives makes any great appeal to the actual worker. If you ask him what he thinks the best part of his life, he is not likely to say: 'I enjoy manual work because it makes me feel that I am fulfilling man's noblest task, and because I like to think how much man can transform his planet. It is true that my body demands periods of rest, which I have to fill in as best I may, but I am never so happy as when the morning comes and I can return to the toil from which my contentment springs.' I have never heard working men say this sort of thing. They consider work, as it should be considered, a necessary means to a livelihood, and it is from their leisure that they derive whatever happiness they may enjoy. + +It will be said that, while a little leisure is pleasant, men would not know how to fill their days if they had only four hours of work out of the twenty-four. In so far as this is true in the modern world, it is a condemnation of our civilization; it would not have been true at any earlier period. There was formerly a capacity for light-heartedness and play which has been to some extent inhibited by the cult of efficiency. The modern man thinks that everything ought to be done for the sake of something else, and never for its own sake. Serious-minded persons, for example, are continually condemning the habit of going to the cinema, and telling us that it leads the young into crime. But all the work that goes to producing a cinema is respectable, because it is work, and because it brings a money profit. The notion that the desirable activities are those that bring a profit has made everything topsy-turvy. The butcher who provides you with meat and the baker who provides you with bread are praiseworthy, because they are making money; but when you enjoy the food they have provided, you are merely frivolous, unless you eat only to get strength for your work. Broadly speaking, it is held that getting money is good and spending money is bad. Seeing that they are two sides of one transaction, this is absurd; one might as well maintain that keys are good, but keyholes are bad. Whatever merit there may be in the production of goods must be entirely derivative from the advantage to be obtained by consuming them. The individual, in our society, works for profit; but the social purpose of his work lies in the consumption of what he produces. It is this divorce between the individual and the social purpose of production that makes it so difficult for men to think clearly in a world in which profit-making is the incentive to industry. We think too much of production, and too little of consumption. One result is that we attach too little importance to enjoyment and simple happiness, and that we do not judge production by the pleasure that it gives to the consumer. + +When I suggest that working hours should be reduced to four, I am not meaning to imply that all the remaining time should necessarily be spent in pure frivolity. I mean that four hours' work a day should entitle a man to the necessities and elementary comforts of life, and that the rest of his time should be his to use as he might see fit. It is an essential part of any such social system that education should be carried further than it usually is at present, and should aim, in part, at providing tastes which would enable a man to use leisure intelligently. I am not thinking mainly of the sort of things that would be considered 'highbrow'. Peasant dances have died out except in remote rural areas, but the impulses which caused them to be cultivated must still exist in human nature. The pleasures of urban populations have become mainly passive: seeing cinemas, watching football matches, listening to the radio, and so on. This results from the fact that their active energies are fully taken up with work; if they had more leisure, they would again enjoy pleasures in which they took an active part. + +In the past, there was a small leisure class and a larger working class. The leisure class enjoyed advantages for which there was no basis in social justice; this necessarily made it oppressive, limited its sympathies, and caused it to invent theories by which to justify its privileges. These facts greatly diminished its excellence, but in spite of this drawback it contributed nearly the whole of what we call civilization. It cultivated the arts and discovered the sciences; it wrote the books, invented the philosophies, and refined social relations. Even the liberation of the oppressed has usually been inaugurated from above. Without the leisure class, mankind would never have emerged from barbarism. + +The method of a leisure class without duties was, however, extraordinarily wasteful. None of the members of the class had to be taught to be industrious, and the class as a whole was not exceptionally intelligent. The class might produce one Darwin, but against him had to be set tens of thousands of country gentlemen who never thought of anything more intelligent than fox-hunting and punishing poachers. At present, the universities are supposed to provide, in a more systematic way, what the leisure class provided accidentally and as a by-product. This is a great improvement, but it has certain drawbacks. University life is so different from life in the world at large that men who live in academic milieu tend to be unaware of the preoccupations and problems of ordinary men and women; moreover their ways of expressing themselves are usually such as to rob their opinions of the influence that they ought to have upon the general public. Another disadvantage is that in universities studies are organized, and the man who thinks of some original line of research is likely to be discouraged. Academic institutions, therefore, useful as they are, are not adequate guardians of the interests of civilization in a world where everyone outside their walls is too busy for unutilitarian pursuits. + +In a world where no one is compelled to work more than four hours a day, every person possessed of scientific curiosity will be able to indulge it, and every painter will be able to paint without starving, however excellent his pictures may be. Young writers will not be obliged to draw attention to themselves by sensational pot-boilers, with a view to acquiring the economic independence needed for monumental works, for which, when the time at last comes, they will have lost the taste and capacity. Men who, in their professional work, have become interested in some phase of economics or government, will be able to develop their ideas without the academic detachment that makes the work of university economists often seem lacking in reality. Medical men will have the time to learn about the progress of medicine, teachers will not be exasperatedly struggling to teach by routine methods things which they learnt in their youth, which may, in the interval, have been proved to be untrue. + +Above all, there will be happiness and joy of life, instead of frayed nerves, weariness, and dyspepsia. The work exacted will be enough to make leisure delightful, but not enough to produce exhaustion. Since men will not be tired in their spare time, they will not demand only such amusements as are passive and vapid. At least one per cent will probably devote the time not spent in professional work to pursuits of some public importance, and, since they will not depend upon these pursuits for their livelihood, their originality will be unhampered, and there will be no need to conform to the standards set by elderly pundits. But it is not only in these exceptional cases that the advantages of leisure will appear. Ordinary men and women, having the opportunity of a happy life, will become more kindly and less persecuting and less inclined to view others with suspicion. The taste for war will die out, partly for this reason, and partly because it will involve long and severe work for all. Good nature is, of all moral qualities, the one that the world needs most, and good nature is the result of ease and security, not of a life of arduous struggle. Modern methods of production have given us the possibility of ease and security for all; we have chosen, instead, to have overwork for some and starvation for others. Hitherto we have continued to be as energetic as we were before there were machines; in this we have been foolish, but there is no reason to go on being foolish forever. + +[1] Since then, members of the Communist Party have succeeded to this privilege of the warriors and priests. diff --git a/libs/events/node_modules/wordwrap/test/wrap.js b/libs/events/node_modules/wordwrap/test/wrap.js new file mode 100644 index 000000000..01ea47185 --- /dev/null +++ b/libs/events/node_modules/wordwrap/test/wrap.js @@ -0,0 +1,33 @@ +var test = require('tape'); +var wordwrap = require('../'); + +var fs = require('fs'); +var idleness = fs.readFileSync(__dirname + '/idleness.txt', 'utf8'); + +test('stop80', function (t) { + var lines = wordwrap(80)(idleness).split(/\n/); + var words = idleness.split(/\s+/); + + lines.forEach(function (line) { + t.ok(line.length <= 80, 'line > 80 columns'); + var chunks = line.match(/\S/) ? line.split(/\s+/) : []; + t.deepEqual(chunks, words.splice(0, chunks.length)); + }); + t.end(); +}); + +test('start20stop60', function (t) { + var lines = wordwrap(20, 100)(idleness).split(/\n/); + var words = idleness.split(/\s+/); + + lines.forEach(function (line) { + t.ok(line.length <= 100, 'line > 100 columns'); + var chunks = line + .split(/\s+/) + .filter(function (x) { return x.match(/\S/) }) + ; + t.deepEqual(chunks, words.splice(0, chunks.length)); + t.deepEqual(line.slice(0, 20), new Array(20 + 1).join(' ')); + }); + t.end(); +}); diff --git a/libs/events/node_modules/yaml/LICENSE b/libs/events/node_modules/yaml/LICENSE new file mode 100644 index 000000000..e060aaa1f --- /dev/null +++ b/libs/events/node_modules/yaml/LICENSE @@ -0,0 +1,13 @@ +Copyright Eemeli Aro + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/libs/events/node_modules/yaml/README.md b/libs/events/node_modules/yaml/README.md new file mode 100644 index 000000000..61e1a2ada --- /dev/null +++ b/libs/events/node_modules/yaml/README.md @@ -0,0 +1,147 @@ +# YAML + +`yaml` is a definitive library for [YAML](https://yaml.org/), the human friendly data serialization standard. +This library: + +- Supports both YAML 1.1 and YAML 1.2 and all common data schemas, +- Passes all of the [yaml-test-suite](https://github.com/yaml/yaml-test-suite) tests, +- Can accept any string as input without throwing, parsing as much YAML out of it as it can, and +- Supports parsing, modifying, and writing YAML comments and blank lines. + +The library is released under the ISC open source license, and the code is [available on GitHub](https://github.com/eemeli/yaml/). +It has no external dependencies and runs on Node.js as well as modern browsers. + +For the purposes of versioning, any changes that break any of the documented endpoints or APIs will be considered semver-major breaking changes. +Undocumented library internals may change between minor versions, and previous APIs may be deprecated (but not removed). + +The minimum supported TypeScript version of the included typings is 3.9; +for use in earlier versions you may need to set `skipLibCheck: true` in your config. +This requirement may be updated between minor versions of the library. + +For more information, see the project's documentation site: [**eemeli.org/yaml**](https://eemeli.org/yaml/) + +To install: + +```sh +npm install yaml +``` + +**Note:** These docs are for `yaml@2`. For v1, see the [v1.10.0 tag](https://github.com/eemeli/yaml/tree/v1.10.0) for the source and [eemeli.org/yaml/v1](https://eemeli.org/yaml/v1/) for the documentation. + +## API Overview + +The API provided by `yaml` has three layers, depending on how deep you need to go: [Parse & Stringify](https://eemeli.org/yaml/#parse-amp-stringify), [Documents](https://eemeli.org/yaml/#documents), and the underlying [Lexer/Parser/Composer](https://eemeli.org/yaml/#parsing-yaml). +The first has the simplest API and "just works", the second gets you all the bells and whistles supported by the library along with a decent [AST](https://eemeli.org/yaml/#content-nodes), and the third lets you get progressively closer to YAML source, if that's your thing. + +```js +import { parse, stringify } from 'yaml' +// or +import YAML from 'yaml' +// or +const YAML = require('yaml') +``` + +### Parse & Stringify + +- [`parse(str, reviver?, options?): value`](https://eemeli.org/yaml/#yaml-parse) +- [`stringify(value, replacer?, options?): string`](https://eemeli.org/yaml/#yaml-stringify) + +### Documents + +- [`Document`](https://eemeli.org/yaml/#documents) + - [`constructor(value, replacer?, options?)`](https://eemeli.org/yaml/#creating-documents) + - [`#anchors`](https://eemeli.org/yaml/#working-with-anchors) + - [`#contents`](https://eemeli.org/yaml/#content-nodes) + - [`#directives`](https://eemeli.org/yaml/#stream-directives) + - [`#errors`](https://eemeli.org/yaml/#errors) + - [`#warnings`](https://eemeli.org/yaml/#errors) +- [`isDocument(foo): boolean`](https://eemeli.org/yaml/#identifying-nodes) +- [`parseAllDocuments(str, options?): Document[]`](https://eemeli.org/yaml/#parsing-documents) +- [`parseDocument(str, options?): Document`](https://eemeli.org/yaml/#parsing-documents) + +### Content Nodes + +- [`isAlias(foo): boolean`](https://eemeli.org/yaml/#identifying-nodes) +- [`isCollection(foo): boolean`](https://eemeli.org/yaml/#identifying-nodes) +- [`isMap(foo): boolean`](https://eemeli.org/yaml/#identifying-nodes) +- [`isNode(foo): boolean`](https://eemeli.org/yaml/#identifying-nodes) +- [`isPair(foo): boolean`](https://eemeli.org/yaml/#identifying-nodes) +- [`isScalar(foo): boolean`](https://eemeli.org/yaml/#identifying-nodes) +- [`isSeq(foo): boolean`](https://eemeli.org/yaml/#identifying-nodes) +- [`new Scalar(value)`](https://eemeli.org/yaml/#scalar-values) +- [`new YAMLMap()`](https://eemeli.org/yaml/#collections) +- [`new YAMLSeq()`](https://eemeli.org/yaml/#collections) +- [`doc.createAlias(node, name?): Alias`](https://eemeli.org/yaml/#working-with-anchors) +- [`doc.createNode(value, options?): Node`](https://eemeli.org/yaml/#creating-nodes) +- [`doc.createPair(key, value): Pair`](https://eemeli.org/yaml/#creating-nodes) +- [`visit(node, visitor)`](https://eemeli.org/yaml/#modifying-nodes) + +### Parsing YAML + +- [`new Lexer().lex(src)`](https://eemeli.org/yaml/#lexer) +- [`new Parser(onNewLine?).parse(src)`](https://eemeli.org/yaml/#parser) +- [`new Composer(options?).compose(tokens)`](https://eemeli.org/yaml/#composer) + +## YAML.parse + +```yaml +# file.yml +YAML: + - A human-readable data serialization language + - https://en.wikipedia.org/wiki/YAML +yaml: + - A complete JavaScript implementation + - https://www.npmjs.com/package/yaml +``` + +```js +import fs from 'fs' +import YAML from 'yaml' + +YAML.parse('3.14159') +// 3.14159 + +YAML.parse('[ true, false, maybe, null ]\n') +// [ true, false, 'maybe', null ] + +const file = fs.readFileSync('./file.yml', 'utf8') +YAML.parse(file) +// { YAML: +// [ 'A human-readable data serialization language', +// 'https://en.wikipedia.org/wiki/YAML' ], +// yaml: +// [ 'A complete JavaScript implementation', +// 'https://www.npmjs.com/package/yaml' ] } +``` + +## YAML.stringify + +```js +import YAML from 'yaml' + +YAML.stringify(3.14159) +// '3.14159\n' + +YAML.stringify([true, false, 'maybe', null]) +// `- true +// - false +// - maybe +// - null +// ` + +YAML.stringify({ number: 3, plain: 'string', block: 'two\nlines\n' }) +// `number: 3 +// plain: string +// block: | +// two +// lines +// ` +``` + +--- + +Browser testing provided by: + + + + diff --git a/libs/events/node_modules/yaml/browser/index.js b/libs/events/node_modules/yaml/browser/index.js new file mode 100644 index 000000000..5f7327183 --- /dev/null +++ b/libs/events/node_modules/yaml/browser/index.js @@ -0,0 +1,5 @@ +// `export * as default from ...` fails on Webpack v4 +// https://github.com/eemeli/yaml/issues/228 +import * as YAML from './dist/index.js' +export default YAML +export * from './dist/index.js' diff --git a/libs/events/node_modules/yaml/browser/package.json b/libs/events/node_modules/yaml/browser/package.json new file mode 100644 index 000000000..3dbc1ca59 --- /dev/null +++ b/libs/events/node_modules/yaml/browser/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/libs/events/node_modules/yaml/package.json b/libs/events/node_modules/yaml/package.json new file mode 100644 index 000000000..ceb2f637f --- /dev/null +++ b/libs/events/node_modules/yaml/package.json @@ -0,0 +1,95 @@ +{ + "name": "yaml", + "version": "2.3.2", + "license": "ISC", + "author": "Eemeli Aro ", + "repository": "github:eemeli/yaml", + "description": "JavaScript parser and stringifier for YAML", + "keywords": [ + "YAML", + "parser", + "stringifier" + ], + "homepage": "https://eemeli.org/yaml/", + "files": [ + "browser/", + "dist/", + "util.js" + ], + "type": "commonjs", + "main": "./dist/index.js", + "browser": { + "./dist/index.js": "./browser/index.js", + "./dist/util.js": "./browser/dist/util.js", + "./util.js": "./browser/dist/util.js" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "node": "./dist/index.js", + "default": "./browser/index.js" + }, + "./package.json": "./package.json", + "./util": { + "types": "./dist/util.d.ts", + "node": "./dist/util.js", + "default": "./browser/dist/util.js" + } + }, + "scripts": { + "build": "npm run build:node && npm run build:browser", + "build:browser": "rollup -c config/rollup.browser-config.mjs", + "build:node": "rollup -c config/rollup.node-config.mjs", + "clean": "git clean -fdxe node_modules", + "lint": "eslint src/", + "prettier": "prettier --write .", + "prestart": "npm run build:node", + "start": "node -i -e 'YAML=require(\"./dist/index.js\")'", + "test": "jest --config config/jest.config.js", + "test:all": "npm test && npm run test:types && npm run test:dist && npm run test:dist:types", + "test:browsers": "cd playground && npm test", + "test:dist": "npm run build:node && jest --config config/jest.config.js", + "test:dist:types": "tsc --allowJs --moduleResolution node --noEmit --target es5 dist/index.js", + "test:types": "tsc --noEmit && tsc --noEmit -p tests/tsconfig.json", + "docs:install": "cd docs-slate && bundle install", + "docs:deploy": "cd docs-slate && ./deploy.sh", + "docs": "cd docs-slate && bundle exec middleman server", + "preversion": "npm test && npm run build", + "prepublishOnly": "npm run clean && npm test && npm run build" + }, + "browserslist": "defaults, not ie 11", + "prettier": { + "arrowParens": "avoid", + "semi": false, + "singleQuote": true, + "trailingComma": "none" + }, + "devDependencies": { + "@babel/core": "^7.12.10", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-transform-typescript": "^7.12.17", + "@babel/preset-env": "^7.12.11", + "@rollup/plugin-babel": "^6.0.3", + "@rollup/plugin-replace": "^5.0.2", + "@rollup/plugin-typescript": "^11.0.0", + "@types/jest": "^29.2.4", + "@types/node": "^14.18.35", + "@typescript-eslint/eslint-plugin": "^6.4.1", + "@typescript-eslint/parser": "^6.4.1", + "babel-jest": "^29.0.1", + "cross-env": "^7.0.3", + "eslint": "^8.2.0", + "eslint-config-prettier": "^9.0.0", + "fast-check": "^2.12.0", + "jest": "^29.0.1", + "jest-ts-webcompat-resolver": "^1.0.0", + "prettier": "^3.0.2", + "rollup": "^3.7.5", + "tslib": "^2.1.0", + "typescript": "^5.0.3" + }, + "engines": { + "node": ">= 14" + } +} diff --git a/libs/events/node_modules/yaml/util.js b/libs/events/node_modules/yaml/util.js new file mode 100644 index 000000000..070103f91 --- /dev/null +++ b/libs/events/node_modules/yaml/util.js @@ -0,0 +1,2 @@ +// Re-exporter for Node.js < 12.16.0 +module.exports = require('./dist/util.js') diff --git a/libs/events/package-lock.json b/libs/events/package-lock.json new file mode 100644 index 000000000..e0048eba4 --- /dev/null +++ b/libs/events/package-lock.json @@ -0,0 +1,618 @@ +{ + "name": "formancehq-events", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "formancehq-events", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "json-schema-static-docs": "^0.24.1", + "yaml": "^2.3.2" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-10.1.0.tgz", + "integrity": "sha512-3e+viyMuXdrcK8v5pvP+SDoAQ77FH6OyRmuK48SZKmdHJRFm87RsSs8qm6kP39a/pOPURByJw+OXzQIqcfmKtA==", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.11", + "@types/lodash.clonedeep": "^4.5.7", + "js-yaml": "^4.1.0", + "lodash.clonedeep": "^4.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", + "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==" + }, + "node_modules/@types/lodash": { + "version": "4.14.198", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", + "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==" + }, + "node_modules/@types/lodash.clonedeep": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.7.tgz", + "integrity": "sha512-ccNqkPptFIXrpVqUECi60/DFxjNKsfoQxSQsgcBJCX/fuX1wgyQieojkcWH/KpE3xzLoWN/2k+ZeGqIN3paSvw==", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-static-docs": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/json-schema-static-docs/-/json-schema-static-docs-0.24.1.tgz", + "integrity": "sha512-rNcAuIPkQeqtJy012ycclJlf5AFJeimp2Ui6wwP+xEVndckOW5EfoCtr59cnyfPtF5RuP80gNPvHQ//sVux7Tg==", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^10.1.0", + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "extend": "^3.0.2", + "fast-glob": "^3.3.1", + "handlebars": "^4.7.7", + "jsonpointer": "^5.0.1", + "lodash": ">=4.17.21", + "make-dir": "^3.1.0", + "mkdirp": "^2.1.6", + "optimist": "^0.5.2", + "rimraf": "^4.4.1", + "yaml": "^2.2.2" + }, + "bin": { + "json-schema-static-docs": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/optimist": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.5.2.tgz", + "integrity": "sha512-r9M8ZpnM9SXV5Wii7TCqienfcaY3tAiJe9Jchof87icbmbruKgK0xKXngmrnowTDnEawmmI1Qbha59JEoBkBGA==", + "dependencies": { + "wordwrap": "~0.0.2" + } + }, + "node_modules/optimist/node_modules/wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, + "node_modules/yaml": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", + "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/libs/events/package.json b/libs/events/package.json new file mode 100644 index 000000000..42f918bc7 --- /dev/null +++ b/libs/events/package.json @@ -0,0 +1,15 @@ +{ + "name": "formancehq-events", + "version": "1.0.0", + "description": "This repository centralizes event schemas across the Formance Stack. For each stack version, a repository named \"vX\" contains all related events.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "json-schema-static-docs": "^0.24.1", + "yaml": "^2.3.2" + } +} diff --git a/libs/events/v1/ledger/COMMITTED_TRANSACTIONS.yaml b/libs/events/services/ledger/v1.0.0/COMMITTED_TRANSACTIONS.yaml similarity index 100% rename from libs/events/v1/ledger/COMMITTED_TRANSACTIONS.yaml rename to libs/events/services/ledger/v1.0.0/COMMITTED_TRANSACTIONS.yaml diff --git a/libs/events/v1/ledger/REVERTED_TRANSACTION.yaml b/libs/events/services/ledger/v1.0.0/REVERTED_TRANSACTION.yaml similarity index 100% rename from libs/events/v1/ledger/REVERTED_TRANSACTION.yaml rename to libs/events/services/ledger/v1.0.0/REVERTED_TRANSACTION.yaml diff --git a/libs/events/v1/ledger/SAVED_METADATA.yaml b/libs/events/services/ledger/v1.0.0/SAVED_METADATA.yaml similarity index 100% rename from libs/events/v1/ledger/SAVED_METADATA.yaml rename to libs/events/services/ledger/v1.0.0/SAVED_METADATA.yaml diff --git a/libs/events/services/ledger/v2.0.0/COMMITTED_TRANSACTIONS.yaml b/libs/events/services/ledger/v2.0.0/COMMITTED_TRANSACTIONS.yaml new file mode 100644 index 000000000..c03f96b47 --- /dev/null +++ b/libs/events/services/ledger/v2.0.0/COMMITTED_TRANSACTIONS.yaml @@ -0,0 +1,49 @@ +type: object +properties: + ledger: + type: string + transactions: + type: array + items: + type: object + properties: + postings: + type: array + items: + type: object + properties: + source: + type: string + destination: + type: string + amount: + type: number + asset: + type: string + required: + - source + - destination + - amount + - asset + reference: + type: string + metadata: + type: object + properties: {} + required: [] + id: + type: number + timestamp: + type: string + reverted: + type: boolean + required: + - postings + - reference + - metadata + - id + - timestamp + - reverted +required: +- ledger +- transactions diff --git a/libs/events/services/ledger/v2.0.0/DELETED_METADATA.yaml b/libs/events/services/ledger/v2.0.0/DELETED_METADATA.yaml new file mode 100644 index 000000000..8fbddf245 --- /dev/null +++ b/libs/events/services/ledger/v2.0.0/DELETED_METADATA.yaml @@ -0,0 +1,15 @@ +type: object +properties: + ledger: + type: string + targetType: + type: string + targetId: + type: string + key: + type: string +required: + - ledger + - targetType + - targetId + - key diff --git a/libs/events/services/ledger/v2.0.0/REVERTED_TRANSACTION.yaml b/libs/events/services/ledger/v2.0.0/REVERTED_TRANSACTION.yaml new file mode 100644 index 000000000..24e3f077a --- /dev/null +++ b/libs/events/services/ledger/v2.0.0/REVERTED_TRANSACTION.yaml @@ -0,0 +1,85 @@ +type: object +properties: + ledger: + type: string + revertedTransaction: + type: object + properties: + postings: + type: array + items: + type: object + properties: + source: + type: string + destination: + type: string + amount: + type: number + asset: + type: string + required: + - source + - destination + - amount + - asset + reference: + type: string + metadata: + type: object + properties: { } + required: [ ] + id: + type: number + timestamp: + type: string + reverted: + type: boolean + required: + - postings + - reference + - metadata + - id + - timestamp + - reverted + revertTransaction: + type: object + properties: + postings: + type: array + items: + type: object + properties: + source: + type: string + destination: + type: string + amount: + type: number + asset: + type: string + required: + - source + - destination + - amount + - asset + reference: + type: string + metadata: + type: object + properties: { } + required: [ ] + id: + type: number + timestamp: + type: string + required: + - postings + - reference + - metadata + - id + - timestamp +required: +- ledger +- revertedTransaction +- revertTransaction diff --git a/libs/events/services/ledger/v2.0.0/SAVED_METADATA.yaml b/libs/events/services/ledger/v2.0.0/SAVED_METADATA.yaml new file mode 100644 index 000000000..0333be348 --- /dev/null +++ b/libs/events/services/ledger/v2.0.0/SAVED_METADATA.yaml @@ -0,0 +1,16 @@ +type: object +properties: + ledger: + type: string + targetType: + type: string + targetId: + type: string + metadata: + type: object + additionalProperties: {} +required: +- ledger +- targetType +- targetId +- metadata diff --git a/libs/events/v1/payments/CONNECTOR_RESET.yaml b/libs/events/services/payments/v1.0.0/CONNECTOR_RESET.yaml similarity index 100% rename from libs/events/v1/payments/CONNECTOR_RESET.yaml rename to libs/events/services/payments/v1.0.0/CONNECTOR_RESET.yaml diff --git a/libs/events/v1/payments/SAVED_PAYMENT.yaml b/libs/events/services/payments/v1.0.0/SAVED_PAYMENT.yaml similarity index 100% rename from libs/events/v1/payments/SAVED_PAYMENT.yaml rename to libs/events/services/payments/v1.0.0/SAVED_PAYMENT.yaml diff --git a/libs/go-libs/bun/bundebug/debug_hook.go b/libs/go-libs/bun/bundebug/debug_hook.go new file mode 100644 index 000000000..236177352 --- /dev/null +++ b/libs/go-libs/bun/bundebug/debug_hook.go @@ -0,0 +1,41 @@ +package bundebug + +import ( + "context" + "fmt" + "time" + + "github.com/formancehq/stack/libs/go-libs/logging" + + "github.com/uptrace/bun" +) + +type QueryHook struct{} + +var _ bun.QueryHook = (*QueryHook)(nil) + +func NewQueryHook() *QueryHook { + return &QueryHook{} +} + +func (h *QueryHook) BeforeQuery( + ctx context.Context, event *bun.QueryEvent, +) context.Context { + return ctx +} + +func (h *QueryHook) AfterQuery(ctx context.Context, event *bun.QueryEvent) { + dur := time.Since(event.StartTime) + + fields := map[string]any{ + "component": "bun", + "operation": event.Operation(), + "duration": fmt.Sprintf("%s", dur.Round(time.Microsecond)), + } + + if event.Err != nil { + fields["err"] = event.Err.Error() + } + + logging.FromContext(ctx).WithFields(fields).Debug(event.Query) +} diff --git a/libs/go-libs/bun/bunexplain/explain_hook.go b/libs/go-libs/bun/bunexplain/explain_hook.go new file mode 100644 index 000000000..5767cc30a --- /dev/null +++ b/libs/go-libs/bun/bunexplain/explain_hook.go @@ -0,0 +1,50 @@ +package bunexplain + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/uptrace/bun" +) + +//nolint:unused +type explainHook struct{} + +//nolint:unused +func (h *explainHook) AfterQuery(ctx context.Context, event *bun.QueryEvent) {} + +//nolint:unused +func (h *explainHook) BeforeQuery(ctx context.Context, event *bun.QueryEvent) context.Context { + lowerQuery := strings.ToLower(event.Query) + if strings.HasPrefix(lowerQuery, "explain") || + strings.HasPrefix(lowerQuery, "create") || + strings.HasPrefix(lowerQuery, "begin") || + strings.HasPrefix(lowerQuery, "alter") || + strings.HasPrefix(lowerQuery, "rollback") || + strings.HasPrefix(lowerQuery, "commit") { + return ctx + } + + event.DB.RunInTx(context.Background(), &sql.TxOptions{}, func(ctx context.Context, tx bun.Tx) error { + rows, err := tx.Query("explain analyze " + event.Query) + if err != nil { + return err + } + defer rows.Next() + + for rows.Next() { + var line string + if err := rows.Scan(&line); err != nil { + return err + } + fmt.Println(line) + } + + return tx.Rollback() + + }) + + return ctx +} diff --git a/libs/go-libs/httpserver/serverport.go b/libs/go-libs/httpserver/serverport.go index 86a16f761..d1e096d06 100644 --- a/libs/go-libs/httpserver/serverport.go +++ b/libs/go-libs/httpserver/serverport.go @@ -18,7 +18,7 @@ type serverInfoContextKey string var serverInfoKey serverInfoContextKey = "_serverInfo" -func getActualServerInfo(ctx context.Context) *serverInfo { +func GetActualServerInfo(ctx context.Context) *serverInfo { siAsAny := ctx.Value(serverInfoKey) if siAsAny == nil { return nil @@ -33,7 +33,7 @@ func ContextWithServerInfo(ctx context.Context) context.Context { } func Started(ctx context.Context) chan struct{} { - si := getActualServerInfo(ctx) + si := GetActualServerInfo(ctx) if si == nil { return nil } @@ -41,7 +41,7 @@ func Started(ctx context.Context) chan struct{} { } func Port(ctx context.Context) int { - si := getActualServerInfo(ctx) + si := GetActualServerInfo(ctx) if si == nil { return 0 } @@ -49,7 +49,7 @@ func Port(ctx context.Context) int { } func StartedServer(ctx context.Context, listener net.Listener) { - si := getActualServerInfo(ctx) + si := GetActualServerInfo(ctx) if si == nil { return } diff --git a/libs/go-libs/migrations/migration.go b/libs/go-libs/migrations/migration.go index f3aecbe0a..1405f18bd 100644 --- a/libs/go-libs/migrations/migration.go +++ b/libs/go-libs/migrations/migration.go @@ -1,9 +1,13 @@ package migrations import ( + "context" + "github.com/uptrace/bun" ) type Migration struct { - Up func(tx bun.Tx) error + Name string + Up func(tx bun.Tx) error + UpWithContext func(ctx context.Context, tx bun.Tx) error } diff --git a/libs/go-libs/migrations/migrator.go b/libs/go-libs/migrations/migrator.go index 9c5c02aba..858f12d61 100644 --- a/libs/go-libs/migrations/migrator.go +++ b/libs/go-libs/migrations/migrator.go @@ -15,8 +15,28 @@ const ( migrationTable = "goose_db_version" ) +type Info struct { + bun.BaseModel `bun:"goose_db_version"` + + Version string `json:"version" bun:"version_id"` + Name string `json:"name" bun:"-"` + State string `json:"state,omitempty" bun:"-"` + Date time.Time `json:"date,omitempty" bun:"tstamp"` +} + type Migrator struct { - migrations []Migration + migrations []Migration + schema string + createSchema bool +} + +type option func(m *Migrator) + +func WithSchema(schema string, create bool) option { + return func(m *Migrator) { + m.schema = schema + m.createSchema = create + } } func (m *Migrator) RegisterMigrations(migrations ...Migration) *Migrator { @@ -82,8 +102,8 @@ func (m *Migrator) GetDBVersion(ctx context.Context, db *bun.DB) (int64, error) return m.getLastVersion(ctx, db) } -func (m *Migrator) Up(ctx context.Context, db *bun.DB) error { - tx, err := db.Begin() +func (m *Migrator) Up(ctx context.Context, db bun.IDB) error { + tx, err := db.BeginTx(ctx, &sql.TxOptions{}) if err != nil { return err } @@ -91,6 +111,19 @@ func (m *Migrator) Up(ctx context.Context, db *bun.DB) error { _ = tx.Rollback() }() + if m.schema != "" { + if m.createSchema { + _, err := tx.ExecContext(ctx, fmt.Sprintf(`create schema if not exists "%s"`, m.schema)) + if err != nil { + return err + } + } + _, err := tx.ExecContext(ctx, fmt.Sprintf(`set search_path = "%s"`, m.schema)) + if err != nil { + return err + } + } + if err := m.createVersionTable(ctx, tx); err != nil { return err } @@ -102,9 +135,17 @@ func (m *Migrator) Up(ctx context.Context, db *bun.DB) error { if len(m.migrations) > int(lastMigration)-1 { for ind, migration := range m.migrations[lastMigration:] { + if migration.UpWithContext != nil { + if err := migration.UpWithContext(ctx, tx); err != nil { + return err + } + } else if migration.Up != nil { if err := migration.Up(tx); err != nil { return err } + } else { + return errors.New("no code defined for migration") + } if err := m.insertVersion(ctx, tx, int(lastMigration)+ind+1); err != nil { return err @@ -115,6 +156,42 @@ func (m *Migrator) Up(ctx context.Context, db *bun.DB) error { return tx.Commit() } -func NewMigrator() *Migrator { - return &Migrator{} +func (m *Migrator) GetMigrations(ctx context.Context, db bun.IDB) ([]Info, error) { + migrationTableName := migrationTable + if m.schema != "" { + migrationTableName = fmt.Sprintf(`"%s".%s`, m.schema, migrationTableName) + } + + ret := make([]Info, 0) + if err := db.NewSelect(). + TableExpr(migrationTableName). + Order("version_id"). + Where("version_id >= 1"). + Column("version_id", "tstamp"). + Scan(ctx, &ret); err != nil { + return nil, err + } + + for i := 0; i < len(ret); i++ { + ret[i].Name = m.migrations[i].Name + ret[i].State = "DONE" + } + + for i := len(ret); i < len(m.migrations); i++ { + ret = append(ret, Info{ + Version: fmt.Sprint(i), + Name: m.migrations[i].Name, + State: "TO DO", + }) + } + + return ret, nil +} + +func NewMigrator(opts ...option) *Migrator { + ret := &Migrator{} + for _, opt := range opts { + opt(ret) + } + return ret } diff --git a/libs/go-libs/otlp/otlpmetrics/cli.go b/libs/go-libs/otlp/otlpmetrics/cli.go index 894564cd1..98e8072c7 100644 --- a/libs/go-libs/otlp/otlpmetrics/cli.go +++ b/libs/go-libs/otlp/otlpmetrics/cli.go @@ -24,7 +24,7 @@ func InitOTLPMetricsFlags(flags *flag.FlagSet) { otlp.InitOTLPFlags(flags) flags.Bool(OtelMetricsFlag, false, "Enable OpenTelemetry traces support") - flags.Duration(OtelMetricsExporterPushIntervalFlag, 100*time.Millisecond, "OpenTelemetry metrics exporter push interval") + flags.Duration(OtelMetricsExporterPushIntervalFlag, 10*time.Second, "OpenTelemetry metrics exporter push interval") flags.Bool(OtelMetricsRuntimeFlag, false, "Enable OpenTelemetry runtime metrics") flags.Duration(OtelMetricsRuntimeMinimumReadMemStatsIntervalFlag, 15*time.Second, "OpenTelemetry runtime metrics minimum read mem stats interval") flags.String(OtelMetricsExporterFlag, "stdout", "OpenTelemetry metrics exporter") diff --git a/libs/go-libs/otlp/otlpmetrics/module.go b/libs/go-libs/otlp/otlpmetrics/module.go index 3628cea21..77366f863 100644 --- a/libs/go-libs/otlp/otlpmetrics/module.go +++ b/libs/go-libs/otlp/otlpmetrics/module.go @@ -2,6 +2,7 @@ package otlpmetrics import ( "context" + "fmt" "time" "github.com/formancehq/stack/libs/go-libs/logging" @@ -63,9 +64,11 @@ func MetricsModule(cfg ModuleConfig) fx.Option { otlp.LoadResource(cfg.ServiceName, cfg.ResourceAttributes), fx.Decorate(fx.Annotate(func(mp *sdkmetric.MeterProvider) metric.MeterProvider { return mp }, fx.As(new(metric.MeterProvider)))), fx.Provide(fx.Annotate(func(options ...sdkmetric.Option) *sdkmetric.MeterProvider { + fmt.Println("run meter provider with options", options) return sdkmetric.NewMeterProvider(options...) }, fx.ParamTags(metricsProviderOptionKey))), fx.Invoke(func(lc fx.Lifecycle, metricProvider *sdkmetric.MeterProvider, options ...runtime.Option) { + fmt.Println("start meter provider") // set global propagator to tracecontext (the default is no-op). otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator( b3.New(), propagation.TraceContext{})) // B3 format is common and used by zipkin. Always enabled right now. @@ -99,7 +102,7 @@ func MetricsModule(cfg ModuleConfig) fx.Option { ProvideMetricsProviderOption(sdkmetric.WithResource), ProvideMetricsProviderOption(sdkmetric.WithReader), fx.Provide( - fx.Annotate(sdkmetric.NewPeriodicReader, fx.As(new(sdkmetric.Reader))), + fx.Annotate(sdkmetric.NewPeriodicReader, fx.ParamTags(``, OTLPMetricsPeriodicReaderOptionsKey), fx.As(new(sdkmetric.Reader))), ), ProvideOTLPMetricsPeriodicReaderOption(func() sdkmetric.PeriodicReaderOption { return sdkmetric.WithInterval(cfg.PushInterval) diff --git a/libs/go-libs/pgtesting/postgres.go b/libs/go-libs/pgtesting/postgres.go index 578044a42..372001e6b 100644 --- a/libs/go-libs/pgtesting/postgres.go +++ b/libs/go-libs/pgtesting/postgres.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "fmt" + "os" "strconv" "sync" "time" @@ -76,12 +77,14 @@ func (s *pgServer) NewDatabase(t TestingT) *pgDatabase { _, err := s.db.ExecContext(context.Background(), fmt.Sprintf(`CREATE DATABASE "%s"`, databaseName)) require.NoError(t, err) - t.Cleanup(func() { - s.lock.Lock() - defer s.lock.Unlock() + if os.Getenv("NO_CLEANUP") != "true" { + t.Cleanup(func() { + s.lock.Lock() + defer s.lock.Unlock() - _, _ = s.db.ExecContext(context.Background(), fmt.Sprintf(`DROP DATABASE "%s"`, databaseName)) - }) + _, _ = s.db.ExecContext(context.Background(), fmt.Sprintf(`DROP DATABASE "%s"`, databaseName)) + }) + } return &pgDatabase{ url: s.GetDatabaseDSN(databaseName), @@ -92,6 +95,9 @@ func (s *pgServer) Close() error { if s.db == nil { return nil } + if os.Getenv("NO_CLEANUP") == "true" { + return nil + } if err := s.db.Close(); err != nil { return err } diff --git a/libs/go-libs/publish/module.go b/libs/go-libs/publish/module.go index 3b7c4b966..1f0df0bf9 100644 --- a/libs/go-libs/publish/module.go +++ b/libs/go-libs/publish/module.go @@ -9,12 +9,12 @@ import ( "go.uber.org/fx" ) -func newGoChannel(logger watermill.LoggerAdapter) *gochannel.GoChannel { +func newGoChannel() *gochannel.GoChannel { return gochannel.NewGoChannel( gochannel.Config{ BlockPublishUntilSubscriberAck: true, }, - logger, + watermill.NopLogger{}, ) } diff --git a/libs/go-libs/service/app.go b/libs/go-libs/service/app.go index 85ed6b41a..f1ce5831d 100644 --- a/libs/go-libs/service/app.go +++ b/libs/go-libs/service/app.go @@ -18,8 +18,9 @@ type App struct { } func (a *App) Run(ctx context.Context) error { - app := a.newFxApp(ctx) - if err := app.Start(ctx); err != nil { + logger := GetDefaultLogger(a.output, viper.GetBool(DebugFlag), viper.GetBool(JsonFormattingLoggerFlag)) + app := a.newFxApp(logger) + if err := app.Start(logging.ContextWithLogger(ctx, logger)); err != nil { return err } @@ -30,22 +31,19 @@ func (a *App) Run(ctx context.Context) error { // app.Stop in order to gracefully shutdown the app } - return app.Stop(context.Background()) + return app.Stop(logging.ContextWithLogger(context.Background(), logger)) } func (a *App) Start(ctx context.Context) error { - return a.newFxApp(ctx).Start(ctx) + logger := GetDefaultLogger(a.output, viper.GetBool(DebugFlag), viper.GetBool(JsonFormattingLoggerFlag)) + return a.newFxApp(logger).Start(ctx) } -func (a *App) newFxApp(ctx context.Context) *fx.App { - ctx = defaultLoggingContext(ctx, a.output, viper.GetBool(DebugFlag), viper.GetBool(JsonFormattingLoggerFlag)) - options := append(a.options, +func (a *App) newFxApp(logger logging.Logger) *fx.App { + return fx.New(append(a.options, fx.NopLogger, - fx.Provide(func() logging.Logger { - return logging.FromContext(ctx) - }), - ) - return fx.New(options...) + fx.Supply(fx.Annotate(logger, fx.As(new(logging.Logger)))), + )...) } func New(output io.Writer, options ...fx.Option) *App { diff --git a/libs/go-libs/service/logging.go b/libs/go-libs/service/logging.go index 20821588f..5b20fd01b 100644 --- a/libs/go-libs/service/logging.go +++ b/libs/go-libs/service/logging.go @@ -1,7 +1,6 @@ package service import ( - "context" "io" "github.com/formancehq/stack/libs/go-libs/logging" @@ -42,7 +41,3 @@ func GetDefaultLogger(w io.Writer, debug, jsonFormattingLog bool) logging.Logger } return logging.NewLogrus(l) } - -func defaultLoggingContext(parent context.Context, w io.Writer, debug, jsonFormattingLog bool) context.Context { - return logging.ContextWithLogger(parent, GetDefaultLogger(w, debug, jsonFormattingLog)) -} diff --git a/openapi/build/generate.json b/openapi/build/generate.json index c89f0207a..f4cb8ae1d 100644 --- a/openapi/build/generate.json +++ b/openapi/build/generate.json @@ -12,7 +12,7 @@ "url": "https://avatars.githubusercontent.com/u/84325077?s=200&v=4", "altText": "Formance" }, - "version": "v1.0.20230907" + "version": "v1.0.20230908" }, "servers": [ { @@ -648,7 +648,7 @@ } } }, - "/api/ledger/_info": { + "/api/ledger/v2/_info": { "get": { "tags": [ "Ledger", @@ -680,7 +680,7 @@ } } }, - "/api/ledger/{ledger}/_info": { + "/api/ledger/v2/{ledger}/_info": { "get": { "summary": "Get information about a ledger", "operationId": "getLedgerInfo", @@ -723,7 +723,7 @@ } } }, - "/api/ledger/{ledger}/accounts": { + "/api/ledger/v2/{ledger}/accounts": { "head": { "summary": "Count the accounts from a ledger", "operationId": "countAccounts", @@ -741,31 +741,18 @@ "type": "string", "example": "ledger001" } - }, - { - "name": "address", - "in": "query", - "description": "Filter accounts by address pattern (regular expression placed between ^ and $).", - "schema": { - "type": "string", - "example": "users:.+" - } - }, - { - "name": "metadata", - "in": "query", - "description": "Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2", - "style": "deepObject", - "explode": true, - "schema": { - "type": "object", - "properties": {} - }, - "example": { - "admin": "true" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + }, "responses": { "204": { "description": "OK", @@ -823,40 +810,44 @@ } }, { - "name": "address", + "name": "cursor", "in": "query", - "description": "Filter accounts by address pattern (regular expression placed between ^ and $).", + "description": "Parameter used in pagination requests. Maximum page size is set to 15.\nSet to the value of next for the next page of results.\nSet to the value of previous for the previous page of results.\nNo other parameters can be set when this parameter is set.\n", "schema": { "type": "string", - "example": "users:.+" + "example": "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==" } }, { - "name": "metadata", + "name": "expand", "in": "query", - "description": "Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2", - "style": "deepObject", "schema": { - "type": "object", - "properties": {}, - "additionalProperties": { + "type": "string", + "items": { "type": "string" } - }, - "example": { - "admin": "true" } }, { - "name": "cursor", + "name": "pit", "in": "query", - "description": "Parameter used in pagination requests. Maximum page size is set to 15.\nSet to the value of next for the next page of results.\nSet to the value of previous for the previous page of results.\nNo other parameters can be set when this parameter is set.\n", + "required": false, "schema": { "type": "string", - "example": "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==" + "format": "date-time" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + }, "responses": { "200": { "description": "OK", @@ -881,7 +872,7 @@ } } }, - "/api/ledger/{ledger}/accounts/{address}": { + "/api/ledger/v2/{ledger}/accounts/{address}": { "get": { "summary": "Get account by its address", "operationId": "getAccount", @@ -909,6 +900,16 @@ "type": "string", "example": "users:001" } + }, + { + "name": "expand", + "in": "query", + "schema": { + "type": "string", + "items": { + "type": "string" + } + } } ], "responses": { @@ -935,7 +936,7 @@ } } }, - "/api/ledger/{ledger}/accounts/{address}/metadata": { + "/api/ledger/v2/{ledger}/accounts/{address}/metadata": { "post": { "summary": "Add metadata to an account", "operationId": "addMetadataToAccount", @@ -973,15 +974,6 @@ "example": true } }, - { - "name": "async", - "in": "query", - "description": "Set async mode.", - "schema": { - "type": "boolean", - "example": true - } - }, { "name": "Idempotency-Key", "in": "header", @@ -1020,7 +1012,7 @@ } } }, - "/api/ledger/{ledger}/stats": { + "/api/ledger/v2/{ledger}/stats": { "get": { "tags": [ "Ledger", @@ -1065,7 +1057,7 @@ } } }, - "/api/ledger/{ledger}/transactions": { + "/api/ledger/v2/{ledger}/transactions": { "head": { "tags": [ "Ledger", @@ -1085,76 +1077,25 @@ } }, { - "name": "reference", + "name": "pit", "in": "query", - "description": "Filter transactions by reference field.", - "schema": { - "type": "string", - "example": "ref:001" - } - }, - { - "name": "account", - "in": "query", - "description": "Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $).", - "schema": { - "type": "string", - "example": "users:001" - } - }, - { - "name": "source", - "in": "query", - "description": "Filter transactions with postings involving given account at source (regular expression placed between ^ and $).", - "schema": { - "type": "string", - "example": "users:001" - } - }, - { - "name": "destination", - "in": "query", - "description": "Filter transactions with postings involving given account at destination (regular expression placed between ^ and $).", - "schema": { - "type": "string", - "example": "users:001" - } - }, - { - "name": "startTime", - "in": "query", - "description": "Filter transactions that occurred after this timestamp.\nThe format is RFC3339 and is inclusive (for example, \"2023-01-02T15:04:01Z\" includes the first second of 4th minute).\n", - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "endTime", - "in": "query", - "description": "Filter transactions that occurred before this timestamp.\nThe format is RFC3339 and is exclusive (for example, \"2023-01-02T15:04:01Z\" excludes the first second of 4th minute).\n", + "required": false, "schema": { "type": "string", "format": "date-time" } - }, - { - "name": "metadata", - "in": "query", - "description": "Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2", - "style": "deepObject", - "schema": { - "type": "object", - "properties": {}, - "additionalProperties": { - "type": "string" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true } - }, - "example": { - "admin": "true" } } - ], + }, "responses": { "204": { "description": "OK", @@ -1186,7 +1127,7 @@ "Transactions" ], "summary": "List transactions from a ledger", - "description": "List transactions from a ledger, sorted by txid in descending order.", + "description": "List transactions from a ledger, sorted by id in descending order.", "operationId": "listTransactions", "parameters": [ { @@ -1212,85 +1153,44 @@ } }, { - "name": "reference", - "in": "query", - "description": "Find transactions by reference field.", - "schema": { - "type": "string", - "example": "ref:001" - } - }, - { - "name": "account", - "in": "query", - "description": "Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $).", - "schema": { - "type": "string", - "example": "users:001" - } - }, - { - "name": "source", - "in": "query", - "description": "Filter transactions with postings involving given account at source (regular expression placed between ^ and $).", - "schema": { - "type": "string", - "example": "users:001" - } - }, - { - "name": "destination", + "name": "cursor", "in": "query", - "description": "Filter transactions with postings involving given account at destination (regular expression placed between ^ and $).", + "description": "Parameter used in pagination requests. Maximum page size is set to 15.\nSet to the value of next for the next page of results.\nSet to the value of previous for the previous page of results.\nNo other parameters can be set when this parameter is set.\n", "schema": { "type": "string", - "example": "users:001" + "example": "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==" } }, { - "name": "startTime", + "name": "expand", "in": "query", - "description": "Filter transactions that occurred after this timestamp.\nThe format is RFC3339 and is inclusive (for example, \"2023-01-02T15:04:01Z\" includes the first second of 4th minute).\n", "schema": { "type": "string", - "format": "date-time" + "items": { + "type": "string" + } } }, { - "name": "endTime", + "name": "pit", "in": "query", - "description": "Filter transactions that occurred before this timestamp.\nThe format is RFC3339 and is exclusive (for example, \"2023-01-02T15:04:01Z\" excludes the first second of 4th minute).\n", + "required": false, "schema": { "type": "string", "format": "date-time" } - }, - { - "name": "cursor", - "in": "query", - "description": "Parameter used in pagination requests. Maximum page size is set to 15.\nSet to the value of next for the next page of results.\nSet to the value of previous for the previous page of results.\nNo other parameters can be set when this parameter is set.\n", - "schema": { - "type": "string", - "example": "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==" - } - }, - { - "name": "metadata", - "in": "query", - "description": "Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below.", - "style": "deepObject", - "schema": { - "type": "object", - "properties": {}, - "additionalProperties": { - "type": "string" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true } - }, - "example": { - "admin": "true" } } - ], + }, "responses": { "200": { "description": "OK", @@ -1341,15 +1241,6 @@ "example": true } }, - { - "name": "async", - "in": "query", - "description": "Set async mode.", - "schema": { - "type": "boolean", - "example": true - } - }, { "name": "Idempotency-Key", "in": "header", @@ -1394,7 +1285,7 @@ } } }, - "/api/ledger/{ledger}/transactions/{txid}": { + "/api/ledger/v2/{ledger}/transactions/{id}": { "get": { "tags": [ "Ledger", @@ -1414,7 +1305,7 @@ } }, { - "name": "txid", + "name": "id", "in": "path", "description": "Transaction ID.", "required": true, @@ -1424,6 +1315,16 @@ "minimum": 0, "example": 1234 } + }, + { + "name": "expand", + "in": "query", + "schema": { + "type": "string", + "items": { + "type": "string" + } + } } ], "responses": { @@ -1450,7 +1351,7 @@ } } }, - "/api/ledger/{ledger}/transactions/{txid}/metadata": { + "/api/ledger/v2/{ledger}/transactions/{id}/metadata": { "post": { "tags": [ "Ledger", @@ -1470,7 +1371,7 @@ } }, { - "name": "txid", + "name": "id", "in": "path", "description": "Transaction ID.", "required": true, @@ -1490,15 +1391,6 @@ "example": true } }, - { - "name": "async", - "in": "query", - "description": "Set async mode.", - "schema": { - "type": "boolean", - "example": true - } - }, { "name": "Idempotency-Key", "in": "header", @@ -1536,7 +1428,7 @@ } } }, - "/api/ledger/{ledger}/transactions/{txid}/revert": { + "/api/ledger/v2/{ledger}/transactions/{id}/revert": { "post": { "tags": [ "Ledger", @@ -1556,7 +1448,7 @@ } }, { - "name": "txid", + "name": "id", "in": "path", "description": "Transaction ID.", "required": true, @@ -1592,81 +1484,7 @@ } } }, - "/api/ledger/{ledger}/balances": { - "get": { - "tags": [ - "Ledger", - "Balances" - ], - "summary": "Get the balances from a ledger's account", - "operationId": "getBalances", - "parameters": [ - { - "name": "ledger", - "in": "path", - "description": "Name of the ledger.", - "required": true, - "schema": { - "type": "string", - "example": "ledger001" - } - }, - { - "name": "address", - "in": "query", - "description": "Filter balances involving given account, either as source or destination.", - "schema": { - "type": "string", - "example": "users:001" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "The maximum number of results to return per page.\n", - "example": 100, - "schema": { - "type": "integer", - "format": "int64", - "minimum": 1, - "maximum": 1000 - } - }, - { - "name": "cursor", - "in": "query", - "description": "Parameter used in pagination requests. Maximum page size is set to 15.\nSet to the value of next for the next page of results.\nSet to the value of previous for the previous page of results.\nNo other parameters can be set when this parameter is set.\n", - "schema": { - "type": "string", - "example": "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BalancesCursorResponse" - } - } - } - }, - "default": { - "description": "Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/ledger/{ledger}/aggregate/balances": { + "/api/ledger/v2/{ledger}/aggregate/balances": { "get": { "tags": [ "Ledger", @@ -1684,15 +1502,6 @@ "type": "string", "example": "ledger001" } - }, - { - "name": "address", - "in": "query", - "description": "Filter balances involving given account, either as source or destination.", - "schema": { - "type": "string", - "example": "users:001" - } } ], "responses": { @@ -1719,7 +1528,7 @@ } } }, - "/api/ledger/{ledger}/logs": { + "/api/ledger/v2/{ledger}/logs": { "get": { "tags": [ "Ledger", @@ -1752,33 +1561,34 @@ } }, { - "name": "startTime", + "name": "cursor", "in": "query", - "description": "Filter transactions that occurred after this timestamp.\nThe format is RFC3339 and is inclusive (for example, \"2023-01-02T15:04:01Z\" includes the first second of 4th minute).\n", + "description": "Parameter used in pagination requests. Maximum page size is set to 15.\nSet to the value of next for the next page of results.\nSet to the value of previous for the previous page of results.\nNo other parameters can be set when this parameter is set.\n", "schema": { "type": "string", - "format": "date-time" + "example": "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==" } }, { - "name": "endTime", + "name": "pit", "in": "query", - "description": "Filter transactions that occurred before this timestamp.\nThe format is RFC3339 and is exclusive (for example, \"2023-01-02T15:04:01Z\" excludes the first second of 4th minute).\n", + "required": false, "schema": { "type": "string", "format": "date-time" } - }, - { - "name": "cursor", - "in": "query", - "description": "Parameter used in pagination requests. Maximum page size is set to 15.\nSet to the value of next for the next page of results.\nSet to the value of previous for the previous page of results.\nNo other parameters can be set when this parameter is set.\n", - "schema": { - "type": "string", - "example": "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + }, "responses": { "200": { "description": "OK", @@ -4382,9 +4192,7 @@ "type": "object", "required": [ "address", - "metadata", - "volumes", - "balances" + "metadata" ], "properties": { "address": { @@ -4421,16 +4229,6 @@ "output": 0 } } - }, - "balances": { - "type": "object", - "additionalProperties": { - "type": "integer", - "format": "bigint" - }, - "example": { - "COIN": 100 - } } } }, @@ -4538,17 +4336,21 @@ "metadata": { "$ref": "#/components/schemas/ledgerMetadata" }, - "txid": { + "id": { "type": "integer", "format": "int64", "minimum": 0 + }, + "reverted": { + "type": "boolean" } }, "required": [ "postings", "timestamp", - "txid", - "metadata" + "id", + "metadata", + "reverted" ] }, "ExpandedTransaction": { @@ -4565,11 +4367,7 @@ "postCommitVolumes": { "$ref": "#/components/schemas/AggregatedVolumes" } - }, - "required": [ - "preCommitVolumes", - "postCommitVolumes" - ] + } } ] }, @@ -6073,7 +5871,7 @@ }, "sort": { "type": "string", - "example": "txid:asc" + "example": "id:asc" }, "policy": { "type": "string", @@ -6624,7 +6422,7 @@ }, "description": "Metadata associated with the wallet." }, - "txid": { + "id": { "type": "integer", "format": "int64", "minimum": 0 @@ -6639,7 +6437,7 @@ "required": [ "postings", "timestamp", - "txid", + "ix", "metadata" ] }, diff --git a/sdks/go/README.md b/sdks/go/README.md index 3cf8398c8..b7d5c068f 100755 --- a/sdks/go/README.md +++ b/sdks/go/README.md @@ -79,7 +79,6 @@ func main() { * [CountTransactions](docs/sdks/ledger/README.md#counttransactions) - Count the transactions from a ledger * [CreateTransaction](docs/sdks/ledger/README.md#createtransaction) - Create a new transaction to a ledger * [GetAccount](docs/sdks/ledger/README.md#getaccount) - Get account by its address -* [GetBalances](docs/sdks/ledger/README.md#getbalances) - Get the balances from a ledger's account * [GetBalancesAggregated](docs/sdks/ledger/README.md#getbalancesaggregated) - Get the aggregated balances from selected accounts * [GetInfo](docs/sdks/ledger/README.md#getinfo) - Show server information * [GetLedgerInfo](docs/sdks/ledger/README.md#getledgerinfo) - Get information about a ledger diff --git a/sdks/go/docs/models/operations/addmetadataontransactionrequest.md b/sdks/go/docs/models/operations/addmetadataontransactionrequest.md index 3b5672e2e..98e248435 100755 --- a/sdks/go/docs/models/operations/addmetadataontransactionrequest.md +++ b/sdks/go/docs/models/operations/addmetadataontransactionrequest.md @@ -7,7 +7,6 @@ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | `IdempotencyKey` | **string* | :heavy_minus_sign: | Use an idempotency key | | | `RequestBody` | map[string]*string* | :heavy_minus_sign: | metadata | | -| `Async` | **bool* | :heavy_minus_sign: | Set async mode. | true | | `DryRun` | **bool* | :heavy_minus_sign: | Set the dryRun mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | -| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `Txid` | *int64* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `ID` | *int64* | :heavy_check_mark: | Transaction ID. | 1234 | +| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/addmetadatatoaccountrequest.md b/sdks/go/docs/models/operations/addmetadatatoaccountrequest.md index cf926e2f6..4a0c93c84 100755 --- a/sdks/go/docs/models/operations/addmetadatatoaccountrequest.md +++ b/sdks/go/docs/models/operations/addmetadatatoaccountrequest.md @@ -8,6 +8,5 @@ | `IdempotencyKey` | **string* | :heavy_minus_sign: | Use an idempotency key | | | `RequestBody` | map[string]*string* | :heavy_check_mark: | metadata | | | `Address` | *string* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | -| `Async` | **bool* | :heavy_minus_sign: | Set async mode. | true | | `DryRun` | **bool* | :heavy_minus_sign: | Set the dry run mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/countaccountsmetadata.md b/sdks/go/docs/models/operations/countaccountsmetadata.md deleted file mode 100755 index 7ea898a09..000000000 --- a/sdks/go/docs/models/operations/countaccountsmetadata.md +++ /dev/null @@ -1,9 +0,0 @@ -# CountAccountsMetadata - -Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/countaccountsrequest.md b/sdks/go/docs/models/operations/countaccountsrequest.md index 554ffbf69..4d7af9de8 100755 --- a/sdks/go/docs/models/operations/countaccountsrequest.md +++ b/sdks/go/docs/models/operations/countaccountsrequest.md @@ -3,8 +3,7 @@ ## Fields -| Field | Type | Required | Description | Example | -| ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `Address` | **string* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | -| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `Metadata` | [*CountAccountsMetadata](../../models/operations/countaccountsmetadata.md) | :heavy_minus_sign: | Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------------ | ------------------------ | ------------------------ | ------------------------ | ------------------------ | +| `RequestBody` | map[string]*interface{}* | :heavy_minus_sign: | N/A | | +| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/counttransactionsrequest.md b/sdks/go/docs/models/operations/counttransactionsrequest.md index c95e48a53..2d0b62567 100755 --- a/sdks/go/docs/models/operations/counttransactionsrequest.md +++ b/sdks/go/docs/models/operations/counttransactionsrequest.md @@ -3,13 +3,8 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `Account` | **string* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | -| `Destination` | **string* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `EndTime` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | -| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `Metadata` | map[string]*string* | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `Reference` | **string* | :heavy_minus_sign: | Filter transactions by reference field. | ref:001 | -| `Source` | **string* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `StartTime` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | +| `RequestBody` | map[string]*interface{}* | :heavy_minus_sign: | N/A | | +| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | +| `Pit` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/counttransactionsrequestbody.md b/sdks/go/docs/models/operations/counttransactionsrequestbody.md deleted file mode 100755 index 94a1f6eee..000000000 --- a/sdks/go/docs/models/operations/counttransactionsrequestbody.md +++ /dev/null @@ -1,7 +0,0 @@ -# CountTransactionsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/createtransactionrequest.md b/sdks/go/docs/models/operations/createtransactionrequest.md index 6a5b9e629..2cf1e48f7 100755 --- a/sdks/go/docs/models/operations/createtransactionrequest.md +++ b/sdks/go/docs/models/operations/createtransactionrequest.md @@ -7,6 +7,5 @@ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `IdempotencyKey` | **string* | :heavy_minus_sign: | Use an idempotency key | | | `PostTransaction` | [shared.PostTransaction](../../models/shared/posttransaction.md) | :heavy_check_mark: | The request body must contain at least one of the following objects:
    - `postings`: suitable for simple transactions
    - `script`: enabling more complex transactions with Numscript
    | | -| `Async` | **bool* | :heavy_minus_sign: | Set async mode. | true | | `DryRun` | **bool* | :heavy_minus_sign: | Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/getaccountrequest.md b/sdks/go/docs/models/operations/getaccountrequest.md index e7c7fcf39..c5e1cf726 100755 --- a/sdks/go/docs/models/operations/getaccountrequest.md +++ b/sdks/go/docs/models/operations/getaccountrequest.md @@ -6,4 +6,5 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | `Address` | *string* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | +| `Expand` | **string* | :heavy_minus_sign: | N/A | | | `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/getbalancesaggregatedrequest.md b/sdks/go/docs/models/operations/getbalancesaggregatedrequest.md index 99a64f8da..1c8124aa5 100755 --- a/sdks/go/docs/models/operations/getbalancesaggregatedrequest.md +++ b/sdks/go/docs/models/operations/getbalancesaggregatedrequest.md @@ -3,7 +3,6 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -| `Address` | **string* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/getbalancesrequest.md b/sdks/go/docs/models/operations/getbalancesrequest.md deleted file mode 100755 index 1aa587192..000000000 --- a/sdks/go/docs/models/operations/getbalancesrequest.md +++ /dev/null @@ -1,11 +0,0 @@ -# GetBalancesRequest - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `Address` | **string* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `Cursor` | **string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `PageSize` | **int64* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/getbalancesresponse.md b/sdks/go/docs/models/operations/getbalancesresponse.md deleted file mode 100755 index 68a899713..000000000 --- a/sdks/go/docs/models/operations/getbalancesresponse.md +++ /dev/null @@ -1,12 +0,0 @@ -# GetBalancesResponse - - -## Fields - -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -| `BalancesCursorResponse` | [*shared.BalancesCursorResponse](../../models/shared/balancescursorresponse.md) | :heavy_minus_sign: | OK | -| `ContentType` | *string* | :heavy_check_mark: | N/A | -| `ErrorResponse` | [*shared.ErrorResponse](../../models/shared/errorresponse.md) | :heavy_minus_sign: | Error | -| `StatusCode` | *int* | :heavy_check_mark: | N/A | -| `RawResponse` | [*http.Response](https://pkg.go.dev/net/http#Response) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/gettransactionrequest.md b/sdks/go/docs/models/operations/gettransactionrequest.md index 9d6da7dd3..b23059a91 100755 --- a/sdks/go/docs/models/operations/gettransactionrequest.md +++ b/sdks/go/docs/models/operations/gettransactionrequest.md @@ -5,5 +5,6 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `Txid` | *int64* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `Expand` | **string* | :heavy_minus_sign: | N/A | | +| `ID` | *int64* | :heavy_check_mark: | Transaction ID. | 1234 | +| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/listaccountsrequest.md b/sdks/go/docs/models/operations/listaccountsrequest.md index 8c81c9916..c9fc78dc3 100755 --- a/sdks/go/docs/models/operations/listaccountsrequest.md +++ b/sdks/go/docs/models/operations/listaccountsrequest.md @@ -5,8 +5,9 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `Address` | **string* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | +| `RequestBody` | map[string]*interface{}* | :heavy_minus_sign: | N/A | | | `Cursor` | **string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | +| `Expand` | **string* | :heavy_minus_sign: | N/A | | | `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `Metadata` | map[string]*string* | :heavy_minus_sign: | Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `PageSize` | **int64* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file +| `PageSize` | **int64* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | +| `Pit` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/listaccountsrequestbody.md b/sdks/go/docs/models/operations/listaccountsrequestbody.md deleted file mode 100755 index 22f1ad984..000000000 --- a/sdks/go/docs/models/operations/listaccountsrequestbody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListAccountsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/listlogsrequest.md b/sdks/go/docs/models/operations/listlogsrequest.md index ae024d669..942596639 100755 --- a/sdks/go/docs/models/operations/listlogsrequest.md +++ b/sdks/go/docs/models/operations/listlogsrequest.md @@ -5,8 +5,8 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `RequestBody` | map[string]*interface{}* | :heavy_minus_sign: | N/A | | | `Cursor` | **string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `EndTime` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | | `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | | `PageSize` | **int64* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `StartTime` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| `Pit` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/listlogsrequestbody.md b/sdks/go/docs/models/operations/listlogsrequestbody.md deleted file mode 100755 index 6dbd158df..000000000 --- a/sdks/go/docs/models/operations/listlogsrequestbody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListLogsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/listtransactionsrequest.md b/sdks/go/docs/models/operations/listtransactionsrequest.md index bda492ddb..3853d6928 100755 --- a/sdks/go/docs/models/operations/listtransactionsrequest.md +++ b/sdks/go/docs/models/operations/listtransactionsrequest.md @@ -5,13 +5,9 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `Account` | **string* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | +| `RequestBody` | map[string]*interface{}* | :heavy_minus_sign: | N/A | | | `Cursor` | **string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `Destination` | **string* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `EndTime` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | +| `Expand` | **string* | :heavy_minus_sign: | N/A | | | `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `Metadata` | map[string]*string* | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below. | | | `PageSize` | **int64* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `Reference` | **string* | :heavy_minus_sign: | Find transactions by reference field. | ref:001 | -| `Source` | **string* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `StartTime` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| `Pit` | [*time.Time](https://pkg.go.dev/time#Time) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/listtransactionsrequestbody.md b/sdks/go/docs/models/operations/listtransactionsrequestbody.md deleted file mode 100755 index 990f2baf5..000000000 --- a/sdks/go/docs/models/operations/listtransactionsrequestbody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListTransactionsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/go/docs/models/operations/reverttransactionrequest.md b/sdks/go/docs/models/operations/reverttransactionrequest.md index 902139e94..b7890c775 100755 --- a/sdks/go/docs/models/operations/reverttransactionrequest.md +++ b/sdks/go/docs/models/operations/reverttransactionrequest.md @@ -5,5 +5,5 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `Txid` | *int64* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `ID` | *int64* | :heavy_check_mark: | Transaction ID. | 1234 | +| `Ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/go/docs/models/shared/accountwithvolumesandbalances.md b/sdks/go/docs/models/shared/accountwithvolumesandbalances.md index f9a5740aa..5a2e8c56a 100755 --- a/sdks/go/docs/models/shared/accountwithvolumesandbalances.md +++ b/sdks/go/docs/models/shared/accountwithvolumesandbalances.md @@ -6,7 +6,6 @@ | Field | Type | Required | Description | Example | | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | | `Address` | *string* | :heavy_check_mark: | N/A | users:001 | -| `Balances` | map[string][*big.Int](https://pkg.go.dev/math/big#Int) | :heavy_check_mark: | N/A | | | `Metadata` | map[string]*string* | :heavy_check_mark: | N/A | | | `Type` | **string* | :heavy_minus_sign: | N/A | virtual | -| `Volumes` | map[string]map[string][*big.Int](https://pkg.go.dev/math/big#Int) | :heavy_check_mark: | N/A | | \ No newline at end of file +| `Volumes` | map[string]map[string][*big.Int](https://pkg.go.dev/math/big#Int) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/go/docs/models/shared/balancescursorresponse.md b/sdks/go/docs/models/shared/balancescursorresponse.md deleted file mode 100755 index 1728a5e9b..000000000 --- a/sdks/go/docs/models/shared/balancescursorresponse.md +++ /dev/null @@ -1,10 +0,0 @@ -# BalancesCursorResponse - -OK - - -## Fields - -| Field | Type | Required | Description | -| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | -| `Cursor` | [BalancesCursorResponseCursor](../../models/shared/balancescursorresponsecursor.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/sdks/go/docs/models/shared/balancescursorresponsecursor.md b/sdks/go/docs/models/shared/balancescursorresponsecursor.md deleted file mode 100755 index d61b77ea2..000000000 --- a/sdks/go/docs/models/shared/balancescursorresponsecursor.md +++ /dev/null @@ -1,12 +0,0 @@ -# BalancesCursorResponseCursor - - -## Fields - -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | -| `Data` | []map[string]map[string][*big.Int](https://pkg.go.dev/math/big#Int) | :heavy_check_mark: | N/A | | -| `HasMore` | *bool* | :heavy_check_mark: | N/A | false | -| `Next` | **string* | :heavy_minus_sign: | N/A | | -| `PageSize` | *int64* | :heavy_check_mark: | N/A | 15 | -| `Previous` | **string* | :heavy_minus_sign: | N/A | YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= | \ No newline at end of file diff --git a/sdks/go/docs/models/shared/expandedtransaction.md b/sdks/go/docs/models/shared/expandedtransaction.md index 6da97cc12..aa53bee62 100755 --- a/sdks/go/docs/models/shared/expandedtransaction.md +++ b/sdks/go/docs/models/shared/expandedtransaction.md @@ -5,10 +5,11 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | +| `ID` | *int64* | :heavy_check_mark: | N/A | | | `Metadata` | map[string]*string* | :heavy_check_mark: | N/A | | -| `PostCommitVolumes` | map[string]map[string][Volume](../../models/shared/volume.md) | :heavy_check_mark: | N/A | | +| `PostCommitVolumes` | map[string]map[string][Volume](../../models/shared/volume.md) | :heavy_minus_sign: | N/A | | | `Postings` | [][Posting](../../models/shared/posting.md) | :heavy_check_mark: | N/A | | -| `PreCommitVolumes` | map[string]map[string][Volume](../../models/shared/volume.md) | :heavy_check_mark: | N/A | | +| `PreCommitVolumes` | map[string]map[string][Volume](../../models/shared/volume.md) | :heavy_minus_sign: | N/A | | | `Reference` | **string* | :heavy_minus_sign: | N/A | ref:001 | -| `Timestamp` | [time.Time](https://pkg.go.dev/time#Time) | :heavy_check_mark: | N/A | | -| `Txid` | *int64* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `Reverted` | *bool* | :heavy_check_mark: | N/A | | +| `Timestamp` | [time.Time](https://pkg.go.dev/time#Time) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/go/docs/models/shared/posttransactionscriptvars.md b/sdks/go/docs/models/shared/posttransactionscriptvars.md new file mode 100755 index 000000000..ef1a0de95 --- /dev/null +++ b/sdks/go/docs/models/shared/posttransactionscriptvars.md @@ -0,0 +1,7 @@ +# PostTransactionScriptVars + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/go/docs/models/shared/query.md b/sdks/go/docs/models/shared/query.md index 81299e27f..a5aa0c11c 100755 --- a/sdks/go/docs/models/shared/query.md +++ b/sdks/go/docs/models/shared/query.md @@ -11,6 +11,6 @@ | `PageSize` | **int64* | :heavy_minus_sign: | N/A | | | `Policy` | **string* | :heavy_minus_sign: | N/A | OR | | `Raw` | [*QueryRaw](../../models/shared/queryraw.md) | :heavy_minus_sign: | N/A | | -| `Sort` | **string* | :heavy_minus_sign: | N/A | txid:asc | +| `Sort` | **string* | :heavy_minus_sign: | N/A | id:asc | | `Target` | **string* | :heavy_minus_sign: | N/A | | | `Terms` | []*string* | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/go/docs/models/shared/responsedata.md b/sdks/go/docs/models/shared/responsedata.md new file mode 100755 index 000000000..c3a85e750 --- /dev/null +++ b/sdks/go/docs/models/shared/responsedata.md @@ -0,0 +1,9 @@ +# ResponseData + +The payload + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/go/docs/models/shared/transaction.md b/sdks/go/docs/models/shared/transaction.md index a277103a2..563666ed7 100755 --- a/sdks/go/docs/models/shared/transaction.md +++ b/sdks/go/docs/models/shared/transaction.md @@ -5,8 +5,9 @@ | Field | Type | Required | Description | Example | | ------------------------------------------- | ------------------------------------------- | ------------------------------------------- | ------------------------------------------- | ------------------------------------------- | +| `ID` | *int64* | :heavy_check_mark: | N/A | | | `Metadata` | map[string]*string* | :heavy_check_mark: | N/A | | | `Postings` | [][Posting](../../models/shared/posting.md) | :heavy_check_mark: | N/A | | | `Reference` | **string* | :heavy_minus_sign: | N/A | ref:001 | -| `Timestamp` | [time.Time](https://pkg.go.dev/time#Time) | :heavy_check_mark: | N/A | | -| `Txid` | *int64* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `Reverted` | *bool* | :heavy_check_mark: | N/A | | +| `Timestamp` | [time.Time](https://pkg.go.dev/time#Time) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/go/docs/models/shared/walletstransaction.md b/sdks/go/docs/models/shared/walletstransaction.md index 2c8840724..1c54e336d 100755 --- a/sdks/go/docs/models/shared/walletstransaction.md +++ b/sdks/go/docs/models/shared/walletstransaction.md @@ -5,11 +5,11 @@ | Field | Type | Required | Description | Example | | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | +| `ID` | **int64* | :heavy_minus_sign: | N/A | | | `Ledger` | **string* | :heavy_minus_sign: | N/A | | | `Metadata` | map[string]*string* | :heavy_check_mark: | Metadata associated with the wallet. | | | `PostCommitVolumes` | map[string]map[string][WalletsVolume](../../models/shared/walletsvolume.md) | :heavy_minus_sign: | N/A | | | `Postings` | [][Posting](../../models/shared/posting.md) | :heavy_check_mark: | N/A | | | `PreCommitVolumes` | map[string]map[string][WalletsVolume](../../models/shared/walletsvolume.md) | :heavy_minus_sign: | N/A | | | `Reference` | **string* | :heavy_minus_sign: | N/A | ref:001 | -| `Timestamp` | [time.Time](https://pkg.go.dev/time#Time) | :heavy_check_mark: | N/A | | -| `Txid` | *int64* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `Timestamp` | [time.Time](https://pkg.go.dev/time#Time) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/go/docs/sdks/ledger/README.md b/sdks/go/docs/sdks/ledger/README.md index d74a09192..53362ff22 100755 --- a/sdks/go/docs/sdks/ledger/README.md +++ b/sdks/go/docs/sdks/ledger/README.md @@ -8,7 +8,6 @@ * [CountTransactions](#counttransactions) - Count the transactions from a ledger * [CreateTransaction](#createtransaction) - Create a new transaction to a ledger * [GetAccount](#getaccount) - Get account by its address -* [GetBalances](#getbalances) - Get the balances from a ledger's account * [GetBalancesAggregated](#getbalancesaggregated) - Get the aggregated balances from selected accounts * [GetInfo](#getinfo) - Show server information * [GetLedgerInfo](#getledgerinfo) - Get information about a ledger @@ -50,10 +49,9 @@ func main() { "explicabo": "nobis", "enim": "omnis", }, - Async: formance.Bool(true), DryRun: formance.Bool(true), + ID: 1234, Ledger: "ledger001", - Txid: 1234, }) if err != nil { log.Fatal(err) @@ -110,7 +108,6 @@ func main() { "iure": "culpa", }, Address: "users:001", - Async: formance.Bool(true), DryRun: formance.Bool(true), Ledger: "ledger001", }) @@ -163,9 +160,13 @@ func main() { ctx := context.Background() res, err := s.Ledger.CountAccounts(ctx, operations.CountAccountsRequest{ - Address: formance.String("users:.+"), + RequestBody: map[string]interface{}{ + "sapiente": "architecto", + "mollitia": "dolorem", + "culpa": "consequuntur", + "repellat": "mollitia", + }, Ledger: "ledger001", - Metadata: &operations.CountAccountsMetadata{}, }) if err != nil { log.Fatal(err) @@ -217,16 +218,13 @@ func main() { ctx := context.Background() res, err := s.Ledger.CountTransactions(ctx, operations.CountTransactionsRequest{ - Account: formance.String("users:001"), - Destination: formance.String("users:001"), - EndTime: types.MustTimeFromString("2020-02-15T22:48:47.492Z"), - Ledger: "ledger001", - Metadata: map[string]string{ - "mollitia": "dolorem", + RequestBody: map[string]interface{}{ + "numquam": "commodi", + "quam": "molestiae", + "velit": "error", }, - Reference: formance.String("ref:001"), - Source: formance.String("users:001"), - StartTime: types.MustTimeFromString("2022-09-05T05:51:25.673Z"), + Ledger: "ledger001", + Pit: types.MustTimeFromString("2022-08-30T15:03:11.112Z"), }) if err != nil { log.Fatal(err) @@ -279,12 +277,12 @@ func main() { ctx := context.Background() res, err := s.Ledger.CreateTransaction(ctx, operations.CreateTransactionRequest{ - IdempotencyKey: formance.String("repellat"), + IdempotencyKey: formance.String("vitae"), PostTransaction: shared.PostTransaction{ Metadata: map[string]string{ - "occaecati": "numquam", - "commodi": "quam", - "molestiae": "velit", + "animi": "enim", + "odit": "quo", + "sequi": "tenetur", }, Postings: []shared.Posting{ shared.Posting{ @@ -299,12 +297,6 @@ func main() { Destination: "users:002", Source: "users:001", }, - shared.Posting{ - Amount: big.NewInt(100), - Asset: "COIN", - Destination: "users:002", - Source: "users:001", - }, }, Reference: formance.String("ref:001"), Script: &shared.PostTransactionScript{ @@ -317,12 +309,13 @@ func main() { ) ", Vars: map[string]interface{}{ - "quis": "vitae", + "possimus": "aut", + "quasi": "error", + "temporibus": "laborum", }, }, - Timestamp: types.MustTimeFromString("2021-09-08T21:06:19.630Z"), + Timestamp: types.MustTimeFromString("2022-01-11T05:45:42.485Z"), }, - Async: formance.Bool(true), DryRun: formance.Bool(true), Ledger: "ledger001", }) @@ -376,6 +369,7 @@ func main() { ctx := context.Background() res, err := s.Ledger.GetAccount(ctx, operations.GetAccountRequest{ Address: "users:001", + Expand: formance.String("voluptatibus"), Ledger: "ledger001", }) if err != nil { @@ -401,60 +395,6 @@ func main() { **[*operations.GetAccountResponse](../../models/operations/getaccountresponse.md), error** -## GetBalances - -Get the balances from a ledger's account - -### Example Usage - -```go -package main - -import( - "context" - "log" - "github.com/formancehq/formance-sdk-go" - "github.com/formancehq/formance-sdk-go/pkg/models/shared" - "github.com/formancehq/formance-sdk-go/pkg/models/operations" -) - -func main() { - s := formance.New( - formance.WithSecurity(shared.Security{ - Authorization: "", - }), - ) - - ctx := context.Background() - res, err := s.Ledger.GetBalances(ctx, operations.GetBalancesRequest{ - Address: formance.String("users:001"), - Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - Ledger: "ledger001", - PageSize: formance.Int64(317202), - }) - if err != nil { - log.Fatal(err) - } - - if res.BalancesCursorResponse != nil { - // handle response - } -} -``` - -### Parameters - -| Parameter | Type | Required | Description | -| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | -| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | -| `request` | [operations.GetBalancesRequest](../../models/operations/getbalancesrequest.md) | :heavy_check_mark: | The request object to use for the request. | - - -### Response - -**[*operations.GetBalancesResponse](../../models/operations/getbalancesresponse.md), error** - - ## GetBalancesAggregated Get the aggregated balances from selected accounts @@ -481,7 +421,6 @@ func main() { ctx := context.Background() res, err := s.Ledger.GetBalancesAggregated(ctx, operations.GetBalancesAggregatedRequest{ - Address: formance.String("users:001"), Ledger: "ledger001", }) if err != nil { @@ -631,8 +570,9 @@ func main() { ctx := context.Background() res, err := s.Ledger.GetTransaction(ctx, operations.GetTransactionRequest{ + Expand: formance.String("vero"), + ID: 1234, Ledger: "ledger001", - Txid: 1234, }) if err != nil { log.Fatal(err) @@ -672,6 +612,7 @@ import( "github.com/formancehq/formance-sdk-go" "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/formancehq/formance-sdk-go/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/pkg/types" ) func main() { @@ -683,13 +624,15 @@ func main() { ctx := context.Background() res, err := s.Ledger.ListAccounts(ctx, operations.ListAccountsRequest{ - Address: formance.String("users:.+"), + RequestBody: map[string]interface{}{ + "praesentium": "voluptatibus", + "ipsa": "omnis", + }, Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), + Expand: formance.String("voluptate"), Ledger: "ledger001", - Metadata: map[string]string{ - "quo": "sequi", - }, - PageSize: formance.Int64(949572), + PageSize: formance.Int64(739264), + Pit: types.MustTimeFromString("2022-12-17T16:42:52.927Z"), }) if err != nil { log.Fatal(err) @@ -741,11 +684,14 @@ func main() { ctx := context.Background() res, err := s.Ledger.ListLogs(ctx, operations.ListLogsRequest{ + RequestBody: map[string]interface{}{ + "ut": "maiores", + "dicta": "corporis", + }, Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - EndTime: types.MustTimeFromString("2022-05-04T04:15:52.352Z"), Ledger: "ledger001", - PageSize: formance.Int64(820994), - StartTime: types.MustTimeFromString("2022-11-26T13:23:33.410Z"), + PageSize: formance.Int64(296140), + Pit: types.MustTimeFromString("2022-11-18T15:56:41.921Z"), }) if err != nil { log.Fatal(err) @@ -772,7 +718,7 @@ func main() { ## ListTransactions -List transactions from a ledger, sorted by txid in descending order. +List transactions from a ledger, sorted by id in descending order. ### Example Usage @@ -797,20 +743,16 @@ func main() { ctx := context.Background() res, err := s.Ledger.ListTransactions(ctx, operations.ListTransactionsRequest{ - Account: formance.String("users:001"), + RequestBody: map[string]interface{}{ + "enim": "accusamus", + "commodi": "repudiandae", + "quae": "ipsum", + }, Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - Destination: formance.String("users:001"), - EndTime: types.MustTimeFromString("2021-04-29T07:12:18.684Z"), + Expand: formance.String("quidem"), Ledger: "ledger001", - Metadata: map[string]string{ - "quasi": "reiciendis", - "voluptatibus": "vero", - "nihil": "praesentium", - }, - PageSize: formance.Int64(976762), - Reference: formance.String("ref:001"), - Source: formance.String("users:001"), - StartTime: types.MustTimeFromString("2022-05-25T05:33:11.349Z"), + PageSize: formance.Int64(565189), + Pit: types.MustTimeFromString("2021-04-09T11:24:10.949Z"), }) if err != nil { log.Fatal(err) @@ -913,8 +855,8 @@ func main() { ctx := context.Background() res, err := s.Ledger.RevertTransaction(ctx, operations.RevertTransactionRequest{ + ID: 1234, Ledger: "ledger001", - Txid: 1234, }) if err != nil { log.Fatal(err) diff --git a/sdks/go/docs/sdks/orchestration/README.md b/sdks/go/docs/sdks/orchestration/README.md index 875537e7d..9bc0e129c 100755 --- a/sdks/go/docs/sdks/orchestration/README.md +++ b/sdks/go/docs/sdks/orchestration/README.md @@ -41,7 +41,7 @@ func main() { ctx := context.Background() res, err := s.Orchestration.CancelEvent(ctx, operations.CancelEventRequest{ - InstanceID: "voluptate", + InstanceID: "modi", }) if err != nil { log.Fatal(err) @@ -91,23 +91,13 @@ func main() { ctx := context.Background() res, err := s.Orchestration.CreateWorkflow(ctx, shared.CreateWorkflowRequest{ - Name: formance.String("Thomas Batz"), + Name: formance.String("Dr. Jordan Von"), Stages: []map[string]interface{}{ map[string]interface{}{ - "corporis": "dolore", - }, - map[string]interface{}{ - "dicta": "harum", - "enim": "accusamus", - }, - map[string]interface{}{ - "repudiandae": "quae", - "ipsum": "quidem", - }, - map[string]interface{}{ - "excepturi": "pariatur", - "modi": "praesentium", - "rem": "voluptates", + "incidunt": "enim", + "consequatur": "est", + "quibusdam": "explicabo", + "deserunt": "distinctio", }, }, }) @@ -160,7 +150,7 @@ func main() { ctx := context.Background() res, err := s.Orchestration.DeleteWorkflow(ctx, operations.DeleteWorkflowRequest{ - FlowID: "quasi", + FlowID: "quibusdam", }) if err != nil { log.Fatal(err) @@ -211,7 +201,7 @@ func main() { ctx := context.Background() res, err := s.Orchestration.GetInstance(ctx, operations.GetInstanceRequest{ - InstanceID: "repudiandae", + InstanceID: "labore", }) if err != nil { log.Fatal(err) @@ -262,7 +252,7 @@ func main() { ctx := context.Background() res, err := s.Orchestration.GetInstanceHistory(ctx, operations.GetInstanceHistoryRequest{ - InstanceID: "sint", + InstanceID: "modi", }) if err != nil { log.Fatal(err) @@ -313,8 +303,8 @@ func main() { ctx := context.Background() res, err := s.Orchestration.GetInstanceStageHistory(ctx, operations.GetInstanceStageHistoryRequest{ - InstanceID: "veritatis", - Number: 929297, + InstanceID: "qui", + Number: 397821, }) if err != nil { log.Fatal(err) @@ -365,7 +355,7 @@ func main() { ctx := context.Background() res, err := s.Orchestration.GetWorkflow(ctx, operations.GetWorkflowRequest{ - FlowID: "incidunt", + FlowID: "cupiditate", }) if err != nil { log.Fatal(err) @@ -417,7 +407,7 @@ func main() { ctx := context.Background() res, err := s.Orchestration.ListInstances(ctx, operations.ListInstancesRequest{ Running: formance.Bool(false), - WorkflowID: formance.String("enim"), + WorkflowID: formance.String("quos"), }) if err != nil { log.Fatal(err) @@ -563,10 +553,10 @@ func main() { ctx := context.Background() res, err := s.Orchestration.RunWorkflow(ctx, operations.RunWorkflowRequest{ RequestBody: map[string]string{ - "est": "quibusdam", + "magni": "assumenda", }, Wait: formance.Bool(false), - WorkflowID: "explicabo", + WorkflowID: "ipsam", }) if err != nil { log.Fatal(err) @@ -618,9 +608,9 @@ func main() { ctx := context.Background() res, err := s.Orchestration.SendEvent(ctx, operations.SendEventRequest{ RequestBody: &operations.SendEventRequestBody{ - Name: "Rudy Spencer", + Name: "Denise Pagac", }, - InstanceID: "qui", + InstanceID: "facilis", }) if err != nil { log.Fatal(err) diff --git a/sdks/go/docs/sdks/payments/README.md b/sdks/go/docs/sdks/payments/README.md index 97fdedff8..2e3f199e6 100755 --- a/sdks/go/docs/sdks/payments/README.md +++ b/sdks/go/docs/sdks/payments/README.md @@ -108,7 +108,7 @@ func main() { Destination: "acct_1Gqj58KZcSIg2N2q", Source: formance.String("acct_1Gqj58KZcSIg2N2q"), }, - Connector: shared.ConnectorModulr, + Connector: shared.ConnectorBankingCircle, }) if err != nil { log.Fatal(err) @@ -160,16 +160,17 @@ func main() { ctx := context.Background() res, err := s.Payments.GetAccountBalances(ctx, operations.GetAccountBalancesRequest{ - AccountID: "cupiditate", - Asset: formance.String("quos"), + AccountID: "labore", + Asset: formance.String("delectus"), Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - From: types.MustTimeFromString("2022-11-01T19:07:16.800Z"), - Limit: formance.Int64(828940), - PageSize: formance.Int64(369808), + From: types.MustTimeFromString("2022-10-02T04:55:20.234Z"), + Limit: formance.Int64(756107), + PageSize: formance.Int64(576157), Sort: []string{ - "fugit", + "provident", + "necessitatibus", }, - To: types.MustTimeFromString("2021-11-11T04:17:07.569Z"), + To: types.MustTimeFromString("2021-09-21T14:06:09.271Z"), }) if err != nil { log.Fatal(err) @@ -220,8 +221,8 @@ func main() { ctx := context.Background() res, err := s.Payments.GetConnectorTask(ctx, operations.GetConnectorTaskRequest{ - Connector: shared.ConnectorWise, - TaskID: "facilis", + Connector: shared.ConnectorDummyPay, + TaskID: "debitis", }) if err != nil { log.Fatal(err) @@ -272,7 +273,7 @@ func main() { ctx := context.Background() res, err := s.Payments.GetPayment(ctx, operations.GetPaymentRequest{ - PaymentID: "tempore", + PaymentID: "a", }) if err != nil { log.Fatal(err) @@ -323,11 +324,16 @@ func main() { ctx := context.Background() res, err := s.Payments.InstallConnector(ctx, operations.InstallConnectorRequest{ - RequestBody: shared.WiseConfig{ - APIKey: "XXX", + RequestBody: shared.BankingCircleConfig{ + AuthorizationEndpoint: "XXX", + Endpoint: "XXX", + Password: "XXX", PollingPeriod: formance.String("60s"), + UserCertificate: "XXX", + UserCertificateKey: "XXX", + Username: "XXX", }, - Connector: shared.ConnectorMoneycorp, + Connector: shared.ConnectorModulr, }) if err != nil { log.Fatal(err) @@ -474,7 +480,7 @@ func main() { res, err := s.Payments.ListConnectorTasks(ctx, operations.ListConnectorTasksRequest{ Connector: shared.ConnectorModulr, Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - PageSize: formance.Int64(248753), + PageSize: formance.Int64(846409), }) if err != nil { log.Fatal(err) @@ -525,7 +531,7 @@ func main() { ctx := context.Background() res, err := s.Payments.ListConnectorsTransfers(ctx, operations.ListConnectorsTransfersRequest{ - Connector: shared.ConnectorMangopay, + Connector: shared.ConnectorMoneycorp, }) if err != nil { log.Fatal(err) @@ -577,10 +583,9 @@ func main() { ctx := context.Background() res, err := s.Payments.ListPayments(ctx, operations.ListPaymentsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - PageSize: formance.Int64(576157), + PageSize: formance.Int64(699479), Sort: []string{ - "provident", - "necessitatibus", + "magnam", }, }) if err != nil { @@ -632,7 +637,7 @@ func main() { ctx := context.Background() res, err := s.Payments.PaymentsgetAccount(ctx, operations.PaymentsgetAccountRequest{ - AccountID: "sint", + AccountID: "cumque", }) if err != nil { log.Fatal(err) @@ -731,9 +736,10 @@ func main() { ctx := context.Background() res, err := s.Payments.PaymentslistAccounts(ctx, operations.PaymentslistAccountsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - PageSize: formance.Int64(638921), + PageSize: formance.Int64(813798), Sort: []string{ - "debitis", + "aliquid", + "laborum", }, }) if err != nil { @@ -838,7 +844,7 @@ func main() { ctx := context.Background() res, err := s.Payments.ResetConnector(ctx, operations.ResetConnectorRequest{ - Connector: shared.ConnectorBankingCircle, + Connector: shared.ConnectorDummyPay, }) if err != nil { log.Fatal(err) @@ -889,7 +895,7 @@ func main() { ctx := context.Background() res, err := s.Payments.UninstallConnector(ctx, operations.UninstallConnectorRequest{ - Connector: shared.ConnectorModulr, + Connector: shared.ConnectorCurrencyCloud, }) if err != nil { log.Fatal(err) @@ -941,9 +947,9 @@ func main() { ctx := context.Background() res, err := s.Payments.UpdateMetadata(ctx, operations.UpdateMetadataRequest{ PaymentMetadata: shared.PaymentMetadata{ - Key: formance.String("in"), + Key: formance.String("enim"), }, - PaymentID: "illum", + PaymentID: "accusamus", }) if err != nil { log.Fatal(err) diff --git a/sdks/go/docs/sdks/search/README.md b/sdks/go/docs/sdks/search/README.md index 4c96844b8..b60e5c0ad 100755 --- a/sdks/go/docs/sdks/search/README.md +++ b/sdks/go/docs/sdks/search/README.md @@ -42,16 +42,15 @@ func main() { "quickstart", "quickstart", }, - PageSize: formance.Int64(116202), + PageSize: formance.Int64(588465), Policy: formance.String("OR"), Raw: &shared.QueryRaw{}, - Sort: formance.String("txid:asc"), - Target: formance.String("magnam"), + Sort: formance.String("id:asc"), + Target: formance.String("nam"), Terms: []string{ "destination=central_bank1", "destination=central_bank1", "destination=central_bank1", - "destination=central_bank1", }, }) if err != nil { diff --git a/sdks/go/docs/sdks/wallets/README.md b/sdks/go/docs/sdks/wallets/README.md index dae10f4dd..ffb27c75b 100755 --- a/sdks/go/docs/sdks/wallets/README.md +++ b/sdks/go/docs/sdks/wallets/README.md @@ -50,7 +50,7 @@ func main() { Amount: big.NewInt(100), Final: formance.Bool(true), }, - HoldID: "facere", + HoldID: "blanditiis", }) if err != nil { log.Fatal(err) @@ -104,11 +104,11 @@ func main() { ctx := context.Background() res, err := s.Wallets.CreateBalance(ctx, operations.CreateBalanceRequest{ CreateBalanceRequest: &shared.CreateBalanceRequest{ - ExpiresAt: types.MustTimeFromString("2022-08-09T06:36:34.417Z"), - Name: "Tomas Friesen", - Priority: big.NewInt(881736), + ExpiresAt: types.MustTimeFromString("2021-02-02T01:24:52.629Z"), + Name: "Sandy Huels", + Priority: big.NewInt(606393), }, - ID: "fb9ba88f-3a66-4997-874b-a4469b6e2141", + ID: "7074ba44-69b6-4e21-8195-9890afa563e2", }) if err != nil { log.Fatal(err) @@ -159,11 +159,10 @@ func main() { ctx := context.Background() res, err := s.Wallets.CreateWallet(ctx, shared.CreateWalletRequest{ Metadata: map[string]string{ - "ullam": "provident", - "quos": "sint", - "accusantium": "mollitia", + "quasi": "iure", + "doloribus": "debitis", }, - Name: "Shaun Hammes", + Name: "Jasmine Lind", }) if err != nil { log.Fatal(err) @@ -217,20 +216,23 @@ func main() { res, err := s.Wallets.CreditWallet(ctx, operations.CreditWalletRequest{ CreditWalletRequest: &shared.CreditWalletRequest{ Amount: shared.Monetary{ - Amount: big.NewInt(896547), - Asset: "odit", + Amount: big.NewInt(100226), + Asset: "architecto", }, - Balance: formance.String("nemo"), + Balance: formance.String("repudiandae"), Metadata: map[string]string{ - "iure": "doloribus", + "expedita": "nihil", + "repellat": "quibusdam", }, - Reference: formance.String("debitis"), + Reference: formance.String("sed"), Sources: []shared.Subject{ shared.Subject{}, shared.Subject{}, + shared.Subject{}, + shared.Subject{}, }, }, - ID: "c8b711e5-b7fd-42ed-8289-21cddc692601", + ID: "d028921c-ddc6-4926-81fb-576b0d5f0d30", }) if err != nil { log.Fatal(err) @@ -284,21 +286,24 @@ func main() { res, err := s.Wallets.DebitWallet(ctx, operations.DebitWalletRequest{ DebitWalletRequest: &shared.DebitWalletRequest{ Amount: shared.Monetary{ - Amount: big.NewInt(982575), - Asset: "quidem", + Amount: big.NewInt(764912), + Asset: "corporis", }, Balances: []string{ - "voluptate", - "autem", + "libero", + "nobis", + "dolores", + "quis", }, - Description: formance.String("nam"), + Description: formance.String("totam"), Destination: &shared.Subject{}, Metadata: map[string]string{ - "pariatur": "nemo", + "eaque": "quis", + "nesciunt": "eos", }, Pending: formance.Bool(false), }, - ID: "f0d30c5f-bb25-4870-9320-2c73d5fe9b90", + ID: "02c73d5f-e9b9-40c2-8909-b3fe49a8d9cb", }) if err != nil { log.Fatal(err) @@ -349,8 +354,8 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetBalance(ctx, operations.GetBalanceRequest{ - BalanceName: "porro", - ID: "28909b3f-e49a-48d9-8bf4-8633323f9b77", + BalanceName: "delectus", + ID: "48633323-f9b7-47f3-a410-0674ebf69280", }) if err != nil { log.Fatal(err) @@ -401,7 +406,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetHold(ctx, operations.GetHoldRequest{ - HoldID: "reiciendis", + HoldID: "fugiat", }) if err != nil { log.Fatal(err) @@ -454,10 +459,10 @@ func main() { res, err := s.Wallets.GetHolds(ctx, operations.GetHoldsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), Metadata: map[string]string{ - "dolorum": "numquam", + "soluta": "dolorum", }, - PageSize: formance.Int64(85295), - WalletID: formance.String("ipsa"), + PageSize: formance.Int64(478596), + WalletID: formance.String("voluptate"), }) if err != nil { log.Fatal(err) @@ -507,8 +512,8 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetTransactions(ctx, operations.GetTransactionsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), - PageSize: formance.Int64(56418), - WalletID: formance.String("iure"), + PageSize: formance.Int64(677082), + WalletID: formance.String("deleniti"), }) if err != nil { log.Fatal(err) @@ -559,7 +564,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetWallet(ctx, operations.GetWalletRequest{ - ID: "74ebf692-80d1-4ba7-ba89-ebf737ae4203", + ID: "9ebf737a-e420-43ce-9e6a-95d8a0d446ce", }) if err != nil { log.Fatal(err) @@ -610,7 +615,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.GetWalletSummary(ctx, operations.GetWalletSummaryRequest{ - ID: "ce5e6a95-d8a0-4d44-ace2-af7a73cf3be4", + ID: "2af7a73c-f3be-4453-b870-b326b5a73429", }) if err != nil { log.Fatal(err) @@ -661,7 +666,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.ListBalances(ctx, operations.ListBalancesRequest{ - ID: "53f870b3-26b5-4a73-829c-db1a8422bb67", + ID: "cdb1a842-2bb6-479d-a322-715bf0cbb1e3", }) if err != nil { log.Fatal(err) @@ -714,12 +719,10 @@ func main() { res, err := s.Wallets.ListWallets(ctx, operations.ListWalletsRequest{ Cursor: formance.String("aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="), Metadata: map[string]string{ - "temporibus": "qui", - "neque": "fugit", - "magni": "odio", + "nobis": "quos", }, - Name: formance.String("Marion Reichert DDS"), - PageSize: formance.Int64(746994), + Name: formance.String("Kent Bayer"), + PageSize: formance.Int64(292147), }) if err != nil { log.Fatal(err) @@ -772,12 +775,11 @@ func main() { res, err := s.Wallets.UpdateWallet(ctx, operations.UpdateWalletRequest{ RequestBody: &operations.UpdateWalletRequestBody{ Metadata: map[string]string{ - "et": "saepe", - "ipsum": "veritatis", - "nobis": "quos", + "adipisci": "dolorum", + "architecto": "quae", }, }, - ID: "b90f3443-a110-48e0-adcf-4b921879fce9", + ID: "08e0adcf-4b92-4187-9fce-953f73ef7fbc", }) if err != nil { log.Fatal(err) @@ -828,7 +830,7 @@ func main() { ctx := context.Background() res, err := s.Wallets.VoidHold(ctx, operations.VoidHoldRequest{ - HoldID: "quis", + HoldID: "odio", }) if err != nil { log.Fatal(err) diff --git a/sdks/go/docs/sdks/webhooks/README.md b/sdks/go/docs/sdks/webhooks/README.md index 41ac00607..2e3da64a5 100755 --- a/sdks/go/docs/sdks/webhooks/README.md +++ b/sdks/go/docs/sdks/webhooks/README.md @@ -310,6 +310,8 @@ func main() { Endpoint: "https://example.com", EventTypes: []string{ "TYPE1", + "TYPE1", + "TYPE1", }, Secret: formance.String("V0bivxRWveaoz08afqjU6Ko/jwO0Cb+3"), }) diff --git a/sdks/go/files.gen b/sdks/go/files.gen index 505aa4981..ed9ec863c 100755 --- a/sdks/go/files.gen +++ b/sdks/go/files.gen @@ -46,7 +46,6 @@ pkg/models/operations/countaccounts.go pkg/models/operations/counttransactions.go pkg/models/operations/createtransaction.go pkg/models/operations/getaccount.go -pkg/models/operations/getbalances.go pkg/models/operations/getbalancesaggregated.go pkg/models/operations/getinfo.go pkg/models/operations/getledgerinfo.go @@ -142,7 +141,6 @@ pkg/models/shared/posting.go pkg/models/shared/posttransaction.go pkg/models/shared/accountresponse.go pkg/models/shared/accountwithvolumesandbalances.go -pkg/models/shared/balancescursorresponse.go pkg/models/shared/aggregatebalancesresponse.go pkg/models/shared/configinforesponse.go pkg/models/shared/configinfo.go @@ -332,7 +330,6 @@ docs/models/operations/addmetadataontransactionrequest.md docs/models/operations/addmetadataontransactionresponse.md docs/models/operations/addmetadatatoaccountrequest.md docs/models/operations/addmetadatatoaccountresponse.md -docs/models/operations/countaccountsmetadata.md docs/models/operations/countaccountsrequest.md docs/models/operations/countaccountsresponse.md docs/models/operations/counttransactionsrequest.md @@ -341,8 +338,6 @@ docs/models/operations/createtransactionrequest.md docs/models/operations/createtransactionresponse.md docs/models/operations/getaccountrequest.md docs/models/operations/getaccountresponse.md -docs/models/operations/getbalancesrequest.md -docs/models/operations/getbalancesresponse.md docs/models/operations/getbalancesaggregatedrequest.md docs/models/operations/getbalancesaggregatedresponse.md docs/models/operations/getinforesponse.md @@ -492,8 +487,6 @@ docs/models/shared/posttransactionscript.md docs/models/shared/posttransaction.md docs/models/shared/accountresponse.md docs/models/shared/accountwithvolumesandbalances.md -docs/models/shared/balancescursorresponsecursor.md -docs/models/shared/balancescursorresponse.md docs/models/shared/aggregatebalancesresponse.md docs/models/shared/configinforesponse.md docs/models/shared/configinfo.md diff --git a/sdks/go/formance.go b/sdks/go/formance.go index d59cb3654..619712c44 100755 --- a/sdks/go/formance.go +++ b/sdks/go/formance.go @@ -155,7 +155,7 @@ func New(opts ...SDKOption) *Formance { sdk := &Formance{ sdkConfiguration: sdkConfiguration{ Language: "go", - OpenAPIDocVersion: "v1.0.20230907", + OpenAPIDocVersion: "v1.0.20230908", SDKVersion: "v0.1.0", GenVersion: "2.96.3", ServerDefaults: []map[string]string{ diff --git a/sdks/go/gen.yaml b/sdks/go/gen.yaml index aea35d708..85c23fac9 100755 --- a/sdks/go/gen.yaml +++ b/sdks/go/gen.yaml @@ -7,6 +7,7 @@ features: go: core: 2.86.4 deprecations: 2.81.1 + getRequestBodies: 2.81.1 globalSecurity: 2.81.1 globalServerURLs: 2.82.0 unions: 2.81.2 diff --git a/sdks/go/ledger.go b/sdks/go/ledger.go index 95a00129b..3f059e43f 100755 --- a/sdks/go/ledger.go +++ b/sdks/go/ledger.go @@ -28,7 +28,7 @@ func newLedger(sdkConfig sdkConfiguration) *ledger { // AddMetadataOnTransaction - Set the metadata of a transaction by its ID func (s *ledger) AddMetadataOnTransaction(ctx context.Context, request operations.AddMetadataOnTransactionRequest) (*operations.AddMetadataOnTransactionResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions/{txid}/metadata", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/transactions/{id}/metadata", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } @@ -99,7 +99,7 @@ func (s *ledger) AddMetadataOnTransaction(ctx context.Context, request operation // AddMetadataToAccount - Add metadata to an account func (s *ledger) AddMetadataToAccount(ctx context.Context, request operations.AddMetadataToAccountRequest) (*operations.AddMetadataToAccountResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/accounts/{address}/metadata", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/accounts/{address}/metadata", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } @@ -173,21 +173,24 @@ func (s *ledger) AddMetadataToAccount(ctx context.Context, request operations.Ad // CountAccounts - Count the accounts from a ledger func (s *ledger) CountAccounts(ctx context.Context, request operations.CountAccountsRequest) (*operations.CountAccountsResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/accounts", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/accounts", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } - req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "RequestBody", "json") + if err != nil { + return nil, fmt.Errorf("error serializing request body: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "HEAD", url, bodyReader) if err != nil { return nil, fmt.Errorf("error creating request: %w", err) } req.Header.Set("Accept", "application/json") req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { - return nil, fmt.Errorf("error populating query params: %w", err) - } + req.Header.Set("Content-Type", reqContentType) client := s.sdkConfiguration.SecurityClient @@ -237,18 +240,25 @@ func (s *ledger) CountAccounts(ctx context.Context, request operations.CountAcco // CountTransactions - Count the transactions from a ledger func (s *ledger) CountTransactions(ctx context.Context, request operations.CountTransactionsRequest) (*operations.CountTransactionsResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/transactions", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } - req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "RequestBody", "json") + if err != nil { + return nil, fmt.Errorf("error serializing request body: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "HEAD", url, bodyReader) if err != nil { return nil, fmt.Errorf("error creating request: %w", err) } req.Header.Set("Accept", "application/json") req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) + req.Header.Set("Content-Type", reqContentType) + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { return nil, fmt.Errorf("error populating query params: %w", err) } @@ -301,7 +311,7 @@ func (s *ledger) CountTransactions(ctx context.Context, request operations.Count // CreateTransaction - Create a new transaction to a ledger func (s *ledger) CreateTransaction(ctx context.Context, request operations.CreateTransactionRequest) (*operations.CreateTransactionResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/transactions", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } @@ -386,76 +396,7 @@ func (s *ledger) CreateTransaction(ctx context.Context, request operations.Creat // GetAccount - Get account by its address func (s *ledger) GetAccount(ctx context.Context, request operations.GetAccountRequest) (*operations.GetAccountResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/accounts/{address}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.GetAccountResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.AccountResponse - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.AccountResponse = out - default: - return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) - } - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.ErrorResponse - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.ErrorResponse = out - default: - return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) - } - } - - return res, nil -} - -// GetBalances - Get the balances from a ledger's account -func (s *ledger) GetBalances(ctx context.Context, request operations.GetBalancesRequest) (*operations.GetBalancesResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/balances", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/accounts/{address}", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } @@ -490,7 +431,7 @@ func (s *ledger) GetBalances(ctx context.Context, request operations.GetBalances contentType := httpRes.Header.Get("Content-Type") - res := &operations.GetBalancesResponse{ + res := &operations.GetAccountResponse{ StatusCode: httpRes.StatusCode, ContentType: contentType, RawResponse: httpRes, @@ -499,12 +440,12 @@ func (s *ledger) GetBalances(ctx context.Context, request operations.GetBalances case httpRes.StatusCode == 200: switch { case utils.MatchContentType(contentType, `application/json`): - var out *shared.BalancesCursorResponse + var out *shared.AccountResponse if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { return nil, err } - res.BalancesCursorResponse = out + res.AccountResponse = out default: return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) } @@ -528,7 +469,7 @@ func (s *ledger) GetBalances(ctx context.Context, request operations.GetBalances // GetBalancesAggregated - Get the aggregated balances from selected accounts func (s *ledger) GetBalancesAggregated(ctx context.Context, request operations.GetBalancesAggregatedRequest) (*operations.GetBalancesAggregatedResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/aggregate/balances", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/aggregate/balances", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } @@ -540,10 +481,6 @@ func (s *ledger) GetBalancesAggregated(ctx context.Context, request operations.G req.Header.Set("Accept", "application/json") req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { - return nil, fmt.Errorf("error populating query params: %w", err) - } - client := s.sdkConfiguration.SecurityClient httpRes, err := client.Do(req) @@ -601,7 +538,7 @@ func (s *ledger) GetBalancesAggregated(ctx context.Context, request operations.G // GetInfo - Show server information func (s *ledger) GetInfo(ctx context.Context) (*operations.GetInfoResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/api/ledger/_info" + url := strings.TrimSuffix(baseURL, "/") + "/api/ledger/v2/_info" req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { @@ -667,7 +604,7 @@ func (s *ledger) GetInfo(ctx context.Context) (*operations.GetInfoResponse, erro // GetLedgerInfo - Get information about a ledger func (s *ledger) GetLedgerInfo(ctx context.Context, request operations.GetLedgerInfoRequest) (*operations.GetLedgerInfoResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/_info", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/_info", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } @@ -736,7 +673,7 @@ func (s *ledger) GetLedgerInfo(ctx context.Context, request operations.GetLedger // GetTransaction - Get transaction from a ledger by its ID func (s *ledger) GetTransaction(ctx context.Context, request operations.GetTransactionRequest) (*operations.GetTransactionResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions/{txid}", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/transactions/{id}", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } @@ -748,6 +685,10 @@ func (s *ledger) GetTransaction(ctx context.Context, request operations.GetTrans req.Header.Set("Accept", "application/json") req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { + return nil, fmt.Errorf("error populating query params: %w", err) + } + client := s.sdkConfiguration.SecurityClient httpRes, err := client.Do(req) @@ -806,18 +747,25 @@ func (s *ledger) GetTransaction(ctx context.Context, request operations.GetTrans // List accounts from a ledger, sorted by address in descending order. func (s *ledger) ListAccounts(ctx context.Context, request operations.ListAccountsRequest) (*operations.ListAccountsResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/accounts", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/accounts", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "RequestBody", "json") + if err != nil { + return nil, fmt.Errorf("error serializing request body: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, bodyReader) if err != nil { return nil, fmt.Errorf("error creating request: %w", err) } req.Header.Set("Accept", "application/json") req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) + req.Header.Set("Content-Type", reqContentType) + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { return nil, fmt.Errorf("error populating query params: %w", err) } @@ -880,18 +828,25 @@ func (s *ledger) ListAccounts(ctx context.Context, request operations.ListAccoun // List the logs from a ledger, sorted by ID in descending order. func (s *ledger) ListLogs(ctx context.Context, request operations.ListLogsRequest) (*operations.ListLogsResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/logs", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/logs", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "RequestBody", "json") + if err != nil { + return nil, fmt.Errorf("error serializing request body: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, bodyReader) if err != nil { return nil, fmt.Errorf("error creating request: %w", err) } req.Header.Set("Accept", "application/json") req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) + req.Header.Set("Content-Type", reqContentType) + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { return nil, fmt.Errorf("error populating query params: %w", err) } @@ -951,21 +906,28 @@ func (s *ledger) ListLogs(ctx context.Context, request operations.ListLogsReques } // ListTransactions - List transactions from a ledger -// List transactions from a ledger, sorted by txid in descending order. +// List transactions from a ledger, sorted by id in descending order. func (s *ledger) ListTransactions(ctx context.Context, request operations.ListTransactionsRequest) (*operations.ListTransactionsResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/transactions", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "RequestBody", "json") + if err != nil { + return nil, fmt.Errorf("error serializing request body: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, bodyReader) if err != nil { return nil, fmt.Errorf("error creating request: %w", err) } req.Header.Set("Accept", "application/json") req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) + req.Header.Set("Content-Type", reqContentType) + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { return nil, fmt.Errorf("error populating query params: %w", err) } @@ -1028,7 +990,7 @@ func (s *ledger) ListTransactions(ctx context.Context, request operations.ListTr // Get statistics from a ledger. (aggregate metrics on accounts and transactions) func (s *ledger) ReadStats(ctx context.Context, request operations.ReadStatsRequest) (*operations.ReadStatsResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/stats", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/stats", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } @@ -1097,7 +1059,7 @@ func (s *ledger) ReadStats(ctx context.Context, request operations.ReadStatsRequ // RevertTransaction - Revert a ledger transaction by its ID func (s *ledger) RevertTransaction(ctx context.Context, request operations.RevertTransactionRequest) (*operations.RevertTransactionResponse, error) { baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/{ledger}/transactions/{txid}/revert", request, nil) + url, err := utils.GenerateURL(ctx, baseURL, "/api/ledger/v2/{ledger}/transactions/{id}/revert", request, nil) if err != nil { return nil, fmt.Errorf("error generating URL: %w", err) } diff --git a/sdks/go/pkg/models/operations/addmetadataontransaction.go b/sdks/go/pkg/models/operations/addmetadataontransaction.go index 4a4f7ace3..56c8b2622 100755 --- a/sdks/go/pkg/models/operations/addmetadataontransaction.go +++ b/sdks/go/pkg/models/operations/addmetadataontransaction.go @@ -12,14 +12,12 @@ type AddMetadataOnTransactionRequest struct { IdempotencyKey *string `header:"style=simple,explode=false,name=Idempotency-Key"` // metadata RequestBody map[string]string `request:"mediaType=application/json"` - // Set async mode. - Async *bool `queryParam:"style=form,explode=true,name=async"` // Set the dryRun mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. DryRun *bool `queryParam:"style=form,explode=true,name=dryRun"` + // Transaction ID. + ID int64 `pathParam:"style=simple,explode=false,name=id"` // Name of the ledger. Ledger string `pathParam:"style=simple,explode=false,name=ledger"` - // Transaction ID. - Txid int64 `pathParam:"style=simple,explode=false,name=txid"` } func (o *AddMetadataOnTransactionRequest) GetIdempotencyKey() *string { @@ -36,18 +34,18 @@ func (o *AddMetadataOnTransactionRequest) GetRequestBody() map[string]string { return o.RequestBody } -func (o *AddMetadataOnTransactionRequest) GetAsync() *bool { +func (o *AddMetadataOnTransactionRequest) GetDryRun() *bool { if o == nil { return nil } - return o.Async + return o.DryRun } -func (o *AddMetadataOnTransactionRequest) GetDryRun() *bool { +func (o *AddMetadataOnTransactionRequest) GetID() int64 { if o == nil { - return nil + return 0 } - return o.DryRun + return o.ID } func (o *AddMetadataOnTransactionRequest) GetLedger() string { @@ -57,13 +55,6 @@ func (o *AddMetadataOnTransactionRequest) GetLedger() string { return o.Ledger } -func (o *AddMetadataOnTransactionRequest) GetTxid() int64 { - if o == nil { - return 0 - } - return o.Txid -} - type AddMetadataOnTransactionResponse struct { ContentType string // Error diff --git a/sdks/go/pkg/models/operations/addmetadatatoaccount.go b/sdks/go/pkg/models/operations/addmetadatatoaccount.go index 208d191ae..bfc820ccc 100755 --- a/sdks/go/pkg/models/operations/addmetadatatoaccount.go +++ b/sdks/go/pkg/models/operations/addmetadatatoaccount.go @@ -18,8 +18,6 @@ type AddMetadataToAccountRequest struct { // ``` // Address string `pathParam:"style=simple,explode=false,name=address"` - // Set async mode. - Async *bool `queryParam:"style=form,explode=true,name=async"` // Set the dry run mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. DryRun *bool `queryParam:"style=form,explode=true,name=dryRun"` // Name of the ledger. @@ -47,13 +45,6 @@ func (o *AddMetadataToAccountRequest) GetAddress() string { return o.Address } -func (o *AddMetadataToAccountRequest) GetAsync() *bool { - if o == nil { - return nil - } - return o.Async -} - func (o *AddMetadataToAccountRequest) GetDryRun() *bool { if o == nil { return nil diff --git a/sdks/go/pkg/models/operations/countaccounts.go b/sdks/go/pkg/models/operations/countaccounts.go index e5719d972..0357853bd 100755 --- a/sdks/go/pkg/models/operations/countaccounts.go +++ b/sdks/go/pkg/models/operations/countaccounts.go @@ -7,24 +7,17 @@ import ( "net/http" ) -// CountAccountsMetadata - Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 -type CountAccountsMetadata struct { -} - type CountAccountsRequest struct { - // Filter accounts by address pattern (regular expression placed between ^ and $). - Address *string `queryParam:"style=form,explode=true,name=address"` + RequestBody map[string]interface{} `request:"mediaType=application/json"` // Name of the ledger. Ledger string `pathParam:"style=simple,explode=false,name=ledger"` - // Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - Metadata *CountAccountsMetadata `queryParam:"style=deepObject,explode=true,name=metadata"` } -func (o *CountAccountsRequest) GetAddress() *string { +func (o *CountAccountsRequest) GetRequestBody() map[string]interface{} { if o == nil { return nil } - return o.Address + return o.RequestBody } func (o *CountAccountsRequest) GetLedger() string { @@ -34,13 +27,6 @@ func (o *CountAccountsRequest) GetLedger() string { return o.Ledger } -func (o *CountAccountsRequest) GetMetadata() *CountAccountsMetadata { - if o == nil { - return nil - } - return o.Metadata -} - type CountAccountsResponse struct { ContentType string // Error diff --git a/sdks/go/pkg/models/operations/counttransactions.go b/sdks/go/pkg/models/operations/counttransactions.go index 0911219fb..b7286dc29 100755 --- a/sdks/go/pkg/models/operations/counttransactions.go +++ b/sdks/go/pkg/models/operations/counttransactions.go @@ -9,47 +9,17 @@ import ( ) type CountTransactionsRequest struct { - // Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). - Account *string `queryParam:"style=form,explode=true,name=account"` - // Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). - Destination *string `queryParam:"style=form,explode=true,name=destination"` - // Filter transactions that occurred before this timestamp. - // The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - // - EndTime *time.Time `queryParam:"style=form,explode=true,name=endTime"` + RequestBody map[string]interface{} `request:"mediaType=application/json"` // Name of the ledger. - Ledger string `pathParam:"style=simple,explode=false,name=ledger"` - // Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - Metadata map[string]string `queryParam:"style=deepObject,explode=true,name=metadata"` - // Filter transactions by reference field. - Reference *string `queryParam:"style=form,explode=true,name=reference"` - // Filter transactions with postings involving given account at source (regular expression placed between ^ and $). - Source *string `queryParam:"style=form,explode=true,name=source"` - // Filter transactions that occurred after this timestamp. - // The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - // - StartTime *time.Time `queryParam:"style=form,explode=true,name=startTime"` + Ledger string `pathParam:"style=simple,explode=false,name=ledger"` + Pit *time.Time `queryParam:"style=form,explode=true,name=pit"` } -func (o *CountTransactionsRequest) GetAccount() *string { +func (o *CountTransactionsRequest) GetRequestBody() map[string]interface{} { if o == nil { return nil } - return o.Account -} - -func (o *CountTransactionsRequest) GetDestination() *string { - if o == nil { - return nil - } - return o.Destination -} - -func (o *CountTransactionsRequest) GetEndTime() *time.Time { - if o == nil { - return nil - } - return o.EndTime + return o.RequestBody } func (o *CountTransactionsRequest) GetLedger() string { @@ -59,32 +29,11 @@ func (o *CountTransactionsRequest) GetLedger() string { return o.Ledger } -func (o *CountTransactionsRequest) GetMetadata() map[string]string { - if o == nil { - return nil - } - return o.Metadata -} - -func (o *CountTransactionsRequest) GetReference() *string { - if o == nil { - return nil - } - return o.Reference -} - -func (o *CountTransactionsRequest) GetSource() *string { - if o == nil { - return nil - } - return o.Source -} - -func (o *CountTransactionsRequest) GetStartTime() *time.Time { +func (o *CountTransactionsRequest) GetPit() *time.Time { if o == nil { return nil } - return o.StartTime + return o.Pit } type CountTransactionsResponse struct { diff --git a/sdks/go/pkg/models/operations/createtransaction.go b/sdks/go/pkg/models/operations/createtransaction.go index 19c09e7ad..6db5c5a67 100755 --- a/sdks/go/pkg/models/operations/createtransaction.go +++ b/sdks/go/pkg/models/operations/createtransaction.go @@ -15,8 +15,6 @@ type CreateTransactionRequest struct { // - `script`: enabling more complex transactions with Numscript // PostTransaction shared.PostTransaction `request:"mediaType=application/json"` - // Set async mode. - Async *bool `queryParam:"style=form,explode=true,name=async"` // Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker. DryRun *bool `queryParam:"style=form,explode=true,name=dryRun"` // Name of the ledger. @@ -37,13 +35,6 @@ func (o *CreateTransactionRequest) GetPostTransaction() shared.PostTransaction { return o.PostTransaction } -func (o *CreateTransactionRequest) GetAsync() *bool { - if o == nil { - return nil - } - return o.Async -} - func (o *CreateTransactionRequest) GetDryRun() *bool { if o == nil { return nil diff --git a/sdks/go/pkg/models/operations/getaccount.go b/sdks/go/pkg/models/operations/getaccount.go index 54b710dc9..31da12a56 100755 --- a/sdks/go/pkg/models/operations/getaccount.go +++ b/sdks/go/pkg/models/operations/getaccount.go @@ -13,7 +13,8 @@ type GetAccountRequest struct { // ^\w+(:\w+)*$ // ``` // - Address string `pathParam:"style=simple,explode=false,name=address"` + Address string `pathParam:"style=simple,explode=false,name=address"` + Expand *string `queryParam:"style=form,explode=true,name=expand"` // Name of the ledger. Ledger string `pathParam:"style=simple,explode=false,name=ledger"` } @@ -25,6 +26,13 @@ func (o *GetAccountRequest) GetAddress() string { return o.Address } +func (o *GetAccountRequest) GetExpand() *string { + if o == nil { + return nil + } + return o.Expand +} + func (o *GetAccountRequest) GetLedger() string { if o == nil { return "" diff --git a/sdks/go/pkg/models/operations/getbalancesaggregated.go b/sdks/go/pkg/models/operations/getbalancesaggregated.go index 34d19e465..153bf3b9b 100755 --- a/sdks/go/pkg/models/operations/getbalancesaggregated.go +++ b/sdks/go/pkg/models/operations/getbalancesaggregated.go @@ -8,19 +8,10 @@ import ( ) type GetBalancesAggregatedRequest struct { - // Filter balances involving given account, either as source or destination. - Address *string `queryParam:"style=form,explode=true,name=address"` // Name of the ledger. Ledger string `pathParam:"style=simple,explode=false,name=ledger"` } -func (o *GetBalancesAggregatedRequest) GetAddress() *string { - if o == nil { - return nil - } - return o.Address -} - func (o *GetBalancesAggregatedRequest) GetLedger() string { if o == nil { return "" diff --git a/sdks/go/pkg/models/operations/gettransaction.go b/sdks/go/pkg/models/operations/gettransaction.go index 1738f2562..d906ea174 100755 --- a/sdks/go/pkg/models/operations/gettransaction.go +++ b/sdks/go/pkg/models/operations/gettransaction.go @@ -8,24 +8,32 @@ import ( ) type GetTransactionRequest struct { + Expand *string `queryParam:"style=form,explode=true,name=expand"` + // Transaction ID. + ID int64 `pathParam:"style=simple,explode=false,name=id"` // Name of the ledger. Ledger string `pathParam:"style=simple,explode=false,name=ledger"` - // Transaction ID. - Txid int64 `pathParam:"style=simple,explode=false,name=txid"` } -func (o *GetTransactionRequest) GetLedger() string { +func (o *GetTransactionRequest) GetExpand() *string { if o == nil { - return "" + return nil } - return o.Ledger + return o.Expand } -func (o *GetTransactionRequest) GetTxid() int64 { +func (o *GetTransactionRequest) GetID() int64 { if o == nil { return 0 } - return o.Txid + return o.ID +} + +func (o *GetTransactionRequest) GetLedger() string { + if o == nil { + return "" + } + return o.Ledger } type GetTransactionResponse struct { diff --git a/sdks/go/pkg/models/operations/listaccounts.go b/sdks/go/pkg/models/operations/listaccounts.go index 112070c19..bfb8cf95d 100755 --- a/sdks/go/pkg/models/operations/listaccounts.go +++ b/sdks/go/pkg/models/operations/listaccounts.go @@ -5,31 +5,31 @@ package operations import ( "github.com/formancehq/formance-sdk-go/pkg/models/shared" "net/http" + "time" ) type ListAccountsRequest struct { - // Filter accounts by address pattern (regular expression placed between ^ and $). - Address *string `queryParam:"style=form,explode=true,name=address"` + RequestBody map[string]interface{} `request:"mediaType=application/json"` // Parameter used in pagination requests. Maximum page size is set to 15. // Set to the value of next for the next page of results. // Set to the value of previous for the previous page of results. // No other parameters can be set when this parameter is set. // Cursor *string `queryParam:"style=form,explode=true,name=cursor"` + Expand *string `queryParam:"style=form,explode=true,name=expand"` // Name of the ledger. Ledger string `pathParam:"style=simple,explode=false,name=ledger"` - // Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - Metadata map[string]string `queryParam:"style=deepObject,explode=true,name=metadata"` // The maximum number of results to return per page. // - PageSize *int64 `queryParam:"style=form,explode=true,name=pageSize"` + PageSize *int64 `queryParam:"style=form,explode=true,name=pageSize"` + Pit *time.Time `queryParam:"style=form,explode=true,name=pit"` } -func (o *ListAccountsRequest) GetAddress() *string { +func (o *ListAccountsRequest) GetRequestBody() map[string]interface{} { if o == nil { return nil } - return o.Address + return o.RequestBody } func (o *ListAccountsRequest) GetCursor() *string { @@ -39,6 +39,13 @@ func (o *ListAccountsRequest) GetCursor() *string { return o.Cursor } +func (o *ListAccountsRequest) GetExpand() *string { + if o == nil { + return nil + } + return o.Expand +} + func (o *ListAccountsRequest) GetLedger() string { if o == nil { return "" @@ -46,18 +53,18 @@ func (o *ListAccountsRequest) GetLedger() string { return o.Ledger } -func (o *ListAccountsRequest) GetMetadata() map[string]string { +func (o *ListAccountsRequest) GetPageSize() *int64 { if o == nil { return nil } - return o.Metadata + return o.PageSize } -func (o *ListAccountsRequest) GetPageSize() *int64 { +func (o *ListAccountsRequest) GetPit() *time.Time { if o == nil { return nil } - return o.PageSize + return o.Pit } type ListAccountsResponse struct { diff --git a/sdks/go/pkg/models/operations/listlogs.go b/sdks/go/pkg/models/operations/listlogs.go index 4e479a10f..e89aa9d6c 100755 --- a/sdks/go/pkg/models/operations/listlogs.go +++ b/sdks/go/pkg/models/operations/listlogs.go @@ -9,39 +9,33 @@ import ( ) type ListLogsRequest struct { + RequestBody map[string]interface{} `request:"mediaType=application/json"` // Parameter used in pagination requests. Maximum page size is set to 15. // Set to the value of next for the next page of results. // Set to the value of previous for the previous page of results. // No other parameters can be set when this parameter is set. // Cursor *string `queryParam:"style=form,explode=true,name=cursor"` - // Filter transactions that occurred before this timestamp. - // The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - // - EndTime *time.Time `queryParam:"style=form,explode=true,name=endTime"` // Name of the ledger. Ledger string `pathParam:"style=simple,explode=false,name=ledger"` // The maximum number of results to return per page. // - PageSize *int64 `queryParam:"style=form,explode=true,name=pageSize"` - // Filter transactions that occurred after this timestamp. - // The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - // - StartTime *time.Time `queryParam:"style=form,explode=true,name=startTime"` + PageSize *int64 `queryParam:"style=form,explode=true,name=pageSize"` + Pit *time.Time `queryParam:"style=form,explode=true,name=pit"` } -func (o *ListLogsRequest) GetCursor() *string { +func (o *ListLogsRequest) GetRequestBody() map[string]interface{} { if o == nil { return nil } - return o.Cursor + return o.RequestBody } -func (o *ListLogsRequest) GetEndTime() *time.Time { +func (o *ListLogsRequest) GetCursor() *string { if o == nil { return nil } - return o.EndTime + return o.Cursor } func (o *ListLogsRequest) GetLedger() string { @@ -58,11 +52,11 @@ func (o *ListLogsRequest) GetPageSize() *int64 { return o.PageSize } -func (o *ListLogsRequest) GetStartTime() *time.Time { +func (o *ListLogsRequest) GetPit() *time.Time { if o == nil { return nil } - return o.StartTime + return o.Pit } type ListLogsResponse struct { diff --git a/sdks/go/pkg/models/operations/listtransactions.go b/sdks/go/pkg/models/operations/listtransactions.go index 81adec32e..19d24764e 100755 --- a/sdks/go/pkg/models/operations/listtransactions.go +++ b/sdks/go/pkg/models/operations/listtransactions.go @@ -9,42 +9,27 @@ import ( ) type ListTransactionsRequest struct { - // Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). - Account *string `queryParam:"style=form,explode=true,name=account"` + RequestBody map[string]interface{} `request:"mediaType=application/json"` // Parameter used in pagination requests. Maximum page size is set to 15. // Set to the value of next for the next page of results. // Set to the value of previous for the previous page of results. // No other parameters can be set when this parameter is set. // Cursor *string `queryParam:"style=form,explode=true,name=cursor"` - // Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). - Destination *string `queryParam:"style=form,explode=true,name=destination"` - // Filter transactions that occurred before this timestamp. - // The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - // - EndTime *time.Time `queryParam:"style=form,explode=true,name=endTime"` + Expand *string `queryParam:"style=form,explode=true,name=expand"` // Name of the ledger. Ledger string `pathParam:"style=simple,explode=false,name=ledger"` - // Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below. - Metadata map[string]string `queryParam:"style=deepObject,explode=true,name=metadata"` // The maximum number of results to return per page. // - PageSize *int64 `queryParam:"style=form,explode=true,name=pageSize"` - // Find transactions by reference field. - Reference *string `queryParam:"style=form,explode=true,name=reference"` - // Filter transactions with postings involving given account at source (regular expression placed between ^ and $). - Source *string `queryParam:"style=form,explode=true,name=source"` - // Filter transactions that occurred after this timestamp. - // The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - // - StartTime *time.Time `queryParam:"style=form,explode=true,name=startTime"` + PageSize *int64 `queryParam:"style=form,explode=true,name=pageSize"` + Pit *time.Time `queryParam:"style=form,explode=true,name=pit"` } -func (o *ListTransactionsRequest) GetAccount() *string { +func (o *ListTransactionsRequest) GetRequestBody() map[string]interface{} { if o == nil { return nil } - return o.Account + return o.RequestBody } func (o *ListTransactionsRequest) GetCursor() *string { @@ -54,18 +39,11 @@ func (o *ListTransactionsRequest) GetCursor() *string { return o.Cursor } -func (o *ListTransactionsRequest) GetDestination() *string { +func (o *ListTransactionsRequest) GetExpand() *string { if o == nil { return nil } - return o.Destination -} - -func (o *ListTransactionsRequest) GetEndTime() *time.Time { - if o == nil { - return nil - } - return o.EndTime + return o.Expand } func (o *ListTransactionsRequest) GetLedger() string { @@ -75,13 +53,6 @@ func (o *ListTransactionsRequest) GetLedger() string { return o.Ledger } -func (o *ListTransactionsRequest) GetMetadata() map[string]string { - if o == nil { - return nil - } - return o.Metadata -} - func (o *ListTransactionsRequest) GetPageSize() *int64 { if o == nil { return nil @@ -89,25 +60,11 @@ func (o *ListTransactionsRequest) GetPageSize() *int64 { return o.PageSize } -func (o *ListTransactionsRequest) GetReference() *string { - if o == nil { - return nil - } - return o.Reference -} - -func (o *ListTransactionsRequest) GetSource() *string { - if o == nil { - return nil - } - return o.Source -} - -func (o *ListTransactionsRequest) GetStartTime() *time.Time { +func (o *ListTransactionsRequest) GetPit() *time.Time { if o == nil { return nil } - return o.StartTime + return o.Pit } type ListTransactionsResponse struct { diff --git a/sdks/go/pkg/models/operations/reverttransaction.go b/sdks/go/pkg/models/operations/reverttransaction.go index 9a6d96f7e..4d3d0c406 100755 --- a/sdks/go/pkg/models/operations/reverttransaction.go +++ b/sdks/go/pkg/models/operations/reverttransaction.go @@ -8,24 +8,24 @@ import ( ) type RevertTransactionRequest struct { + // Transaction ID. + ID int64 `pathParam:"style=simple,explode=false,name=id"` // Name of the ledger. Ledger string `pathParam:"style=simple,explode=false,name=ledger"` - // Transaction ID. - Txid int64 `pathParam:"style=simple,explode=false,name=txid"` } -func (o *RevertTransactionRequest) GetLedger() string { +func (o *RevertTransactionRequest) GetID() int64 { if o == nil { - return "" + return 0 } - return o.Ledger + return o.ID } -func (o *RevertTransactionRequest) GetTxid() int64 { +func (o *RevertTransactionRequest) GetLedger() string { if o == nil { - return 0 + return "" } - return o.Txid + return o.Ledger } type RevertTransactionResponse struct { diff --git a/sdks/go/pkg/models/shared/accountwithvolumesandbalances.go b/sdks/go/pkg/models/shared/accountwithvolumesandbalances.go index 0791bb8b2..0f1d53bd3 100755 --- a/sdks/go/pkg/models/shared/accountwithvolumesandbalances.go +++ b/sdks/go/pkg/models/shared/accountwithvolumesandbalances.go @@ -8,10 +8,9 @@ import ( type AccountWithVolumesAndBalances struct { Address string `json:"address"` - Balances map[string]*big.Int `json:"balances"` Metadata map[string]string `json:"metadata"` Type *string `json:"type,omitempty"` - Volumes map[string]map[string]*big.Int `json:"volumes"` + Volumes map[string]map[string]*big.Int `json:"volumes,omitempty"` } func (o *AccountWithVolumesAndBalances) GetAddress() string { @@ -21,13 +20,6 @@ func (o *AccountWithVolumesAndBalances) GetAddress() string { return o.Address } -func (o *AccountWithVolumesAndBalances) GetBalances() map[string]*big.Int { - if o == nil { - return map[string]*big.Int{} - } - return o.Balances -} - func (o *AccountWithVolumesAndBalances) GetMetadata() map[string]string { if o == nil { return map[string]string{} @@ -44,7 +36,7 @@ func (o *AccountWithVolumesAndBalances) GetType() *string { func (o *AccountWithVolumesAndBalances) GetVolumes() map[string]map[string]*big.Int { if o == nil { - return map[string]map[string]*big.Int{} + return nil } return o.Volumes } diff --git a/sdks/go/pkg/models/shared/expandedtransaction.go b/sdks/go/pkg/models/shared/expandedtransaction.go index 6faba2f90..3443748cd 100755 --- a/sdks/go/pkg/models/shared/expandedtransaction.go +++ b/sdks/go/pkg/models/shared/expandedtransaction.go @@ -7,13 +7,21 @@ import ( ) type ExpandedTransaction struct { + ID int64 `json:"id"` Metadata map[string]string `json:"metadata"` - PostCommitVolumes map[string]map[string]Volume `json:"postCommitVolumes"` + PostCommitVolumes map[string]map[string]Volume `json:"postCommitVolumes,omitempty"` Postings []Posting `json:"postings"` - PreCommitVolumes map[string]map[string]Volume `json:"preCommitVolumes"` + PreCommitVolumes map[string]map[string]Volume `json:"preCommitVolumes,omitempty"` Reference *string `json:"reference,omitempty"` + Reverted bool `json:"reverted"` Timestamp time.Time `json:"timestamp"` - Txid int64 `json:"txid"` +} + +func (o *ExpandedTransaction) GetID() int64 { + if o == nil { + return 0 + } + return o.ID } func (o *ExpandedTransaction) GetMetadata() map[string]string { @@ -25,7 +33,7 @@ func (o *ExpandedTransaction) GetMetadata() map[string]string { func (o *ExpandedTransaction) GetPostCommitVolumes() map[string]map[string]Volume { if o == nil { - return map[string]map[string]Volume{} + return nil } return o.PostCommitVolumes } @@ -39,7 +47,7 @@ func (o *ExpandedTransaction) GetPostings() []Posting { func (o *ExpandedTransaction) GetPreCommitVolumes() map[string]map[string]Volume { if o == nil { - return map[string]map[string]Volume{} + return nil } return o.PreCommitVolumes } @@ -51,16 +59,16 @@ func (o *ExpandedTransaction) GetReference() *string { return o.Reference } -func (o *ExpandedTransaction) GetTimestamp() time.Time { +func (o *ExpandedTransaction) GetReverted() bool { if o == nil { - return time.Time{} + return false } - return o.Timestamp + return o.Reverted } -func (o *ExpandedTransaction) GetTxid() int64 { +func (o *ExpandedTransaction) GetTimestamp() time.Time { if o == nil { - return 0 + return time.Time{} } - return o.Txid + return o.Timestamp } diff --git a/sdks/go/pkg/models/shared/transaction.go b/sdks/go/pkg/models/shared/transaction.go index 6e0a8ca98..ef96df579 100755 --- a/sdks/go/pkg/models/shared/transaction.go +++ b/sdks/go/pkg/models/shared/transaction.go @@ -7,11 +7,19 @@ import ( ) type Transaction struct { + ID int64 `json:"id"` Metadata map[string]string `json:"metadata"` Postings []Posting `json:"postings"` Reference *string `json:"reference,omitempty"` + Reverted bool `json:"reverted"` Timestamp time.Time `json:"timestamp"` - Txid int64 `json:"txid"` +} + +func (o *Transaction) GetID() int64 { + if o == nil { + return 0 + } + return o.ID } func (o *Transaction) GetMetadata() map[string]string { @@ -35,16 +43,16 @@ func (o *Transaction) GetReference() *string { return o.Reference } -func (o *Transaction) GetTimestamp() time.Time { +func (o *Transaction) GetReverted() bool { if o == nil { - return time.Time{} + return false } - return o.Timestamp + return o.Reverted } -func (o *Transaction) GetTxid() int64 { +func (o *Transaction) GetTimestamp() time.Time { if o == nil { - return 0 + return time.Time{} } - return o.Txid + return o.Timestamp } diff --git a/sdks/go/pkg/models/shared/walletstransaction.go b/sdks/go/pkg/models/shared/walletstransaction.go index c2ebbb4ea..43c9f5fd6 100755 --- a/sdks/go/pkg/models/shared/walletstransaction.go +++ b/sdks/go/pkg/models/shared/walletstransaction.go @@ -7,6 +7,7 @@ import ( ) type WalletsTransaction struct { + ID *int64 `json:"id,omitempty"` Ledger *string `json:"ledger,omitempty"` // Metadata associated with the wallet. Metadata map[string]string `json:"metadata"` @@ -15,7 +16,13 @@ type WalletsTransaction struct { PreCommitVolumes map[string]map[string]WalletsVolume `json:"preCommitVolumes,omitempty"` Reference *string `json:"reference,omitempty"` Timestamp time.Time `json:"timestamp"` - Txid int64 `json:"txid"` +} + +func (o *WalletsTransaction) GetID() *int64 { + if o == nil { + return nil + } + return o.ID } func (o *WalletsTransaction) GetLedger() *string { @@ -66,10 +73,3 @@ func (o *WalletsTransaction) GetTimestamp() time.Time { } return o.Timestamp } - -func (o *WalletsTransaction) GetTxid() int64 { - if o == nil { - return 0 - } - return o.Txid -} diff --git a/sdks/java/README.md b/sdks/java/README.md index 2e1af8163..cbbd58ece 100755 --- a/sdks/java/README.md +++ b/sdks/java/README.md @@ -91,7 +91,6 @@ public class Application { * [countTransactions](docs/sdks/ledger/README.md#counttransactions) - Count the transactions from a ledger * [createTransaction](docs/sdks/ledger/README.md#createtransaction) - Create a new transaction to a ledger * [getAccount](docs/sdks/ledger/README.md#getaccount) - Get account by its address -* [getBalances](docs/sdks/ledger/README.md#getbalances) - Get the balances from a ledger's account * [getBalancesAggregated](docs/sdks/ledger/README.md#getbalancesaggregated) - Get the aggregated balances from selected accounts * [getInfo](docs/sdks/ledger/README.md#getinfo) - Show server information * [getLedgerInfo](docs/sdks/ledger/README.md#getledgerinfo) - Get information about a ledger diff --git a/sdks/java/docs/models/operations/AddMetadataOnTransactionRequest.md b/sdks/java/docs/models/operations/AddMetadataOnTransactionRequest.md index 6235bd8c8..eaaa0164c 100755 --- a/sdks/java/docs/models/operations/AddMetadataOnTransactionRequest.md +++ b/sdks/java/docs/models/operations/AddMetadataOnTransactionRequest.md @@ -7,7 +7,6 @@ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | `idempotencyKey` | *String* | :heavy_minus_sign: | Use an idempotency key | | | `requestBody` | Map | :heavy_minus_sign: | metadata | | -| `async` | *Boolean* | :heavy_minus_sign: | Set async mode. | true | | `dryRun` | *Boolean* | :heavy_minus_sign: | Set the dryRun mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | -| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *Long* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `id` | *Long* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/AddMetadataToAccountRequest.md b/sdks/java/docs/models/operations/AddMetadataToAccountRequest.md index 66896e658..6cb2b035f 100755 --- a/sdks/java/docs/models/operations/AddMetadataToAccountRequest.md +++ b/sdks/java/docs/models/operations/AddMetadataToAccountRequest.md @@ -8,6 +8,5 @@ | `idempotencyKey` | *String* | :heavy_minus_sign: | Use an idempotency key | | | `requestBody` | Map | :heavy_check_mark: | metadata | | | `address` | *String* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | -| `async` | *Boolean* | :heavy_minus_sign: | Set async mode. | true | | `dryRun` | *Boolean* | :heavy_minus_sign: | Set the dry run mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/CountAccountsMetadata.md b/sdks/java/docs/models/operations/CountAccountsMetadata.md deleted file mode 100755 index 7ea898a09..000000000 --- a/sdks/java/docs/models/operations/CountAccountsMetadata.md +++ /dev/null @@ -1,9 +0,0 @@ -# CountAccountsMetadata - -Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/CountAccountsRequest.md b/sdks/java/docs/models/operations/CountAccountsRequest.md index 0e4c1c35a..d3361ad4e 100755 --- a/sdks/java/docs/models/operations/CountAccountsRequest.md +++ b/sdks/java/docs/models/operations/CountAccountsRequest.md @@ -3,8 +3,7 @@ ## Fields -| Field | Type | Required | Description | Example | -| ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *String* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | -| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | [CountAccountsMetadata](../../models/operations/CountAccountsMetadata.md) | :heavy_minus_sign: | Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| --------------------- | --------------------- | --------------------- | --------------------- | --------------------- | +| `requestBody` | Map | :heavy_minus_sign: | N/A | | +| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/CountTransactionsRequest.md b/sdks/java/docs/models/operations/CountTransactionsRequest.md index c7c4b56cd..2b0d03d3e 100755 --- a/sdks/java/docs/models/operations/CountTransactionsRequest.md +++ b/sdks/java/docs/models/operations/CountTransactionsRequest.md @@ -3,13 +3,8 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `account` | *String* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | -| `destination` | *String* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `endTime` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | -| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | Map | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `reference` | *String* | :heavy_minus_sign: | Filter transactions by reference field. | ref:001 | -| `source` | *String* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `startTime` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `requestBody` | Map | :heavy_minus_sign: | N/A | | +| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | +| `pit` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/CountTransactionsRequestBody.md b/sdks/java/docs/models/operations/CountTransactionsRequestBody.md deleted file mode 100755 index 94a1f6eee..000000000 --- a/sdks/java/docs/models/operations/CountTransactionsRequestBody.md +++ /dev/null @@ -1,7 +0,0 @@ -# CountTransactionsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/CreateTransactionRequest.md b/sdks/java/docs/models/operations/CreateTransactionRequest.md index b54bea16e..d8f9b3f3c 100755 --- a/sdks/java/docs/models/operations/CreateTransactionRequest.md +++ b/sdks/java/docs/models/operations/CreateTransactionRequest.md @@ -7,6 +7,5 @@ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `idempotencyKey` | *String* | :heavy_minus_sign: | Use an idempotency key | | | `postTransaction` | [com.formance.formance_sdk.models.shared.PostTransaction](../../models/shared/PostTransaction.md) | :heavy_check_mark: | The request body must contain at least one of the following objects:
    - `postings`: suitable for simple transactions
    - `script`: enabling more complex transactions with Numscript
    | | -| `async` | *Boolean* | :heavy_minus_sign: | Set async mode. | true | | `dryRun` | *Boolean* | :heavy_minus_sign: | Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/GetAccountRequest.md b/sdks/java/docs/models/operations/GetAccountRequest.md index 32fe7be8d..28f560687 100755 --- a/sdks/java/docs/models/operations/GetAccountRequest.md +++ b/sdks/java/docs/models/operations/GetAccountRequest.md @@ -6,4 +6,5 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | `address` | *String* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | +| `expand` | *String* | :heavy_minus_sign: | N/A | | | `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/GetBalancesAggregatedRequest.md b/sdks/java/docs/models/operations/GetBalancesAggregatedRequest.md index 21a23ce98..c4a176d3c 100755 --- a/sdks/java/docs/models/operations/GetBalancesAggregatedRequest.md +++ b/sdks/java/docs/models/operations/GetBalancesAggregatedRequest.md @@ -3,7 +3,6 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -| `address` | *String* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/GetBalancesRequest.md b/sdks/java/docs/models/operations/GetBalancesRequest.md deleted file mode 100755 index 59cf02613..000000000 --- a/sdks/java/docs/models/operations/GetBalancesRequest.md +++ /dev/null @@ -1,11 +0,0 @@ -# GetBalancesRequest - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *String* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `cursor` | *String* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `pageSize` | *Long* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/GetBalancesResponse.md b/sdks/java/docs/models/operations/GetBalancesResponse.md deleted file mode 100755 index 54ab9d455..000000000 --- a/sdks/java/docs/models/operations/GetBalancesResponse.md +++ /dev/null @@ -1,12 +0,0 @@ -# GetBalancesResponse - - -## Fields - -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | -| `balancesCursorResponse` | [com.formance.formance_sdk.models.shared.BalancesCursorResponse](../../models/shared/BalancesCursorResponse.md) | :heavy_minus_sign: | OK | -| `contentType` | *String* | :heavy_check_mark: | N/A | -| `errorResponse` | [com.formance.formance_sdk.models.shared.ErrorResponse](../../models/shared/ErrorResponse.md) | :heavy_minus_sign: | Error | -| `statusCode` | *Integer* | :heavy_check_mark: | N/A | -| `rawResponse` | [HttpResponse](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.html) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/GetTransactionRequest.md b/sdks/java/docs/models/operations/GetTransactionRequest.md index 575627fec..561b4f415 100755 --- a/sdks/java/docs/models/operations/GetTransactionRequest.md +++ b/sdks/java/docs/models/operations/GetTransactionRequest.md @@ -5,5 +5,6 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *Long* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `expand` | *String* | :heavy_minus_sign: | N/A | | +| `id` | *Long* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/ListAccountsRequest.md b/sdks/java/docs/models/operations/ListAccountsRequest.md index ed2d76605..7474517c0 100755 --- a/sdks/java/docs/models/operations/ListAccountsRequest.md +++ b/sdks/java/docs/models/operations/ListAccountsRequest.md @@ -5,8 +5,9 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *String* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | +| `requestBody` | Map | :heavy_minus_sign: | N/A | | | `cursor` | *String* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | +| `expand` | *String* | :heavy_minus_sign: | N/A | | | `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | Map | :heavy_minus_sign: | Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `pageSize` | *Long* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file +| `pageSize` | *Long* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | +| `pit` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/ListAccountsRequestBody.md b/sdks/java/docs/models/operations/ListAccountsRequestBody.md deleted file mode 100755 index 22f1ad984..000000000 --- a/sdks/java/docs/models/operations/ListAccountsRequestBody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListAccountsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/ListLogsRequest.md b/sdks/java/docs/models/operations/ListLogsRequest.md index 1fd7931cf..5ba3d64fc 100755 --- a/sdks/java/docs/models/operations/ListLogsRequest.md +++ b/sdks/java/docs/models/operations/ListLogsRequest.md @@ -5,8 +5,8 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `requestBody` | Map | :heavy_minus_sign: | N/A | | | `cursor` | *String* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `endTime` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | | `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | | `pageSize` | *Long* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `startTime` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| `pit` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/ListLogsRequestBody.md b/sdks/java/docs/models/operations/ListLogsRequestBody.md deleted file mode 100755 index 6dbd158df..000000000 --- a/sdks/java/docs/models/operations/ListLogsRequestBody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListLogsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/ListTransactionsRequest.md b/sdks/java/docs/models/operations/ListTransactionsRequest.md index d23b0adc5..f32771f86 100755 --- a/sdks/java/docs/models/operations/ListTransactionsRequest.md +++ b/sdks/java/docs/models/operations/ListTransactionsRequest.md @@ -5,13 +5,9 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `account` | *String* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | +| `requestBody` | Map | :heavy_minus_sign: | N/A | | | `cursor` | *String* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `destination` | *String* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `endTime` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | +| `expand` | *String* | :heavy_minus_sign: | N/A | | | `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | Map | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below. | | | `pageSize` | *Long* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `reference` | *String* | :heavy_minus_sign: | Find transactions by reference field. | ref:001 | -| `source` | *String* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `startTime` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| `pit` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/ListTransactionsRequestBody.md b/sdks/java/docs/models/operations/ListTransactionsRequestBody.md deleted file mode 100755 index 990f2baf5..000000000 --- a/sdks/java/docs/models/operations/ListTransactionsRequestBody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListTransactionsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/java/docs/models/operations/RevertTransactionRequest.md b/sdks/java/docs/models/operations/RevertTransactionRequest.md index bf5ca74be..9d74b4651 100755 --- a/sdks/java/docs/models/operations/RevertTransactionRequest.md +++ b/sdks/java/docs/models/operations/RevertTransactionRequest.md @@ -5,5 +5,5 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *Long* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `id` | *Long* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *String* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/java/docs/models/shared/AccountWithVolumesAndBalances.md b/sdks/java/docs/models/shared/AccountWithVolumesAndBalances.md index 9240f0150..32d18af81 100755 --- a/sdks/java/docs/models/shared/AccountWithVolumesAndBalances.md +++ b/sdks/java/docs/models/shared/AccountWithVolumesAndBalances.md @@ -6,7 +6,6 @@ | Field | Type | Required | Description | Example | | -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- | | `address` | *String* | :heavy_check_mark: | N/A | users:001 | -| `balances` | Map | :heavy_check_mark: | N/A | | | `metadata` | Map | :heavy_check_mark: | N/A | | | `type` | *String* | :heavy_minus_sign: | N/A | virtual | -| `volumes` | Map> | :heavy_check_mark: | N/A | | \ No newline at end of file +| `volumes` | Map> | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/java/docs/models/shared/BalancesCursorResponse.md b/sdks/java/docs/models/shared/BalancesCursorResponse.md deleted file mode 100755 index bbd2d4560..000000000 --- a/sdks/java/docs/models/shared/BalancesCursorResponse.md +++ /dev/null @@ -1,10 +0,0 @@ -# BalancesCursorResponse - -OK - - -## Fields - -| Field | Type | Required | Description | -| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | -| `cursor` | [BalancesCursorResponseCursor](../../models/shared/BalancesCursorResponseCursor.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/sdks/java/docs/models/shared/BalancesCursorResponseCursor.md b/sdks/java/docs/models/shared/BalancesCursorResponseCursor.md deleted file mode 100755 index 534451e24..000000000 --- a/sdks/java/docs/models/shared/BalancesCursorResponseCursor.md +++ /dev/null @@ -1,12 +0,0 @@ -# BalancesCursorResponseCursor - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -| `data` | List>> | :heavy_check_mark: | N/A | | -| `hasMore` | *Boolean* | :heavy_check_mark: | N/A | false | -| `next` | *String* | :heavy_minus_sign: | N/A | | -| `pageSize` | *Long* | :heavy_check_mark: | N/A | 15 | -| `previous` | *String* | :heavy_minus_sign: | N/A | YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= | \ No newline at end of file diff --git a/sdks/java/docs/models/shared/ExpandedTransaction.md b/sdks/java/docs/models/shared/ExpandedTransaction.md index 451667cc4..6db6533ac 100755 --- a/sdks/java/docs/models/shared/ExpandedTransaction.md +++ b/sdks/java/docs/models/shared/ExpandedTransaction.md @@ -5,10 +5,11 @@ | Field | Type | Required | Description | Example | | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `id` | *Long* | :heavy_check_mark: | N/A | | | `metadata` | Map | :heavy_check_mark: | N/A | | -| `postCommitVolumes` | Map> | :heavy_check_mark: | N/A | | +| `postCommitVolumes` | Map> | :heavy_minus_sign: | N/A | | | `postings` | List<[Posting](../../models/shared/Posting.md)> | :heavy_check_mark: | N/A | | -| `preCommitVolumes` | Map> | :heavy_check_mark: | N/A | | +| `preCommitVolumes` | Map> | :heavy_minus_sign: | N/A | | | `reference` | *String* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_check_mark: | N/A | | -| `txid` | *Long* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `reverted` | *Boolean* | :heavy_check_mark: | N/A | | +| `timestamp` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/java/docs/models/shared/PostTransactionScriptVars.md b/sdks/java/docs/models/shared/PostTransactionScriptVars.md new file mode 100755 index 000000000..ef1a0de95 --- /dev/null +++ b/sdks/java/docs/models/shared/PostTransactionScriptVars.md @@ -0,0 +1,7 @@ +# PostTransactionScriptVars + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/java/docs/models/shared/Query.md b/sdks/java/docs/models/shared/Query.md index 0e625816f..467fd3c68 100755 --- a/sdks/java/docs/models/shared/Query.md +++ b/sdks/java/docs/models/shared/Query.md @@ -11,6 +11,6 @@ | `pageSize` | *Long* | :heavy_minus_sign: | N/A | | | `policy` | *String* | :heavy_minus_sign: | N/A | OR | | `raw` | [QueryRaw](../../models/shared/QueryRaw.md) | :heavy_minus_sign: | N/A | | -| `sort` | *String* | :heavy_minus_sign: | N/A | txid:asc | +| `sort` | *String* | :heavy_minus_sign: | N/A | id:asc | | `target` | *String* | :heavy_minus_sign: | N/A | | | `terms` | List<*String*> | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/java/docs/models/shared/ResponseData.md b/sdks/java/docs/models/shared/ResponseData.md new file mode 100755 index 000000000..c3a85e750 --- /dev/null +++ b/sdks/java/docs/models/shared/ResponseData.md @@ -0,0 +1,9 @@ +# ResponseData + +The payload + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/java/docs/models/shared/Transaction.md b/sdks/java/docs/models/shared/Transaction.md index 6cbbb12e0..5d06fadff 100755 --- a/sdks/java/docs/models/shared/Transaction.md +++ b/sdks/java/docs/models/shared/Transaction.md @@ -5,8 +5,9 @@ | Field | Type | Required | Description | Example | | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `id` | *Long* | :heavy_check_mark: | N/A | | | `metadata` | Map | :heavy_check_mark: | N/A | | | `postings` | List<[Posting](../../models/shared/Posting.md)> | :heavy_check_mark: | N/A | | | `reference` | *String* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_check_mark: | N/A | | -| `txid` | *Long* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `reverted` | *Boolean* | :heavy_check_mark: | N/A | | +| `timestamp` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/java/docs/models/shared/WalletsTransaction.md b/sdks/java/docs/models/shared/WalletsTransaction.md index 124af0576..3d626b967 100755 --- a/sdks/java/docs/models/shared/WalletsTransaction.md +++ b/sdks/java/docs/models/shared/WalletsTransaction.md @@ -5,11 +5,11 @@ | Field | Type | Required | Description | Example | | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `id` | *Long* | :heavy_minus_sign: | N/A | | | `ledger` | *String* | :heavy_minus_sign: | N/A | | | `metadata` | Map | :heavy_check_mark: | Metadata associated with the wallet. | | | `postCommitVolumes` | Map> | :heavy_minus_sign: | N/A | | | `postings` | List<[Posting](../../models/shared/Posting.md)> | :heavy_check_mark: | N/A | | | `preCommitVolumes` | Map> | :heavy_minus_sign: | N/A | | | `reference` | *String* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_check_mark: | N/A | | -| `txid` | *Long* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `timestamp` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/java/docs/sdks/ledger/README.md b/sdks/java/docs/sdks/ledger/README.md index e8c69d9e9..e7aa1ef69 100755 --- a/sdks/java/docs/sdks/ledger/README.md +++ b/sdks/java/docs/sdks/ledger/README.md @@ -8,7 +8,6 @@ * [countTransactions](#counttransactions) - Count the transactions from a ledger * [createTransaction](#createtransaction) - Create a new transaction to a ledger * [getAccount](#getaccount) - Get account by its address -* [getBalances](#getbalances) - Get the balances from a ledger's account * [getBalancesAggregated](#getbalancesaggregated) - Get the aggregated balances from selected accounts * [getInfo](#getinfo) - Show server information * [getLedgerInfo](#getledgerinfo) - Get information about a ledger @@ -42,14 +41,13 @@ public class Application { }}) .build(); - AddMetadataOnTransactionRequest req = new AddMetadataOnTransactionRequest("ledger001", 1234L) {{ + AddMetadataOnTransactionRequest req = new AddMetadataOnTransactionRequest(1234L, "ledger001") {{ idempotencyKey = "enim"; requestBody = new java.util.HashMap() {{ put("nemo", "minima"); put("excepturi", "accusantium"); put("iure", "culpa"); }}; - async = true; dryRun = true; }}; @@ -107,7 +105,6 @@ public class Application { put("mollitia", "occaecati"); }}, "users:001", "ledger001") {{ idempotencyKey = "numquam"; - async = true; dryRun = true; }}; @@ -145,7 +142,6 @@ Count the accounts from a ledger package hello.world; import com.formance.formance_sdk.SDK; -import com.formance.formance_sdk.models.operations.CountAccountsMetadata; import com.formance.formance_sdk.models.operations.CountAccountsRequest; import com.formance.formance_sdk.models.operations.CountAccountsResponse; import com.formance.formance_sdk.models.shared.Security; @@ -160,8 +156,10 @@ public class Application { .build(); CountAccountsRequest req = new CountAccountsRequest("ledger001") {{ - address = "users:.+"; - metadata = new CountAccountsMetadata();; + requestBody = new java.util.HashMap() {{ + put("molestiae", "velit"); + put("error", "quia"); + }}; }}; CountAccountsResponse res = sdk.ledger.countAccounts(req); @@ -207,23 +205,16 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("quam") {{ + .setSecurity(new Security("quis") {{ authorization = ""; }}) .build(); CountTransactionsRequest req = new CountTransactionsRequest("ledger001") {{ - account = "users:001"; - destination = "users:001"; - endTime = OffsetDateTime.parse("2022-10-03T18:49:53.900Z"); - metadata = new java.util.HashMap() {{ - put("quia", "quis"); - put("vitae", "laborum"); - put("animi", "enim"); + requestBody = new java.util.HashMap() {{ + put("laborum", "animi"); }}; - reference = "ref:001"; - source = "users:001"; - startTime = OffsetDateTime.parse("2022-03-22T21:41:36.666Z"); + pit = OffsetDateTime.parse("2022-11-11T13:31:01.643Z"); }}; CountTransactionsResponse res = sdk.ledger.countTransactions(req); @@ -272,16 +263,13 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("sequi") {{ + .setSecurity(new Security("quo") {{ authorization = ""; }}) .build(); CreateTransactionRequest req = new CreateTransactionRequest( new PostTransaction( new java.util.HashMap() {{ - put("ipsam", "id"); - put("possimus", "aut"); - put("quasi", "error"); - put("temporibus", "laborum"); + put("tenetur", "ipsam"); }}) {{ postings = new com.formance.formance_sdk.models.shared.Posting[]{{ add(new Posting(100L, "COIN", "users:002", "users:001") {{ @@ -290,6 +278,18 @@ public class Application { destination = "users:002"; source = "users:001"; }}), + add(new Posting(100L, "COIN", "users:002", "users:001") {{ + amount = 100L; + asset = "COIN"; + destination = "users:002"; + source = "users:001"; + }}), + add(new Posting(100L, "COIN", "users:002", "users:001") {{ + amount = 100L; + asset = "COIN"; + destination = "users:002"; + source = "users:001"; + }}), }}; reference = "ref:001"; script = new PostTransactionScript("vars { @@ -301,16 +301,15 @@ public class Application { ) ") {{ vars = new java.util.HashMap() {{ - put("voluptatibus", "vero"); - put("nihil", "praesentium"); - put("voluptatibus", "ipsa"); - put("omnis", "voluptate"); + put("aut", "quasi"); + put("error", "temporibus"); + put("laborum", "quasi"); + put("reiciendis", "voluptatibus"); }}; }};; - timestamp = OffsetDateTime.parse("2022-12-17T09:48:56.551Z"); + timestamp = OffsetDateTime.parse("2021-08-05T19:50:46.898Z"); }};, "ledger001") {{ - idempotencyKey = "doloremque"; - async = true; + idempotencyKey = "praesentium"; dryRun = true; }}; @@ -356,12 +355,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("reprehenderit") {{ + .setSecurity(new Security("voluptatibus") {{ authorization = ""; }}) .build(); - GetAccountRequest req = new GetAccountRequest("users:001", "ledger001"); + GetAccountRequest req = new GetAccountRequest("users:001", "ledger001") {{ + expand = "ipsa"; + }}; GetAccountResponse res = sdk.ledger.getAccount(req); @@ -387,59 +388,6 @@ public class Application { **[com.formance.formance_sdk.models.operations.GetAccountResponse](../../models/operations/GetAccountResponse.md)** -## getBalances - -Get the balances from a ledger's account - -### Example Usage - -```java -package hello.world; - -import com.formance.formance_sdk.SDK; -import com.formance.formance_sdk.models.operations.GetBalancesRequest; -import com.formance.formance_sdk.models.operations.GetBalancesResponse; -import com.formance.formance_sdk.models.shared.Security; - -public class Application { - public static void main(String[] args) { - try { - SDK sdk = SDK.builder() - .setSecurity(new Security("ut") {{ - authorization = ""; - }}) - .build(); - - GetBalancesRequest req = new GetBalancesRequest("ledger001") {{ - address = "users:001"; - cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - pageSize = 979587L; - }}; - - GetBalancesResponse res = sdk.ledger.getBalances(req); - - if (res.balancesCursorResponse != null) { - // handle response - } - } catch (Exception e) { - // handle exception - } - } -} -``` - -### Parameters - -| Parameter | Type | Required | Description | -| --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | -| `request` | [com.formance.formance_sdk.models.operations.GetBalancesRequest](../../models/operations/GetBalancesRequest.md) | :heavy_check_mark: | The request object to use for the request. | - - -### Response - -**[com.formance.formance_sdk.models.operations.GetBalancesResponse](../../models/operations/GetBalancesResponse.md)** - - ## getBalancesAggregated Get the aggregated balances from selected accounts @@ -458,14 +406,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("dicta") {{ + .setSecurity(new Security("omnis") {{ authorization = ""; }}) .build(); - GetBalancesAggregatedRequest req = new GetBalancesAggregatedRequest("ledger001") {{ - address = "users:001"; - }}; + GetBalancesAggregatedRequest req = new GetBalancesAggregatedRequest("ledger001"); GetBalancesAggregatedResponse res = sdk.ledger.getBalancesAggregated(req); @@ -508,7 +454,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("corporis") {{ + .setSecurity(new Security("voluptate") {{ authorization = ""; }}) .build(); @@ -549,7 +495,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("dolore") {{ + .setSecurity(new Security("cum") {{ authorization = ""; }}) .build(); @@ -598,12 +544,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("iusto") {{ + .setSecurity(new Security("perferendis") {{ authorization = ""; }}) .build(); - GetTransactionRequest req = new GetTransactionRequest("ledger001", 1234L); + GetTransactionRequest req = new GetTransactionRequest(1234L, "ledger001") {{ + expand = "doloremque"; + }}; GetTransactionResponse res = sdk.ledger.getTransaction(req); @@ -642,25 +590,26 @@ import com.formance.formance_sdk.SDK; import com.formance.formance_sdk.models.operations.ListAccountsRequest; import com.formance.formance_sdk.models.operations.ListAccountsResponse; import com.formance.formance_sdk.models.shared.Security; +import java.time.OffsetDateTime; public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("dicta") {{ + .setSecurity(new Security("reprehenderit") {{ authorization = ""; }}) .build(); ListAccountsRequest req = new ListAccountsRequest("ledger001") {{ - address = "users:.+"; - cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - metadata = new java.util.HashMap() {{ - put("enim", "accusamus"); - put("commodi", "repudiandae"); - put("quae", "ipsum"); + requestBody = new java.util.HashMap() {{ + put("maiores", "dicta"); + put("corporis", "dolore"); }}; - pageSize = 692472L; + cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; + expand = "iusto"; + pageSize = 118727L; + pit = OffsetDateTime.parse("2022-05-13T20:56:04.612Z"); }}; ListAccountsResponse res = sdk.ledger.listAccounts(req); @@ -706,16 +655,19 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("molestias") {{ + .setSecurity(new Security("accusamus") {{ authorization = ""; }}) .build(); ListLogsRequest req = new ListLogsRequest("ledger001") {{ + requestBody = new java.util.HashMap() {{ + put("repudiandae", "quae"); + put("ipsum", "quidem"); + }}; cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - endTime = OffsetDateTime.parse("2021-04-09T11:24:10.949Z"); - pageSize = 265389L; - startTime = OffsetDateTime.parse("2021-12-15T00:41:38.329Z"); + pageSize = 565189L; + pit = OffsetDateTime.parse("2021-04-09T11:24:10.949Z"); }}; ListLogsResponse res = sdk.ledger.listLogs(req); @@ -744,7 +696,7 @@ public class Application { ## listTransactions -List transactions from a ledger, sorted by txid in descending order. +List transactions from a ledger, sorted by id in descending order. ### Example Usage @@ -761,25 +713,21 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("voluptates") {{ + .setSecurity(new Security("modi") {{ authorization = ""; }}) .build(); ListTransactionsRequest req = new ListTransactionsRequest("ledger001") {{ - account = "users:001"; - cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - destination = "users:001"; - endTime = OffsetDateTime.parse("2022-01-29T18:39:33.469Z"); - metadata = new java.util.HashMap() {{ - put("veritatis", "itaque"); - put("incidunt", "enim"); - put("consequatur", "est"); + requestBody = new java.util.HashMap() {{ + put("rem", "voluptates"); + put("quasi", "repudiandae"); + put("sint", "veritatis"); }}; - pageSize = 842342L; - reference = "ref:001"; - source = "users:001"; - startTime = OffsetDateTime.parse("2022-05-09T18:45:16.013Z"); + cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; + expand = "itaque"; + pageSize = 277718L; + pit = OffsetDateTime.parse("2022-12-28T14:02:06.064Z"); }}; ListTransactionsResponse res = sdk.ledger.listTransactions(req); @@ -825,7 +773,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("distinctio") {{ + .setSecurity(new Security("est") {{ authorization = ""; }}) .build(); @@ -879,7 +827,7 @@ public class Application { }}) .build(); - RevertTransactionRequest req = new RevertTransactionRequest("ledger001", 1234L); + RevertTransactionRequest req = new RevertTransactionRequest(1234L, "ledger001"); RevertTransactionResponse res = sdk.ledger.revertTransaction(req); diff --git a/sdks/java/docs/sdks/orchestration/README.md b/sdks/java/docs/sdks/orchestration/README.md index ebf719879..cb6ceeb90 100755 --- a/sdks/java/docs/sdks/orchestration/README.md +++ b/sdks/java/docs/sdks/orchestration/README.md @@ -33,12 +33,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("labore") {{ + .setSecurity(new Security("explicabo") {{ authorization = ""; }}) .build(); - CancelEventRequest req = new CancelEventRequest("modi"); + CancelEventRequest req = new CancelEventRequest("deserunt"); CancelEventResponse res = sdk.orchestration.cancelEvent(req); @@ -82,22 +82,32 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("qui") {{ + .setSecurity(new Security("distinctio") {{ authorization = ""; }}) .build(); com.formance.formance_sdk.models.shared.CreateWorkflowRequest req = new CreateWorkflowRequest( new java.util.HashMap[]{{ add(new java.util.HashMap() {{ - put("quos", "perferendis"); - put("magni", "assumenda"); - put("ipsam", "alias"); + put("modi", "qui"); + put("aliquid", "cupiditate"); }}), add(new java.util.HashMap() {{ - put("dolorum", "excepturi"); + put("perferendis", "magni"); + put("assumenda", "ipsam"); + put("alias", "fugit"); + }}), + add(new java.util.HashMap() {{ + put("excepturi", "tempora"); + put("facilis", "tempore"); + put("labore", "delectus"); + }}), + add(new java.util.HashMap() {{ + put("non", "eligendi"); + put("sint", "aliquid"); }}), }}) {{ - name = "Olivia Rice"; + name = "Terence Marquardt"; }}; CreateWorkflowResponse res = sdk.orchestration.createWorkflow(req); @@ -142,12 +152,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("eum") {{ + .setSecurity(new Security("debitis") {{ authorization = ""; }}) .build(); - DeleteWorkflowRequest req = new DeleteWorkflowRequest("non"); + DeleteWorkflowRequest req = new DeleteWorkflowRequest("a"); DeleteWorkflowResponse res = sdk.orchestration.deleteWorkflow(req); @@ -191,12 +201,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("eligendi") {{ + .setSecurity(new Security("dolorum") {{ authorization = ""; }}) .build(); - GetInstanceRequest req = new GetInstanceRequest("sint"); + GetInstanceRequest req = new GetInstanceRequest("in"); GetInstanceResponse res = sdk.orchestration.getInstance(req); @@ -240,12 +250,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("aliquid") {{ + .setSecurity(new Security("in") {{ authorization = ""; }}) .build(); - GetInstanceHistoryRequest req = new GetInstanceHistoryRequest("provident"); + GetInstanceHistoryRequest req = new GetInstanceHistoryRequest("illum"); GetInstanceHistoryResponse res = sdk.orchestration.getInstanceHistory(req); @@ -289,12 +299,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("necessitatibus") {{ + .setSecurity(new Security("maiores") {{ authorization = ""; }}) .build(); - GetInstanceStageHistoryRequest req = new GetInstanceStageHistoryRequest("sint", 638921L); + GetInstanceStageHistoryRequest req = new GetInstanceStageHistoryRequest("rerum", 116202L); GetInstanceStageHistoryResponse res = sdk.orchestration.getInstanceStageHistory(req); @@ -338,12 +348,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("dolor") {{ + .setSecurity(new Security("magnam") {{ authorization = ""; }}) .build(); - GetWorkflowRequest req = new GetWorkflowRequest("debitis"); + GetWorkflowRequest req = new GetWorkflowRequest("cumque"); GetWorkflowResponse res = sdk.orchestration.getWorkflow(req); @@ -387,14 +397,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("a") {{ + .setSecurity(new Security("facere") {{ authorization = ""; }}) .build(); ListInstancesRequest req = new ListInstancesRequest() {{ running = false; - workflowID = "dolorum"; + workflowID = "ea"; }}; ListInstancesResponse res = sdk.orchestration.listInstances(req); @@ -438,7 +448,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("in") {{ + .setSecurity(new Security("aliquid") {{ authorization = ""; }}) .build(); @@ -478,7 +488,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("in") {{ + .setSecurity(new Security("laborum") {{ authorization = ""; }}) .build(); @@ -519,16 +529,16 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("illum") {{ + .setSecurity(new Security("accusamus") {{ authorization = ""; }}) .build(); - RunWorkflowRequest req = new RunWorkflowRequest("maiores") {{ + RunWorkflowRequest req = new RunWorkflowRequest("non") {{ requestBody = new java.util.HashMap() {{ - put("dicta", "magnam"); - put("cumque", "facere"); - put("ea", "aliquid"); + put("enim", "accusamus"); + put("delectus", "quidem"); + put("provident", "nam"); }}; wait = false; }}; @@ -576,13 +586,13 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("laborum") {{ + .setSecurity(new Security("id") {{ authorization = ""; }}) .build(); - SendEventRequest req = new SendEventRequest("accusamus") {{ - requestBody = new SendEventRequestBody("non");; + SendEventRequest req = new SendEventRequest("blanditiis") {{ + requestBody = new SendEventRequestBody("deleniti");; }}; SendEventResponse res = sdk.orchestration.sendEvent(req); diff --git a/sdks/java/docs/sdks/payments/README.md b/sdks/java/docs/sdks/payments/README.md index 63b0a4468..63597dd49 100755 --- a/sdks/java/docs/sdks/payments/README.md +++ b/sdks/java/docs/sdks/payments/README.md @@ -40,7 +40,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("occaecati") {{ + .setSecurity(new Security("sapiente") {{ authorization = ""; }}) .build(); @@ -96,14 +96,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("enim") {{ + .setSecurity(new Security("amet") {{ authorization = ""; }}) .build(); ConnectorsTransferRequest req = new ConnectorsTransferRequest( new TransferRequest(100L, "USD", "acct_1Gqj58KZcSIg2N2q") {{ source = "acct_1Gqj58KZcSIg2N2q"; - }};, Connector.MONEYCORP); + }};, Connector.BANKING_CIRCLE); ConnectorsTransferResponse res = sdk.payments.connectorsTransfer(req); @@ -148,24 +148,22 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("delectus") {{ + .setSecurity(new Security("nisi") {{ authorization = ""; }}) .build(); - GetAccountBalancesRequest req = new GetAccountBalancesRequest("quidem") {{ - asset = "provident"; + GetAccountBalancesRequest req = new GetAccountBalancesRequest("vel") {{ + asset = "natus"; cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - from = OffsetDateTime.parse("2021-09-06T10:36:33.442Z"); - limit = 501324L; - pageSize = 533206L; + from = OffsetDateTime.parse("2022-01-19T08:19:15.156Z"); + limit = 19193L; + pageSize = 470132L; sort = new String[]{{ - add("amet"), - add("deserunt"), - add("nisi"), - add("vel"), + add("distinctio"), + add("id"), }}; - to = OffsetDateTime.parse("2021-10-15T07:59:26.631Z"); + to = OffsetDateTime.parse("2022-09-17T02:55:11.783Z"); }}; GetAccountBalancesResponse res = sdk.payments.getAccountBalances(req); @@ -211,12 +209,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("molestiae") {{ + .setSecurity(new Security("suscipit") {{ authorization = ""; }}) .build(); - GetConnectorTaskRequest req = new GetConnectorTaskRequest(Connector.STRIPE, "nihil"); + GetConnectorTaskRequest req = new GetConnectorTaskRequest(Connector.CURRENCY_CLOUD, "nobis"); GetConnectorTaskResponse res = sdk.payments.getConnectorTask(req); @@ -260,12 +258,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("magnam") {{ + .setSecurity(new Security("eum") {{ authorization = ""; }}) .build(); - GetPaymentRequest req = new GetPaymentRequest("distinctio"); + GetPaymentRequest req = new GetPaymentRequest("vero"); GetPaymentResponse res = sdk.payments.getPayment(req); @@ -318,13 +316,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("id") {{ + .setSecurity(new Security("aspernatur") {{ authorization = ""; }}) .build(); - InstallConnectorRequest req = new InstallConnectorRequest( new WiseConfig("XXX") {{ + InstallConnectorRequest req = new InstallConnectorRequest( new StripeConfig("XXX") {{ apiKey = "XXX"; + pageSize = 50L; pollingPeriod = "60s"; }}, Connector.WISE); @@ -369,7 +368,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("suscipit") {{ + .setSecurity(new Security("et") {{ authorization = ""; }}) .build(); @@ -409,7 +408,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("natus") {{ + .setSecurity(new Security("excepturi") {{ authorization = ""; }}) .build(); @@ -451,14 +450,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("nobis") {{ + .setSecurity(new Security("ullam") {{ authorization = ""; }}) .build(); - ListConnectorTasksRequest req = new ListConnectorTasksRequest(Connector.MODULR) {{ + ListConnectorTasksRequest req = new ListConnectorTasksRequest(Connector.CURRENCY_CLOUD) {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - pageSize = 878453L; + pageSize = 551816L; }}; ListConnectorTasksResponse res = sdk.payments.listConnectorTasks(req); @@ -504,7 +503,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("aspernatur") {{ + .setSecurity(new Security("sint") {{ authorization = ""; }}) .build(); @@ -553,18 +552,18 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("magnam") {{ + .setSecurity(new Security("mollitia") {{ authorization = ""; }}) .build(); ListPaymentsRequest req = new ListPaymentsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - pageSize = 92373L; + pageSize = 968962L; sort = new String[]{{ - add("ullam"), - add("provident"), - add("quos"), + add("ad"), + add("eum"), + add("dolor"), }}; }}; @@ -610,12 +609,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("sint") {{ + .setSecurity(new Security("necessitatibus") {{ authorization = ""; }}) .build(); - PaymentsgetAccountRequest req = new PaymentsgetAccountRequest("accusantium"); + PaymentsgetAccountRequest req = new PaymentsgetAccountRequest("odit"); PaymentsgetAccountResponse res = sdk.payments.paymentsgetAccount(req); @@ -658,7 +657,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("mollitia") {{ + .setSecurity(new Security("nemo") {{ authorization = ""; }}) .build(); @@ -699,17 +698,19 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("reiciendis") {{ + .setSecurity(new Security("quasi") {{ authorization = ""; }}) .build(); PaymentslistAccountsRequest req = new PaymentslistAccountsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - pageSize = 652103L; + pageSize = 435865L; sort = new String[]{{ - add("eum"), - add("dolor"), + add("debitis"), + add("eius"), + add("maxime"), + add("deleniti"), }}; }}; @@ -756,12 +757,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("necessitatibus") {{ + .setSecurity(new Security("facilis") {{ authorization = ""; }}) .build(); - ReadConnectorConfigRequest req = new ReadConnectorConfigRequest(Connector.DUMMY_PAY); + ReadConnectorConfigRequest req = new ReadConnectorConfigRequest(Connector.MODULR); ReadConnectorConfigResponse res = sdk.payments.readConnectorConfig(req); @@ -808,7 +809,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("nemo") {{ + .setSecurity(new Security("architecto") {{ authorization = ""; }}) .build(); @@ -858,12 +859,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("iure") {{ + .setSecurity(new Security("repudiandae") {{ authorization = ""; }}) .build(); - UninstallConnectorRequest req = new UninstallConnectorRequest(Connector.MONEYCORP); + UninstallConnectorRequest req = new UninstallConnectorRequest(Connector.WISE); UninstallConnectorResponse res = sdk.payments.uninstallConnector(req); @@ -908,14 +909,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("debitis") {{ + .setSecurity(new Security("expedita") {{ authorization = ""; }}) .build(); UpdateMetadataRequest req = new UpdateMetadataRequest( new PaymentMetadata() {{ - key = "eius"; - }};, "maxime"); + key = "nihil"; + }};, "repellat"); UpdateMetadataResponse res = sdk.payments.updateMetadata(req); diff --git a/sdks/java/docs/sdks/search/README.md b/sdks/java/docs/sdks/search/README.md index ad75f6840..0cbbc22da 100755 --- a/sdks/java/docs/sdks/search/README.md +++ b/sdks/java/docs/sdks/search/README.md @@ -24,7 +24,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("deleniti") {{ + .setSecurity(new Security("quibusdam") {{ authorization = ""; }}) .build(); @@ -32,24 +32,21 @@ public class Application { com.formance.formance_sdk.models.shared.Query req = new Query() {{ after = new String[]{{ add("users:002"), - add("users:002"), - add("users:002"), }}; cursor = "YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol="; ledgers = new String[]{{ add("quickstart"), add("quickstart"), + add("quickstart"), + add("quickstart"), }}; - pageSize = 100226L; + pageSize = 868126L; policy = "OR"; raw = new QueryRaw();; - sort = "txid:asc"; - target = "architecto"; + sort = "id:asc"; + target = "accusantium"; terms = new String[]{{ add("destination=central_bank1"), - add("destination=central_bank1"), - add("destination=central_bank1"), - add("destination=central_bank1"), }}; }}; @@ -94,7 +91,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("ullam") {{ + .setSecurity(new Security("praesentium") {{ authorization = ""; }}) .build(); diff --git a/sdks/java/docs/sdks/wallets/README.md b/sdks/java/docs/sdks/wallets/README.md index c26a88258..b8c830ba7 100755 --- a/sdks/java/docs/sdks/wallets/README.md +++ b/sdks/java/docs/sdks/wallets/README.md @@ -38,12 +38,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("expedita") {{ + .setSecurity(new Security("natus") {{ authorization = ""; }}) .build(); - ConfirmHoldRequest req = new ConfirmHoldRequest("nihil") {{ + ConfirmHoldRequest req = new ConfirmHoldRequest("magni") {{ confirmHoldRequest = new ConfirmHoldRequest() {{ amount = 100L; final_ = true; @@ -94,15 +94,15 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("repellat") {{ + .setSecurity(new Security("sunt") {{ authorization = ""; }}) .build(); - CreateBalanceRequest req = new CreateBalanceRequest("quibusdam") {{ - createBalanceRequest = new CreateBalanceRequest("sed") {{ - expiresAt = OffsetDateTime.parse("2020-05-25T09:38:49.528Z"); - priority = 37559L; + CreateBalanceRequest req = new CreateBalanceRequest("quo") {{ + createBalanceRequest = new CreateBalanceRequest("illum") {{ + expiresAt = OffsetDateTime.parse("2020-07-30T23:39:27.609Z"); + priority = 411397L; }};; }}; @@ -148,16 +148,14 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("consequuntur") {{ + .setSecurity(new Security("excepturi") {{ authorization = ""; }}) .build(); com.formance.formance_sdk.models.shared.CreateWalletRequest req = new CreateWalletRequest( new java.util.HashMap() {{ - put("natus", "magni"); - put("sunt", "quo"); - put("illum", "pariatur"); - }}, "maxime"); + put("ea", "accusantium"); + }}, "ab"); CreateWalletResponse res = sdk.wallets.createWallet(req); @@ -205,31 +203,35 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("ea") {{ + .setSecurity(new Security("maiores") {{ authorization = ""; }}) .build(); - CreditWalletRequest req = new CreditWalletRequest("excepturi") {{ - creditWalletRequest = new CreditWalletRequest( new Monetary(139972L, "ea");, new java.util.HashMap() {{ - put("ab", "maiores"); + CreditWalletRequest req = new CreditWalletRequest("quidem") {{ + creditWalletRequest = new CreditWalletRequest( new Monetary(373291L, "voluptate");, new java.util.HashMap() {{ + put("nam", "eaque"); + put("pariatur", "nemo"); }}, new Object[]{{ - add(new LedgerAccountSubject("nam", "eaque") {{ - identifier = "voluptate"; - type = "autem"; + add(new LedgerAccountSubject("aut", "cumque") {{ + identifier = "fugiat"; + type = "amet"; }}), - add(new WalletSubject("fugiat", "amet") {{ - balance = "nemo"; - identifier = "voluptatibus"; - type = "perferendis"; + add(new LedgerAccountSubject("nobis", "dolores") {{ + identifier = "hic"; + type = "libero"; + }}), + add(new LedgerAccountSubject("eaque", "quis") {{ + identifier = "totam"; + type = "dignissimos"; }}), - add(new LedgerAccountSubject("hic", "libero") {{ - identifier = "cumque"; - type = "corporis"; + add(new LedgerAccountSubject("dolores", "minus") {{ + identifier = "eos"; + type = "perferendis"; }}), }}) {{ - balance = "nobis"; - reference = "dolores"; + balance = "quam"; + reference = "dolor"; }};; }}; @@ -279,25 +281,25 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("quis") {{ + .setSecurity(new Security("vero") {{ authorization = ""; }}) .build(); - DebitWalletRequest req = new DebitWalletRequest("totam") {{ - debitWalletRequest = new DebitWalletRequest( new Monetary(489549L, "eaque");, new java.util.HashMap() {{ - put("nesciunt", "eos"); - put("perferendis", "dolores"); + DebitWalletRequest req = new DebitWalletRequest("nostrum") {{ + debitWalletRequest = new DebitWalletRequest( new Monetary(944120L, "recusandae");, new java.util.HashMap() {{ + put("facilis", "perspiciatis"); + put("voluptatem", "porro"); + put("consequuntur", "blanditiis"); }}) {{ balances = new String[]{{ - add("quam"), - add("dolor"), - add("vero"), - add("nostrum"), + add("eaque"), + add("occaecati"), + add("rerum"), }}; - description = "hic"; - destination = new WalletSubject("omnis", "facilis") {{ - balance = "perspiciatis"; + description = "adipisci"; + destination = new WalletSubject("earum", "modi") {{ + balance = "iste"; }};; pending = false; }};; @@ -345,12 +347,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("voluptatem") {{ + .setSecurity(new Security("dolorum") {{ authorization = ""; }}) .build(); - GetBalanceRequest req = new GetBalanceRequest("porro", "consequuntur"); + GetBalanceRequest req = new GetBalanceRequest("deleniti", "pariatur"); GetBalanceResponse res = sdk.wallets.getBalance(req); @@ -394,12 +396,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("blanditiis") {{ + .setSecurity(new Security("provident") {{ authorization = ""; }}) .build(); - GetHoldRequest req = new GetHoldRequest("error"); + GetHoldRequest req = new GetHoldRequest("nobis"); GetHoldResponse res = sdk.wallets.getHold(req); @@ -443,7 +445,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("eaque") {{ + .setSecurity(new Security("libero") {{ authorization = ""; }}) .build(); @@ -451,12 +453,13 @@ public class Application { GetHoldsRequest req = new GetHoldsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; metadata = new java.util.HashMap() {{ - put("rerum", "adipisci"); - put("asperiores", "earum"); - put("modi", "iste"); + put("quaerat", "quos"); + put("aliquid", "dolorem"); + put("dolorem", "dolor"); + put("qui", "ipsum"); }}; - pageSize = 679091L; - walletID = "deleniti"; + pageSize = 944373L; + walletID = "excepturi"; }}; GetHoldsResponse res = sdk.wallets.getHolds(req); @@ -499,15 +502,15 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("pariatur") {{ + .setSecurity(new Security("cum") {{ authorization = ""; }}) .build(); GetTransactionsRequest req = new GetTransactionsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; - pageSize = 589910L; - walletID = "nobis"; + pageSize = 452109L; + walletID = "dignissimos"; }}; GetTransactionsResponse res = sdk.wallets.getTransactions(req); @@ -552,12 +555,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("libero") {{ + .setSecurity(new Security("reiciendis") {{ authorization = ""; }}) .build(); - GetWalletRequest req = new GetWalletRequest("delectus"); + GetWalletRequest req = new GetWalletRequest("amet"); GetWalletResponse res = sdk.wallets.getWallet(req); @@ -601,12 +604,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("quaerat") {{ + .setSecurity(new Security("dolorum") {{ authorization = ""; }}) .build(); - GetWalletSummaryRequest req = new GetWalletSummaryRequest("quos"); + GetWalletSummaryRequest req = new GetWalletSummaryRequest("numquam"); GetWalletSummaryResponse res = sdk.wallets.getWalletSummary(req); @@ -650,12 +653,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("aliquid") {{ + .setSecurity(new Security("veritatis") {{ authorization = ""; }}) .build(); - ListBalancesRequest req = new ListBalancesRequest("dolorem"); + ListBalancesRequest req = new ListBalancesRequest("ipsa"); ListBalancesResponse res = sdk.wallets.listBalances(req); @@ -699,7 +702,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("dolorem") {{ + .setSecurity(new Security("ipsa") {{ authorization = ""; }}) .build(); @@ -707,10 +710,11 @@ public class Application { ListWalletsRequest req = new ListWalletsRequest() {{ cursor = "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=="; metadata = new java.util.HashMap() {{ - put("qui", "ipsum"); + put("odio", "quaerat"); + put("accusamus", "quidem"); }}; - name = "Marshall Ritchie"; - pageSize = 970237L; + name = "Hector Mosciski"; + pageSize = 24678L; }}; ListWalletsResponse res = sdk.wallets.listWallets(req); @@ -756,15 +760,16 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("amet") {{ + .setSecurity(new Security("fugiat") {{ authorization = ""; }}) .build(); - UpdateWalletRequest req = new UpdateWalletRequest("dolorum") {{ + UpdateWalletRequest req = new UpdateWalletRequest("ab") {{ requestBody = new UpdateWalletRequestBody( new java.util.HashMap() {{ - put("veritatis", "ipsa"); - put("ipsa", "iure"); + put("dolorum", "iusto"); + put("voluptate", "dolorum"); + put("deleniti", "omnis"); }});; }}; @@ -810,12 +815,12 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("odio") {{ + .setSecurity(new Security("necessitatibus") {{ authorization = ""; }}) .build(); - VoidHoldRequest req = new VoidHoldRequest("quaerat"); + VoidHoldRequest req = new VoidHoldRequest("distinctio"); VoidHoldResponse res = sdk.wallets.voidHold(req); @@ -858,7 +863,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("accusamus") {{ + .setSecurity(new Security("asperiores") {{ authorization = ""; }}) .build(); diff --git a/sdks/java/docs/sdks/webhooks/README.md b/sdks/java/docs/sdks/webhooks/README.md index 15aef678c..b76a0d5dc 100755 --- a/sdks/java/docs/sdks/webhooks/README.md +++ b/sdks/java/docs/sdks/webhooks/README.md @@ -28,7 +28,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("quidem") {{ + .setSecurity(new Security("nihil") {{ authorization = ""; }}) .build(); @@ -82,7 +82,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("voluptatibus") {{ + .setSecurity(new Security("ipsum") {{ authorization = ""; }}) .build(); @@ -133,7 +133,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("voluptas") {{ + .setSecurity(new Security("voluptate") {{ authorization = ""; }}) .build(); @@ -182,7 +182,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("natus") {{ + .setSecurity(new Security("id") {{ authorization = ""; }}) .build(); @@ -231,7 +231,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("eos") {{ + .setSecurity(new Security("saepe") {{ authorization = ""; }}) .build(); @@ -292,7 +292,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("atque") {{ + .setSecurity(new Security("eius") {{ authorization = ""; }}) .build(); @@ -345,7 +345,7 @@ public class Application { public static void main(String[] args) { try { SDK sdk = SDK.builder() - .setSecurity(new Security("fugiat") {{ + .setSecurity(new Security("perferendis") {{ authorization = ""; }}) .build(); diff --git a/sdks/java/files.gen b/sdks/java/files.gen index d1d719e32..6df524f29 100755 --- a/sdks/java/files.gen +++ b/sdks/java/files.gen @@ -72,7 +72,6 @@ lib/src/main/java/com/formance/formance_sdk/models/operations/AddMetadataOnTrans lib/src/main/java/com/formance/formance_sdk/models/operations/AddMetadataOnTransactionResponse.java lib/src/main/java/com/formance/formance_sdk/models/operations/AddMetadataToAccountRequest.java lib/src/main/java/com/formance/formance_sdk/models/operations/AddMetadataToAccountResponse.java -lib/src/main/java/com/formance/formance_sdk/models/operations/CountAccountsMetadata.java lib/src/main/java/com/formance/formance_sdk/models/operations/CountAccountsRequest.java lib/src/main/java/com/formance/formance_sdk/models/operations/CountAccountsResponse.java lib/src/main/java/com/formance/formance_sdk/models/operations/CountTransactionsRequest.java @@ -81,8 +80,6 @@ lib/src/main/java/com/formance/formance_sdk/models/operations/CreateTransactionR lib/src/main/java/com/formance/formance_sdk/models/operations/CreateTransactionResponse.java lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountRequest.java lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountResponse.java -lib/src/main/java/com/formance/formance_sdk/models/operations/GetBalancesRequest.java -lib/src/main/java/com/formance/formance_sdk/models/operations/GetBalancesResponse.java lib/src/main/java/com/formance/formance_sdk/models/operations/GetBalancesAggregatedRequest.java lib/src/main/java/com/formance/formance_sdk/models/operations/GetBalancesAggregatedResponse.java lib/src/main/java/com/formance/formance_sdk/models/operations/GetInfoResponse.java @@ -232,8 +229,6 @@ lib/src/main/java/com/formance/formance_sdk/models/shared/PostTransactionScript. lib/src/main/java/com/formance/formance_sdk/models/shared/PostTransaction.java lib/src/main/java/com/formance/formance_sdk/models/shared/AccountResponse.java lib/src/main/java/com/formance/formance_sdk/models/shared/AccountWithVolumesAndBalances.java -lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursorResponseCursor.java -lib/src/main/java/com/formance/formance_sdk/models/shared/BalancesCursorResponse.java lib/src/main/java/com/formance/formance_sdk/models/shared/AggregateBalancesResponse.java lib/src/main/java/com/formance/formance_sdk/models/shared/ConfigInfoResponse.java lib/src/main/java/com/formance/formance_sdk/models/shared/ConfigInfo.java @@ -471,7 +466,6 @@ docs/models/operations/AddMetadataOnTransactionRequest.md docs/models/operations/AddMetadataOnTransactionResponse.md docs/models/operations/AddMetadataToAccountRequest.md docs/models/operations/AddMetadataToAccountResponse.md -docs/models/operations/CountAccountsMetadata.md docs/models/operations/CountAccountsRequest.md docs/models/operations/CountAccountsResponse.md docs/models/operations/CountTransactionsRequest.md @@ -480,8 +474,6 @@ docs/models/operations/CreateTransactionRequest.md docs/models/operations/CreateTransactionResponse.md docs/models/operations/GetAccountRequest.md docs/models/operations/GetAccountResponse.md -docs/models/operations/GetBalancesRequest.md -docs/models/operations/GetBalancesResponse.md docs/models/operations/GetBalancesAggregatedRequest.md docs/models/operations/GetBalancesAggregatedResponse.md docs/models/operations/GetInfoResponse.md @@ -631,8 +623,6 @@ docs/models/shared/PostTransactionScript.md docs/models/shared/PostTransaction.md docs/models/shared/AccountResponse.md docs/models/shared/AccountWithVolumesAndBalances.md -docs/models/shared/BalancesCursorResponseCursor.md -docs/models/shared/BalancesCursorResponse.md docs/models/shared/AggregateBalancesResponse.md docs/models/shared/ConfigInfoResponse.md docs/models/shared/ConfigInfo.md diff --git a/sdks/java/gen.yaml b/sdks/java/gen.yaml index ed8fa62a7..e797cab75 100755 --- a/sdks/java/gen.yaml +++ b/sdks/java/gen.yaml @@ -7,6 +7,7 @@ features: java: core: 2.85.2 deprecations: 2.81.1 + getRequestBodies: 2.81.1 globalSecurity: 2.81.1 globalServerURLs: 2.82.0 java: diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/Ledger.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/Ledger.java index eca670852..4b975d504 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/Ledger.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/Ledger.java @@ -31,7 +31,7 @@ public Ledger(SDKConfiguration sdkConfiguration) { */ public com.formance.formance_sdk.models.operations.AddMetadataOnTransactionResponse addMetadataOnTransaction(com.formance.formance_sdk.models.operations.AddMetadataOnTransactionRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.AddMetadataOnTransactionRequest.class, baseUrl, "/api/ledger/{ledger}/transactions/{txid}/metadata", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.AddMetadataOnTransactionRequest.class, baseUrl, "/api/ledger/v2/{ledger}/transactions/{id}/metadata", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("POST"); @@ -88,7 +88,7 @@ public com.formance.formance_sdk.models.operations.AddMetadataOnTransactionRespo */ public com.formance.formance_sdk.models.operations.AddMetadataToAccountResponse addMetadataToAccount(com.formance.formance_sdk.models.operations.AddMetadataToAccountRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.AddMetadataToAccountRequest.class, baseUrl, "/api/ledger/{ledger}/accounts/{address}/metadata", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.AddMetadataToAccountRequest.class, baseUrl, "/api/ledger/v2/{ledger}/accounts/{address}/metadata", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("POST"); @@ -148,20 +148,16 @@ public com.formance.formance_sdk.models.operations.AddMetadataToAccountResponse */ public com.formance.formance_sdk.models.operations.CountAccountsResponse countAccounts(com.formance.formance_sdk.models.operations.CountAccountsRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.CountAccountsRequest.class, baseUrl, "/api/ledger/{ledger}/accounts", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.CountAccountsRequest.class, baseUrl, "/api/ledger/v2/{ledger}/accounts", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("HEAD"); req.setURL(url); + SerializedBody serializedRequestBody = com.formance.formance_sdk.utils.Utils.serializeRequestBody(request, "requestBody", "json"); + req.setBody(serializedRequestBody); req.addHeader("Accept", "application/json"); req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s %s", this.sdkConfiguration.language, this.sdkConfiguration.sdkVersion, this.sdkConfiguration.genVersion, this.sdkConfiguration.openapiDocVersion)); - java.util.List queryParams = com.formance.formance_sdk.utils.Utils.getQueryParams(com.formance.formance_sdk.models.operations.CountAccountsRequest.class, request, null); - if (queryParams != null) { - for (NameValuePair queryParam : queryParams) { - req.addQueryParam(queryParam); - } - } HTTPClient client = this.sdkConfiguration.securityClient; @@ -197,11 +193,13 @@ public com.formance.formance_sdk.models.operations.CountAccountsResponse countAc */ public com.formance.formance_sdk.models.operations.CountTransactionsResponse countTransactions(com.formance.formance_sdk.models.operations.CountTransactionsRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.CountTransactionsRequest.class, baseUrl, "/api/ledger/{ledger}/transactions", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.CountTransactionsRequest.class, baseUrl, "/api/ledger/v2/{ledger}/transactions", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("HEAD"); req.setURL(url); + SerializedBody serializedRequestBody = com.formance.formance_sdk.utils.Utils.serializeRequestBody(request, "requestBody", "json"); + req.setBody(serializedRequestBody); req.addHeader("Accept", "application/json"); req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s %s", this.sdkConfiguration.language, this.sdkConfiguration.sdkVersion, this.sdkConfiguration.genVersion, this.sdkConfiguration.openapiDocVersion)); @@ -246,7 +244,7 @@ public com.formance.formance_sdk.models.operations.CountTransactionsResponse cou */ public com.formance.formance_sdk.models.operations.CreateTransactionResponse createTransaction(com.formance.formance_sdk.models.operations.CreateTransactionRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.CreateTransactionRequest.class, baseUrl, "/api/ledger/{ledger}/transactions", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.CreateTransactionRequest.class, baseUrl, "/api/ledger/v2/{ledger}/transactions", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("POST"); @@ -312,7 +310,7 @@ public com.formance.formance_sdk.models.operations.CreateTransactionResponse cre */ public com.formance.formance_sdk.models.operations.GetAccountResponse getAccount(com.formance.formance_sdk.models.operations.GetAccountRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetAccountRequest.class, baseUrl, "/api/ledger/{ledger}/accounts/{address}", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetAccountRequest.class, baseUrl, "/api/ledger/v2/{ledger}/accounts/{address}", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("GET"); @@ -320,54 +318,7 @@ public com.formance.formance_sdk.models.operations.GetAccountResponse getAccount req.addHeader("Accept", "application/json"); req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s %s", this.sdkConfiguration.language, this.sdkConfiguration.sdkVersion, this.sdkConfiguration.genVersion, this.sdkConfiguration.openapiDocVersion)); - - HTTPClient client = this.sdkConfiguration.securityClient; - - HttpResponse httpRes = client.send(req); - - String contentType = httpRes.headers().firstValue("Content-Type").orElse("application/octet-stream"); - - com.formance.formance_sdk.models.operations.GetAccountResponse res = new com.formance.formance_sdk.models.operations.GetAccountResponse(contentType, httpRes.statusCode()) {{ - accountResponse = null; - errorResponse = null; - }}; - res.rawResponse = httpRes; - - if (httpRes.statusCode() == 200) { - if (com.formance.formance_sdk.utils.Utils.matchContentType(contentType, "application/json")) { - ObjectMapper mapper = JSON.getMapper(); - com.formance.formance_sdk.models.shared.AccountResponse out = mapper.readValue(new String(httpRes.body(), StandardCharsets.UTF_8), com.formance.formance_sdk.models.shared.AccountResponse.class); - res.accountResponse = out; - } - } - else { - if (com.formance.formance_sdk.utils.Utils.matchContentType(contentType, "application/json")) { - ObjectMapper mapper = JSON.getMapper(); - com.formance.formance_sdk.models.shared.ErrorResponse out = mapper.readValue(new String(httpRes.body(), StandardCharsets.UTF_8), com.formance.formance_sdk.models.shared.ErrorResponse.class); - res.errorResponse = out; - } - } - - return res; - } - - /** - * Get the balances from a ledger's account - * @param request the request object containing all of the parameters for the API call - * @return the response from the API call - * @throws Exception if the API call fails - */ - public com.formance.formance_sdk.models.operations.GetBalancesResponse getBalances(com.formance.formance_sdk.models.operations.GetBalancesRequest request) throws Exception { - String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetBalancesRequest.class, baseUrl, "/api/ledger/{ledger}/balances", request, null); - - HTTPRequest req = new HTTPRequest(); - req.setMethod("GET"); - req.setURL(url); - - req.addHeader("Accept", "application/json"); - req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s %s", this.sdkConfiguration.language, this.sdkConfiguration.sdkVersion, this.sdkConfiguration.genVersion, this.sdkConfiguration.openapiDocVersion)); - java.util.List queryParams = com.formance.formance_sdk.utils.Utils.getQueryParams(com.formance.formance_sdk.models.operations.GetBalancesRequest.class, request, null); + java.util.List queryParams = com.formance.formance_sdk.utils.Utils.getQueryParams(com.formance.formance_sdk.models.operations.GetAccountRequest.class, request, null); if (queryParams != null) { for (NameValuePair queryParam : queryParams) { req.addQueryParam(queryParam); @@ -380,8 +331,8 @@ public com.formance.formance_sdk.models.operations.GetBalancesResponse getBalanc String contentType = httpRes.headers().firstValue("Content-Type").orElse("application/octet-stream"); - com.formance.formance_sdk.models.operations.GetBalancesResponse res = new com.formance.formance_sdk.models.operations.GetBalancesResponse(contentType, httpRes.statusCode()) {{ - balancesCursorResponse = null; + com.formance.formance_sdk.models.operations.GetAccountResponse res = new com.formance.formance_sdk.models.operations.GetAccountResponse(contentType, httpRes.statusCode()) {{ + accountResponse = null; errorResponse = null; }}; res.rawResponse = httpRes; @@ -389,8 +340,8 @@ public com.formance.formance_sdk.models.operations.GetBalancesResponse getBalanc if (httpRes.statusCode() == 200) { if (com.formance.formance_sdk.utils.Utils.matchContentType(contentType, "application/json")) { ObjectMapper mapper = JSON.getMapper(); - com.formance.formance_sdk.models.shared.BalancesCursorResponse out = mapper.readValue(new String(httpRes.body(), StandardCharsets.UTF_8), com.formance.formance_sdk.models.shared.BalancesCursorResponse.class); - res.balancesCursorResponse = out; + com.formance.formance_sdk.models.shared.AccountResponse out = mapper.readValue(new String(httpRes.body(), StandardCharsets.UTF_8), com.formance.formance_sdk.models.shared.AccountResponse.class); + res.accountResponse = out; } } else { @@ -412,7 +363,7 @@ public com.formance.formance_sdk.models.operations.GetBalancesResponse getBalanc */ public com.formance.formance_sdk.models.operations.GetBalancesAggregatedResponse getBalancesAggregated(com.formance.formance_sdk.models.operations.GetBalancesAggregatedRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetBalancesAggregatedRequest.class, baseUrl, "/api/ledger/{ledger}/aggregate/balances", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetBalancesAggregatedRequest.class, baseUrl, "/api/ledger/v2/{ledger}/aggregate/balances", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("GET"); @@ -420,12 +371,6 @@ public com.formance.formance_sdk.models.operations.GetBalancesAggregatedResponse req.addHeader("Accept", "application/json"); req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s %s", this.sdkConfiguration.language, this.sdkConfiguration.sdkVersion, this.sdkConfiguration.genVersion, this.sdkConfiguration.openapiDocVersion)); - java.util.List queryParams = com.formance.formance_sdk.utils.Utils.getQueryParams(com.formance.formance_sdk.models.operations.GetBalancesAggregatedRequest.class, request, null); - if (queryParams != null) { - for (NameValuePair queryParam : queryParams) { - req.addQueryParam(queryParam); - } - } HTTPClient client = this.sdkConfiguration.securityClient; @@ -464,7 +409,7 @@ public com.formance.formance_sdk.models.operations.GetBalancesAggregatedResponse */ public com.formance.formance_sdk.models.operations.GetInfoResponse getInfo() throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(baseUrl, "/api/ledger/_info"); + String url = com.formance.formance_sdk.utils.Utils.generateURL(baseUrl, "/api/ledger/v2/_info"); HTTPRequest req = new HTTPRequest(); req.setMethod("GET"); @@ -511,7 +456,7 @@ public com.formance.formance_sdk.models.operations.GetInfoResponse getInfo() thr */ public com.formance.formance_sdk.models.operations.GetLedgerInfoResponse getLedgerInfo(com.formance.formance_sdk.models.operations.GetLedgerInfoRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetLedgerInfoRequest.class, baseUrl, "/api/ledger/{ledger}/_info", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetLedgerInfoRequest.class, baseUrl, "/api/ledger/v2/{ledger}/_info", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("GET"); @@ -558,7 +503,7 @@ public com.formance.formance_sdk.models.operations.GetLedgerInfoResponse getLedg */ public com.formance.formance_sdk.models.operations.GetTransactionResponse getTransaction(com.formance.formance_sdk.models.operations.GetTransactionRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetTransactionRequest.class, baseUrl, "/api/ledger/{ledger}/transactions/{txid}", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.GetTransactionRequest.class, baseUrl, "/api/ledger/v2/{ledger}/transactions/{id}", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("GET"); @@ -566,6 +511,12 @@ public com.formance.formance_sdk.models.operations.GetTransactionResponse getTra req.addHeader("Accept", "application/json"); req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s %s", this.sdkConfiguration.language, this.sdkConfiguration.sdkVersion, this.sdkConfiguration.genVersion, this.sdkConfiguration.openapiDocVersion)); + java.util.List queryParams = com.formance.formance_sdk.utils.Utils.getQueryParams(com.formance.formance_sdk.models.operations.GetTransactionRequest.class, request, null); + if (queryParams != null) { + for (NameValuePair queryParam : queryParams) { + req.addQueryParam(queryParam); + } + } HTTPClient client = this.sdkConfiguration.securityClient; @@ -606,11 +557,13 @@ public com.formance.formance_sdk.models.operations.GetTransactionResponse getTra */ public com.formance.formance_sdk.models.operations.ListAccountsResponse listAccounts(com.formance.formance_sdk.models.operations.ListAccountsRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.ListAccountsRequest.class, baseUrl, "/api/ledger/{ledger}/accounts", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.ListAccountsRequest.class, baseUrl, "/api/ledger/v2/{ledger}/accounts", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("GET"); req.setURL(url); + SerializedBody serializedRequestBody = com.formance.formance_sdk.utils.Utils.serializeRequestBody(request, "requestBody", "json"); + req.setBody(serializedRequestBody); req.addHeader("Accept", "application/json"); req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s %s", this.sdkConfiguration.language, this.sdkConfiguration.sdkVersion, this.sdkConfiguration.genVersion, this.sdkConfiguration.openapiDocVersion)); @@ -660,11 +613,13 @@ public com.formance.formance_sdk.models.operations.ListAccountsResponse listAcco */ public com.formance.formance_sdk.models.operations.ListLogsResponse listLogs(com.formance.formance_sdk.models.operations.ListLogsRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.ListLogsRequest.class, baseUrl, "/api/ledger/{ledger}/logs", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.ListLogsRequest.class, baseUrl, "/api/ledger/v2/{ledger}/logs", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("GET"); req.setURL(url); + SerializedBody serializedRequestBody = com.formance.formance_sdk.utils.Utils.serializeRequestBody(request, "requestBody", "json"); + req.setBody(serializedRequestBody); req.addHeader("Accept", "application/json"); req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s %s", this.sdkConfiguration.language, this.sdkConfiguration.sdkVersion, this.sdkConfiguration.genVersion, this.sdkConfiguration.openapiDocVersion)); @@ -707,18 +662,20 @@ public com.formance.formance_sdk.models.operations.ListLogsResponse listLogs(com /** * List transactions from a ledger - * List transactions from a ledger, sorted by txid in descending order. + * List transactions from a ledger, sorted by id in descending order. * @param request the request object containing all of the parameters for the API call * @return the response from the API call * @throws Exception if the API call fails */ public com.formance.formance_sdk.models.operations.ListTransactionsResponse listTransactions(com.formance.formance_sdk.models.operations.ListTransactionsRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.ListTransactionsRequest.class, baseUrl, "/api/ledger/{ledger}/transactions", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.ListTransactionsRequest.class, baseUrl, "/api/ledger/v2/{ledger}/transactions", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("GET"); req.setURL(url); + SerializedBody serializedRequestBody = com.formance.formance_sdk.utils.Utils.serializeRequestBody(request, "requestBody", "json"); + req.setBody(serializedRequestBody); req.addHeader("Accept", "application/json"); req.addHeader("user-agent", String.format("speakeasy-sdk/%s %s %s %s", this.sdkConfiguration.language, this.sdkConfiguration.sdkVersion, this.sdkConfiguration.genVersion, this.sdkConfiguration.openapiDocVersion)); @@ -769,7 +726,7 @@ public com.formance.formance_sdk.models.operations.ListTransactionsResponse list */ public com.formance.formance_sdk.models.operations.ReadStatsResponse readStats(com.formance.formance_sdk.models.operations.ReadStatsRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.ReadStatsRequest.class, baseUrl, "/api/ledger/{ledger}/stats", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.ReadStatsRequest.class, baseUrl, "/api/ledger/v2/{ledger}/stats", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("GET"); @@ -816,7 +773,7 @@ public com.formance.formance_sdk.models.operations.ReadStatsResponse readStats(c */ public com.formance.formance_sdk.models.operations.RevertTransactionResponse revertTransaction(com.formance.formance_sdk.models.operations.RevertTransactionRequest request) throws Exception { String baseUrl = com.formance.formance_sdk.utils.Utils.templateUrl(this.sdkConfiguration.serverUrl, this.sdkConfiguration.getServerVariableDefaults()); - String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.RevertTransactionRequest.class, baseUrl, "/api/ledger/{ledger}/transactions/{txid}/revert", request, null); + String url = com.formance.formance_sdk.utils.Utils.generateURL(com.formance.formance_sdk.models.operations.RevertTransactionRequest.class, baseUrl, "/api/ledger/v2/{ledger}/transactions/{id}/revert", request, null); HTTPRequest req = new HTTPRequest(); req.setMethod("POST"); diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/SDKConfiguration.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/SDKConfiguration.java index bd9e9771d..af74d1ee2 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/SDKConfiguration.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/SDKConfiguration.java @@ -24,7 +24,7 @@ class SDKConfiguration { }}); }}; public String language = "java"; - public String openapiDocVersion = "v1.0.20230907"; + public String openapiDocVersion = "v1.0.20230908"; public String sdkVersion = "v0.1.0"; public String genVersion = "2.96.3"; diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/AddMetadataOnTransactionRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/AddMetadataOnTransactionRequest.java index 55e62c099..0b69bc155 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/AddMetadataOnTransactionRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/AddMetadataOnTransactionRequest.java @@ -31,17 +31,6 @@ public AddMetadataOnTransactionRequest withRequestBody(java.util.Map requestBody; - public CountAccountsRequest withAddress(String address) { - this.address = address; + public CountAccountsRequest withRequestBody(java.util.Map requestBody) { + this.requestBody = requestBody; return this; } @@ -31,17 +28,6 @@ public CountAccountsRequest withLedger(String ledger) { return this; } - /** - * Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - */ - @SpeakeasyMetadata("queryParam:style=deepObject,explode=true,name=metadata") - public CountAccountsMetadata metadata; - - public CountAccountsRequest withMetadata(CountAccountsMetadata metadata) { - this.metadata = metadata; - return this; - } - public CountAccountsRequest(@JsonProperty("ledger") String ledger) { this.ledger = ledger; } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CountTransactionsRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CountTransactionsRequest.java index 73d902631..2bdb9cffd 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CountTransactionsRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CountTransactionsRequest.java @@ -10,38 +10,11 @@ public class CountTransactionsRequest { - /** - * Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=account") - public String account; + @SpeakeasyMetadata("request:mediaType=application/json") + public java.util.Map requestBody; - public CountTransactionsRequest withAccount(String account) { - this.account = account; - return this; - } - - /** - * Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=destination") - public String destination; - - public CountTransactionsRequest withDestination(String destination) { - this.destination = destination; - return this; - } - - /** - * Filter transactions that occurred before this timestamp. - * The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - * - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=endTime") - public OffsetDateTime endTime; - - public CountTransactionsRequest withEndTime(OffsetDateTime endTime) { - this.endTime = endTime; + public CountTransactionsRequest withRequestBody(java.util.Map requestBody) { + this.requestBody = requestBody; return this; } @@ -56,49 +29,11 @@ public CountTransactionsRequest withLedger(String ledger) { return this; } - /** - * Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - */ - @SpeakeasyMetadata("queryParam:style=deepObject,explode=true,name=metadata") - public java.util.Map metadata; - - public CountTransactionsRequest withMetadata(java.util.Map metadata) { - this.metadata = metadata; - return this; - } - - /** - * Filter transactions by reference field. - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=reference") - public String reference; - - public CountTransactionsRequest withReference(String reference) { - this.reference = reference; - return this; - } - - /** - * Filter transactions with postings involving given account at source (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=source") - public String source; - - public CountTransactionsRequest withSource(String source) { - this.source = source; - return this; - } - - /** - * Filter transactions that occurred after this timestamp. - * The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - * - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=startTime") - public OffsetDateTime startTime; + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=pit") + public OffsetDateTime pit; - public CountTransactionsRequest withStartTime(OffsetDateTime startTime) { - this.startTime = startTime; + public CountTransactionsRequest withPit(OffsetDateTime pit) { + this.pit = pit; return this; } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CountTransactionsRequestBody.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CountTransactionsRequestBody.java deleted file mode 100755 index daa7bf5e4..000000000 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CountTransactionsRequestBody.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - */ - -package com.formance.formance_sdk.models.operations; - - - - -public class CountTransactionsRequestBody { - public CountTransactionsRequestBody(){} -} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CreateTransactionRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CreateTransactionRequest.java index 71377f12f..504555cc1 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CreateTransactionRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/CreateTransactionRequest.java @@ -34,17 +34,6 @@ public CreateTransactionRequest withPostTransaction(com.formance.formance_sdk.mo return this; } - /** - * Set async mode. - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=async") - public Boolean async; - - public CreateTransactionRequest withAsync(Boolean async) { - this.async = async; - return this; - } - /** * Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker. */ diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountRequest.java index 45caf330e..bbaf092ef 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetAccountRequest.java @@ -24,6 +24,14 @@ public GetAccountRequest withAddress(String address) { return this; } + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=expand") + public String expand; + + public GetAccountRequest withExpand(String expand) { + this.expand = expand; + return this; + } + /** * Name of the ledger. */ diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetBalancesAggregatedRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetBalancesAggregatedRequest.java index 422070f88..26f949320 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetBalancesAggregatedRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetBalancesAggregatedRequest.java @@ -9,17 +9,6 @@ public class GetBalancesAggregatedRequest { - /** - * Filter balances involving given account, either as source or destination. - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=address") - public String address; - - public GetBalancesAggregatedRequest withAddress(String address) { - this.address = address; - return this; - } - /** * Name of the ledger. */ diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetTransactionRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetTransactionRequest.java index 93c1d3ee7..07dbbb349 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetTransactionRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/GetTransactionRequest.java @@ -9,30 +9,38 @@ public class GetTransactionRequest { + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=expand") + public String expand; + + public GetTransactionRequest withExpand(String expand) { + this.expand = expand; + return this; + } + /** - * Name of the ledger. + * Transaction ID. */ - @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=ledger") - public String ledger; + @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=id") + public Long id; - public GetTransactionRequest withLedger(String ledger) { - this.ledger = ledger; + public GetTransactionRequest withId(Long id) { + this.id = id; return this; } /** - * Transaction ID. + * Name of the ledger. */ - @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=txid") - public Long txid; + @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=ledger") + public String ledger; - public GetTransactionRequest withTxid(Long txid) { - this.txid = txid; + public GetTransactionRequest withLedger(String ledger) { + this.ledger = ledger; return this; } - public GetTransactionRequest(@JsonProperty("ledger") String ledger, @JsonProperty("txid") Long txid) { + public GetTransactionRequest(@JsonProperty("id") Long id, @JsonProperty("ledger") String ledger) { + this.id = id; this.ledger = ledger; - this.txid = txid; } } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListAccountsRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListAccountsRequest.java index 6691e89b0..5b6701bd9 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListAccountsRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListAccountsRequest.java @@ -6,17 +6,15 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.formance.formance_sdk.utils.SpeakeasyMetadata; +import java.time.OffsetDateTime; public class ListAccountsRequest { - /** - * Filter accounts by address pattern (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=address") - public String address; + @SpeakeasyMetadata("request:mediaType=application/json") + public java.util.Map requestBody; - public ListAccountsRequest withAddress(String address) { - this.address = address; + public ListAccountsRequest withRequestBody(java.util.Map requestBody) { + this.requestBody = requestBody; return this; } @@ -35,6 +33,14 @@ public ListAccountsRequest withCursor(String cursor) { return this; } + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=expand") + public String expand; + + public ListAccountsRequest withExpand(String expand) { + this.expand = expand; + return this; + } + /** * Name of the ledger. */ @@ -46,17 +52,6 @@ public ListAccountsRequest withLedger(String ledger) { return this; } - /** - * Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - */ - @SpeakeasyMetadata("queryParam:style=deepObject,explode=true,name=metadata") - public java.util.Map metadata; - - public ListAccountsRequest withMetadata(java.util.Map metadata) { - this.metadata = metadata; - return this; - } - /** * The maximum number of results to return per page. * @@ -69,6 +64,14 @@ public ListAccountsRequest withPageSize(Long pageSize) { return this; } + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=pit") + public OffsetDateTime pit; + + public ListAccountsRequest withPit(OffsetDateTime pit) { + this.pit = pit; + return this; + } + public ListAccountsRequest(@JsonProperty("ledger") String ledger) { this.ledger = ledger; } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListAccountsRequestBody.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListAccountsRequestBody.java deleted file mode 100755 index 247d38f4a..000000000 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListAccountsRequestBody.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - */ - -package com.formance.formance_sdk.models.operations; - - - - -public class ListAccountsRequestBody { - public ListAccountsRequestBody(){} -} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListLogsRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListLogsRequest.java index 0f87d6215..1512e77df 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListLogsRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListLogsRequest.java @@ -10,6 +10,14 @@ public class ListLogsRequest { + @SpeakeasyMetadata("request:mediaType=application/json") + public java.util.Map requestBody; + + public ListLogsRequest withRequestBody(java.util.Map requestBody) { + this.requestBody = requestBody; + return this; + } + /** * Parameter used in pagination requests. Maximum page size is set to 15. * Set to the value of next for the next page of results. @@ -25,19 +33,6 @@ public ListLogsRequest withCursor(String cursor) { return this; } - /** - * Filter transactions that occurred before this timestamp. - * The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - * - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=endTime") - public OffsetDateTime endTime; - - public ListLogsRequest withEndTime(OffsetDateTime endTime) { - this.endTime = endTime; - return this; - } - /** * Name of the ledger. */ @@ -61,16 +56,11 @@ public ListLogsRequest withPageSize(Long pageSize) { return this; } - /** - * Filter transactions that occurred after this timestamp. - * The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - * - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=startTime") - public OffsetDateTime startTime; + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=pit") + public OffsetDateTime pit; - public ListLogsRequest withStartTime(OffsetDateTime startTime) { - this.startTime = startTime; + public ListLogsRequest withPit(OffsetDateTime pit) { + this.pit = pit; return this; } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListLogsRequestBody.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListLogsRequestBody.java deleted file mode 100755 index bc3525e48..000000000 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListLogsRequestBody.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - */ - -package com.formance.formance_sdk.models.operations; - - - - -public class ListLogsRequestBody { - public ListLogsRequestBody(){} -} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListTransactionsRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListTransactionsRequest.java index f571b609f..71729f1c1 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListTransactionsRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListTransactionsRequest.java @@ -10,14 +10,11 @@ public class ListTransactionsRequest { - /** - * Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=account") - public String account; + @SpeakeasyMetadata("request:mediaType=application/json") + public java.util.Map requestBody; - public ListTransactionsRequest withAccount(String account) { - this.account = account; + public ListTransactionsRequest withRequestBody(java.util.Map requestBody) { + this.requestBody = requestBody; return this; } @@ -36,27 +33,11 @@ public ListTransactionsRequest withCursor(String cursor) { return this; } - /** - * Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=destination") - public String destination; - - public ListTransactionsRequest withDestination(String destination) { - this.destination = destination; - return this; - } - - /** - * Filter transactions that occurred before this timestamp. - * The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - * - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=endTime") - public OffsetDateTime endTime; + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=expand") + public String expand; - public ListTransactionsRequest withEndTime(OffsetDateTime endTime) { - this.endTime = endTime; + public ListTransactionsRequest withExpand(String expand) { + this.expand = expand; return this; } @@ -71,17 +52,6 @@ public ListTransactionsRequest withLedger(String ledger) { return this; } - /** - * Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below. - */ - @SpeakeasyMetadata("queryParam:style=deepObject,explode=true,name=metadata") - public java.util.Map metadata; - - public ListTransactionsRequest withMetadata(java.util.Map metadata) { - this.metadata = metadata; - return this; - } - /** * The maximum number of results to return per page. * @@ -94,38 +64,11 @@ public ListTransactionsRequest withPageSize(Long pageSize) { return this; } - /** - * Find transactions by reference field. - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=reference") - public String reference; - - public ListTransactionsRequest withReference(String reference) { - this.reference = reference; - return this; - } - - /** - * Filter transactions with postings involving given account at source (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=source") - public String source; - - public ListTransactionsRequest withSource(String source) { - this.source = source; - return this; - } - - /** - * Filter transactions that occurred after this timestamp. - * The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - * - */ - @SpeakeasyMetadata("queryParam:style=form,explode=true,name=startTime") - public OffsetDateTime startTime; + @SpeakeasyMetadata("queryParam:style=form,explode=true,name=pit") + public OffsetDateTime pit; - public ListTransactionsRequest withStartTime(OffsetDateTime startTime) { - this.startTime = startTime; + public ListTransactionsRequest withPit(OffsetDateTime pit) { + this.pit = pit; return this; } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListTransactionsRequestBody.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListTransactionsRequestBody.java deleted file mode 100755 index be210bb18..000000000 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/ListTransactionsRequestBody.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - */ - -package com.formance.formance_sdk.models.operations; - - - - -public class ListTransactionsRequestBody { - public ListTransactionsRequestBody(){} -} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/RevertTransactionRequest.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/RevertTransactionRequest.java index 4e54641bb..d042f8352 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/RevertTransactionRequest.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/operations/RevertTransactionRequest.java @@ -10,29 +10,29 @@ public class RevertTransactionRequest { /** - * Name of the ledger. + * Transaction ID. */ - @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=ledger") - public String ledger; + @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=id") + public Long id; - public RevertTransactionRequest withLedger(String ledger) { - this.ledger = ledger; + public RevertTransactionRequest withId(Long id) { + this.id = id; return this; } /** - * Transaction ID. + * Name of the ledger. */ - @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=txid") - public Long txid; + @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=ledger") + public String ledger; - public RevertTransactionRequest withTxid(Long txid) { - this.txid = txid; + public RevertTransactionRequest withLedger(String ledger) { + this.ledger = ledger; return this; } - public RevertTransactionRequest(@JsonProperty("ledger") String ledger, @JsonProperty("txid") Long txid) { + public RevertTransactionRequest(@JsonProperty("id") Long id, @JsonProperty("ledger") String ledger) { + this.id = id; this.ledger = ledger; - this.txid = txid; } } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/AccountWithVolumesAndBalances.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/AccountWithVolumesAndBalances.java index b2c5abfac..9e3dd2267 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/AccountWithVolumesAndBalances.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/AccountWithVolumesAndBalances.java @@ -18,14 +18,6 @@ public AccountWithVolumesAndBalances withAddress(String address) { return this; } - @JsonProperty("balances") - public java.util.Map balances; - - public AccountWithVolumesAndBalances withBalances(java.util.Map balances) { - this.balances = balances; - return this; - } - @JsonProperty("metadata") public java.util.Map metadata; @@ -43,6 +35,7 @@ public AccountWithVolumesAndBalances withType(String type) { return this; } + @JsonInclude(Include.NON_ABSENT) @JsonProperty("volumes") public java.util.Map> volumes; @@ -51,10 +44,8 @@ public AccountWithVolumesAndBalances withVolumes(java.util.Map balances, @JsonProperty("metadata") java.util.Map metadata, @JsonProperty("volumes") java.util.Map> volumes) { + public AccountWithVolumesAndBalances(@JsonProperty("address") String address, @JsonProperty("metadata") java.util.Map metadata) { this.address = address; - this.balances = balances; this.metadata = metadata; - this.volumes = volumes; } } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ExpandedTransaction.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ExpandedTransaction.java index c48a9353e..65691df64 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ExpandedTransaction.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ExpandedTransaction.java @@ -15,6 +15,14 @@ public class ExpandedTransaction { + @JsonProperty("id") + public Long id; + + public ExpandedTransaction withId(Long id) { + this.id = id; + return this; + } + @JsonProperty("metadata") public java.util.Map metadata; @@ -23,6 +31,7 @@ public ExpandedTransaction withMetadata(java.util.Map metadata) return this; } + @JsonInclude(Include.NON_ABSENT) @JsonProperty("postCommitVolumes") public java.util.Map> postCommitVolumes; @@ -39,6 +48,7 @@ public ExpandedTransaction withPostings(Posting[] postings) { return this; } + @JsonInclude(Include.NON_ABSENT) @JsonProperty("preCommitVolumes") public java.util.Map> preCommitVolumes; @@ -56,6 +66,14 @@ public ExpandedTransaction withReference(String reference) { return this; } + @JsonProperty("reverted") + public Boolean reverted; + + public ExpandedTransaction withReverted(Boolean reverted) { + this.reverted = reverted; + return this; + } + @JsonSerialize(using = DateTimeSerializer.class) @JsonDeserialize(using = DateTimeDeserializer.class) @JsonProperty("timestamp") @@ -66,20 +84,11 @@ public ExpandedTransaction withTimestamp(OffsetDateTime timestamp) { return this; } - @JsonProperty("txid") - public Long txid; - - public ExpandedTransaction withTxid(Long txid) { - this.txid = txid; - return this; - } - - public ExpandedTransaction(@JsonProperty("metadata") java.util.Map metadata, @JsonProperty("postCommitVolumes") java.util.Map> postCommitVolumes, @JsonProperty("postings") Posting[] postings, @JsonProperty("preCommitVolumes") java.util.Map> preCommitVolumes, @JsonProperty("timestamp") OffsetDateTime timestamp, @JsonProperty("txid") Long txid) { + public ExpandedTransaction(@JsonProperty("id") Long id, @JsonProperty("metadata") java.util.Map metadata, @JsonProperty("postings") Posting[] postings, @JsonProperty("reverted") Boolean reverted, @JsonProperty("timestamp") OffsetDateTime timestamp) { + this.id = id; this.metadata = metadata; - this.postCommitVolumes = postCommitVolumes; this.postings = postings; - this.preCommitVolumes = preCommitVolumes; + this.reverted = reverted; this.timestamp = timestamp; - this.txid = txid; } } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/PostTransactionScriptVars.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/PostTransactionScriptVars.java new file mode 100755 index 000000000..dd980444a --- /dev/null +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/PostTransactionScriptVars.java @@ -0,0 +1,12 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +package com.formance.formance_sdk.models.shared; + + + + +public class PostTransactionScriptVars { + public PostTransactionScriptVars(){} +} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ResponseData.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ResponseData.java new file mode 100755 index 000000000..47f584f06 --- /dev/null +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/ResponseData.java @@ -0,0 +1,15 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +package com.formance.formance_sdk.models.shared; + + + +/** + * ResponseData - The payload + */ + +public class ResponseData { + public ResponseData(){} +} diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/Transaction.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/Transaction.java index 0b120d0fa..6f2f1c633 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/Transaction.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/Transaction.java @@ -15,6 +15,14 @@ public class Transaction { + @JsonProperty("id") + public Long id; + + public Transaction withId(Long id) { + this.id = id; + return this; + } + @JsonProperty("metadata") public java.util.Map metadata; @@ -40,6 +48,14 @@ public Transaction withReference(String reference) { return this; } + @JsonProperty("reverted") + public Boolean reverted; + + public Transaction withReverted(Boolean reverted) { + this.reverted = reverted; + return this; + } + @JsonSerialize(using = DateTimeSerializer.class) @JsonDeserialize(using = DateTimeDeserializer.class) @JsonProperty("timestamp") @@ -50,18 +66,11 @@ public Transaction withTimestamp(OffsetDateTime timestamp) { return this; } - @JsonProperty("txid") - public Long txid; - - public Transaction withTxid(Long txid) { - this.txid = txid; - return this; - } - - public Transaction(@JsonProperty("metadata") java.util.Map metadata, @JsonProperty("postings") Posting[] postings, @JsonProperty("timestamp") OffsetDateTime timestamp, @JsonProperty("txid") Long txid) { + public Transaction(@JsonProperty("id") Long id, @JsonProperty("metadata") java.util.Map metadata, @JsonProperty("postings") Posting[] postings, @JsonProperty("reverted") Boolean reverted, @JsonProperty("timestamp") OffsetDateTime timestamp) { + this.id = id; this.metadata = metadata; this.postings = postings; + this.reverted = reverted; this.timestamp = timestamp; - this.txid = txid; } } diff --git a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/WalletsTransaction.java b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/WalletsTransaction.java index 1928f950b..d4dee8dbe 100755 --- a/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/WalletsTransaction.java +++ b/sdks/java/lib/src/main/java/com/formance/formance_sdk/models/shared/WalletsTransaction.java @@ -15,6 +15,15 @@ public class WalletsTransaction { + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("id") + public Long id; + + public WalletsTransaction withId(Long id) { + this.id = id; + return this; + } + @JsonInclude(Include.NON_ABSENT) @JsonProperty("ledger") public String ledger; @@ -80,18 +89,9 @@ public WalletsTransaction withTimestamp(OffsetDateTime timestamp) { return this; } - @JsonProperty("txid") - public Long txid; - - public WalletsTransaction withTxid(Long txid) { - this.txid = txid; - return this; - } - - public WalletsTransaction(@JsonProperty("metadata") java.util.Map metadata, @JsonProperty("postings") Posting[] postings, @JsonProperty("timestamp") OffsetDateTime timestamp, @JsonProperty("txid") Long txid) { + public WalletsTransaction(@JsonProperty("metadata") java.util.Map metadata, @JsonProperty("postings") Posting[] postings, @JsonProperty("timestamp") OffsetDateTime timestamp) { this.metadata = metadata; this.postings = postings; this.timestamp = timestamp; - this.txid = txid; } } diff --git a/sdks/php/README.md b/sdks/php/README.md index d119b4e91..235b16b5c 100755 --- a/sdks/php/README.md +++ b/sdks/php/README.md @@ -103,7 +103,6 @@ try { * [countTransactions](docs/sdks/ledger/README.md#counttransactions) - Count the transactions from a ledger * [createTransaction](docs/sdks/ledger/README.md#createtransaction) - Create a new transaction to a ledger * [getAccount](docs/sdks/ledger/README.md#getaccount) - Get account by its address -* [getBalances](docs/sdks/ledger/README.md#getbalances) - Get the balances from a ledger's account * [getBalancesAggregated](docs/sdks/ledger/README.md#getbalancesaggregated) - Get the aggregated balances from selected accounts * [getInfo](docs/sdks/ledger/README.md#getinfo) - Show server information * [getLedgerInfo](docs/sdks/ledger/README.md#getledgerinfo) - Get information about a ledger diff --git a/sdks/php/docs/models/operations/AddMetadataOnTransactionRequest.md b/sdks/php/docs/models/operations/AddMetadataOnTransactionRequest.md index b3c756e98..d7878cd9c 100755 --- a/sdks/php/docs/models/operations/AddMetadataOnTransactionRequest.md +++ b/sdks/php/docs/models/operations/AddMetadataOnTransactionRequest.md @@ -7,7 +7,6 @@ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | `idempotencyKey` | *?string* | :heavy_minus_sign: | Use an idempotency key | | | `requestBody` | array | :heavy_minus_sign: | metadata | | -| `async` | *?bool* | :heavy_minus_sign: | Set async mode. | true | | `dryRun` | *?bool* | :heavy_minus_sign: | Set the dryRun mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `id` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/AddMetadataToAccountRequest.md b/sdks/php/docs/models/operations/AddMetadataToAccountRequest.md index 1bbbd3eb4..6c5d2ed16 100755 --- a/sdks/php/docs/models/operations/AddMetadataToAccountRequest.md +++ b/sdks/php/docs/models/operations/AddMetadataToAccountRequest.md @@ -8,6 +8,5 @@ | `idempotencyKey` | *?string* | :heavy_minus_sign: | Use an idempotency key | | | `requestBody` | array | :heavy_check_mark: | metadata | | | `address` | *string* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | -| `async` | *?bool* | :heavy_minus_sign: | Set async mode. | true | | `dryRun` | *?bool* | :heavy_minus_sign: | Set the dry run mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/CountAccountsMetadata.md b/sdks/php/docs/models/operations/CountAccountsMetadata.md deleted file mode 100755 index 7ea898a09..000000000 --- a/sdks/php/docs/models/operations/CountAccountsMetadata.md +++ /dev/null @@ -1,9 +0,0 @@ -# CountAccountsMetadata - -Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/CountAccountsRequest.md b/sdks/php/docs/models/operations/CountAccountsRequest.md index ebe990763..fe53928d1 100755 --- a/sdks/php/docs/models/operations/CountAccountsRequest.md +++ b/sdks/php/docs/models/operations/CountAccountsRequest.md @@ -3,8 +3,7 @@ ## Fields -| Field | Type | Required | Description | Example | -| ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *?string* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | [?CountAccountsMetadata](../../models/operations/CountAccountsMetadata.md) | :heavy_minus_sign: | Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ---------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- | +| `requestBody` | array | :heavy_minus_sign: | N/A | | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/CountTransactionsRequest.md b/sdks/php/docs/models/operations/CountTransactionsRequest.md index c4c50eee5..d387c07a4 100755 --- a/sdks/php/docs/models/operations/CountTransactionsRequest.md +++ b/sdks/php/docs/models/operations/CountTransactionsRequest.md @@ -3,13 +3,8 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `account` | *?string* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | -| `destination` | *?string* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `endTime` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | array | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `reference` | *?string* | :heavy_minus_sign: | Filter transactions by reference field. | ref:001 | -| `source` | *?string* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `startTime` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | +| `requestBody` | array | :heavy_minus_sign: | N/A | | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | +| `pit` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/CountTransactionsRequestBody.md b/sdks/php/docs/models/operations/CountTransactionsRequestBody.md deleted file mode 100755 index 94a1f6eee..000000000 --- a/sdks/php/docs/models/operations/CountTransactionsRequestBody.md +++ /dev/null @@ -1,7 +0,0 @@ -# CountTransactionsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/CreateTransactionRequest.md b/sdks/php/docs/models/operations/CreateTransactionRequest.md index 70b6d3049..67bbf9134 100755 --- a/sdks/php/docs/models/operations/CreateTransactionRequest.md +++ b/sdks/php/docs/models/operations/CreateTransactionRequest.md @@ -7,6 +7,5 @@ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `idempotencyKey` | *?string* | :heavy_minus_sign: | Use an idempotency key | | | `postTransaction` | [\formance\stack\Models\Shared\PostTransaction](../../models/shared/PostTransaction.md) | :heavy_check_mark: | The request body must contain at least one of the following objects:
    - `postings`: suitable for simple transactions
    - `script`: enabling more complex transactions with Numscript
    | | -| `async` | *?bool* | :heavy_minus_sign: | Set async mode. | true | | `dryRun` | *?bool* | :heavy_minus_sign: | Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/GetAccountRequest.md b/sdks/php/docs/models/operations/GetAccountRequest.md index eea42675e..faa37df78 100755 --- a/sdks/php/docs/models/operations/GetAccountRequest.md +++ b/sdks/php/docs/models/operations/GetAccountRequest.md @@ -6,4 +6,5 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | `address` | *string* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | +| `expand` | *?string* | :heavy_minus_sign: | N/A | | | `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/GetBalancesAggregatedRequest.md b/sdks/php/docs/models/operations/GetBalancesAggregatedRequest.md index c46c34fee..f39be3cb8 100755 --- a/sdks/php/docs/models/operations/GetBalancesAggregatedRequest.md +++ b/sdks/php/docs/models/operations/GetBalancesAggregatedRequest.md @@ -3,7 +3,6 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -| `address` | *?string* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/GetBalancesRequest.md b/sdks/php/docs/models/operations/GetBalancesRequest.md deleted file mode 100755 index ebc597dd9..000000000 --- a/sdks/php/docs/models/operations/GetBalancesRequest.md +++ /dev/null @@ -1,11 +0,0 @@ -# GetBalancesRequest - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *?string* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `cursor` | *?string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `pageSize` | *?int* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/GetBalancesResponse.md b/sdks/php/docs/models/operations/GetBalancesResponse.md deleted file mode 100755 index 7df960d48..000000000 --- a/sdks/php/docs/models/operations/GetBalancesResponse.md +++ /dev/null @@ -1,12 +0,0 @@ -# GetBalancesResponse - - -## Fields - -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | -| `balancesCursorResponse` | [?\formance\stack\Models\Shared\BalancesCursorResponse](../../models/shared/BalancesCursorResponse.md) | :heavy_minus_sign: | OK | -| `contentType` | *string* | :heavy_check_mark: | N/A | -| `errorResponse` | [?\formance\stack\Models\Shared\ErrorResponse](../../models/shared/ErrorResponse.md) | :heavy_minus_sign: | Error | -| `statusCode` | *int* | :heavy_check_mark: | N/A | -| `rawResponse` | [\Psr\Http\Message\ResponseInterface](https://www.php-fig.org/psr/psr-7/#33-psrhttpmessageresponseinterface) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/GetTransactionRequest.md b/sdks/php/docs/models/operations/GetTransactionRequest.md index b697726f8..9e3417cbf 100755 --- a/sdks/php/docs/models/operations/GetTransactionRequest.md +++ b/sdks/php/docs/models/operations/GetTransactionRequest.md @@ -5,5 +5,6 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `expand` | *?string* | :heavy_minus_sign: | N/A | | +| `id` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/ListAccountsRequest.md b/sdks/php/docs/models/operations/ListAccountsRequest.md index 1aa074bac..a402dd2bd 100755 --- a/sdks/php/docs/models/operations/ListAccountsRequest.md +++ b/sdks/php/docs/models/operations/ListAccountsRequest.md @@ -5,8 +5,9 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *?string* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | +| `requestBody` | array | :heavy_minus_sign: | N/A | | | `cursor` | *?string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | +| `expand` | *?string* | :heavy_minus_sign: | N/A | | | `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | array | :heavy_minus_sign: | Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `pageSize` | *?int* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file +| `pageSize` | *?int* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | +| `pit` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/ListAccountsRequestBody.md b/sdks/php/docs/models/operations/ListAccountsRequestBody.md deleted file mode 100755 index 22f1ad984..000000000 --- a/sdks/php/docs/models/operations/ListAccountsRequestBody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListAccountsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/ListLogsRequest.md b/sdks/php/docs/models/operations/ListLogsRequest.md index 58410c897..299e1879d 100755 --- a/sdks/php/docs/models/operations/ListLogsRequest.md +++ b/sdks/php/docs/models/operations/ListLogsRequest.md @@ -5,8 +5,8 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `requestBody` | array | :heavy_minus_sign: | N/A | | | `cursor` | *?string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `endTime` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | | `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | | `pageSize` | *?int* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `startTime` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| `pit` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/ListLogsRequestBody.md b/sdks/php/docs/models/operations/ListLogsRequestBody.md deleted file mode 100755 index 6dbd158df..000000000 --- a/sdks/php/docs/models/operations/ListLogsRequestBody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListLogsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/ListTransactionsRequest.md b/sdks/php/docs/models/operations/ListTransactionsRequest.md index f271f8c63..ed2395733 100755 --- a/sdks/php/docs/models/operations/ListTransactionsRequest.md +++ b/sdks/php/docs/models/operations/ListTransactionsRequest.md @@ -5,13 +5,9 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `account` | *?string* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | +| `requestBody` | array | :heavy_minus_sign: | N/A | | | `cursor` | *?string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `destination` | *?string* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `endTime` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | +| `expand` | *?string* | :heavy_minus_sign: | N/A | | | `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | array | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below. | | | `pageSize` | *?int* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `reference` | *?string* | :heavy_minus_sign: | Find transactions by reference field. | ref:001 | -| `source` | *?string* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `startTime` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| `pit` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/ListTransactionsRequestBody.md b/sdks/php/docs/models/operations/ListTransactionsRequestBody.md deleted file mode 100755 index 990f2baf5..000000000 --- a/sdks/php/docs/models/operations/ListTransactionsRequestBody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListTransactionsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/php/docs/models/operations/RevertTransactionRequest.md b/sdks/php/docs/models/operations/RevertTransactionRequest.md index 318b663b1..664affd6d 100755 --- a/sdks/php/docs/models/operations/RevertTransactionRequest.md +++ b/sdks/php/docs/models/operations/RevertTransactionRequest.md @@ -5,5 +5,5 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `id` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/php/docs/models/shared/AccountWithVolumesAndBalances.md b/sdks/php/docs/models/shared/AccountWithVolumesAndBalances.md index 0d67eb598..bcb6c0db5 100755 --- a/sdks/php/docs/models/shared/AccountWithVolumesAndBalances.md +++ b/sdks/php/docs/models/shared/AccountWithVolumesAndBalances.md @@ -6,7 +6,6 @@ | Field | Type | Required | Description | Example | | ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | | `address` | *string* | :heavy_check_mark: | N/A | users:001 | -| `balances` | array | :heavy_check_mark: | N/A | | | `metadata` | array | :heavy_check_mark: | N/A | | | `type` | *?string* | :heavy_minus_sign: | N/A | virtual | -| `volumes` | array> | :heavy_check_mark: | N/A | | \ No newline at end of file +| `volumes` | array> | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/php/docs/models/shared/BalancesCursorResponse.md b/sdks/php/docs/models/shared/BalancesCursorResponse.md deleted file mode 100755 index bbd2d4560..000000000 --- a/sdks/php/docs/models/shared/BalancesCursorResponse.md +++ /dev/null @@ -1,10 +0,0 @@ -# BalancesCursorResponse - -OK - - -## Fields - -| Field | Type | Required | Description | -| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | -| `cursor` | [BalancesCursorResponseCursor](../../models/shared/BalancesCursorResponseCursor.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/sdks/php/docs/models/shared/BalancesCursorResponseCursor.md b/sdks/php/docs/models/shared/BalancesCursorResponseCursor.md deleted file mode 100755 index 780c596ef..000000000 --- a/sdks/php/docs/models/shared/BalancesCursorResponseCursor.md +++ /dev/null @@ -1,12 +0,0 @@ -# BalancesCursorResponseCursor - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -| `data` | array>> | :heavy_check_mark: | N/A | | -| `hasMore` | *bool* | :heavy_check_mark: | N/A | false | -| `next` | *?string* | :heavy_minus_sign: | N/A | | -| `pageSize` | *int* | :heavy_check_mark: | N/A | 15 | -| `previous` | *?string* | :heavy_minus_sign: | N/A | YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= | \ No newline at end of file diff --git a/sdks/php/docs/models/shared/ExpandedTransaction.md b/sdks/php/docs/models/shared/ExpandedTransaction.md index 2ff955c39..f00fe01de 100755 --- a/sdks/php/docs/models/shared/ExpandedTransaction.md +++ b/sdks/php/docs/models/shared/ExpandedTransaction.md @@ -5,10 +5,11 @@ | Field | Type | Required | Description | Example | | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | +| `id` | *int* | :heavy_check_mark: | N/A | | | `metadata` | array | :heavy_check_mark: | N/A | | -| `postCommitVolumes` | array> | :heavy_check_mark: | N/A | | +| `postCommitVolumes` | array> | :heavy_minus_sign: | N/A | | | `postings` | array<[Posting](../../models/shared/Posting.md)> | :heavy_check_mark: | N/A | | -| `preCommitVolumes` | array> | :heavy_check_mark: | N/A | | +| `preCommitVolumes` | array> | :heavy_minus_sign: | N/A | | | `reference` | *?string* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_check_mark: | N/A | | -| `txid` | *int* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `reverted` | *bool* | :heavy_check_mark: | N/A | | +| `timestamp` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/php/docs/models/shared/PostTransactionScriptVars.md b/sdks/php/docs/models/shared/PostTransactionScriptVars.md new file mode 100755 index 000000000..ef1a0de95 --- /dev/null +++ b/sdks/php/docs/models/shared/PostTransactionScriptVars.md @@ -0,0 +1,7 @@ +# PostTransactionScriptVars + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/php/docs/models/shared/Query.md b/sdks/php/docs/models/shared/Query.md index 01af4edd0..940e2336c 100755 --- a/sdks/php/docs/models/shared/Query.md +++ b/sdks/php/docs/models/shared/Query.md @@ -11,6 +11,6 @@ | `pageSize` | *?int* | :heavy_minus_sign: | N/A | | | `policy` | *?string* | :heavy_minus_sign: | N/A | OR | | `raw` | [?QueryRaw](../../models/shared/QueryRaw.md) | :heavy_minus_sign: | N/A | | -| `sort` | *?string* | :heavy_minus_sign: | N/A | txid:asc | +| `sort` | *?string* | :heavy_minus_sign: | N/A | id:asc | | `target` | *?string* | :heavy_minus_sign: | N/A | | | `terms` | array<*string*> | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/php/docs/models/shared/ResponseData.md b/sdks/php/docs/models/shared/ResponseData.md new file mode 100755 index 000000000..c3a85e750 --- /dev/null +++ b/sdks/php/docs/models/shared/ResponseData.md @@ -0,0 +1,9 @@ +# ResponseData + +The payload + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/php/docs/models/shared/Transaction.md b/sdks/php/docs/models/shared/Transaction.md index c5c76bef9..a74fe95f7 100755 --- a/sdks/php/docs/models/shared/Transaction.md +++ b/sdks/php/docs/models/shared/Transaction.md @@ -5,8 +5,9 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | +| `id` | *int* | :heavy_check_mark: | N/A | | | `metadata` | array | :heavy_check_mark: | N/A | | | `postings` | array<[Posting](../../models/shared/Posting.md)> | :heavy_check_mark: | N/A | | | `reference` | *?string* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_check_mark: | N/A | | -| `txid` | *int* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `reverted` | *bool* | :heavy_check_mark: | N/A | | +| `timestamp` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/php/docs/models/shared/WalletsTransaction.md b/sdks/php/docs/models/shared/WalletsTransaction.md index 5da50fb60..548e52473 100755 --- a/sdks/php/docs/models/shared/WalletsTransaction.md +++ b/sdks/php/docs/models/shared/WalletsTransaction.md @@ -5,11 +5,11 @@ | Field | Type | Required | Description | Example | | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| `id` | *?int* | :heavy_minus_sign: | N/A | | | `ledger` | *?string* | :heavy_minus_sign: | N/A | | | `metadata` | array | :heavy_check_mark: | Metadata associated with the wallet. | | | `postCommitVolumes` | array> | :heavy_minus_sign: | N/A | | | `postings` | array<[Posting](../../models/shared/Posting.md)> | :heavy_check_mark: | N/A | | | `preCommitVolumes` | array> | :heavy_minus_sign: | N/A | | | `reference` | *?string* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_check_mark: | N/A | | -| `txid` | *int* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `timestamp` | [\DateTime](https://www.php.net/manual/en/class.datetime.php) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/php/docs/sdks/ledger/README.md b/sdks/php/docs/sdks/ledger/README.md index 3f254bfb2..f4725fec8 100755 --- a/sdks/php/docs/sdks/ledger/README.md +++ b/sdks/php/docs/sdks/ledger/README.md @@ -8,7 +8,6 @@ * [countTransactions](#counttransactions) - Count the transactions from a ledger * [createTransaction](#createtransaction) - Create a new transaction to a ledger * [getAccount](#getaccount) - Get account by its address -* [getBalances](#getbalances) - Get the balances from a ledger's account * [getBalancesAggregated](#getbalancesaggregated) - Get the aggregated balances from selected accounts * [getInfo](#getinfo) - Show server information * [getLedgerInfo](#getledgerinfo) - Get information about a ledger @@ -45,10 +44,9 @@ try { 'explicabo' => 'nobis', 'enim' => 'omnis', ]; - $request->async = true; $request->dryRun = true; + $request->id = 1234; $request->ledger = 'ledger001'; - $request->txid = 1234; $response = $sdk->ledger->addMetadataOnTransaction($request); @@ -99,7 +97,6 @@ try { 'iure' => 'culpa', ]; $request->address = 'users:001'; - $request->async = true; $request->dryRun = true; $request->ledger = 'ledger001'; @@ -140,16 +137,19 @@ require_once 'vendor/autoload.php'; use \formance\stack\SDK; use \formance\stack\Models\Shared\Security; use \formance\stack\Models\Operations\CountAccountsRequest; -use \formance\stack\Models\Operations\CountAccountsMetadata; $sdk = SDK::builder() ->build(); try { $request = new CountAccountsRequest(); - $request->address = 'users:.+'; + $request->requestBody = [ + 'sapiente' => 'architecto', + 'mollitia' => 'dolorem', + 'culpa' => 'consequuntur', + 'repellat' => 'mollitia', + ]; $request->ledger = 'ledger001'; - $request->metadata = new CountAccountsMetadata(); $response = $sdk->ledger->countAccounts($request); @@ -194,16 +194,13 @@ $sdk = SDK::builder() try { $request = new CountTransactionsRequest(); - $request->account = 'users:001'; - $request->destination = 'users:001'; - $request->endTime = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2020-02-15T22:48:47.492Z'); - $request->ledger = 'ledger001'; - $request->metadata = [ - 'mollitia' => 'dolorem', + $request->requestBody = [ + 'numquam' => 'commodi', + 'quam' => 'molestiae', + 'velit' => 'error', ]; - $request->reference = 'ref:001'; - $request->source = 'users:001'; - $request->startTime = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-09-05T05:51:25.673Z'); + $request->ledger = 'ledger001'; + $request->pit = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-08-30T15:03:11.112Z'); $response = $sdk->ledger->countTransactions($request); @@ -251,17 +248,16 @@ $sdk = SDK::builder() try { $request = new CreateTransactionRequest(); - $request->idempotencyKey = 'repellat'; + $request->idempotencyKey = 'vitae'; $request->postTransaction = new PostTransaction(); $request->postTransaction->metadata = [ - 'occaecati' => 'numquam', - 'commodi' => 'quam', - 'molestiae' => 'velit', + 'animi' => 'enim', + 'odit' => 'quo', + 'sequi' => 'tenetur', ]; $request->postTransaction->postings = [ new Posting(), new Posting(), - new Posting(), ]; $request->postTransaction->reference = 'ref:001'; $request->postTransaction->script = new PostTransactionScript(); @@ -274,10 +270,11 @@ try { ) '; $request->postTransaction->script->vars = [ - 'quis' => 'vitae', + 'possimus' => 'aut', + 'quasi' => 'error', + 'temporibus' => 'laborum', ]; - $request->postTransaction->timestamp = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-09-08T21:06:19.630Z'); - $request->async = true; + $request->postTransaction->timestamp = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-01-11T05:45:42.485Z'); $request->dryRun = true; $request->ledger = 'ledger001'; @@ -325,6 +322,7 @@ $sdk = SDK::builder() try { $request = new GetAccountRequest(); $request->address = 'users:001'; + $request->expand = 'voluptatibus'; $request->ledger = 'ledger001'; $response = $sdk->ledger->getAccount($request); @@ -349,54 +347,6 @@ try { **[?\formance\stack\Models\Operations\GetAccountResponse](../../models/operations/GetAccountResponse.md)** -## getBalances - -Get the balances from a ledger's account - -### Example Usage - -```php -build(); - -try { - $request = new GetBalancesRequest(); - $request->address = 'users:001'; - $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->ledger = 'ledger001'; - $request->pageSize = 317202; - - $response = $sdk->ledger->getBalances($request); - - if ($response->balancesCursorResponse !== null) { - // handle response - } -} catch (Exception $e) { - // handle exception -} -``` - -### Parameters - -| Parameter | Type | Required | Description | -| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | -| `$request` | [\formance\stack\Models\Operations\GetBalancesRequest](../../models/operations/GetBalancesRequest.md) | :heavy_check_mark: | The request object to use for the request. | - - -### Response - -**[?\formance\stack\Models\Operations\GetBalancesResponse](../../models/operations/GetBalancesResponse.md)** - - ## getBalancesAggregated Get the aggregated balances from selected accounts @@ -418,7 +368,6 @@ $sdk = SDK::builder() try { $request = new GetBalancesAggregatedRequest(); - $request->address = 'users:001'; $request->ledger = 'ledger001'; $response = $sdk->ledger->getBalancesAggregated($request); @@ -544,8 +493,9 @@ $sdk = SDK::builder() try { $request = new GetTransactionRequest(); + $request->expand = 'vero'; + $request->id = 1234; $request->ledger = 'ledger001'; - $request->txid = 1234; $response = $sdk->ledger->getTransaction($request); @@ -590,13 +540,15 @@ $sdk = SDK::builder() try { $request = new ListAccountsRequest(); - $request->address = 'users:.+'; + $request->requestBody = [ + 'praesentium' => 'voluptatibus', + 'ipsa' => 'omnis', + ]; $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; + $request->expand = 'voluptate'; $request->ledger = 'ledger001'; - $request->metadata = [ - 'quo' => 'sequi', - ]; - $request->pageSize = 949572; + $request->pageSize = 739264; + $request->pit = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-12-17T16:42:52.927Z'); $response = $sdk->ledger->listAccounts($request); @@ -641,11 +593,14 @@ $sdk = SDK::builder() try { $request = new ListLogsRequest(); + $request->requestBody = [ + 'ut' => 'maiores', + 'dicta' => 'corporis', + ]; $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->endTime = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-05-04T04:15:52.352Z'); $request->ledger = 'ledger001'; - $request->pageSize = 820994; - $request->startTime = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-11-26T13:23:33.410Z'); + $request->pageSize = 296140; + $request->pit = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-11-18T15:56:41.921Z'); $response = $sdk->ledger->listLogs($request); @@ -671,7 +626,7 @@ try { ## listTransactions -List transactions from a ledger, sorted by txid in descending order. +List transactions from a ledger, sorted by id in descending order. ### Example Usage @@ -690,20 +645,16 @@ $sdk = SDK::builder() try { $request = new ListTransactionsRequest(); - $request->account = 'users:001'; + $request->requestBody = [ + 'enim' => 'accusamus', + 'commodi' => 'repudiandae', + 'quae' => 'ipsum', + ]; $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->destination = 'users:001'; - $request->endTime = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-04-29T07:12:18.684Z'); + $request->expand = 'quidem'; $request->ledger = 'ledger001'; - $request->metadata = [ - 'quasi' => 'reiciendis', - 'voluptatibus' => 'vero', - 'nihil' => 'praesentium', - ]; - $request->pageSize = 976762; - $request->reference = 'ref:001'; - $request->source = 'users:001'; - $request->startTime = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-05-25T05:33:11.349Z'); + $request->pageSize = 565189; + $request->pit = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-04-09T11:24:10.949Z'); $response = $sdk->ledger->listTransactions($request); @@ -794,8 +745,8 @@ $sdk = SDK::builder() try { $request = new RevertTransactionRequest(); + $request->id = 1234; $request->ledger = 'ledger001'; - $request->txid = 1234; $response = $sdk->ledger->revertTransaction($request); diff --git a/sdks/php/docs/sdks/orchestration/README.md b/sdks/php/docs/sdks/orchestration/README.md index 997400155..4fd780c10 100755 --- a/sdks/php/docs/sdks/orchestration/README.md +++ b/sdks/php/docs/sdks/orchestration/README.md @@ -36,7 +36,7 @@ $sdk = SDK::builder() try { $request = new CancelEventRequest(); - $request->instanceID = 'voluptate'; + $request->instanceID = 'modi'; $response = $sdk->orchestration->cancelEvent($request); @@ -81,23 +81,13 @@ $sdk = SDK::builder() try { $request = new CreateWorkflowRequest(); - $request->name = 'Thomas Batz'; + $request->name = 'Dr. Jordan Von'; $request->stages = [ [ - 'corporis' => 'dolore', - ], - [ - 'dicta' => 'harum', - 'enim' => 'accusamus', - ], - [ - 'repudiandae' => 'quae', - 'ipsum' => 'quidem', - ], - [ - 'excepturi' => 'pariatur', - 'modi' => 'praesentium', - 'rem' => 'voluptates', + 'incidunt' => 'enim', + 'consequatur' => 'est', + 'quibusdam' => 'explicabo', + 'deserunt' => 'distinctio', ], ]; @@ -144,7 +134,7 @@ $sdk = SDK::builder() try { $request = new DeleteWorkflowRequest(); - $request->flowId = 'quasi'; + $request->flowId = 'quibusdam'; $response = $sdk->orchestration->deleteWorkflow($request); @@ -189,7 +179,7 @@ $sdk = SDK::builder() try { $request = new GetInstanceRequest(); - $request->instanceID = 'repudiandae'; + $request->instanceID = 'labore'; $response = $sdk->orchestration->getInstance($request); @@ -234,7 +224,7 @@ $sdk = SDK::builder() try { $request = new GetInstanceHistoryRequest(); - $request->instanceID = 'sint'; + $request->instanceID = 'modi'; $response = $sdk->orchestration->getInstanceHistory($request); @@ -279,8 +269,8 @@ $sdk = SDK::builder() try { $request = new GetInstanceStageHistoryRequest(); - $request->instanceID = 'veritatis'; - $request->number = 929297; + $request->instanceID = 'qui'; + $request->number = 397821; $response = $sdk->orchestration->getInstanceStageHistory($request); @@ -325,7 +315,7 @@ $sdk = SDK::builder() try { $request = new GetWorkflowRequest(); - $request->flowId = 'incidunt'; + $request->flowId = 'cupiditate'; $response = $sdk->orchestration->getWorkflow($request); @@ -371,7 +361,7 @@ $sdk = SDK::builder() try { $request = new ListInstancesRequest(); $request->running = false; - $request->workflowID = 'enim'; + $request->workflowID = 'quos'; $response = $sdk->orchestration->listInstances($request); @@ -487,10 +477,10 @@ $sdk = SDK::builder() try { $request = new RunWorkflowRequest(); $request->requestBody = [ - 'est' => 'quibusdam', + 'magni' => 'assumenda', ]; $request->wait = false; - $request->workflowID = 'explicabo'; + $request->workflowID = 'ipsam'; $response = $sdk->orchestration->runWorkflow($request); @@ -537,8 +527,8 @@ $sdk = SDK::builder() try { $request = new SendEventRequest(); $request->requestBody = new SendEventRequestBody(); - $request->requestBody->name = 'Rudy Spencer'; - $request->instanceID = 'qui'; + $request->requestBody->name = 'Denise Pagac'; + $request->instanceID = 'facilis'; $response = $sdk->orchestration->sendEvent($request); diff --git a/sdks/php/docs/sdks/payments/README.md b/sdks/php/docs/sdks/payments/README.md index 9b734b368..da2e75be9 100755 --- a/sdks/php/docs/sdks/payments/README.md +++ b/sdks/php/docs/sdks/payments/README.md @@ -98,7 +98,7 @@ try { $request->transferRequest->asset = 'USD'; $request->transferRequest->destination = 'acct_1Gqj58KZcSIg2N2q'; $request->transferRequest->source = 'acct_1Gqj58KZcSIg2N2q'; - $request->connector = Connector::Modulr; + $request->connector = Connector::BankingCircle; $response = $sdk->payments->connectorsTransfer($request); @@ -143,16 +143,17 @@ $sdk = SDK::builder() try { $request = new GetAccountBalancesRequest(); - $request->accountId = 'cupiditate'; - $request->asset = 'quos'; + $request->accountId = 'labore'; + $request->asset = 'delectus'; $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->from = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-11-01T19:07:16.800Z'); - $request->limit = 828940; - $request->pageSize = 369808; + $request->from = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-10-02T04:55:20.234Z'); + $request->limit = 756107; + $request->pageSize = 576157; $request->sort = [ - 'fugit', + 'provident', + 'necessitatibus', ]; - $request->to = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-11-11T04:17:07.569Z'); + $request->to = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-09-21T14:06:09.271Z'); $response = $sdk->payments->getAccountBalances($request); @@ -198,8 +199,8 @@ $sdk = SDK::builder() try { $request = new GetConnectorTaskRequest(); - $request->connector = Connector::Wise; - $request->taskId = 'facilis'; + $request->connector = Connector::DummyPay; + $request->taskId = 'debitis'; $response = $sdk->payments->getConnectorTask($request); @@ -244,7 +245,7 @@ $sdk = SDK::builder() try { $request = new GetPaymentRequest(); - $request->paymentId = 'tempore'; + $request->paymentId = 'a'; $response = $sdk->payments->getPayment($request); @@ -290,10 +291,15 @@ $sdk = SDK::builder() try { $request = new InstallConnectorRequest(); - $request->requestBody = new WiseConfig(); - $request->requestBody->apiKey = 'XXX'; + $request->requestBody = new BankingCircleConfig(); + $request->requestBody->authorizationEndpoint = 'XXX'; + $request->requestBody->endpoint = 'XXX'; + $request->requestBody->password = 'XXX'; $request->requestBody->pollingPeriod = '60s'; - $request->connector = Connector::Moneycorp; + $request->requestBody->userCertificate = 'XXX'; + $request->requestBody->userCertificateKey = 'XXX'; + $request->requestBody->username = 'XXX'; + $request->connector = Connector::Modulr; $response = $sdk->payments->installConnector($request); @@ -411,7 +417,7 @@ try { $request = new ListConnectorTasksRequest(); $request->connector = Connector::Modulr; $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->pageSize = 248753; + $request->pageSize = 846409; $response = $sdk->payments->listConnectorTasks($request); @@ -457,7 +463,7 @@ $sdk = SDK::builder() try { $request = new ListConnectorsTransfersRequest(); - $request->connector = Connector::Mangopay; + $request->connector = Connector::Moneycorp; $response = $sdk->payments->listConnectorsTransfers($request); @@ -503,10 +509,9 @@ $sdk = SDK::builder() try { $request = new ListPaymentsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->pageSize = 576157; + $request->pageSize = 699479; $request->sort = [ - 'provident', - 'necessitatibus', + 'magnam', ]; $response = $sdk->payments->listPayments($request); @@ -552,7 +557,7 @@ $sdk = SDK::builder() try { $request = new PaymentsgetAccountRequest(); - $request->accountId = 'sint'; + $request->accountId = 'cumque'; $response = $sdk->payments->paymentsgetAccount($request); @@ -633,9 +638,10 @@ $sdk = SDK::builder() try { $request = new PaymentslistAccountsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->pageSize = 638921; + $request->pageSize = 813798; $request->sort = [ - 'debitis', + 'aliquid', + 'laborum', ]; $response = $sdk->payments->paymentslistAccounts($request); @@ -730,7 +736,7 @@ $sdk = SDK::builder() try { $request = new ResetConnectorRequest(); - $request->connector = Connector::BankingCircle; + $request->connector = Connector::DummyPay; $response = $sdk->payments->resetConnector($request); @@ -776,7 +782,7 @@ $sdk = SDK::builder() try { $request = new UninstallConnectorRequest(); - $request->connector = Connector::Modulr; + $request->connector = Connector::CurrencyCloud; $response = $sdk->payments->uninstallConnector($request); @@ -823,8 +829,8 @@ $sdk = SDK::builder() try { $request = new UpdateMetadataRequest(); $request->paymentMetadata = new PaymentMetadata(); - $request->paymentMetadata->key = 'in'; - $request->paymentId = 'illum'; + $request->paymentMetadata->key = 'enim'; + $request->paymentId = 'accusamus'; $response = $sdk->payments->updateMetadata($request); diff --git a/sdks/php/docs/sdks/search/README.md b/sdks/php/docs/sdks/search/README.md index 98f17f6d3..b13d9cf25 100755 --- a/sdks/php/docs/sdks/search/README.md +++ b/sdks/php/docs/sdks/search/README.md @@ -39,16 +39,15 @@ try { 'quickstart', 'quickstart', ]; - $request->pageSize = 116202; + $request->pageSize = 588465; $request->policy = 'OR'; $request->raw = new QueryRaw(); - $request->sort = 'txid:asc'; - $request->target = 'magnam'; + $request->sort = 'id:asc'; + $request->target = 'nam'; $request->terms = [ 'destination=central_bank1', 'destination=central_bank1', 'destination=central_bank1', - 'destination=central_bank1', ]; $response = $sdk->search->search($request); diff --git a/sdks/php/docs/sdks/wallets/README.md b/sdks/php/docs/sdks/wallets/README.md index d82fb073e..1d6e50659 100755 --- a/sdks/php/docs/sdks/wallets/README.md +++ b/sdks/php/docs/sdks/wallets/README.md @@ -44,7 +44,7 @@ try { $request->confirmHoldRequest = new ConfirmHoldRequest(); $request->confirmHoldRequest->amount = 100; $request->confirmHoldRequest->final = true; - $request->holdId = 'facere'; + $request->holdId = 'blanditiis'; $response = $sdk->wallets->confirmHold($request); @@ -91,10 +91,10 @@ $sdk = SDK::builder() try { $request = new CreateBalanceRequest(); $request->createBalanceRequest = new CreateBalanceRequest(); - $request->createBalanceRequest->expiresAt = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2022-08-09T06:36:34.417Z'); - $request->createBalanceRequest->name = 'Tomas Friesen'; - $request->createBalanceRequest->priority = 881736; - $request->id = 'fb9ba88f-3a66-4997-874b-a4469b6e2141'; + $request->createBalanceRequest->expiresAt = DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-02-02T01:24:52.629Z'); + $request->createBalanceRequest->name = 'Sandy Huels'; + $request->createBalanceRequest->priority = 606393; + $request->id = '7074ba44-69b6-4e21-8195-9890afa563e2'; $response = $sdk->wallets->createBalance($request); @@ -140,11 +140,10 @@ $sdk = SDK::builder() try { $request = new CreateWalletRequest(); $request->metadata = [ - 'ullam' => 'provident', - 'quos' => 'sint', - 'accusantium' => 'mollitia', + 'quasi' => 'iure', + 'doloribus' => 'debitis', ]; - $request->name = 'Shaun Hammes'; + $request->name = 'Jasmine Lind'; $response = $sdk->wallets->createWallet($request); @@ -193,18 +192,21 @@ try { $request = new CreditWalletRequest(); $request->creditWalletRequest = new CreditWalletRequest(); $request->creditWalletRequest->amount = new Monetary(); - $request->creditWalletRequest->amount->amount = 896547; - $request->creditWalletRequest->amount->asset = 'odit'; - $request->creditWalletRequest->balance = 'nemo'; + $request->creditWalletRequest->amount->amount = 100226; + $request->creditWalletRequest->amount->asset = 'architecto'; + $request->creditWalletRequest->balance = 'repudiandae'; $request->creditWalletRequest->metadata = [ - 'iure' => 'doloribus', + 'expedita' => 'nihil', + 'repellat' => 'quibusdam', ]; - $request->creditWalletRequest->reference = 'debitis'; + $request->creditWalletRequest->reference = 'sed'; $request->creditWalletRequest->sources = [ new WalletSubject(), + new LedgerAccountSubject(), + new LedgerAccountSubject(), new WalletSubject(), ]; - $request->id = 'b711e5b7-fd2e-4d02-8921-cddc692601fb'; + $request->id = '921cddc6-9260-41fb-976b-0d5f0d30c5fb'; $response = $sdk->wallets->creditWallet($request); @@ -253,24 +255,21 @@ try { $request = new DebitWalletRequest(); $request->debitWalletRequest = new DebitWalletRequest(); $request->debitWalletRequest->amount = new Monetary(); - $request->debitWalletRequest->amount->amount = 373291; - $request->debitWalletRequest->amount->asset = 'voluptate'; + $request->debitWalletRequest->amount->amount = 749999; + $request->debitWalletRequest->amount->asset = 'dolores'; $request->debitWalletRequest->balances = [ - 'nam', - 'eaque', + 'totam', + 'dignissimos', ]; - $request->debitWalletRequest->description = 'pariatur'; + $request->debitWalletRequest->description = 'eaque'; $request->debitWalletRequest->destination = new LedgerAccountSubject(); - $request->debitWalletRequest->destination->identifier = 'voluptatibus'; - $request->debitWalletRequest->destination->type = 'perferendis'; + $request->debitWalletRequest->destination->identifier = 'nesciunt'; + $request->debitWalletRequest->destination->type = 'eos'; $request->debitWalletRequest->metadata = [ - 'amet' => 'aut', - 'cumque' => 'corporis', - 'hic' => 'libero', - 'nobis' => 'dolores', + 'dolores' => 'minus', ]; $request->debitWalletRequest->pending = false; - $request->id = '58705320-2c73-4d5f-a9b9-0c28909b3fe4'; + $request->id = '73d5fe9b-90c2-4890-9b3f-e49a8d9cbf48'; $response = $sdk->wallets->debitWallet($request); @@ -315,8 +314,8 @@ $sdk = SDK::builder() try { $request = new GetBalanceRequest(); - $request->balanceName = 'iste'; - $request->id = 'a8d9cbf4-8633-4323-b9b7-7f3a4100674e'; + $request->balanceName = 'aliquid'; + $request->id = '33323f9b-77f3-4a41-8067-4ebf69280d1b'; $response = $sdk->wallets->getBalance($request); @@ -361,7 +360,7 @@ $sdk = SDK::builder() try { $request = new GetHoldRequest(); - $request->holdID = 'quidem'; + $request->holdID = 'dolorum'; $response = $sdk->wallets->getHold($request); @@ -408,13 +407,11 @@ try { $request = new GetHoldsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; $request->metadata = [ - 'voluptas' => 'natus', - 'eos' => 'atque', - 'sit' => 'fugiat', - 'ab' => 'soluta', + 'voluptate' => 'dolorum', + 'deleniti' => 'omnis', ]; - $request->pageSize = 679393; - $request->walletID = 'iusto'; + $request->pageSize = 896672; + $request->walletID = 'distinctio'; $response = $sdk->wallets->getHolds($request); @@ -458,8 +455,8 @@ $sdk = SDK::builder() try { $request = new GetTransactionsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; - $request->pageSize = 453697; - $request->walletID = 'dolorum'; + $request->pageSize = 990339; + $request->walletID = 'nihil'; $response = $sdk->wallets->getTransactions($request); @@ -504,7 +501,7 @@ $sdk = SDK::builder() try { $request = new GetWalletRequest(); - $request->id = '89ebf737-ae42-403c-a5e6-a95d8a0d446c'; + $request->id = '37ae4203-ce5e-46a9-9d8a-0d446ce2af7a'; $response = $sdk->wallets->getWallet($request); @@ -549,7 +546,7 @@ $sdk = SDK::builder() try { $request = new GetWalletSummaryRequest(); - $request->id = 'e2af7a73-cf3b-4e45-bf87-0b326b5a7342'; + $request->id = '73cf3be4-53f8-470b-b26b-5a73429cdb1a'; $response = $sdk->wallets->getWalletSummary($request); @@ -594,7 +591,7 @@ $sdk = SDK::builder() try { $request = new ListBalancesRequest(); - $request->id = '9cdb1a84-22bb-4679-9232-2715bf0cbb1e'; + $request->id = '8422bb67-9d23-4227-95bf-0cbb1e31b8b9'; $response = $sdk->wallets->listBalances($request); @@ -641,10 +638,10 @@ try { $request = new ListWalletsRequest(); $request->cursor = 'aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ=='; $request->metadata = [ - 'veritatis' => 'nobis', + 'delectus' => 'dolorem', ]; - $request->name = 'Dr. Randolph McDermott'; - $request->pageSize = 292147; + $request->name = 'Clara Fisher Jr.'; + $request->pageSize = 16429; $response = $sdk->wallets->listWallets($request); @@ -692,10 +689,11 @@ try { $request = new UpdateWalletRequest(); $request->requestBody = new UpdateWalletRequestBody(); $request->requestBody->metadata = [ - 'adipisci' => 'dolorum', - 'architecto' => 'quae', + 'itaque' => 'consequatur', + 'est' => 'repellendus', + 'porro' => 'doloribus', ]; - $request->id = '08e0adcf-4b92-4187-9fce-953f73ef7fbc'; + $request->id = '4b921879-fce9-453f-b3ef-7fbc7abd74dd'; $response = $sdk->wallets->updateWallet($request); @@ -740,7 +738,7 @@ $sdk = SDK::builder() try { $request = new VoidHoldRequest(); - $request->holdId = 'odio'; + $request->holdId = 'sequi'; $response = $sdk->wallets->voidHold($request); diff --git a/sdks/php/files.gen b/sdks/php/files.gen index 7b86e3995..8e91e55db 100755 --- a/sdks/php/files.gen +++ b/sdks/php/files.gen @@ -62,7 +62,6 @@ src/Models/Operations/AddMetadataOnTransactionRequest.php src/Models/Operations/AddMetadataOnTransactionResponse.php src/Models/Operations/AddMetadataToAccountRequest.php src/Models/Operations/AddMetadataToAccountResponse.php -src/Models/Operations/CountAccountsMetadata.php src/Models/Operations/CountAccountsRequest.php src/Models/Operations/CountAccountsResponse.php src/Models/Operations/CountTransactionsRequest.php @@ -71,8 +70,6 @@ src/Models/Operations/CreateTransactionRequest.php src/Models/Operations/CreateTransactionResponse.php src/Models/Operations/GetAccountRequest.php src/Models/Operations/GetAccountResponse.php -src/Models/Operations/GetBalancesRequest.php -src/Models/Operations/GetBalancesResponse.php src/Models/Operations/GetBalancesAggregatedRequest.php src/Models/Operations/GetBalancesAggregatedResponse.php src/Models/Operations/GetInfoResponse.php @@ -222,8 +219,6 @@ src/Models/Shared/PostTransactionScript.php src/Models/Shared/PostTransaction.php src/Models/Shared/AccountResponse.php src/Models/Shared/AccountWithVolumesAndBalances.php -src/Models/Shared/BalancesCursorResponseCursor.php -src/Models/Shared/BalancesCursorResponse.php src/Models/Shared/AggregateBalancesResponse.php src/Models/Shared/ConfigInfoResponse.php src/Models/Shared/ConfigInfo.php @@ -461,7 +456,6 @@ docs/models/operations/AddMetadataOnTransactionRequest.md docs/models/operations/AddMetadataOnTransactionResponse.md docs/models/operations/AddMetadataToAccountRequest.md docs/models/operations/AddMetadataToAccountResponse.md -docs/models/operations/CountAccountsMetadata.md docs/models/operations/CountAccountsRequest.md docs/models/operations/CountAccountsResponse.md docs/models/operations/CountTransactionsRequest.md @@ -470,8 +464,6 @@ docs/models/operations/CreateTransactionRequest.md docs/models/operations/CreateTransactionResponse.md docs/models/operations/GetAccountRequest.md docs/models/operations/GetAccountResponse.md -docs/models/operations/GetBalancesRequest.md -docs/models/operations/GetBalancesResponse.md docs/models/operations/GetBalancesAggregatedRequest.md docs/models/operations/GetBalancesAggregatedResponse.md docs/models/operations/GetInfoResponse.md @@ -621,8 +613,6 @@ docs/models/shared/PostTransactionScript.md docs/models/shared/PostTransaction.md docs/models/shared/AccountResponse.md docs/models/shared/AccountWithVolumesAndBalances.md -docs/models/shared/BalancesCursorResponseCursor.md -docs/models/shared/BalancesCursorResponse.md docs/models/shared/AggregateBalancesResponse.md docs/models/shared/ConfigInfoResponse.md docs/models/shared/ConfigInfo.md diff --git a/sdks/php/gen.yaml b/sdks/php/gen.yaml index d90ad2c84..2df8e59e7 100755 --- a/sdks/php/gen.yaml +++ b/sdks/php/gen.yaml @@ -7,6 +7,7 @@ features: php: core: 2.85.3 deprecations: 2.81.1 + getRequestBodies: 2.81.1 globalSecurity: 2.81.1 globalServerURLs: 2.82.0 php: diff --git a/sdks/php/src/Ledger.php b/sdks/php/src/Ledger.php index e8d6746ed..fb424f8b7 100755 --- a/sdks/php/src/Ledger.php +++ b/sdks/php/src/Ledger.php @@ -32,7 +32,7 @@ public function addMetadataOnTransaction( ): \formance\stack\Models\Operations\AddMetadataOnTransactionResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/transactions/{txid}/metadata', \formance\stack\Models\Operations\AddMetadataOnTransactionRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/transactions/{id}/metadata', \formance\stack\Models\Operations\AddMetadataOnTransactionRequest::class, $request); $options = ['http_errors' => false]; $body = Utils\Utils::serializeRequestBody($request, "requestBody", "json"); @@ -79,7 +79,7 @@ public function addMetadataToAccount( ): \formance\stack\Models\Operations\AddMetadataToAccountResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/accounts/{address}/metadata', \formance\stack\Models\Operations\AddMetadataToAccountRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/accounts/{address}/metadata', \formance\stack\Models\Operations\AddMetadataToAccountRequest::class, $request); $options = ['http_errors' => false]; $body = Utils\Utils::serializeRequestBody($request, "requestBody", "json"); @@ -127,10 +127,13 @@ public function countAccounts( ): \formance\stack\Models\Operations\CountAccountsResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/accounts', \formance\stack\Models\Operations\CountAccountsRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/accounts', \formance\stack\Models\Operations\CountAccountsRequest::class, $request); $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\CountAccountsRequest::class, $request, null)); + $body = Utils\Utils::serializeRequestBody($request, "requestBody", "json"); + if ($body !== null) { + $options = array_merge_recursive($options, $body); + } $options['headers']['Accept'] = 'application/json'; $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s %s', $this->sdkConfiguration->language, $this->sdkConfiguration->sdkVersion, $this->sdkConfiguration->genVersion, $this->sdkConfiguration->openapiDocVersion); @@ -168,9 +171,13 @@ public function countTransactions( ): \formance\stack\Models\Operations\CountTransactionsResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/transactions', \formance\stack\Models\Operations\CountTransactionsRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/transactions', \formance\stack\Models\Operations\CountTransactionsRequest::class, $request); $options = ['http_errors' => false]; + $body = Utils\Utils::serializeRequestBody($request, "requestBody", "json"); + if ($body !== null) { + $options = array_merge_recursive($options, $body); + } $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\CountTransactionsRequest::class, $request, null)); $options['headers']['Accept'] = 'application/json'; $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s %s', $this->sdkConfiguration->language, $this->sdkConfiguration->sdkVersion, $this->sdkConfiguration->genVersion, $this->sdkConfiguration->openapiDocVersion); @@ -209,7 +216,7 @@ public function createTransaction( ): \formance\stack\Models\Operations\CreateTransactionResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/transactions', \formance\stack\Models\Operations\CreateTransactionRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/transactions', \formance\stack\Models\Operations\CreateTransactionRequest::class, $request); $options = ['http_errors' => false]; $body = Utils\Utils::serializeRequestBody($request, "postTransaction", "json"); @@ -261,9 +268,10 @@ public function getAccount( ): \formance\stack\Models\Operations\GetAccountResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/accounts/{address}', \formance\stack\Models\Operations\GetAccountRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/accounts/{address}', \formance\stack\Models\Operations\GetAccountRequest::class, $request); $options = ['http_errors' => false]; + $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\GetAccountRequest::class, $request, null)); $options['headers']['Accept'] = 'application/json'; $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s %s', $this->sdkConfiguration->language, $this->sdkConfiguration->sdkVersion, $this->sdkConfiguration->genVersion, $this->sdkConfiguration->openapiDocVersion); @@ -292,49 +300,6 @@ public function getAccount( return $response; } - /** - * Get the balances from a ledger's account - * - * @param \formance\stack\Models\Operations\GetBalancesRequest $request - * @return \formance\stack\Models\Operations\GetBalancesResponse - */ - public function getBalances( - ?\formance\stack\Models\Operations\GetBalancesRequest $request, - ): \formance\stack\Models\Operations\GetBalancesResponse - { - $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/balances', \formance\stack\Models\Operations\GetBalancesRequest::class, $request); - - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\GetBalancesRequest::class, $request, null)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s %s', $this->sdkConfiguration->language, $this->sdkConfiguration->sdkVersion, $this->sdkConfiguration->genVersion, $this->sdkConfiguration->openapiDocVersion); - - $httpResponse = $this->sdkConfiguration->securityClient->request('GET', $url, $options); - - $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; - - $response = new \formance\stack\Models\Operations\GetBalancesResponse(); - $response->statusCode = $httpResponse->getStatusCode(); - $response->contentType = $contentType; - $response->rawResponse = $httpResponse; - - if ($httpResponse->getStatusCode() === 200) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $response->balancesCursorResponse = $serializer->deserialize((string)$httpResponse->getBody(), 'formance\stack\Models\Shared\BalancesCursorResponse', 'json'); - } - } - else { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $response->errorResponse = $serializer->deserialize((string)$httpResponse->getBody(), 'formance\stack\Models\Shared\ErrorResponse', 'json'); - } - } - - return $response; - } - /** * Get the aggregated balances from selected accounts * @@ -346,10 +311,9 @@ public function getBalancesAggregated( ): \formance\stack\Models\Operations\GetBalancesAggregatedResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/aggregate/balances', \formance\stack\Models\Operations\GetBalancesAggregatedRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/aggregate/balances', \formance\stack\Models\Operations\GetBalancesAggregatedRequest::class, $request); $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\GetBalancesAggregatedRequest::class, $request, null)); $options['headers']['Accept'] = 'application/json'; $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s %s', $this->sdkConfiguration->language, $this->sdkConfiguration->sdkVersion, $this->sdkConfiguration->genVersion, $this->sdkConfiguration->openapiDocVersion); @@ -387,7 +351,7 @@ public function getInfo( ): \formance\stack\Models\Operations\GetInfoResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/_info'); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/_info'); $options = ['http_errors' => false]; $options['headers']['Accept'] = 'application/json'; @@ -429,7 +393,7 @@ public function getLedgerInfo( ): \formance\stack\Models\Operations\GetLedgerInfoResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/_info', \formance\stack\Models\Operations\GetLedgerInfoRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/_info', \formance\stack\Models\Operations\GetLedgerInfoRequest::class, $request); $options = ['http_errors' => false]; $options['headers']['Accept'] = 'application/json'; @@ -471,9 +435,10 @@ public function getTransaction( ): \formance\stack\Models\Operations\GetTransactionResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/transactions/{txid}', \formance\stack\Models\Operations\GetTransactionRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/transactions/{id}', \formance\stack\Models\Operations\GetTransactionRequest::class, $request); $options = ['http_errors' => false]; + $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\GetTransactionRequest::class, $request, null)); $options['headers']['Accept'] = 'application/json'; $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s %s', $this->sdkConfiguration->language, $this->sdkConfiguration->sdkVersion, $this->sdkConfiguration->genVersion, $this->sdkConfiguration->openapiDocVersion); @@ -515,9 +480,13 @@ public function listAccounts( ): \formance\stack\Models\Operations\ListAccountsResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/accounts', \formance\stack\Models\Operations\ListAccountsRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/accounts', \formance\stack\Models\Operations\ListAccountsRequest::class, $request); $options = ['http_errors' => false]; + $body = Utils\Utils::serializeRequestBody($request, "requestBody", "json"); + if ($body !== null) { + $options = array_merge_recursive($options, $body); + } $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\ListAccountsRequest::class, $request, null)); $options['headers']['Accept'] = 'application/json'; $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s %s', $this->sdkConfiguration->language, $this->sdkConfiguration->sdkVersion, $this->sdkConfiguration->genVersion, $this->sdkConfiguration->openapiDocVersion); @@ -560,9 +529,13 @@ public function listLogs( ): \formance\stack\Models\Operations\ListLogsResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/logs', \formance\stack\Models\Operations\ListLogsRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/logs', \formance\stack\Models\Operations\ListLogsRequest::class, $request); $options = ['http_errors' => false]; + $body = Utils\Utils::serializeRequestBody($request, "requestBody", "json"); + if ($body !== null) { + $options = array_merge_recursive($options, $body); + } $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\ListLogsRequest::class, $request, null)); $options['headers']['Accept'] = 'application/json'; $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s %s', $this->sdkConfiguration->language, $this->sdkConfiguration->sdkVersion, $this->sdkConfiguration->genVersion, $this->sdkConfiguration->openapiDocVersion); @@ -595,7 +568,7 @@ public function listLogs( /** * List transactions from a ledger * - * List transactions from a ledger, sorted by txid in descending order. + * List transactions from a ledger, sorted by id in descending order. * * @param \formance\stack\Models\Operations\ListTransactionsRequest $request * @return \formance\stack\Models\Operations\ListTransactionsResponse @@ -605,9 +578,13 @@ public function listTransactions( ): \formance\stack\Models\Operations\ListTransactionsResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/transactions', \formance\stack\Models\Operations\ListTransactionsRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/transactions', \formance\stack\Models\Operations\ListTransactionsRequest::class, $request); $options = ['http_errors' => false]; + $body = Utils\Utils::serializeRequestBody($request, "requestBody", "json"); + if ($body !== null) { + $options = array_merge_recursive($options, $body); + } $options = array_merge_recursive($options, Utils\Utils::getQueryParams(\formance\stack\Models\Operations\ListTransactionsRequest::class, $request, null)); $options['headers']['Accept'] = 'application/json'; $options['headers']['user-agent'] = sprintf('speakeasy-sdk/%s %s %s %s', $this->sdkConfiguration->language, $this->sdkConfiguration->sdkVersion, $this->sdkConfiguration->genVersion, $this->sdkConfiguration->openapiDocVersion); @@ -651,7 +628,7 @@ public function readStats( ): \formance\stack\Models\Operations\ReadStatsResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/stats', \formance\stack\Models\Operations\ReadStatsRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/stats', \formance\stack\Models\Operations\ReadStatsRequest::class, $request); $options = ['http_errors' => false]; $options['headers']['Accept'] = 'application/json'; @@ -693,7 +670,7 @@ public function revertTransaction( ): \formance\stack\Models\Operations\RevertTransactionResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/{ledger}/transactions/{txid}/revert', \formance\stack\Models\Operations\RevertTransactionRequest::class, $request); + $url = Utils\Utils::generateUrl($baseUrl, '/api/ledger/v2/{ledger}/transactions/{id}/revert', \formance\stack\Models\Operations\RevertTransactionRequest::class, $request); $options = ['http_errors' => false]; $options['headers']['Accept'] = 'application/json'; diff --git a/sdks/php/src/Models/Operations/AddMetadataOnTransactionRequest.php b/sdks/php/src/Models/Operations/AddMetadataOnTransactionRequest.php index e1eef5d0b..2a1ba009a 100755 --- a/sdks/php/src/Models/Operations/AddMetadataOnTransactionRequest.php +++ b/sdks/php/src/Models/Operations/AddMetadataOnTransactionRequest.php @@ -27,14 +27,6 @@ class AddMetadataOnTransactionRequest #[SpeakeasyMetadata('request:mediaType=application/json')] public ?array $requestBody = null; - /** - * Set async mode. - * - * @var ?bool $async - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=async')] - public ?bool $async = null; - /** * Set the dryRun mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. * @@ -44,28 +36,27 @@ class AddMetadataOnTransactionRequest public ?bool $dryRun = null; /** - * Name of the ledger. + * Transaction ID. * - * @var string $ledger + * @var int $id */ - #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=ledger')] - public string $ledger; + #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=id')] + public int $id; /** - * Transaction ID. + * Name of the ledger. * - * @var int $txid + * @var string $ledger */ - #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=txid')] - public int $txid; + #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=ledger')] + public string $ledger; public function __construct() { $this->idempotencyKey = null; $this->requestBody = null; - $this->async = null; $this->dryRun = null; + $this->id = 0; $this->ledger = ""; - $this->txid = 0; } } diff --git a/sdks/php/src/Models/Operations/AddMetadataToAccountRequest.php b/sdks/php/src/Models/Operations/AddMetadataToAccountRequest.php index 0fa4d6e27..9d6ddf9a5 100755 --- a/sdks/php/src/Models/Operations/AddMetadataToAccountRequest.php +++ b/sdks/php/src/Models/Operations/AddMetadataToAccountRequest.php @@ -40,14 +40,6 @@ class AddMetadataToAccountRequest #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=address')] public string $address; - /** - * Set async mode. - * - * @var ?bool $async - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=async')] - public ?bool $async = null; - /** * Set the dry run mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. * @@ -69,7 +61,6 @@ public function __construct() $this->idempotencyKey = null; $this->requestBody = []; $this->address = ""; - $this->async = null; $this->dryRun = null; $this->ledger = ""; } diff --git a/sdks/php/src/Models/Operations/CountAccountsMetadata.php b/sdks/php/src/Models/Operations/CountAccountsMetadata.php deleted file mode 100755 index 6062a7807..000000000 --- a/sdks/php/src/Models/Operations/CountAccountsMetadata.php +++ /dev/null @@ -1,23 +0,0 @@ - metadata[key]=value1&metadata[a.nested.key]=value2 - * - * @package formance\stack\Models\Operations - * @access public - */ -class CountAccountsMetadata -{ - public function __construct() - { - } -} diff --git a/sdks/php/src/Models/Operations/CountAccountsRequest.php b/sdks/php/src/Models/Operations/CountAccountsRequest.php index 8d161ed67..e1f4ffc0a 100755 --- a/sdks/php/src/Models/Operations/CountAccountsRequest.php +++ b/sdks/php/src/Models/Operations/CountAccountsRequest.php @@ -12,12 +12,12 @@ class CountAccountsRequest { /** - * Filter accounts by address pattern (regular expression placed between ^ and $). + * $requestBody * - * @var ?string $address + * @var ?array $requestBody */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=address')] - public ?string $address = null; + #[SpeakeasyMetadata('request:mediaType=application/json')] + public ?array $requestBody = null; /** * Name of the ledger. @@ -27,18 +27,9 @@ class CountAccountsRequest #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=ledger')] public string $ledger; - /** - * Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - * - * @var ?\formance\stack\Models\Operations\CountAccountsMetadata $metadata - */ - #[SpeakeasyMetadata('queryParam:style=deepObject,explode=true,name=metadata')] - public ?CountAccountsMetadata $metadata = null; - public function __construct() { - $this->address = null; + $this->requestBody = null; $this->ledger = ""; - $this->metadata = null; } } diff --git a/sdks/php/src/Models/Operations/CountTransactionsRequest.php b/sdks/php/src/Models/Operations/CountTransactionsRequest.php index 664438c93..621bed81f 100755 --- a/sdks/php/src/Models/Operations/CountTransactionsRequest.php +++ b/sdks/php/src/Models/Operations/CountTransactionsRequest.php @@ -12,31 +12,12 @@ class CountTransactionsRequest { /** - * Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). + * $requestBody * - * @var ?string $account + * @var ?array $requestBody */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=account')] - public ?string $account = null; - - /** - * Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). - * - * @var ?string $destination - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=destination')] - public ?string $destination = null; - - /** - * Filter transactions that occurred before this timestamp. - * - * The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - * - * - * @var ?\DateTime $endTime - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=endTime,dateTimeFormat=Y-m-d\TH:i:s.up')] - public ?\DateTime $endTime = null; + #[SpeakeasyMetadata('request:mediaType=application/json')] + public ?array $requestBody = null; /** * Name of the ledger. @@ -46,50 +27,13 @@ class CountTransactionsRequest #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=ledger')] public string $ledger; - /** - * Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - * - * @var ?array $metadata - */ - #[SpeakeasyMetadata('queryParam:style=deepObject,explode=true,name=metadata')] - public ?array $metadata = null; - - /** - * Filter transactions by reference field. - * - * @var ?string $reference - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=reference')] - public ?string $reference = null; - - /** - * Filter transactions with postings involving given account at source (regular expression placed between ^ and $). - * - * @var ?string $source - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=source')] - public ?string $source = null; - - /** - * Filter transactions that occurred after this timestamp. - * - * The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - * - * - * @var ?\DateTime $startTime - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=startTime,dateTimeFormat=Y-m-d\TH:i:s.up')] - public ?\DateTime $startTime = null; + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=pit,dateTimeFormat=Y-m-d\TH:i:s.up')] + public ?\DateTime $pit = null; public function __construct() { - $this->account = null; - $this->destination = null; - $this->endTime = null; + $this->requestBody = null; $this->ledger = ""; - $this->metadata = null; - $this->reference = null; - $this->source = null; - $this->startTime = null; + $this->pit = null; } } diff --git a/sdks/php/src/Models/Operations/CountTransactionsRequestBody.php b/sdks/php/src/Models/Operations/CountTransactionsRequestBody.php deleted file mode 100755 index b988e0fd9..000000000 --- a/sdks/php/src/Models/Operations/CountTransactionsRequestBody.php +++ /dev/null @@ -1,17 +0,0 @@ -idempotencyKey = null; $this->postTransaction = new \formance\stack\Models\Shared\PostTransaction(); - $this->async = null; $this->dryRun = null; $this->ledger = ""; } diff --git a/sdks/php/src/Models/Operations/GetAccountRequest.php b/sdks/php/src/Models/Operations/GetAccountRequest.php index 60ddb0c8f..93546ecaf 100755 --- a/sdks/php/src/Models/Operations/GetAccountRequest.php +++ b/sdks/php/src/Models/Operations/GetAccountRequest.php @@ -24,6 +24,9 @@ class GetAccountRequest #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=address')] public string $address; + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=expand')] + public ?string $expand = null; + /** * Name of the ledger. * @@ -35,6 +38,7 @@ class GetAccountRequest public function __construct() { $this->address = ""; + $this->expand = null; $this->ledger = ""; } } diff --git a/sdks/php/src/Models/Operations/GetBalancesAggregatedRequest.php b/sdks/php/src/Models/Operations/GetBalancesAggregatedRequest.php index 34b959509..aa5cf72bd 100755 --- a/sdks/php/src/Models/Operations/GetBalancesAggregatedRequest.php +++ b/sdks/php/src/Models/Operations/GetBalancesAggregatedRequest.php @@ -11,14 +11,6 @@ use \formance\stack\Utils\SpeakeasyMetadata; class GetBalancesAggregatedRequest { - /** - * Filter balances involving given account, either as source or destination. - * - * @var ?string $address - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=address')] - public ?string $address = null; - /** * Name of the ledger. * @@ -29,7 +21,6 @@ class GetBalancesAggregatedRequest public function __construct() { - $this->address = null; $this->ledger = ""; } } diff --git a/sdks/php/src/Models/Operations/GetBalancesRequest.php b/sdks/php/src/Models/Operations/GetBalancesRequest.php deleted file mode 100755 index e91ea369e..000000000 --- a/sdks/php/src/Models/Operations/GetBalancesRequest.php +++ /dev/null @@ -1,60 +0,0 @@ -address = null; - $this->cursor = null; - $this->ledger = ""; - $this->pageSize = null; - } -} diff --git a/sdks/php/src/Models/Operations/GetBalancesResponse.php b/sdks/php/src/Models/Operations/GetBalancesResponse.php deleted file mode 100755 index 9f223041d..000000000 --- a/sdks/php/src/Models/Operations/GetBalancesResponse.php +++ /dev/null @@ -1,47 +0,0 @@ -balancesCursorResponse = null; - $this->contentType = ""; - $this->errorResponse = null; - $this->statusCode = 0; - $this->rawResponse = null; - } -} diff --git a/sdks/php/src/Models/Operations/GetTransactionRequest.php b/sdks/php/src/Models/Operations/GetTransactionRequest.php index 559f21f67..c1bd0a761 100755 --- a/sdks/php/src/Models/Operations/GetTransactionRequest.php +++ b/sdks/php/src/Models/Operations/GetTransactionRequest.php @@ -11,25 +11,29 @@ use \formance\stack\Utils\SpeakeasyMetadata; class GetTransactionRequest { + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=expand')] + public ?string $expand = null; + /** - * Name of the ledger. + * Transaction ID. * - * @var string $ledger + * @var int $id */ - #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=ledger')] - public string $ledger; + #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=id')] + public int $id; /** - * Transaction ID. + * Name of the ledger. * - * @var int $txid + * @var string $ledger */ - #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=txid')] - public int $txid; + #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=ledger')] + public string $ledger; public function __construct() { + $this->expand = null; + $this->id = 0; $this->ledger = ""; - $this->txid = 0; } } diff --git a/sdks/php/src/Models/Operations/ListAccountsRequest.php b/sdks/php/src/Models/Operations/ListAccountsRequest.php index fe5419f60..cf138fb78 100755 --- a/sdks/php/src/Models/Operations/ListAccountsRequest.php +++ b/sdks/php/src/Models/Operations/ListAccountsRequest.php @@ -12,12 +12,12 @@ class ListAccountsRequest { /** - * Filter accounts by address pattern (regular expression placed between ^ and $). + * $requestBody * - * @var ?string $address + * @var ?array $requestBody */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=address')] - public ?string $address = null; + #[SpeakeasyMetadata('request:mediaType=application/json')] + public ?array $requestBody = null; /** * Parameter used in pagination requests. Maximum page size is set to 15. @@ -32,6 +32,9 @@ class ListAccountsRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=cursor')] public ?string $cursor = null; + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=expand')] + public ?string $expand = null; + /** * Name of the ledger. * @@ -40,14 +43,6 @@ class ListAccountsRequest #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=ledger')] public string $ledger; - /** - * Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - * - * @var ?array $metadata - */ - #[SpeakeasyMetadata('queryParam:style=deepObject,explode=true,name=metadata')] - public ?array $metadata = null; - /** * The maximum number of results to return per page. * @@ -58,12 +53,16 @@ class ListAccountsRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=pageSize')] public ?int $pageSize = null; + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=pit,dateTimeFormat=Y-m-d\TH:i:s.up')] + public ?\DateTime $pit = null; + public function __construct() { - $this->address = null; + $this->requestBody = null; $this->cursor = null; + $this->expand = null; $this->ledger = ""; - $this->metadata = null; $this->pageSize = null; + $this->pit = null; } } diff --git a/sdks/php/src/Models/Operations/ListAccountsRequestBody.php b/sdks/php/src/Models/Operations/ListAccountsRequestBody.php deleted file mode 100755 index 29e43e79f..000000000 --- a/sdks/php/src/Models/Operations/ListAccountsRequestBody.php +++ /dev/null @@ -1,17 +0,0 @@ - $requestBody + */ + #[SpeakeasyMetadata('request:mediaType=application/json')] + public ?array $requestBody = null; + /** * Parameter used in pagination requests. Maximum page size is set to 15. * @@ -24,17 +32,6 @@ class ListLogsRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=cursor')] public ?string $cursor = null; - /** - * Filter transactions that occurred before this timestamp. - * - * The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - * - * - * @var ?\DateTime $endTime - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=endTime,dateTimeFormat=Y-m-d\TH:i:s.up')] - public ?\DateTime $endTime = null; - /** * Name of the ledger. * @@ -53,23 +50,15 @@ class ListLogsRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=pageSize')] public ?int $pageSize = null; - /** - * Filter transactions that occurred after this timestamp. - * - * The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - * - * - * @var ?\DateTime $startTime - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=startTime,dateTimeFormat=Y-m-d\TH:i:s.up')] - public ?\DateTime $startTime = null; + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=pit,dateTimeFormat=Y-m-d\TH:i:s.up')] + public ?\DateTime $pit = null; public function __construct() { + $this->requestBody = null; $this->cursor = null; - $this->endTime = null; $this->ledger = ""; $this->pageSize = null; - $this->startTime = null; + $this->pit = null; } } diff --git a/sdks/php/src/Models/Operations/ListLogsRequestBody.php b/sdks/php/src/Models/Operations/ListLogsRequestBody.php deleted file mode 100755 index 0e5286287..000000000 --- a/sdks/php/src/Models/Operations/ListLogsRequestBody.php +++ /dev/null @@ -1,17 +0,0 @@ - $requestBody */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=account')] - public ?string $account = null; + #[SpeakeasyMetadata('request:mediaType=application/json')] + public ?array $requestBody = null; /** * Parameter used in pagination requests. Maximum page size is set to 15. @@ -32,24 +32,8 @@ class ListTransactionsRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=cursor')] public ?string $cursor = null; - /** - * Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). - * - * @var ?string $destination - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=destination')] - public ?string $destination = null; - - /** - * Filter transactions that occurred before this timestamp. - * - * The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - * - * - * @var ?\DateTime $endTime - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=endTime,dateTimeFormat=Y-m-d\TH:i:s.up')] - public ?\DateTime $endTime = null; + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=expand')] + public ?string $expand = null; /** * Name of the ledger. @@ -59,14 +43,6 @@ class ListTransactionsRequest #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=ledger')] public string $ledger; - /** - * Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below. - * - * @var ?array $metadata - */ - #[SpeakeasyMetadata('queryParam:style=deepObject,explode=true,name=metadata')] - public ?array $metadata = null; - /** * The maximum number of results to return per page. * @@ -77,44 +53,16 @@ class ListTransactionsRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=pageSize')] public ?int $pageSize = null; - /** - * Find transactions by reference field. - * - * @var ?string $reference - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=reference')] - public ?string $reference = null; - - /** - * Filter transactions with postings involving given account at source (regular expression placed between ^ and $). - * - * @var ?string $source - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=source')] - public ?string $source = null; - - /** - * Filter transactions that occurred after this timestamp. - * - * The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - * - * - * @var ?\DateTime $startTime - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=startTime,dateTimeFormat=Y-m-d\TH:i:s.up')] - public ?\DateTime $startTime = null; + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=pit,dateTimeFormat=Y-m-d\TH:i:s.up')] + public ?\DateTime $pit = null; public function __construct() { - $this->account = null; + $this->requestBody = null; $this->cursor = null; - $this->destination = null; - $this->endTime = null; + $this->expand = null; $this->ledger = ""; - $this->metadata = null; $this->pageSize = null; - $this->reference = null; - $this->source = null; - $this->startTime = null; + $this->pit = null; } } diff --git a/sdks/php/src/Models/Operations/ListTransactionsRequestBody.php b/sdks/php/src/Models/Operations/ListTransactionsRequestBody.php deleted file mode 100755 index c6f712e3d..000000000 --- a/sdks/php/src/Models/Operations/ListTransactionsRequestBody.php +++ /dev/null @@ -1,17 +0,0 @@ -id = 0; $this->ledger = ""; - $this->txid = 0; } } diff --git a/sdks/php/src/Models/Shared/AccountWithVolumesAndBalances.php b/sdks/php/src/Models/Shared/AccountWithVolumesAndBalances.php index 69e6f3238..d2ba2ca50 100755 --- a/sdks/php/src/Models/Shared/AccountWithVolumesAndBalances.php +++ b/sdks/php/src/Models/Shared/AccountWithVolumesAndBalances.php @@ -15,15 +15,6 @@ class AccountWithVolumesAndBalances #[\JMS\Serializer\Annotation\Type('string')] public string $address; - /** - * $balances - * - * @var array $balances - */ - #[\JMS\Serializer\Annotation\SerializedName('balances')] - #[\JMS\Serializer\Annotation\Type('array')] - public array $balances; - /** * $metadata * @@ -41,18 +32,18 @@ class AccountWithVolumesAndBalances /** * $volumes * - * @var array> $volumes + * @var ?array> $volumes */ #[\JMS\Serializer\Annotation\SerializedName('volumes')] #[\JMS\Serializer\Annotation\Type('array>')] - public array $volumes; + #[\JMS\Serializer\Annotation\SkipWhenEmpty] + public ?array $volumes = null; public function __construct() { $this->address = ""; - $this->balances = []; $this->metadata = []; $this->type = null; - $this->volumes = []; + $this->volumes = null; } } diff --git a/sdks/php/src/Models/Shared/BalancesCursorResponse.php b/sdks/php/src/Models/Shared/BalancesCursorResponse.php deleted file mode 100755 index 53d33f19d..000000000 --- a/sdks/php/src/Models/Shared/BalancesCursorResponse.php +++ /dev/null @@ -1,28 +0,0 @@ -cursor = new \formance\stack\Models\Shared\BalancesCursorResponseCursor(); - } -} diff --git a/sdks/php/src/Models/Shared/BalancesCursorResponseCursor.php b/sdks/php/src/Models/Shared/BalancesCursorResponseCursor.php deleted file mode 100755 index fecff2380..000000000 --- a/sdks/php/src/Models/Shared/BalancesCursorResponseCursor.php +++ /dev/null @@ -1,49 +0,0 @@ ->> $data - */ - #[\JMS\Serializer\Annotation\SerializedName('data')] - #[\JMS\Serializer\Annotation\Type('array>>')] - public array $data; - - #[\JMS\Serializer\Annotation\SerializedName('hasMore')] - #[\JMS\Serializer\Annotation\Type('bool')] - public bool $hasMore; - - #[\JMS\Serializer\Annotation\SerializedName('next')] - #[\JMS\Serializer\Annotation\Type('string')] - #[\JMS\Serializer\Annotation\SkipWhenEmpty] - public ?string $next = null; - - #[\JMS\Serializer\Annotation\SerializedName('pageSize')] - #[\JMS\Serializer\Annotation\Type('int')] - public int $pageSize; - - #[\JMS\Serializer\Annotation\SerializedName('previous')] - #[\JMS\Serializer\Annotation\Type('string')] - #[\JMS\Serializer\Annotation\SkipWhenEmpty] - public ?string $previous = null; - - public function __construct() - { - $this->data = []; - $this->hasMore = false; - $this->next = null; - $this->pageSize = 0; - $this->previous = null; - } -} diff --git a/sdks/php/src/Models/Shared/ExpandedTransaction.php b/sdks/php/src/Models/Shared/ExpandedTransaction.php index 222ca5ca8..2acefe474 100755 --- a/sdks/php/src/Models/Shared/ExpandedTransaction.php +++ b/sdks/php/src/Models/Shared/ExpandedTransaction.php @@ -11,6 +11,10 @@ class ExpandedTransaction { + #[\JMS\Serializer\Annotation\SerializedName('id')] + #[\JMS\Serializer\Annotation\Type('int')] + public int $id; + /** * $metadata * @@ -23,11 +27,12 @@ class ExpandedTransaction /** * $postCommitVolumes * - * @var array> $postCommitVolumes + * @var ?array> $postCommitVolumes */ #[\JMS\Serializer\Annotation\SerializedName('postCommitVolumes')] #[\JMS\Serializer\Annotation\Type('array>')] - public array $postCommitVolumes; + #[\JMS\Serializer\Annotation\SkipWhenEmpty] + public ?array $postCommitVolumes = null; /** * $postings @@ -41,33 +46,35 @@ class ExpandedTransaction /** * $preCommitVolumes * - * @var array> $preCommitVolumes + * @var ?array> $preCommitVolumes */ #[\JMS\Serializer\Annotation\SerializedName('preCommitVolumes')] #[\JMS\Serializer\Annotation\Type('array>')] - public array $preCommitVolumes; + #[\JMS\Serializer\Annotation\SkipWhenEmpty] + public ?array $preCommitVolumes = null; #[\JMS\Serializer\Annotation\SerializedName('reference')] #[\JMS\Serializer\Annotation\Type('string')] #[\JMS\Serializer\Annotation\SkipWhenEmpty] public ?string $reference = null; + #[\JMS\Serializer\Annotation\SerializedName('reverted')] + #[\JMS\Serializer\Annotation\Type('bool')] + public bool $reverted; + #[\JMS\Serializer\Annotation\SerializedName('timestamp')] #[\JMS\Serializer\Annotation\Type("DateTime<'Y-m-d\TH:i:s.up'>")] public \DateTime $timestamp; - #[\JMS\Serializer\Annotation\SerializedName('txid')] - #[\JMS\Serializer\Annotation\Type('int')] - public int $txid; - public function __construct() { + $this->id = 0; $this->metadata = []; - $this->postCommitVolumes = []; + $this->postCommitVolumes = null; $this->postings = []; - $this->preCommitVolumes = []; + $this->preCommitVolumes = null; $this->reference = null; + $this->reverted = false; $this->timestamp = new \DateTime(); - $this->txid = 0; } } diff --git a/sdks/php/src/Models/Shared/PostTransactionScriptVars.php b/sdks/php/src/Models/Shared/PostTransactionScriptVars.php new file mode 100755 index 000000000..41d34d68c --- /dev/null +++ b/sdks/php/src/Models/Shared/PostTransactionScriptVars.php @@ -0,0 +1,17 @@ +")] public \DateTime $timestamp; - #[\JMS\Serializer\Annotation\SerializedName('txid')] - #[\JMS\Serializer\Annotation\Type('int')] - public int $txid; - public function __construct() { + $this->id = 0; $this->metadata = []; $this->postings = []; $this->reference = null; + $this->reverted = false; $this->timestamp = new \DateTime(); - $this->txid = 0; } } diff --git a/sdks/php/src/Models/Shared/WalletsTransaction.php b/sdks/php/src/Models/Shared/WalletsTransaction.php index eee370f52..ebc4ee06e 100755 --- a/sdks/php/src/Models/Shared/WalletsTransaction.php +++ b/sdks/php/src/Models/Shared/WalletsTransaction.php @@ -11,6 +11,11 @@ class WalletsTransaction { + #[\JMS\Serializer\Annotation\SerializedName('id')] + #[\JMS\Serializer\Annotation\Type('int')] + #[\JMS\Serializer\Annotation\SkipWhenEmpty] + public ?int $id = null; + #[\JMS\Serializer\Annotation\SerializedName('ledger')] #[\JMS\Serializer\Annotation\Type('string')] #[\JMS\Serializer\Annotation\SkipWhenEmpty] @@ -63,12 +68,9 @@ class WalletsTransaction #[\JMS\Serializer\Annotation\Type("DateTime<'Y-m-d\TH:i:s.up'>")] public \DateTime $timestamp; - #[\JMS\Serializer\Annotation\SerializedName('txid')] - #[\JMS\Serializer\Annotation\Type('int')] - public int $txid; - public function __construct() { + $this->id = null; $this->ledger = null; $this->metadata = []; $this->postCommitVolumes = null; @@ -76,6 +78,5 @@ public function __construct() $this->preCommitVolumes = null; $this->reference = null; $this->timestamp = new \DateTime(); - $this->txid = 0; } } diff --git a/sdks/php/src/SDKConfiguration.php b/sdks/php/src/SDKConfiguration.php index ab55f595d..b0447102a 100755 --- a/sdks/php/src/SDKConfiguration.php +++ b/sdks/php/src/SDKConfiguration.php @@ -24,7 +24,7 @@ class SDKConfiguration ], ]; public string $language = 'php'; - public string $openapiDocVersion = 'v1.0.20230907'; + public string $openapiDocVersion = 'v1.0.20230908'; public string $sdkVersion = 'v0.1.0'; public string $genVersion = '2.96.3'; diff --git a/sdks/python/README.md b/sdks/python/README.md index 486bc9663..bdc6e2e44 100755 --- a/sdks/python/README.md +++ b/sdks/python/README.md @@ -78,7 +78,6 @@ if res.get_versions_response is not None: * [count_transactions](docs/sdks/ledger/README.md#count_transactions) - Count the transactions from a ledger * [create_transaction](docs/sdks/ledger/README.md#create_transaction) - Create a new transaction to a ledger * [get_account](docs/sdks/ledger/README.md#get_account) - Get account by its address -* [get_balances](docs/sdks/ledger/README.md#get_balances) - Get the balances from a ledger's account * [get_balances_aggregated](docs/sdks/ledger/README.md#get_balances_aggregated) - Get the aggregated balances from selected accounts * [get_info](docs/sdks/ledger/README.md#get_info) - Show server information * [get_ledger_info](docs/sdks/ledger/README.md#get_ledger_info) - Get information about a ledger diff --git a/sdks/python/docs/models/operations/addmetadataontransactionrequest.md b/sdks/python/docs/models/operations/addmetadataontransactionrequest.md index 7e548603e..e028535f6 100755 --- a/sdks/python/docs/models/operations/addmetadataontransactionrequest.md +++ b/sdks/python/docs/models/operations/addmetadataontransactionrequest.md @@ -7,7 +7,6 @@ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | `idempotency_key` | *Optional[str]* | :heavy_minus_sign: | Use an idempotency key | | | `request_body` | dict[str, *str*] | :heavy_minus_sign: | metadata | | -| `async_` | *Optional[bool]* | :heavy_minus_sign: | Set async mode. | true | | `dry_run` | *Optional[bool]* | :heavy_minus_sign: | Set the dryRun mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | -| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `id` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/addmetadatatoaccountrequest.md b/sdks/python/docs/models/operations/addmetadatatoaccountrequest.md index 6cc42d1b0..1e2f174d5 100755 --- a/sdks/python/docs/models/operations/addmetadatatoaccountrequest.md +++ b/sdks/python/docs/models/operations/addmetadatatoaccountrequest.md @@ -8,6 +8,5 @@ | `idempotency_key` | *Optional[str]* | :heavy_minus_sign: | Use an idempotency key | | | `request_body` | dict[str, *str*] | :heavy_check_mark: | metadata | | | `address` | *str* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | -| `async_` | *Optional[bool]* | :heavy_minus_sign: | Set async mode. | true | | `dry_run` | *Optional[bool]* | :heavy_minus_sign: | Set the dry run mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/countaccountsmetadata.md b/sdks/python/docs/models/operations/countaccountsmetadata.md deleted file mode 100755 index 7ea898a09..000000000 --- a/sdks/python/docs/models/operations/countaccountsmetadata.md +++ /dev/null @@ -1,9 +0,0 @@ -# CountAccountsMetadata - -Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/countaccountsrequest.md b/sdks/python/docs/models/operations/countaccountsrequest.md index 09396ba08..213c5bb12 100755 --- a/sdks/python/docs/models/operations/countaccountsrequest.md +++ b/sdks/python/docs/models/operations/countaccountsrequest.md @@ -3,8 +3,7 @@ ## Fields -| Field | Type | Required | Description | Example | -| ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *Optional[str]* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | -| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | [Optional[CountAccountsMetadata]](../../models/operations/countaccountsmetadata.md) | :heavy_minus_sign: | Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| `request_body` | dict[str, *Any*] | :heavy_minus_sign: | N/A | | +| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/counttransactionsrequest.md b/sdks/python/docs/models/operations/counttransactionsrequest.md index f01690b58..90c0013e8 100755 --- a/sdks/python/docs/models/operations/counttransactionsrequest.md +++ b/sdks/python/docs/models/operations/counttransactionsrequest.md @@ -3,13 +3,8 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `account` | *Optional[str]* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | -| `destination` | *Optional[str]* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `end_time` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | -| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | dict[str, *str*] | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `reference` | *Optional[str]* | :heavy_minus_sign: | Filter transactions by reference field. | ref:001 | -| `source` | *Optional[str]* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `start_time` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `request_body` | dict[str, *Any*] | :heavy_minus_sign: | N/A | | +| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | +| `pit` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/counttransactionsrequestbody.md b/sdks/python/docs/models/operations/counttransactionsrequestbody.md deleted file mode 100755 index 94a1f6eee..000000000 --- a/sdks/python/docs/models/operations/counttransactionsrequestbody.md +++ /dev/null @@ -1,7 +0,0 @@ -# CountTransactionsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/createtransactionrequest.md b/sdks/python/docs/models/operations/createtransactionrequest.md index 539d20563..1805c032e 100755 --- a/sdks/python/docs/models/operations/createtransactionrequest.md +++ b/sdks/python/docs/models/operations/createtransactionrequest.md @@ -7,6 +7,5 @@ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `idempotency_key` | *Optional[str]* | :heavy_minus_sign: | Use an idempotency key | | | `post_transaction` | [shared.PostTransaction](../../models/shared/posttransaction.md) | :heavy_check_mark: | The request body must contain at least one of the following objects:
    - `postings`: suitable for simple transactions
    - `script`: enabling more complex transactions with Numscript
    | | -| `async_` | *Optional[bool]* | :heavy_minus_sign: | Set async mode. | true | | `dry_run` | *Optional[bool]* | :heavy_minus_sign: | Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/getaccountrequest.md b/sdks/python/docs/models/operations/getaccountrequest.md index 2e2663374..e1ced5def 100755 --- a/sdks/python/docs/models/operations/getaccountrequest.md +++ b/sdks/python/docs/models/operations/getaccountrequest.md @@ -6,4 +6,5 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | `address` | *str* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | +| `expand` | *Optional[str]* | :heavy_minus_sign: | N/A | | | `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/getbalancesaggregatedrequest.md b/sdks/python/docs/models/operations/getbalancesaggregatedrequest.md index 1b236bf94..aa3657548 100755 --- a/sdks/python/docs/models/operations/getbalancesaggregatedrequest.md +++ b/sdks/python/docs/models/operations/getbalancesaggregatedrequest.md @@ -3,7 +3,6 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -| `address` | *Optional[str]* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/getbalancesrequest.md b/sdks/python/docs/models/operations/getbalancesrequest.md deleted file mode 100755 index bd075c70c..000000000 --- a/sdks/python/docs/models/operations/getbalancesrequest.md +++ /dev/null @@ -1,11 +0,0 @@ -# GetBalancesRequest - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *Optional[str]* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `cursor` | *Optional[str]* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `page_size` | *Optional[int]* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/getbalancesresponse.md b/sdks/python/docs/models/operations/getbalancesresponse.md deleted file mode 100755 index 367be1e73..000000000 --- a/sdks/python/docs/models/operations/getbalancesresponse.md +++ /dev/null @@ -1,12 +0,0 @@ -# GetBalancesResponse - - -## Fields - -| Field | Type | Required | Description | -| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -| `balances_cursor_response` | [Optional[shared.BalancesCursorResponse]](../../models/shared/balancescursorresponse.md) | :heavy_minus_sign: | OK | -| `content_type` | *str* | :heavy_check_mark: | N/A | -| `error_response` | [Optional[shared.ErrorResponse]](../../models/shared/errorresponse.md) | :heavy_minus_sign: | Error | -| `status_code` | *int* | :heavy_check_mark: | N/A | -| `raw_response` | [requests.Response](https://requests.readthedocs.io/en/latest/api/#requests.Response) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/gettransactionrequest.md b/sdks/python/docs/models/operations/gettransactionrequest.md index e716105d4..506269312 100755 --- a/sdks/python/docs/models/operations/gettransactionrequest.md +++ b/sdks/python/docs/models/operations/gettransactionrequest.md @@ -5,5 +5,6 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `expand` | *Optional[str]* | :heavy_minus_sign: | N/A | | +| `id` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/listaccountsrequest.md b/sdks/python/docs/models/operations/listaccountsrequest.md index ce77d4b57..24baf4b0e 100755 --- a/sdks/python/docs/models/operations/listaccountsrequest.md +++ b/sdks/python/docs/models/operations/listaccountsrequest.md @@ -5,8 +5,9 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *Optional[str]* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | +| `request_body` | dict[str, *Any*] | :heavy_minus_sign: | N/A | | | `cursor` | *Optional[str]* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | +| `expand` | *Optional[str]* | :heavy_minus_sign: | N/A | | | `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | dict[str, *str*] | :heavy_minus_sign: | Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `page_size` | *Optional[int]* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file +| `page_size` | *Optional[int]* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | +| `pit` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/listaccountsrequestbody.md b/sdks/python/docs/models/operations/listaccountsrequestbody.md deleted file mode 100755 index 22f1ad984..000000000 --- a/sdks/python/docs/models/operations/listaccountsrequestbody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListAccountsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/listlogsrequest.md b/sdks/python/docs/models/operations/listlogsrequest.md index 437ab17bd..c3b7ec5c7 100755 --- a/sdks/python/docs/models/operations/listlogsrequest.md +++ b/sdks/python/docs/models/operations/listlogsrequest.md @@ -5,8 +5,8 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `request_body` | dict[str, *Any*] | :heavy_minus_sign: | N/A | | | `cursor` | *Optional[str]* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `end_time` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | | `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | | `page_size` | *Optional[int]* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `start_time` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| `pit` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/listlogsrequestbody.md b/sdks/python/docs/models/operations/listlogsrequestbody.md deleted file mode 100755 index 6dbd158df..000000000 --- a/sdks/python/docs/models/operations/listlogsrequestbody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListLogsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/listtransactionsrequest.md b/sdks/python/docs/models/operations/listtransactionsrequest.md index 6e0d4ffad..113cb1136 100755 --- a/sdks/python/docs/models/operations/listtransactionsrequest.md +++ b/sdks/python/docs/models/operations/listtransactionsrequest.md @@ -5,13 +5,9 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `account` | *Optional[str]* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | +| `request_body` | dict[str, *Any*] | :heavy_minus_sign: | N/A | | | `cursor` | *Optional[str]* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `destination` | *Optional[str]* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `end_time` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | +| `expand` | *Optional[str]* | :heavy_minus_sign: | N/A | | | `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | dict[str, *str*] | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below. | | | `page_size` | *Optional[int]* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `reference` | *Optional[str]* | :heavy_minus_sign: | Find transactions by reference field. | ref:001 | -| `source` | *Optional[str]* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `start_time` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| `pit` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/listtransactionsrequestbody.md b/sdks/python/docs/models/operations/listtransactionsrequestbody.md deleted file mode 100755 index 990f2baf5..000000000 --- a/sdks/python/docs/models/operations/listtransactionsrequestbody.md +++ /dev/null @@ -1,7 +0,0 @@ -# ListTransactionsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/python/docs/models/operations/reverttransactionrequest.md b/sdks/python/docs/models/operations/reverttransactionrequest.md index b5e4e59a1..7a1a7e933 100755 --- a/sdks/python/docs/models/operations/reverttransactionrequest.md +++ b/sdks/python/docs/models/operations/reverttransactionrequest.md @@ -5,5 +5,5 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `id` | *int* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *str* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/python/docs/models/shared/accountwithvolumesandbalances.md b/sdks/python/docs/models/shared/accountwithvolumesandbalances.md index bfdc67c95..ffacc6a55 100755 --- a/sdks/python/docs/models/shared/accountwithvolumesandbalances.md +++ b/sdks/python/docs/models/shared/accountwithvolumesandbalances.md @@ -6,7 +6,6 @@ | Field | Type | Required | Description | Example | | --------------------------- | --------------------------- | --------------------------- | --------------------------- | --------------------------- | | `address` | *str* | :heavy_check_mark: | N/A | users:001 | -| `balances` | dict[str, *int*] | :heavy_check_mark: | N/A | | | `metadata` | dict[str, *str*] | :heavy_check_mark: | N/A | | | `type` | *Optional[str]* | :heavy_minus_sign: | N/A | virtual | -| `volumes` | dict[str, dict[str, *int*]] | :heavy_check_mark: | N/A | | \ No newline at end of file +| `volumes` | dict[str, dict[str, *int*]] | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/python/docs/models/shared/balancescursorresponse.md b/sdks/python/docs/models/shared/balancescursorresponse.md deleted file mode 100755 index 772cfc7f7..000000000 --- a/sdks/python/docs/models/shared/balancescursorresponse.md +++ /dev/null @@ -1,10 +0,0 @@ -# BalancesCursorResponse - -OK - - -## Fields - -| Field | Type | Required | Description | -| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | -| `cursor` | [BalancesCursorResponseCursor](../../models/shared/balancescursorresponsecursor.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/sdks/python/docs/models/shared/balancescursorresponsecursor.md b/sdks/python/docs/models/shared/balancescursorresponsecursor.md deleted file mode 100755 index 38e9f9152..000000000 --- a/sdks/python/docs/models/shared/balancescursorresponsecursor.md +++ /dev/null @@ -1,12 +0,0 @@ -# BalancesCursorResponseCursor - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -| `data` | list[dict[str, dict[str, *int*]]] | :heavy_check_mark: | N/A | | -| `has_more` | *bool* | :heavy_check_mark: | N/A | false | -| `next` | *Optional[str]* | :heavy_minus_sign: | N/A | | -| `page_size` | *int* | :heavy_check_mark: | N/A | 15 | -| `previous` | *Optional[str]* | :heavy_minus_sign: | N/A | YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= | \ No newline at end of file diff --git a/sdks/python/docs/models/shared/expandedtransaction.md b/sdks/python/docs/models/shared/expandedtransaction.md index 05bf63796..f4b7002c4 100755 --- a/sdks/python/docs/models/shared/expandedtransaction.md +++ b/sdks/python/docs/models/shared/expandedtransaction.md @@ -5,10 +5,11 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `id` | *int* | :heavy_check_mark: | N/A | | | `metadata` | dict[str, *str*] | :heavy_check_mark: | N/A | | -| `post_commit_volumes` | dict[str, dict[str, [Volume](../../models/shared/volume.md)]] | :heavy_check_mark: | N/A | | +| `post_commit_volumes` | dict[str, dict[str, [Volume](../../models/shared/volume.md)]] | :heavy_minus_sign: | N/A | | | `postings` | list[[Posting](../../models/shared/posting.md)] | :heavy_check_mark: | N/A | | -| `pre_commit_volumes` | dict[str, dict[str, [Volume](../../models/shared/volume.md)]] | :heavy_check_mark: | N/A | | +| `pre_commit_volumes` | dict[str, dict[str, [Volume](../../models/shared/volume.md)]] | :heavy_minus_sign: | N/A | | | `reference` | *Optional[str]* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_check_mark: | N/A | | -| `txid` | *int* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `reverted` | *bool* | :heavy_check_mark: | N/A | | +| `timestamp` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/python/docs/models/shared/posttransactionscriptvars.md b/sdks/python/docs/models/shared/posttransactionscriptvars.md new file mode 100755 index 000000000..ef1a0de95 --- /dev/null +++ b/sdks/python/docs/models/shared/posttransactionscriptvars.md @@ -0,0 +1,7 @@ +# PostTransactionScriptVars + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/python/docs/models/shared/query.md b/sdks/python/docs/models/shared/query.md index 6d3ebff8a..3ba0256be 100755 --- a/sdks/python/docs/models/shared/query.md +++ b/sdks/python/docs/models/shared/query.md @@ -11,6 +11,6 @@ | `page_size` | *Optional[int]* | :heavy_minus_sign: | N/A | | | `policy` | *Optional[str]* | :heavy_minus_sign: | N/A | OR | | `raw` | [Optional[QueryRaw]](../../models/shared/queryraw.md) | :heavy_minus_sign: | N/A | | -| `sort` | *Optional[str]* | :heavy_minus_sign: | N/A | txid:asc | +| `sort` | *Optional[str]* | :heavy_minus_sign: | N/A | id:asc | | `target` | *Optional[str]* | :heavy_minus_sign: | N/A | | | `terms` | list[*str*] | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/python/docs/models/shared/responsedata.md b/sdks/python/docs/models/shared/responsedata.md new file mode 100755 index 000000000..c3a85e750 --- /dev/null +++ b/sdks/python/docs/models/shared/responsedata.md @@ -0,0 +1,9 @@ +# ResponseData + +The payload + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/python/docs/models/shared/transaction.md b/sdks/python/docs/models/shared/transaction.md index 7954f4d0b..586a72915 100755 --- a/sdks/python/docs/models/shared/transaction.md +++ b/sdks/python/docs/models/shared/transaction.md @@ -5,8 +5,9 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `id` | *int* | :heavy_check_mark: | N/A | | | `metadata` | dict[str, *str*] | :heavy_check_mark: | N/A | | | `postings` | list[[Posting](../../models/shared/posting.md)] | :heavy_check_mark: | N/A | | | `reference` | *Optional[str]* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_check_mark: | N/A | | -| `txid` | *int* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `reverted` | *bool* | :heavy_check_mark: | N/A | | +| `timestamp` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/python/docs/models/shared/walletstransaction.md b/sdks/python/docs/models/shared/walletstransaction.md index 514779b8b..ee5cac714 100755 --- a/sdks/python/docs/models/shared/walletstransaction.md +++ b/sdks/python/docs/models/shared/walletstransaction.md @@ -5,11 +5,11 @@ | Field | Type | Required | Description | Example | | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | +| `id` | *Optional[int]* | :heavy_minus_sign: | N/A | | | `ledger` | *Optional[str]* | :heavy_minus_sign: | N/A | | | `metadata` | dict[str, *str*] | :heavy_check_mark: | Metadata associated with the wallet. | | | `post_commit_volumes` | dict[str, dict[str, [WalletsVolume](../../models/shared/walletsvolume.md)]] | :heavy_minus_sign: | N/A | | | `postings` | list[[Posting](../../models/shared/posting.md)] | :heavy_check_mark: | N/A | | | `pre_commit_volumes` | dict[str, dict[str, [WalletsVolume](../../models/shared/walletsvolume.md)]] | :heavy_minus_sign: | N/A | | | `reference` | *Optional[str]* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_check_mark: | N/A | | -| `txid` | *int* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `timestamp` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/python/docs/sdks/ledger/README.md b/sdks/python/docs/sdks/ledger/README.md index 4dcfd8529..f56cf7aa0 100755 --- a/sdks/python/docs/sdks/ledger/README.md +++ b/sdks/python/docs/sdks/ledger/README.md @@ -8,7 +8,6 @@ * [count_transactions](#count_transactions) - Count the transactions from a ledger * [create_transaction](#create_transaction) - Create a new transaction to a ledger * [get_account](#get_account) - Get account by its address -* [get_balances](#get_balances) - Get the balances from a ledger's account * [get_balances_aggregated](#get_balances_aggregated) - Get the aggregated balances from selected accounts * [get_info](#get_info) - Show server information * [get_ledger_info](#get_ledger_info) - Get information about a ledger @@ -41,10 +40,9 @@ req = operations.AddMetadataOnTransactionRequest( "explicabo": 'nobis', "enim": 'omnis', }, - async_=True, dry_run=True, + id=1234, ledger='ledger001', - txid=1234, ) res = s.ledger.add_metadata_on_transaction(req) @@ -88,7 +86,6 @@ req = operations.AddMetadataToAccountRequest( "iure": 'culpa', }, address='users:001', - async_=True, dry_run=True, ledger='ledger001', ) @@ -128,9 +125,13 @@ s = sdk.SDK( ) req = operations.CountAccountsRequest( - address='users:.+', + request_body={ + "sapiente": 'architecto', + "mollitia": 'dolorem', + "culpa": 'consequuntur', + "repellat": 'mollitia', + }, ledger='ledger001', - metadata=operations.CountAccountsMetadata(), ) res = s.ledger.count_accounts(req) @@ -169,16 +170,13 @@ s = sdk.SDK( ) req = operations.CountTransactionsRequest( - account='users:001', - destination='users:001', - end_time=dateutil.parser.isoparse('2020-02-15T22:48:47.492Z'), - ledger='ledger001', - metadata={ - "mollitia": 'dolorem', + request_body={ + "numquam": 'commodi', + "quam": 'molestiae', + "velit": 'error', }, - reference='ref:001', - source='users:001', - start_time=dateutil.parser.isoparse('2022-09-05T05:51:25.673Z'), + ledger='ledger001', + pit=dateutil.parser.isoparse('2022-08-30T15:03:11.112Z'), ) res = s.ledger.count_transactions(req) @@ -217,12 +215,12 @@ s = sdk.SDK( ) req = operations.CreateTransactionRequest( - idempotency_key='repellat', + idempotency_key='vitae', post_transaction=shared.PostTransaction( metadata={ - "occaecati": 'numquam', - "commodi": 'quam', - "molestiae": 'velit', + "animi": 'enim', + "odit": 'quo', + "sequi": 'tenetur', }, postings=[ shared.Posting( @@ -237,12 +235,6 @@ req = operations.CreateTransactionRequest( destination='users:002', source='users:001', ), - shared.Posting( - amount=100, - asset='COIN', - destination='users:002', - source='users:001', - ), ], reference='ref:001', script=shared.PostTransactionScript( @@ -255,12 +247,13 @@ req = operations.CreateTransactionRequest( ) ', vars={ - "quis": 'vitae', + "possimus": 'aut', + "quasi": 'error', + "temporibus": 'laborum', }, ), - timestamp=dateutil.parser.isoparse('2021-09-08T21:06:19.630Z'), + timestamp=dateutil.parser.isoparse('2022-01-11T05:45:42.485Z'), ), - async_=True, dry_run=True, ledger='ledger001', ) @@ -301,6 +294,7 @@ s = sdk.SDK( req = operations.GetAccountRequest( address='users:001', + expand='voluptatibus', ledger='ledger001', ) @@ -322,47 +316,6 @@ if res.account_response is not None: **[operations.GetAccountResponse](../../models/operations/getaccountresponse.md)** -## get_balances - -Get the balances from a ledger's account - -### Example Usage - -```python -import sdk -from sdk.models import operations, shared - -s = sdk.SDK( - security=shared.Security( - authorization="", - ), -) - -req = operations.GetBalancesRequest( - address='users:001', - cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - ledger='ledger001', - page_size=317202, -) - -res = s.ledger.get_balances(req) - -if res.balances_cursor_response is not None: - # handle response -``` - -### Parameters - -| Parameter | Type | Required | Description | -| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | -| `request` | [operations.GetBalancesRequest](../../models/operations/getbalancesrequest.md) | :heavy_check_mark: | The request object to use for the request. | - - -### Response - -**[operations.GetBalancesResponse](../../models/operations/getbalancesresponse.md)** - - ## get_balances_aggregated Get the aggregated balances from selected accounts @@ -380,7 +333,6 @@ s = sdk.SDK( ) req = operations.GetBalancesAggregatedRequest( - address='users:001', ledger='ledger001', ) @@ -486,8 +438,9 @@ s = sdk.SDK( ) req = operations.GetTransactionRequest( + expand='vero', + id=1234, ledger='ledger001', - txid=1234, ) res = s.ledger.get_transaction(req) @@ -516,6 +469,7 @@ List accounts from a ledger, sorted by address in descending order. ```python import sdk +import dateutil.parser from sdk.models import operations, shared s = sdk.SDK( @@ -525,13 +479,15 @@ s = sdk.SDK( ) req = operations.ListAccountsRequest( - address='users:.+', + request_body={ + "praesentium": 'voluptatibus', + "ipsa": 'omnis', + }, cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', + expand='voluptate', ledger='ledger001', - metadata={ - "quo": 'sequi', - }, - page_size=949572, + page_size=739264, + pit=dateutil.parser.isoparse('2022-12-17T16:42:52.927Z'), ) res = s.ledger.list_accounts(req) @@ -570,11 +526,14 @@ s = sdk.SDK( ) req = operations.ListLogsRequest( + request_body={ + "ut": 'maiores', + "dicta": 'corporis', + }, cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - end_time=dateutil.parser.isoparse('2022-05-04T04:15:52.352Z'), ledger='ledger001', - page_size=820994, - start_time=dateutil.parser.isoparse('2022-11-26T13:23:33.410Z'), + page_size=296140, + pit=dateutil.parser.isoparse('2022-11-18T15:56:41.921Z'), ) res = s.ledger.list_logs(req) @@ -597,7 +556,7 @@ if res.logs_cursor_response is not None: ## list_transactions -List transactions from a ledger, sorted by txid in descending order. +List transactions from a ledger, sorted by id in descending order. ### Example Usage @@ -613,20 +572,16 @@ s = sdk.SDK( ) req = operations.ListTransactionsRequest( - account='users:001', + request_body={ + "enim": 'accusamus', + "commodi": 'repudiandae', + "quae": 'ipsum', + }, cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - destination='users:001', - end_time=dateutil.parser.isoparse('2021-04-29T07:12:18.684Z'), + expand='quidem', ledger='ledger001', - metadata={ - "quasi": 'reiciendis', - "voluptatibus": 'vero', - "nihil": 'praesentium', - }, - page_size=976762, - reference='ref:001', - source='users:001', - start_time=dateutil.parser.isoparse('2022-05-25T05:33:11.349Z'), + page_size=565189, + pit=dateutil.parser.isoparse('2021-04-09T11:24:10.949Z'), ) res = s.ledger.list_transactions(req) @@ -703,8 +658,8 @@ s = sdk.SDK( ) req = operations.RevertTransactionRequest( + id=1234, ledger='ledger001', - txid=1234, ) res = s.ledger.revert_transaction(req) diff --git a/sdks/python/docs/sdks/orchestration/README.md b/sdks/python/docs/sdks/orchestration/README.md index 92e6e7efb..29b8d6932 100755 --- a/sdks/python/docs/sdks/orchestration/README.md +++ b/sdks/python/docs/sdks/orchestration/README.md @@ -32,7 +32,7 @@ s = sdk.SDK( ) req = operations.CancelEventRequest( - instance_id='voluptate', + instance_id='modi', ) res = s.orchestration.cancel_event(req) @@ -70,23 +70,13 @@ s = sdk.SDK( ) req = shared.CreateWorkflowRequest( - name='Thomas Batz', + name='Dr. Jordan Von', stages=[ { - "corporis": 'dolore', - }, - { - "dicta": 'harum', - "enim": 'accusamus', - }, - { - "repudiandae": 'quae', - "ipsum": 'quidem', - }, - { - "excepturi": 'pariatur', - "modi": 'praesentium', - "rem": 'voluptates', + "incidunt": 'enim', + "consequatur": 'est', + "quibusdam": 'explicabo', + "deserunt": 'distinctio', }, ], ) @@ -126,7 +116,7 @@ s = sdk.SDK( ) req = operations.DeleteWorkflowRequest( - flow_id='quasi', + flow_id='quibusdam', ) res = s.orchestration.delete_workflow(req) @@ -164,7 +154,7 @@ s = sdk.SDK( ) req = operations.GetInstanceRequest( - instance_id='repudiandae', + instance_id='labore', ) res = s.orchestration.get_instance(req) @@ -202,7 +192,7 @@ s = sdk.SDK( ) req = operations.GetInstanceHistoryRequest( - instance_id='sint', + instance_id='modi', ) res = s.orchestration.get_instance_history(req) @@ -240,8 +230,8 @@ s = sdk.SDK( ) req = operations.GetInstanceStageHistoryRequest( - instance_id='veritatis', - number=929297, + instance_id='qui', + number=397821, ) res = s.orchestration.get_instance_stage_history(req) @@ -279,7 +269,7 @@ s = sdk.SDK( ) req = operations.GetWorkflowRequest( - flow_id='incidunt', + flow_id='cupiditate', ) res = s.orchestration.get_workflow(req) @@ -318,7 +308,7 @@ s = sdk.SDK( req = operations.ListInstancesRequest( running=False, - workflow_id='enim', + workflow_id='quos', ) res = s.orchestration.list_instances(req) @@ -415,10 +405,10 @@ s = sdk.SDK( req = operations.RunWorkflowRequest( request_body={ - "est": 'quibusdam', + "magni": 'assumenda', }, wait=False, - workflow_id='explicabo', + workflow_id='ipsam', ) res = s.orchestration.run_workflow(req) @@ -457,9 +447,9 @@ s = sdk.SDK( req = operations.SendEventRequest( request_body=operations.SendEventRequestBody( - name='Rudy Spencer', + name='Denise Pagac', ), - instance_id='qui', + instance_id='facilis', ) res = s.orchestration.send_event(req) diff --git a/sdks/python/docs/sdks/payments/README.md b/sdks/python/docs/sdks/payments/README.md index 9140f74b5..52aea4198 100755 --- a/sdks/python/docs/sdks/payments/README.md +++ b/sdks/python/docs/sdks/payments/README.md @@ -85,7 +85,7 @@ req = operations.ConnectorsTransferRequest( destination='acct_1Gqj58KZcSIg2N2q', source='acct_1Gqj58KZcSIg2N2q', ), - connector=shared.Connector.MODULR, + connector=shared.Connector.BANKING_CIRCLE, ) res = s.payments.connectors_transfer(req) @@ -124,16 +124,17 @@ s = sdk.SDK( ) req = operations.GetAccountBalancesRequest( - account_id='cupiditate', - asset='quos', + account_id='labore', + asset='delectus', cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - from_=dateutil.parser.isoparse('2022-11-01T19:07:16.800Z'), - limit=828940, - page_size=369808, + from_=dateutil.parser.isoparse('2022-10-02T04:55:20.234Z'), + limit=756107, + page_size=576157, sort=[ - 'fugit', + 'provident', + 'necessitatibus', ], - to=dateutil.parser.isoparse('2021-11-11T04:17:07.569Z'), + to=dateutil.parser.isoparse('2021-09-21T14:06:09.271Z'), ) res = s.payments.get_account_balances(req) @@ -171,8 +172,8 @@ s = sdk.SDK( ) req = operations.GetConnectorTaskRequest( - connector=shared.Connector.WISE, - task_id='facilis', + connector=shared.Connector.DUMMY_PAY, + task_id='debitis', ) res = s.payments.get_connector_task(req) @@ -210,7 +211,7 @@ s = sdk.SDK( ) req = operations.GetPaymentRequest( - payment_id='tempore', + payment_id='a', ) res = s.payments.get_payment(req) @@ -248,11 +249,16 @@ s = sdk.SDK( ) req = operations.InstallConnectorRequest( - request_body=shared.WiseConfig( - api_key='XXX', + request_body=shared.BankingCircleConfig( + authorization_endpoint='XXX', + endpoint='XXX', + password='XXX', polling_period='60s', + user_certificate='XXX', + user_certificate_key='XXX', + username='XXX', ), - connector=shared.Connector.MONEYCORP, + connector=shared.Connector.MODULR, ) res = s.payments.install_connector(req) @@ -350,7 +356,7 @@ s = sdk.SDK( req = operations.ListConnectorTasksRequest( connector=shared.Connector.MODULR, cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - page_size=248753, + page_size=846409, ) res = s.payments.list_connector_tasks(req) @@ -388,7 +394,7 @@ s = sdk.SDK( ) req = operations.ListConnectorsTransfersRequest( - connector=shared.Connector.MANGOPAY, + connector=shared.Connector.MONEYCORP, ) res = s.payments.list_connectors_transfers(req) @@ -427,10 +433,9 @@ s = sdk.SDK( req = operations.ListPaymentsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - page_size=576157, + page_size=699479, sort=[ - 'provident', - 'necessitatibus', + 'magnam', ], ) @@ -469,7 +474,7 @@ s = sdk.SDK( ) req = operations.PaymentsgetAccountRequest( - account_id='sint', + account_id='cumque', ) res = s.payments.paymentsget_account(req) @@ -537,9 +542,10 @@ s = sdk.SDK( req = operations.PaymentslistAccountsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - page_size=638921, + page_size=813798, sort=[ - 'debitis', + 'aliquid', + 'laborum', ], ) @@ -618,7 +624,7 @@ s = sdk.SDK( ) req = operations.ResetConnectorRequest( - connector=shared.Connector.BANKING_CIRCLE, + connector=shared.Connector.DUMMY_PAY, ) res = s.payments.reset_connector(req) @@ -656,7 +662,7 @@ s = sdk.SDK( ) req = operations.UninstallConnectorRequest( - connector=shared.Connector.MODULR, + connector=shared.Connector.CURRENCY_CLOUD, ) res = s.payments.uninstall_connector(req) @@ -695,9 +701,9 @@ s = sdk.SDK( req = operations.UpdateMetadataRequest( payment_metadata=shared.PaymentMetadata( - key='in', + key='enim', ), - payment_id='illum', + payment_id='accusamus', ) res = s.payments.update_metadata(req) diff --git a/sdks/python/docs/sdks/search/README.md b/sdks/python/docs/sdks/search/README.md index a00c5f4c3..64719e469 100755 --- a/sdks/python/docs/sdks/search/README.md +++ b/sdks/python/docs/sdks/search/README.md @@ -34,16 +34,15 @@ req = shared.Query( 'quickstart', 'quickstart', ], - page_size=116202, + page_size=588465, policy='OR', raw=shared.QueryRaw(), - sort='txid:asc', - target='magnam', + sort='id:asc', + target='nam', terms=[ 'destination=central_bank1', 'destination=central_bank1', 'destination=central_bank1', - 'destination=central_bank1', ], ) diff --git a/sdks/python/docs/sdks/wallets/README.md b/sdks/python/docs/sdks/wallets/README.md index 7d50afd0c..6c5f9ae62 100755 --- a/sdks/python/docs/sdks/wallets/README.md +++ b/sdks/python/docs/sdks/wallets/README.md @@ -40,7 +40,7 @@ req = operations.ConfirmHoldRequest( amount=100, final=True, ), - hold_id='facere', + hold_id='blanditiis', ) res = s.wallets.confirm_hold(req) @@ -80,11 +80,11 @@ s = sdk.SDK( req = operations.CreateBalanceRequest( create_balance_request=shared.CreateBalanceRequest( - expires_at=dateutil.parser.isoparse('2022-08-09T06:36:34.417Z'), - name='Tomas Friesen', - priority=881736, + expires_at=dateutil.parser.isoparse('2021-02-02T01:24:52.629Z'), + name='Sandy Huels', + priority=606393, ), - id='fb9ba88f-3a66-4997-874b-a4469b6e2141', + id='7074ba44-69b6-4e21-8195-9890afa563e2', ) res = s.wallets.create_balance(req) @@ -123,11 +123,10 @@ s = sdk.SDK( req = shared.CreateWalletRequest( metadata={ - "ullam": 'provident', - "quos": 'sint', - "accusantium": 'mollitia', + "quasi": 'iure', + "doloribus": 'debitis', }, - name='Shaun Hammes', + name='Jasmine Lind', ) res = s.wallets.create_wallet(req) @@ -167,27 +166,39 @@ s = sdk.SDK( req = operations.CreditWalletRequest( credit_wallet_request=shared.CreditWalletRequest( amount=shared.Monetary( - amount=896547, - asset='odit', + amount=100226, + asset='architecto', ), - balance='nemo', + balance='repudiandae', metadata={ - "iure": 'doloribus', + "expedita": 'nihil', + "repellat": 'quibusdam', }, - reference='debitis', + reference='sed', sources=[ shared.WalletSubject( - balance='deleniti', - identifier='facilis', - type='in', + balance='accusantium', + identifier='consequuntur', + type='praesentium', ), - shared.LedgerAccountSubject( - identifier='architecto', - type='repudiandae', + shared.WalletSubject( + balance='magni', + identifier='sunt', + type='quo', + ), + shared.WalletSubject( + balance='pariatur', + identifier='maxime', + type='ea', + ), + shared.WalletSubject( + balance='odit', + identifier='ea', + type='accusantium', ), ], ), - id='5b7fd2ed-0289-421c-9dc6-92601fb576b0', + id='1fb576b0-d5f0-4d30-85fb-b2587053202c', ) res = s.wallets.credit_wallet(req) @@ -227,28 +238,29 @@ s = sdk.SDK( req = operations.DebitWalletRequest( debit_wallet_request=shared.DebitWalletRequest( amount=shared.Monetary( - amount=866383, - asset='nemo', + amount=463451, + asset='dolor', ), balances=[ - 'perferendis', - 'fugiat', - 'amet', - 'aut', + 'nostrum', + 'hic', + 'recusandae', + 'omnis', ], - description='cumque', - destination=shared.LedgerAccountSubject( - identifier='hic', - type='libero', + description='facilis', + destination=shared.WalletSubject( + balance='voluptatem', + identifier='porro', + type='consequuntur', ), metadata={ - "dolores": 'quis', - "totam": 'dignissimos', - "eaque": 'quis', + "error": 'eaque', + "occaecati": 'rerum', + "adipisci": 'asperiores', }, pending=False, ), - id='3202c73d-5fe9-4b90-8289-09b3fe49a8d9', + id='e49a8d9c-bf48-4633-b23f-9b77f3a41006', ) res = s.wallets.debit_wallet(req) @@ -286,8 +298,8 @@ s = sdk.SDK( ) req = operations.GetBalanceRequest( - balance_name='nobis', - id='bf486333-23f9-4b77-b3a4-100674ebf692', + balance_name='odio', + id='4ebf6928-0d1b-4a77-a89e-bf737ae4203c', ) res = s.wallets.get_balance(req) @@ -325,7 +337,7 @@ s = sdk.SDK( ) req = operations.GetHoldRequest( - hold_id='atque', + hold_id='accusamus', ) res = s.wallets.get_hold(req) @@ -365,10 +377,11 @@ s = sdk.SDK( req = operations.GetHoldsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', metadata={ - "fugiat": 'ab', + "saepe": 'suscipit', + "deserunt": 'provident', }, - page_size=743835, - wallet_id='dolorum', + page_size=324683, + wallet_id='repellendus', ) res = s.wallets.get_holds(req) @@ -405,8 +418,8 @@ s = sdk.SDK( req = operations.GetTransactionsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', - page_size=478596, - wallet_id='voluptate', + page_size=519711, + wallet_id='similique', ) res = s.wallets.get_transactions(req) @@ -444,7 +457,7 @@ s = sdk.SDK( ) req = operations.GetWalletRequest( - id='a89ebf73-7ae4-4203-8e5e-6a95d8a0d446', + id='0d446ce2-af7a-473c-b3be-453f870b326b', ) res = s.wallets.get_wallet(req) @@ -482,7 +495,7 @@ s = sdk.SDK( ) req = operations.GetWalletSummaryRequest( - id='ce2af7a7-3cf3-4be4-93f8-70b326b5a734', + id='5a73429c-db1a-4842-abb6-79d2322715bf', ) res = s.wallets.get_wallet_summary(req) @@ -520,7 +533,7 @@ s = sdk.SDK( ) req = operations.ListBalancesRequest( - id='29cdb1a8-422b-4b67-9d23-22715bf0cbb1', + id='0cbb1e31-b8b9-40f3-843a-1108e0adcf4b', ) res = s.wallets.list_balances(req) @@ -560,13 +573,12 @@ s = sdk.SDK( req = operations.ListWalletsRequest( cursor='aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==', metadata={ - "ipsum": 'veritatis', - "nobis": 'quos', - "tempore": 'cupiditate', - "aperiam": 'delectus', + "qui": 'quae', + "laudantium": 'odio', + "occaecati": 'voluptatibus', }, - name='Joanne Grant', - page_size=100294, + name='Ignacio Moen', + page_size=961571, ) res = s.wallets.list_wallets(req) @@ -606,10 +618,11 @@ s = sdk.SDK( req = operations.UpdateWalletRequest( request_body=operations.UpdateWalletRequestBody( metadata={ - "aut": 'quas', + "consectetur": 'vero', + "tenetur": 'dignissimos', }, ), - id='e0adcf4b-9218-479f-8e95-3f73ef7fbc7a', + id='fbc7abd7-4dd3-49c0-b5d2-cff7c70a4562', ) res = s.wallets.update_wallet(req) @@ -647,7 +660,7 @@ s = sdk.SDK( ) req = operations.VoidHoldRequest( - hold_id='facilis', + hold_id='vel', ) res = s.wallets.void_hold(req) diff --git a/sdks/python/files.gen b/sdks/python/files.gen index 390e209b0..d424bdb39 100755 --- a/sdks/python/files.gen +++ b/sdks/python/files.gen @@ -40,7 +40,6 @@ src/sdk/models/operations/countaccounts.py src/sdk/models/operations/counttransactions.py src/sdk/models/operations/createtransaction.py src/sdk/models/operations/getaccount.py -src/sdk/models/operations/getbalances.py src/sdk/models/operations/getbalancesaggregated.py src/sdk/models/operations/getinfo.py src/sdk/models/operations/getledgerinfo.py @@ -137,7 +136,6 @@ src/sdk/models/shared/posting.py src/sdk/models/shared/posttransaction.py src/sdk/models/shared/accountresponse.py src/sdk/models/shared/accountwithvolumesandbalances.py -src/sdk/models/shared/balancescursorresponse.py src/sdk/models/shared/aggregatebalancesresponse.py src/sdk/models/shared/configinforesponse.py src/sdk/models/shared/configinfo.py @@ -328,7 +326,6 @@ docs/models/operations/addmetadataontransactionrequest.md docs/models/operations/addmetadataontransactionresponse.md docs/models/operations/addmetadatatoaccountrequest.md docs/models/operations/addmetadatatoaccountresponse.md -docs/models/operations/countaccountsmetadata.md docs/models/operations/countaccountsrequest.md docs/models/operations/countaccountsresponse.md docs/models/operations/counttransactionsrequest.md @@ -337,8 +334,6 @@ docs/models/operations/createtransactionrequest.md docs/models/operations/createtransactionresponse.md docs/models/operations/getaccountrequest.md docs/models/operations/getaccountresponse.md -docs/models/operations/getbalancesrequest.md -docs/models/operations/getbalancesresponse.md docs/models/operations/getbalancesaggregatedrequest.md docs/models/operations/getbalancesaggregatedresponse.md docs/models/operations/getinforesponse.md @@ -488,8 +483,6 @@ docs/models/shared/posttransactionscript.md docs/models/shared/posttransaction.md docs/models/shared/accountresponse.md docs/models/shared/accountwithvolumesandbalances.md -docs/models/shared/balancescursorresponsecursor.md -docs/models/shared/balancescursorresponse.md docs/models/shared/aggregatebalancesresponse.md docs/models/shared/configinforesponse.md docs/models/shared/configinfo.md diff --git a/sdks/python/gen.yaml b/sdks/python/gen.yaml index 2c890f9c2..6044a3473 100755 --- a/sdks/python/gen.yaml +++ b/sdks/python/gen.yaml @@ -7,6 +7,7 @@ features: python: core: 2.85.3 deprecations: 2.81.1 + getRequestBodies: 2.81.1 globalSecurity: 2.81.1 globalServerURLs: 2.82.0 python: diff --git a/sdks/python/pylintrc b/sdks/python/pylintrc index d5a976c1b..409631707 100755 --- a/sdks/python/pylintrc +++ b/sdks/python/pylintrc @@ -180,8 +180,8 @@ good-names=i, ex, Run, _, - to, - id + id, + to # Good variable names regexes, separated by a comma. If names match any regex, # they will always be accepted diff --git a/sdks/python/src/sdk/ledger.py b/sdks/python/src/sdk/ledger.py index cbcd32a4e..14414c226 100755 --- a/sdks/python/src/sdk/ledger.py +++ b/sdks/python/src/sdk/ledger.py @@ -16,7 +16,7 @@ def add_metadata_on_transaction(self, request: operations.AddMetadataOnTransacti r"""Set the metadata of a transaction by its ID""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.AddMetadataOnTransactionRequest, base_url, '/api/ledger/{ledger}/transactions/{txid}/metadata', request) + url = utils.generate_url(operations.AddMetadataOnTransactionRequest, base_url, '/api/ledger/v2/{ledger}/transactions/{id}/metadata', request) headers = utils.get_headers(request) req_content_type, data, form = utils.serialize_request_body(request, "request_body", 'json') if req_content_type not in ('multipart/form-data', 'multipart/mixed'): @@ -48,7 +48,7 @@ def add_metadata_to_account(self, request: operations.AddMetadataToAccountReques r"""Add metadata to an account""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.AddMetadataToAccountRequest, base_url, '/api/ledger/{ledger}/accounts/{address}/metadata', request) + url = utils.generate_url(operations.AddMetadataToAccountRequest, base_url, '/api/ledger/v2/{ledger}/accounts/{address}/metadata', request) headers = utils.get_headers(request) req_content_type, data, form = utils.serialize_request_body(request, "request_body", 'json') if req_content_type not in ('multipart/form-data', 'multipart/mixed'): @@ -82,15 +82,17 @@ def count_accounts(self, request: operations.CountAccountsRequest) -> operations r"""Count the accounts from a ledger""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.CountAccountsRequest, base_url, '/api/ledger/{ledger}/accounts', request) + url = utils.generate_url(operations.CountAccountsRequest, base_url, '/api/ledger/v2/{ledger}/accounts', request) headers = {} - query_params = utils.get_query_params(operations.CountAccountsRequest, request) + req_content_type, data, form = utils.serialize_request_body(request, "request_body", 'json') + if req_content_type not in ('multipart/form-data', 'multipart/mixed'): + headers['content-type'] = req_content_type headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' client = self.sdk_configuration.security_client - http_res = client.request('HEAD', url, params=query_params, headers=headers) + http_res = client.request('HEAD', url, data=data, files=form, headers=headers) content_type = http_res.headers.get('Content-Type') res = operations.CountAccountsResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) @@ -112,15 +114,18 @@ def count_transactions(self, request: operations.CountTransactionsRequest) -> op r"""Count the transactions from a ledger""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.CountTransactionsRequest, base_url, '/api/ledger/{ledger}/transactions', request) + url = utils.generate_url(operations.CountTransactionsRequest, base_url, '/api/ledger/v2/{ledger}/transactions', request) headers = {} + req_content_type, data, form = utils.serialize_request_body(request, "request_body", 'json') + if req_content_type not in ('multipart/form-data', 'multipart/mixed'): + headers['content-type'] = req_content_type query_params = utils.get_query_params(operations.CountTransactionsRequest, request) headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' client = self.sdk_configuration.security_client - http_res = client.request('HEAD', url, params=query_params, headers=headers) + http_res = client.request('HEAD', url, params=query_params, data=data, files=form, headers=headers) content_type = http_res.headers.get('Content-Type') res = operations.CountTransactionsResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) @@ -142,7 +147,7 @@ def create_transaction(self, request: operations.CreateTransactionRequest) -> op r"""Create a new transaction to a ledger""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.CreateTransactionRequest, base_url, '/api/ledger/{ledger}/transactions', request) + url = utils.generate_url(operations.CreateTransactionRequest, base_url, '/api/ledger/v2/{ledger}/transactions', request) headers = utils.get_headers(request) req_content_type, data, form = utils.serialize_request_body(request, "post_transaction", 'json') if req_content_type not in ('multipart/form-data', 'multipart/mixed'): @@ -180,14 +185,15 @@ def get_account(self, request: operations.GetAccountRequest) -> operations.GetAc r"""Get account by its address""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetAccountRequest, base_url, '/api/ledger/{ledger}/accounts/{address}', request) + url = utils.generate_url(operations.GetAccountRequest, base_url, '/api/ledger/v2/{ledger}/accounts/{address}', request) headers = {} + query_params = utils.get_query_params(operations.GetAccountRequest, request) headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' client = self.sdk_configuration.security_client - http_res = client.request('GET', url, headers=headers) + http_res = client.request('GET', url, params=query_params, headers=headers) content_type = http_res.headers.get('Content-Type') res = operations.GetAccountResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) @@ -208,52 +214,18 @@ def get_account(self, request: operations.GetAccountRequest) -> operations.GetAc return res - def get_balances(self, request: operations.GetBalancesRequest) -> operations.GetBalancesResponse: - r"""Get the balances from a ledger's account""" - base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - - url = utils.generate_url(operations.GetBalancesRequest, base_url, '/api/ledger/{ledger}/balances', request) - headers = {} - query_params = utils.get_query_params(operations.GetBalancesRequest, request) - headers['Accept'] = 'application/json' - headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' - - client = self.sdk_configuration.security_client - - http_res = client.request('GET', url, params=query_params, headers=headers) - content_type = http_res.headers.get('Content-Type') - - res = operations.GetBalancesResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) - - if http_res.status_code == 200: - if utils.match_content_type(content_type, 'application/json'): - out = utils.unmarshal_json(http_res.text, Optional[shared.BalancesCursorResponse]) - res.balances_cursor_response = out - else: - raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) - else: - if utils.match_content_type(content_type, 'application/json'): - out = utils.unmarshal_json(http_res.text, Optional[shared.ErrorResponse]) - res.error_response = out - else: - raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res) - - return res - - def get_balances_aggregated(self, request: operations.GetBalancesAggregatedRequest) -> operations.GetBalancesAggregatedResponse: r"""Get the aggregated balances from selected accounts""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetBalancesAggregatedRequest, base_url, '/api/ledger/{ledger}/aggregate/balances', request) + url = utils.generate_url(operations.GetBalancesAggregatedRequest, base_url, '/api/ledger/v2/{ledger}/aggregate/balances', request) headers = {} - query_params = utils.get_query_params(operations.GetBalancesAggregatedRequest, request) headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' client = self.sdk_configuration.security_client - http_res = client.request('GET', url, params=query_params, headers=headers) + http_res = client.request('GET', url, headers=headers) content_type = http_res.headers.get('Content-Type') res = operations.GetBalancesAggregatedResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) @@ -278,7 +250,7 @@ def get_info(self) -> operations.GetInfoResponse: r"""Show server information""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = base_url + '/api/ledger/_info' + url = base_url + '/api/ledger/v2/_info' headers = {} headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' @@ -310,7 +282,7 @@ def get_ledger_info(self, request: operations.GetLedgerInfoRequest) -> operation r"""Get information about a ledger""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetLedgerInfoRequest, base_url, '/api/ledger/{ledger}/_info', request) + url = utils.generate_url(operations.GetLedgerInfoRequest, base_url, '/api/ledger/v2/{ledger}/_info', request) headers = {} headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' @@ -342,14 +314,15 @@ def get_transaction(self, request: operations.GetTransactionRequest) -> operatio r"""Get transaction from a ledger by its ID""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetTransactionRequest, base_url, '/api/ledger/{ledger}/transactions/{txid}', request) + url = utils.generate_url(operations.GetTransactionRequest, base_url, '/api/ledger/v2/{ledger}/transactions/{id}', request) headers = {} + query_params = utils.get_query_params(operations.GetTransactionRequest, request) headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' client = self.sdk_configuration.security_client - http_res = client.request('GET', url, headers=headers) + http_res = client.request('GET', url, params=query_params, headers=headers) content_type = http_res.headers.get('Content-Type') res = operations.GetTransactionResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) @@ -376,15 +349,18 @@ def list_accounts(self, request: operations.ListAccountsRequest) -> operations.L """ base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.ListAccountsRequest, base_url, '/api/ledger/{ledger}/accounts', request) + url = utils.generate_url(operations.ListAccountsRequest, base_url, '/api/ledger/v2/{ledger}/accounts', request) headers = {} + req_content_type, data, form = utils.serialize_request_body(request, "request_body", 'json') + if req_content_type not in ('multipart/form-data', 'multipart/mixed'): + headers['content-type'] = req_content_type query_params = utils.get_query_params(operations.ListAccountsRequest, request) headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' client = self.sdk_configuration.security_client - http_res = client.request('GET', url, params=query_params, headers=headers) + http_res = client.request('GET', url, params=query_params, data=data, files=form, headers=headers) content_type = http_res.headers.get('Content-Type') res = operations.ListAccountsResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) @@ -411,15 +387,18 @@ def list_logs(self, request: operations.ListLogsRequest) -> operations.ListLogsR """ base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.ListLogsRequest, base_url, '/api/ledger/{ledger}/logs', request) + url = utils.generate_url(operations.ListLogsRequest, base_url, '/api/ledger/v2/{ledger}/logs', request) headers = {} + req_content_type, data, form = utils.serialize_request_body(request, "request_body", 'json') + if req_content_type not in ('multipart/form-data', 'multipart/mixed'): + headers['content-type'] = req_content_type query_params = utils.get_query_params(operations.ListLogsRequest, request) headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' client = self.sdk_configuration.security_client - http_res = client.request('GET', url, params=query_params, headers=headers) + http_res = client.request('GET', url, params=query_params, data=data, files=form, headers=headers) content_type = http_res.headers.get('Content-Type') res = operations.ListLogsResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) @@ -442,19 +421,22 @@ def list_logs(self, request: operations.ListLogsRequest) -> operations.ListLogsR def list_transactions(self, request: operations.ListTransactionsRequest) -> operations.ListTransactionsResponse: r"""List transactions from a ledger - List transactions from a ledger, sorted by txid in descending order. + List transactions from a ledger, sorted by id in descending order. """ base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.ListTransactionsRequest, base_url, '/api/ledger/{ledger}/transactions', request) + url = utils.generate_url(operations.ListTransactionsRequest, base_url, '/api/ledger/v2/{ledger}/transactions', request) headers = {} + req_content_type, data, form = utils.serialize_request_body(request, "request_body", 'json') + if req_content_type not in ('multipart/form-data', 'multipart/mixed'): + headers['content-type'] = req_content_type query_params = utils.get_query_params(operations.ListTransactionsRequest, request) headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' client = self.sdk_configuration.security_client - http_res = client.request('GET', url, params=query_params, headers=headers) + http_res = client.request('GET', url, params=query_params, data=data, files=form, headers=headers) content_type = http_res.headers.get('Content-Type') res = operations.ListTransactionsResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res) @@ -481,7 +463,7 @@ def read_stats(self, request: operations.ReadStatsRequest) -> operations.ReadSta """ base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.ReadStatsRequest, base_url, '/api/ledger/{ledger}/stats', request) + url = utils.generate_url(operations.ReadStatsRequest, base_url, '/api/ledger/v2/{ledger}/stats', request) headers = {} headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' @@ -513,7 +495,7 @@ def revert_transaction(self, request: operations.RevertTransactionRequest) -> op r"""Revert a ledger transaction by its ID""" base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.RevertTransactionRequest, base_url, '/api/ledger/{ledger}/transactions/{txid}/revert', request) + url = utils.generate_url(operations.RevertTransactionRequest, base_url, '/api/ledger/v2/{ledger}/transactions/{id}/revert', request) headers = {} headers['Accept'] = 'application/json' headers['user-agent'] = f'speakeasy-sdk/{self.sdk_configuration.language} {self.sdk_configuration.sdk_version} {self.sdk_configuration.gen_version} {self.sdk_configuration.openapi_doc_version}' diff --git a/sdks/python/src/sdk/models/operations/__init__.py b/sdks/python/src/sdk/models/operations/__init__.py index 81fbcf7ff..e7742a725 100755 --- a/sdks/python/src/sdk/models/operations/__init__.py +++ b/sdks/python/src/sdk/models/operations/__init__.py @@ -32,7 +32,6 @@ from .getaccount import * from .getaccountbalances import * from .getbalance import * -from .getbalances import * from .getbalancesaggregated import * from .getconnectortask import * from .gethold import * @@ -92,4 +91,4 @@ from .voidhold import * from .walletsgetserverinfo import * -__all__ = ["ActivateConfigRequest","ActivateConfigResponse","AddMetadataOnTransactionRequest","AddMetadataOnTransactionResponse","AddMetadataToAccountRequest","AddMetadataToAccountResponse","AddScopeToClientRequest","AddScopeToClientResponse","AddTransientScopeRequest","AddTransientScopeResponse","CancelEventRequest","CancelEventResponse","ChangeConfigSecretRequest","ChangeConfigSecretResponse","ConfirmHoldRequest","ConfirmHoldResponse","ConnectorsStripeTransferResponse","ConnectorsTransferRequest","ConnectorsTransferResponse","CountAccountsMetadata","CountAccountsRequest","CountAccountsResponse","CountTransactionsRequest","CountTransactionsResponse","CreateBalanceRequest","CreateBalanceResponse","CreateClientResponse","CreateScopeResponse","CreateSecretRequest","CreateSecretResponse","CreateTransactionRequest","CreateTransactionResponse","CreateWalletResponse","CreateWorkflowResponse","CreditWalletRequest","CreditWalletResponse","DeactivateConfigRequest","DeactivateConfigResponse","DebitWalletRequest","DebitWalletResponse","DeleteClientRequest","DeleteClientResponse","DeleteConfigRequest","DeleteConfigResponse","DeleteScopeFromClientRequest","DeleteScopeFromClientResponse","DeleteScopeRequest","DeleteScopeResponse","DeleteSecretRequest","DeleteSecretResponse","DeleteTransientScopeRequest","DeleteTransientScopeResponse","DeleteWorkflowRequest","DeleteWorkflowResponse","GetAccountBalancesRequest","GetAccountBalancesResponse","GetAccountRequest","GetAccountResponse","GetBalanceRequest","GetBalanceResponse","GetBalancesAggregatedRequest","GetBalancesAggregatedResponse","GetBalancesRequest","GetBalancesResponse","GetConnectorTaskRequest","GetConnectorTaskResponse","GetHoldRequest","GetHoldResponse","GetHoldsRequest","GetHoldsResponse","GetInfoResponse","GetInstanceHistoryRequest","GetInstanceHistoryResponse","GetInstanceRequest","GetInstanceResponse","GetInstanceStageHistoryRequest","GetInstanceStageHistoryResponse","GetLedgerInfoRequest","GetLedgerInfoResponse","GetManyConfigsRequest","GetManyConfigsResponse","GetPaymentRequest","GetPaymentResponse","GetServerInfoResponse","GetTransactionRequest","GetTransactionResponse","GetTransactionsRequest","GetTransactionsResponse","GetVersionsResponse","GetWalletRequest","GetWalletResponse","GetWalletSummaryRequest","GetWalletSummaryResponse","GetWorkflowRequest","GetWorkflowResponse","InsertConfigResponse","InstallConnectorRequest","InstallConnectorResponse","ListAccountsRequest","ListAccountsResponse","ListAllConnectorsResponse","ListBalancesRequest","ListBalancesResponse","ListClientsResponse","ListConfigsAvailableConnectorsResponse","ListConnectorTasksRequest","ListConnectorTasksResponse","ListConnectorsTransfersRequest","ListConnectorsTransfersResponse","ListInstancesRequest","ListInstancesResponse","ListLogsRequest","ListLogsResponse","ListPaymentsRequest","ListPaymentsResponse","ListScopesResponse","ListTransactionsRequest","ListTransactionsResponse","ListUsersResponse","ListWalletsRequest","ListWalletsResponse","ListWorkflowsResponse","OrchestrationgetServerInfoResponse","PaymentsgetAccountRequest","PaymentsgetAccountResponse","PaymentsgetServerInfoResponse","PaymentslistAccountsRequest","PaymentslistAccountsResponse","ReadClientRequest","ReadClientResponse","ReadConnectorConfigRequest","ReadConnectorConfigResponse","ReadScopeRequest","ReadScopeResponse","ReadStatsRequest","ReadStatsResponse","ReadUserRequest","ReadUserResponse","ResetConnectorRequest","ResetConnectorResponse","RevertTransactionRequest","RevertTransactionResponse","RunWorkflowRequest","RunWorkflowResponse","SearchResponse","SearchgetServerInfoResponse","SendEventRequest","SendEventRequestBody","SendEventResponse","TestConfigRequest","TestConfigResponse","UninstallConnectorRequest","UninstallConnectorResponse","UpdateClientRequest","UpdateClientResponse","UpdateMetadataRequest","UpdateMetadataResponse","UpdateScopeRequest","UpdateScopeResponse","UpdateWalletRequest","UpdateWalletRequestBody","UpdateWalletResponse","VoidHoldRequest","VoidHoldResponse","WalletsgetServerInfoResponse"] +__all__ = ["ActivateConfigRequest","ActivateConfigResponse","AddMetadataOnTransactionRequest","AddMetadataOnTransactionResponse","AddMetadataToAccountRequest","AddMetadataToAccountResponse","AddScopeToClientRequest","AddScopeToClientResponse","AddTransientScopeRequest","AddTransientScopeResponse","CancelEventRequest","CancelEventResponse","ChangeConfigSecretRequest","ChangeConfigSecretResponse","ConfirmHoldRequest","ConfirmHoldResponse","ConnectorsStripeTransferResponse","ConnectorsTransferRequest","ConnectorsTransferResponse","CountAccountsRequest","CountAccountsResponse","CountTransactionsRequest","CountTransactionsResponse","CreateBalanceRequest","CreateBalanceResponse","CreateClientResponse","CreateScopeResponse","CreateSecretRequest","CreateSecretResponse","CreateTransactionRequest","CreateTransactionResponse","CreateWalletResponse","CreateWorkflowResponse","CreditWalletRequest","CreditWalletResponse","DeactivateConfigRequest","DeactivateConfigResponse","DebitWalletRequest","DebitWalletResponse","DeleteClientRequest","DeleteClientResponse","DeleteConfigRequest","DeleteConfigResponse","DeleteScopeFromClientRequest","DeleteScopeFromClientResponse","DeleteScopeRequest","DeleteScopeResponse","DeleteSecretRequest","DeleteSecretResponse","DeleteTransientScopeRequest","DeleteTransientScopeResponse","DeleteWorkflowRequest","DeleteWorkflowResponse","GetAccountBalancesRequest","GetAccountBalancesResponse","GetAccountRequest","GetAccountResponse","GetBalanceRequest","GetBalanceResponse","GetBalancesAggregatedRequest","GetBalancesAggregatedResponse","GetConnectorTaskRequest","GetConnectorTaskResponse","GetHoldRequest","GetHoldResponse","GetHoldsRequest","GetHoldsResponse","GetInfoResponse","GetInstanceHistoryRequest","GetInstanceHistoryResponse","GetInstanceRequest","GetInstanceResponse","GetInstanceStageHistoryRequest","GetInstanceStageHistoryResponse","GetLedgerInfoRequest","GetLedgerInfoResponse","GetManyConfigsRequest","GetManyConfigsResponse","GetPaymentRequest","GetPaymentResponse","GetServerInfoResponse","GetTransactionRequest","GetTransactionResponse","GetTransactionsRequest","GetTransactionsResponse","GetVersionsResponse","GetWalletRequest","GetWalletResponse","GetWalletSummaryRequest","GetWalletSummaryResponse","GetWorkflowRequest","GetWorkflowResponse","InsertConfigResponse","InstallConnectorRequest","InstallConnectorResponse","ListAccountsRequest","ListAccountsResponse","ListAllConnectorsResponse","ListBalancesRequest","ListBalancesResponse","ListClientsResponse","ListConfigsAvailableConnectorsResponse","ListConnectorTasksRequest","ListConnectorTasksResponse","ListConnectorsTransfersRequest","ListConnectorsTransfersResponse","ListInstancesRequest","ListInstancesResponse","ListLogsRequest","ListLogsResponse","ListPaymentsRequest","ListPaymentsResponse","ListScopesResponse","ListTransactionsRequest","ListTransactionsResponse","ListUsersResponse","ListWalletsRequest","ListWalletsResponse","ListWorkflowsResponse","OrchestrationgetServerInfoResponse","PaymentsgetAccountRequest","PaymentsgetAccountResponse","PaymentsgetServerInfoResponse","PaymentslistAccountsRequest","PaymentslistAccountsResponse","ReadClientRequest","ReadClientResponse","ReadConnectorConfigRequest","ReadConnectorConfigResponse","ReadScopeRequest","ReadScopeResponse","ReadStatsRequest","ReadStatsResponse","ReadUserRequest","ReadUserResponse","ResetConnectorRequest","ResetConnectorResponse","RevertTransactionRequest","RevertTransactionResponse","RunWorkflowRequest","RunWorkflowResponse","SearchResponse","SearchgetServerInfoResponse","SendEventRequest","SendEventRequestBody","SendEventResponse","TestConfigRequest","TestConfigResponse","UninstallConnectorRequest","UninstallConnectorResponse","UpdateClientRequest","UpdateClientResponse","UpdateMetadataRequest","UpdateMetadataResponse","UpdateScopeRequest","UpdateScopeResponse","UpdateWalletRequest","UpdateWalletRequestBody","UpdateWalletResponse","VoidHoldRequest","VoidHoldResponse","WalletsgetServerInfoResponse"] diff --git a/sdks/python/src/sdk/models/operations/addmetadataontransaction.py b/sdks/python/src/sdk/models/operations/addmetadataontransaction.py index 43d474457..7d7718b5c 100755 --- a/sdks/python/src/sdk/models/operations/addmetadataontransaction.py +++ b/sdks/python/src/sdk/models/operations/addmetadataontransaction.py @@ -10,12 +10,10 @@ @dataclasses.dataclass class AddMetadataOnTransactionRequest: + id: int = dataclasses.field(metadata={'path_param': { 'field_name': 'id', 'style': 'simple', 'explode': False }}) + r"""Transaction ID.""" ledger: str = dataclasses.field(metadata={'path_param': { 'field_name': 'ledger', 'style': 'simple', 'explode': False }}) r"""Name of the ledger.""" - txid: int = dataclasses.field(metadata={'path_param': { 'field_name': 'txid', 'style': 'simple', 'explode': False }}) - r"""Transaction ID.""" - async_: Optional[bool] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'async', 'style': 'form', 'explode': True }}) - r"""Set async mode.""" dry_run: Optional[bool] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'dryRun', 'style': 'form', 'explode': True }}) r"""Set the dryRun mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker.""" idempotency_key: Optional[str] = dataclasses.field(default=None, metadata={'header': { 'field_name': 'Idempotency-Key', 'style': 'simple', 'explode': False }}) diff --git a/sdks/python/src/sdk/models/operations/addmetadatatoaccount.py b/sdks/python/src/sdk/models/operations/addmetadatatoaccount.py index f4e812a94..93c0d633e 100755 --- a/sdks/python/src/sdk/models/operations/addmetadatatoaccount.py +++ b/sdks/python/src/sdk/models/operations/addmetadatatoaccount.py @@ -20,8 +20,6 @@ class AddMetadataToAccountRequest: r"""Name of the ledger.""" request_body: dict[str, str] = dataclasses.field(metadata={'request': { 'media_type': 'application/json' }}) r"""metadata""" - async_: Optional[bool] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'async', 'style': 'form', 'explode': True }}) - r"""Set async mode.""" dry_run: Optional[bool] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'dryRun', 'style': 'form', 'explode': True }}) r"""Set the dry run mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker.""" idempotency_key: Optional[str] = dataclasses.field(default=None, metadata={'header': { 'field_name': 'Idempotency-Key', 'style': 'simple', 'explode': False }}) diff --git a/sdks/python/src/sdk/models/operations/countaccounts.py b/sdks/python/src/sdk/models/operations/countaccounts.py index 761b95c99..d09a0317a 100755 --- a/sdks/python/src/sdk/models/operations/countaccounts.py +++ b/sdks/python/src/sdk/models/operations/countaccounts.py @@ -4,15 +4,7 @@ import dataclasses import requests as requests_http from ..shared import errorresponse as shared_errorresponse -from typing import Optional - - - -@dataclasses.dataclass -class CountAccountsMetadata: - r"""Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2""" - - +from typing import Any, Optional @@ -20,10 +12,7 @@ class CountAccountsMetadata: class CountAccountsRequest: ledger: str = dataclasses.field(metadata={'path_param': { 'field_name': 'ledger', 'style': 'simple', 'explode': False }}) r"""Name of the ledger.""" - address: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'address', 'style': 'form', 'explode': True }}) - r"""Filter accounts by address pattern (regular expression placed between ^ and $).""" - metadata: Optional[CountAccountsMetadata] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'metadata', 'style': 'deepObject', 'explode': True }}) - r"""Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2""" + request_body: Optional[dict[str, Any]] = dataclasses.field(default=None, metadata={'request': { 'media_type': 'application/json' }}) diff --git a/sdks/python/src/sdk/models/operations/counttransactions.py b/sdks/python/src/sdk/models/operations/counttransactions.py index 0e4327b43..e07f84f38 100755 --- a/sdks/python/src/sdk/models/operations/counttransactions.py +++ b/sdks/python/src/sdk/models/operations/counttransactions.py @@ -5,7 +5,7 @@ import requests as requests_http from ..shared import errorresponse as shared_errorresponse from datetime import datetime -from typing import Optional +from typing import Any, Optional @@ -13,24 +13,8 @@ class CountTransactionsRequest: ledger: str = dataclasses.field(metadata={'path_param': { 'field_name': 'ledger', 'style': 'simple', 'explode': False }}) r"""Name of the ledger.""" - account: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'account', 'style': 'form', 'explode': True }}) - r"""Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $).""" - destination: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'destination', 'style': 'form', 'explode': True }}) - r"""Filter transactions with postings involving given account at destination (regular expression placed between ^ and $).""" - end_time: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'endTime', 'style': 'form', 'explode': True }}) - r"""Filter transactions that occurred before this timestamp. - The format is RFC3339 and is exclusive (for example, \"2023-01-02T15:04:01Z\" excludes the first second of 4th minute). - """ - metadata: Optional[dict[str, str]] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'metadata', 'style': 'deepObject', 'explode': True }}) - r"""Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2""" - reference: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'reference', 'style': 'form', 'explode': True }}) - r"""Filter transactions by reference field.""" - source: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'source', 'style': 'form', 'explode': True }}) - r"""Filter transactions with postings involving given account at source (regular expression placed between ^ and $).""" - start_time: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'startTime', 'style': 'form', 'explode': True }}) - r"""Filter transactions that occurred after this timestamp. - The format is RFC3339 and is inclusive (for example, \"2023-01-02T15:04:01Z\" includes the first second of 4th minute). - """ + pit: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'pit', 'style': 'form', 'explode': True }}) + request_body: Optional[dict[str, Any]] = dataclasses.field(default=None, metadata={'request': { 'media_type': 'application/json' }}) diff --git a/sdks/python/src/sdk/models/operations/createtransaction.py b/sdks/python/src/sdk/models/operations/createtransaction.py index 93a1f7376..3abaa1d0b 100755 --- a/sdks/python/src/sdk/models/operations/createtransaction.py +++ b/sdks/python/src/sdk/models/operations/createtransaction.py @@ -19,8 +19,6 @@ class CreateTransactionRequest: - `postings`: suitable for simple transactions - `script`: enabling more complex transactions with Numscript """ - async_: Optional[bool] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'async', 'style': 'form', 'explode': True }}) - r"""Set async mode.""" dry_run: Optional[bool] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'dryRun', 'style': 'form', 'explode': True }}) r"""Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker.""" idempotency_key: Optional[str] = dataclasses.field(default=None, metadata={'header': { 'field_name': 'Idempotency-Key', 'style': 'simple', 'explode': False }}) diff --git a/sdks/python/src/sdk/models/operations/getaccount.py b/sdks/python/src/sdk/models/operations/getaccount.py index f2ba80e79..d57cbb5cc 100755 --- a/sdks/python/src/sdk/models/operations/getaccount.py +++ b/sdks/python/src/sdk/models/operations/getaccount.py @@ -19,6 +19,7 @@ class GetAccountRequest: """ ledger: str = dataclasses.field(metadata={'path_param': { 'field_name': 'ledger', 'style': 'simple', 'explode': False }}) r"""Name of the ledger.""" + expand: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'expand', 'style': 'form', 'explode': True }}) diff --git a/sdks/python/src/sdk/models/operations/getbalancesaggregated.py b/sdks/python/src/sdk/models/operations/getbalancesaggregated.py index 1b709984d..47eff7be1 100755 --- a/sdks/python/src/sdk/models/operations/getbalancesaggregated.py +++ b/sdks/python/src/sdk/models/operations/getbalancesaggregated.py @@ -13,8 +13,6 @@ class GetBalancesAggregatedRequest: ledger: str = dataclasses.field(metadata={'path_param': { 'field_name': 'ledger', 'style': 'simple', 'explode': False }}) r"""Name of the ledger.""" - address: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'address', 'style': 'form', 'explode': True }}) - r"""Filter balances involving given account, either as source or destination.""" diff --git a/sdks/python/src/sdk/models/operations/gettransaction.py b/sdks/python/src/sdk/models/operations/gettransaction.py index fc4d567a1..f1f1e6332 100755 --- a/sdks/python/src/sdk/models/operations/gettransaction.py +++ b/sdks/python/src/sdk/models/operations/gettransaction.py @@ -11,10 +11,11 @@ @dataclasses.dataclass class GetTransactionRequest: + id: int = dataclasses.field(metadata={'path_param': { 'field_name': 'id', 'style': 'simple', 'explode': False }}) + r"""Transaction ID.""" ledger: str = dataclasses.field(metadata={'path_param': { 'field_name': 'ledger', 'style': 'simple', 'explode': False }}) r"""Name of the ledger.""" - txid: int = dataclasses.field(metadata={'path_param': { 'field_name': 'txid', 'style': 'simple', 'explode': False }}) - r"""Transaction ID.""" + expand: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'expand', 'style': 'form', 'explode': True }}) diff --git a/sdks/python/src/sdk/models/operations/listaccounts.py b/sdks/python/src/sdk/models/operations/listaccounts.py index 4cda44528..cfabb380e 100755 --- a/sdks/python/src/sdk/models/operations/listaccounts.py +++ b/sdks/python/src/sdk/models/operations/listaccounts.py @@ -5,7 +5,8 @@ import requests as requests_http from ..shared import accountscursorresponse as shared_accountscursorresponse from ..shared import errorresponse as shared_errorresponse -from typing import Optional +from datetime import datetime +from typing import Any, Optional @@ -13,18 +14,17 @@ class ListAccountsRequest: ledger: str = dataclasses.field(metadata={'path_param': { 'field_name': 'ledger', 'style': 'simple', 'explode': False }}) r"""Name of the ledger.""" - address: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'address', 'style': 'form', 'explode': True }}) - r"""Filter accounts by address pattern (regular expression placed between ^ and $).""" cursor: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'cursor', 'style': 'form', 'explode': True }}) r"""Parameter used in pagination requests. Maximum page size is set to 15. Set to the value of next for the next page of results. Set to the value of previous for the previous page of results. No other parameters can be set when this parameter is set. """ - metadata: Optional[dict[str, str]] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'metadata', 'style': 'deepObject', 'explode': True }}) - r"""Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2""" + expand: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'expand', 'style': 'form', 'explode': True }}) page_size: Optional[int] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'pageSize', 'style': 'form', 'explode': True }}) r"""The maximum number of results to return per page.""" + pit: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'pit', 'style': 'form', 'explode': True }}) + request_body: Optional[dict[str, Any]] = dataclasses.field(default=None, metadata={'request': { 'media_type': 'application/json' }}) diff --git a/sdks/python/src/sdk/models/operations/listlogs.py b/sdks/python/src/sdk/models/operations/listlogs.py index 09935c89c..f29f6abc8 100755 --- a/sdks/python/src/sdk/models/operations/listlogs.py +++ b/sdks/python/src/sdk/models/operations/listlogs.py @@ -6,7 +6,7 @@ from ..shared import errorresponse as shared_errorresponse from ..shared import logscursorresponse as shared_logscursorresponse from datetime import datetime -from typing import Optional +from typing import Any, Optional @@ -20,16 +20,10 @@ class ListLogsRequest: Set to the value of previous for the previous page of results. No other parameters can be set when this parameter is set. """ - end_time: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'endTime', 'style': 'form', 'explode': True }}) - r"""Filter transactions that occurred before this timestamp. - The format is RFC3339 and is exclusive (for example, \"2023-01-02T15:04:01Z\" excludes the first second of 4th minute). - """ page_size: Optional[int] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'pageSize', 'style': 'form', 'explode': True }}) r"""The maximum number of results to return per page.""" - start_time: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'startTime', 'style': 'form', 'explode': True }}) - r"""Filter transactions that occurred after this timestamp. - The format is RFC3339 and is inclusive (for example, \"2023-01-02T15:04:01Z\" includes the first second of 4th minute). - """ + pit: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'pit', 'style': 'form', 'explode': True }}) + request_body: Optional[dict[str, Any]] = dataclasses.field(default=None, metadata={'request': { 'media_type': 'application/json' }}) diff --git a/sdks/python/src/sdk/models/operations/listtransactions.py b/sdks/python/src/sdk/models/operations/listtransactions.py index 91f5f0217..8060a611e 100755 --- a/sdks/python/src/sdk/models/operations/listtransactions.py +++ b/sdks/python/src/sdk/models/operations/listtransactions.py @@ -6,7 +6,7 @@ from ..shared import errorresponse as shared_errorresponse from ..shared import transactionscursorresponse as shared_transactionscursorresponse from datetime import datetime -from typing import Optional +from typing import Any, Optional @@ -14,32 +14,17 @@ class ListTransactionsRequest: ledger: str = dataclasses.field(metadata={'path_param': { 'field_name': 'ledger', 'style': 'simple', 'explode': False }}) r"""Name of the ledger.""" - account: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'account', 'style': 'form', 'explode': True }}) - r"""Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $).""" cursor: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'cursor', 'style': 'form', 'explode': True }}) r"""Parameter used in pagination requests. Maximum page size is set to 15. Set to the value of next for the next page of results. Set to the value of previous for the previous page of results. No other parameters can be set when this parameter is set. """ - destination: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'destination', 'style': 'form', 'explode': True }}) - r"""Filter transactions with postings involving given account at destination (regular expression placed between ^ and $).""" - end_time: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'endTime', 'style': 'form', 'explode': True }}) - r"""Filter transactions that occurred before this timestamp. - The format is RFC3339 and is exclusive (for example, \"2023-01-02T15:04:01Z\" excludes the first second of 4th minute). - """ - metadata: Optional[dict[str, str]] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'metadata', 'style': 'deepObject', 'explode': True }}) - r"""Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below.""" + expand: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'expand', 'style': 'form', 'explode': True }}) page_size: Optional[int] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'pageSize', 'style': 'form', 'explode': True }}) r"""The maximum number of results to return per page.""" - reference: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'reference', 'style': 'form', 'explode': True }}) - r"""Find transactions by reference field.""" - source: Optional[str] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'source', 'style': 'form', 'explode': True }}) - r"""Filter transactions with postings involving given account at source (regular expression placed between ^ and $).""" - start_time: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'startTime', 'style': 'form', 'explode': True }}) - r"""Filter transactions that occurred after this timestamp. - The format is RFC3339 and is inclusive (for example, \"2023-01-02T15:04:01Z\" includes the first second of 4th minute). - """ + pit: Optional[datetime] = dataclasses.field(default=None, metadata={'query_param': { 'field_name': 'pit', 'style': 'form', 'explode': True }}) + request_body: Optional[dict[str, Any]] = dataclasses.field(default=None, metadata={'request': { 'media_type': 'application/json' }}) diff --git a/sdks/python/src/sdk/models/operations/reverttransaction.py b/sdks/python/src/sdk/models/operations/reverttransaction.py index 66aaf2481..55a51125d 100755 --- a/sdks/python/src/sdk/models/operations/reverttransaction.py +++ b/sdks/python/src/sdk/models/operations/reverttransaction.py @@ -11,10 +11,10 @@ @dataclasses.dataclass class RevertTransactionRequest: + id: int = dataclasses.field(metadata={'path_param': { 'field_name': 'id', 'style': 'simple', 'explode': False }}) + r"""Transaction ID.""" ledger: str = dataclasses.field(metadata={'path_param': { 'field_name': 'ledger', 'style': 'simple', 'explode': False }}) r"""Name of the ledger.""" - txid: int = dataclasses.field(metadata={'path_param': { 'field_name': 'txid', 'style': 'simple', 'explode': False }}) - r"""Transaction ID.""" diff --git a/sdks/python/src/sdk/models/shared/__init__.py b/sdks/python/src/sdk/models/shared/__init__.py index 1ecaec60e..f0fe0c76b 100755 --- a/sdks/python/src/sdk/models/shared/__init__.py +++ b/sdks/python/src/sdk/models/shared/__init__.py @@ -28,7 +28,6 @@ from .attemptresponse import * from .balance import * from .balancescursor import * -from .balancescursorresponse import * from .balancewithassets import * from .bankingcircleconfig import * from .client import * @@ -175,4 +174,4 @@ from .workflowinstancehistorystageinput import * from .workflowinstancehistorystageoutput import * -__all__ = ["Account","AccountBalance","AccountResponse","AccountWithVolumesAndBalances","AccountsCursor","AccountsCursorCursor","AccountsCursorResponse","AccountsCursorResponseCursor","ActivityConfirmHold","ActivityCreateTransaction","ActivityCreateTransactionOutput","ActivityCreditWallet","ActivityDebitWallet","ActivityDebitWalletOutput","ActivityGetAccount","ActivityGetAccountOutput","ActivityGetPayment","ActivityGetPaymentOutput","ActivityGetWallet","ActivityGetWalletOutput","ActivityRevertTransaction","ActivityRevertTransactionOutput","ActivityStripeTransfer","ActivityStripeTransferMetadata","ActivityVoidHold","AggregateBalancesResponse","AssetHolder","Attempt","AttemptResponse","Balance","BalanceWithAssets","BalancesCursor","BalancesCursorCursor","BalancesCursorResponse","BalancesCursorResponseCursor","BankingCircleConfig","Client","ClientSecret","Config","ConfigChangeSecret","ConfigInfo","ConfigInfoResponse","ConfigResponse","ConfigUser","ConfigsResponse","ConfigsResponseCursor","ConfirmHoldRequest","Connector","ConnectorConfigResponse","ConnectorsConfigsResponse","ConnectorsConfigsResponseData","ConnectorsConfigsResponseDataConnector","ConnectorsConfigsResponseDataConnectorKey","ConnectorsResponse","ConnectorsResponseData","CreateBalanceRequest","CreateBalanceResponse","CreateClientRequest","CreateClientResponse","CreateScopeRequest","CreateScopeResponse","CreateSecretRequest","CreateSecretResponse","CreateTransactionResponse","CreateWalletRequest","CreateWalletResponse","CreateWorkflowRequest","CreateWorkflowResponse","CreditWalletRequest","CurrencyCloudConfig","DebitWalletRequest","DebitWalletResponse","DummyPayConfig","Error","ErrorErrorCode","ErrorResponse","ErrorsEnum","ExpandedDebitHold","ExpandedTransaction","GetBalanceResponse","GetHoldResponse","GetHoldsResponse","GetHoldsResponseCursor","GetTransactionResponse","GetTransactionsResponse","GetTransactionsResponseCursor","GetVersionsResponse","GetWalletResponse","GetWalletSummaryResponse","GetWorkflowInstanceHistoryResponse","GetWorkflowInstanceHistoryStageResponse","GetWorkflowInstanceResponse","GetWorkflowResponse","Hold","LedgerAccountSubject","LedgerInfo","LedgerInfoResponse","LedgerInfoStorage","LedgerStorage","ListBalancesResponse","ListBalancesResponseCursor","ListClientsResponse","ListRunsResponse","ListScopesResponse","ListUsersResponse","ListWalletsResponse","ListWalletsResponseCursor","ListWorkflowsResponse","Log","LogType","LogsCursorResponse","LogsCursorResponseCursor","MangoPayConfig","MigrationInfo","MigrationInfoState","ModulrConfig","Monetary","MoneycorpConfig","Payment","PaymentAdjustment","PaymentAdjustmentRaw","PaymentMetadata","PaymentRaw","PaymentResponse","PaymentScheme","PaymentStatus","PaymentType","PaymentsAccount","PaymentsAccountRaw","PaymentsAccountResponse","PaymentsCursor","PaymentsCursorCursor","PostTransaction","PostTransactionScript","Posting","Query","QueryRaw","ReadClientResponse","ReadScopeResponse","ReadUserResponse","Response","ResponseCursor","ResponseCursorTotal","RevertTransactionResponse","RunWorkflowResponse","Scope","Secret","Security","ServerInfo","StageDelay","StageSend","StageSendDestination","StageSendDestinationAccount","StageSendDestinationPayment","StageSendDestinationWallet","StageSendSource","StageSendSourceAccount","StageSendSourcePayment","StageSendSourceWallet","StageStatus","StageWaitEvent","Stats","StatsResponse","StripeConfig","StripeTransferRequest","StripeTransferRequestMetadata","StripeTransferResponse","TaskBankingCircle","TaskBankingCircleDescriptor","TaskBankingCircleState","TaskCurrencyCloud","TaskCurrencyCloudDescriptor","TaskCurrencyCloudState","TaskDummyPay","TaskDummyPayDescriptor","TaskDummyPayState","TaskMangoPay","TaskMangoPayDescriptor","TaskMangoPayState","TaskModulr","TaskModulrDescriptor","TaskModulrState","TaskMoneycorp","TaskMoneycorpDescriptor","TaskMoneycorpState","TaskResponse","TaskStripe","TaskStripeDescriptor","TaskStripeState","TaskWise","TaskWiseDescriptor","TaskWiseState","TasksCursor","TasksCursorCursor","Transaction","TransactionsCursorResponse","TransactionsCursorResponseCursor","TransferRequest","TransferResponse","TransfersResponse","TransfersResponseData","UpdateClientRequest","UpdateClientResponse","UpdateScopeRequest","UpdateScopeResponse","User","Version","Volume","Wallet","WalletSubject","WalletWithBalances","WalletWithBalancesBalances","WalletsErrorResponse","WalletsErrorResponseErrorCode","WalletsTransaction","WalletsVolume","WebhooksConfig","WiseConfig","Workflow","WorkflowConfig","WorkflowInstance","WorkflowInstanceHistory","WorkflowInstanceHistoryStage","WorkflowInstanceHistoryStageInput","WorkflowInstanceHistoryStageOutput"] +__all__ = ["Account","AccountBalance","AccountResponse","AccountWithVolumesAndBalances","AccountsCursor","AccountsCursorCursor","AccountsCursorResponse","AccountsCursorResponseCursor","ActivityConfirmHold","ActivityCreateTransaction","ActivityCreateTransactionOutput","ActivityCreditWallet","ActivityDebitWallet","ActivityDebitWalletOutput","ActivityGetAccount","ActivityGetAccountOutput","ActivityGetPayment","ActivityGetPaymentOutput","ActivityGetWallet","ActivityGetWalletOutput","ActivityRevertTransaction","ActivityRevertTransactionOutput","ActivityStripeTransfer","ActivityStripeTransferMetadata","ActivityVoidHold","AggregateBalancesResponse","AssetHolder","Attempt","AttemptResponse","Balance","BalanceWithAssets","BalancesCursor","BalancesCursorCursor","BankingCircleConfig","Client","ClientSecret","Config","ConfigChangeSecret","ConfigInfo","ConfigInfoResponse","ConfigResponse","ConfigUser","ConfigsResponse","ConfigsResponseCursor","ConfirmHoldRequest","Connector","ConnectorConfigResponse","ConnectorsConfigsResponse","ConnectorsConfigsResponseData","ConnectorsConfigsResponseDataConnector","ConnectorsConfigsResponseDataConnectorKey","ConnectorsResponse","ConnectorsResponseData","CreateBalanceRequest","CreateBalanceResponse","CreateClientRequest","CreateClientResponse","CreateScopeRequest","CreateScopeResponse","CreateSecretRequest","CreateSecretResponse","CreateTransactionResponse","CreateWalletRequest","CreateWalletResponse","CreateWorkflowRequest","CreateWorkflowResponse","CreditWalletRequest","CurrencyCloudConfig","DebitWalletRequest","DebitWalletResponse","DummyPayConfig","Error","ErrorErrorCode","ErrorResponse","ErrorsEnum","ExpandedDebitHold","ExpandedTransaction","GetBalanceResponse","GetHoldResponse","GetHoldsResponse","GetHoldsResponseCursor","GetTransactionResponse","GetTransactionsResponse","GetTransactionsResponseCursor","GetVersionsResponse","GetWalletResponse","GetWalletSummaryResponse","GetWorkflowInstanceHistoryResponse","GetWorkflowInstanceHistoryStageResponse","GetWorkflowInstanceResponse","GetWorkflowResponse","Hold","LedgerAccountSubject","LedgerInfo","LedgerInfoResponse","LedgerInfoStorage","LedgerStorage","ListBalancesResponse","ListBalancesResponseCursor","ListClientsResponse","ListRunsResponse","ListScopesResponse","ListUsersResponse","ListWalletsResponse","ListWalletsResponseCursor","ListWorkflowsResponse","Log","LogType","LogsCursorResponse","LogsCursorResponseCursor","MangoPayConfig","MigrationInfo","MigrationInfoState","ModulrConfig","Monetary","MoneycorpConfig","Payment","PaymentAdjustment","PaymentAdjustmentRaw","PaymentMetadata","PaymentRaw","PaymentResponse","PaymentScheme","PaymentStatus","PaymentType","PaymentsAccount","PaymentsAccountRaw","PaymentsAccountResponse","PaymentsCursor","PaymentsCursorCursor","PostTransaction","PostTransactionScript","Posting","Query","QueryRaw","ReadClientResponse","ReadScopeResponse","ReadUserResponse","Response","ResponseCursor","ResponseCursorTotal","RevertTransactionResponse","RunWorkflowResponse","Scope","Secret","Security","ServerInfo","StageDelay","StageSend","StageSendDestination","StageSendDestinationAccount","StageSendDestinationPayment","StageSendDestinationWallet","StageSendSource","StageSendSourceAccount","StageSendSourcePayment","StageSendSourceWallet","StageStatus","StageWaitEvent","Stats","StatsResponse","StripeConfig","StripeTransferRequest","StripeTransferRequestMetadata","StripeTransferResponse","TaskBankingCircle","TaskBankingCircleDescriptor","TaskBankingCircleState","TaskCurrencyCloud","TaskCurrencyCloudDescriptor","TaskCurrencyCloudState","TaskDummyPay","TaskDummyPayDescriptor","TaskDummyPayState","TaskMangoPay","TaskMangoPayDescriptor","TaskMangoPayState","TaskModulr","TaskModulrDescriptor","TaskModulrState","TaskMoneycorp","TaskMoneycorpDescriptor","TaskMoneycorpState","TaskResponse","TaskStripe","TaskStripeDescriptor","TaskStripeState","TaskWise","TaskWiseDescriptor","TaskWiseState","TasksCursor","TasksCursorCursor","Transaction","TransactionsCursorResponse","TransactionsCursorResponseCursor","TransferRequest","TransferResponse","TransfersResponse","TransfersResponseData","UpdateClientRequest","UpdateClientResponse","UpdateScopeRequest","UpdateScopeResponse","User","Version","Volume","Wallet","WalletSubject","WalletWithBalances","WalletWithBalancesBalances","WalletsErrorResponse","WalletsErrorResponseErrorCode","WalletsTransaction","WalletsVolume","WebhooksConfig","WiseConfig","Workflow","WorkflowConfig","WorkflowInstance","WorkflowInstanceHistory","WorkflowInstanceHistoryStage","WorkflowInstanceHistoryStageInput","WorkflowInstanceHistoryStageOutput"] diff --git a/sdks/python/src/sdk/models/shared/accountwithvolumesandbalances.py b/sdks/python/src/sdk/models/shared/accountwithvolumesandbalances.py index 391f93d9d..61f0fd516 100755 --- a/sdks/python/src/sdk/models/shared/accountwithvolumesandbalances.py +++ b/sdks/python/src/sdk/models/shared/accountwithvolumesandbalances.py @@ -12,9 +12,8 @@ @dataclasses.dataclass class AccountWithVolumesAndBalances: address: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('address') }}) - balances: dict[str, int] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('balances') }}) metadata: dict[str, str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('metadata') }}) - volumes: dict[str, dict[str, int]] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('volumes') }}) type: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('type'), 'exclude': lambda f: f is None }}) + volumes: Optional[dict[str, dict[str, int]]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('volumes'), 'exclude': lambda f: f is None }}) diff --git a/sdks/python/src/sdk/models/shared/expandedtransaction.py b/sdks/python/src/sdk/models/shared/expandedtransaction.py index 20e430f83..684ac3cbf 100755 --- a/sdks/python/src/sdk/models/shared/expandedtransaction.py +++ b/sdks/python/src/sdk/models/shared/expandedtransaction.py @@ -16,12 +16,13 @@ @dataclasses.dataclass class ExpandedTransaction: + id: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('id') }}) metadata: dict[str, str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('metadata') }}) - post_commit_volumes: dict[str, dict[str, shared_volume.Volume]] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('postCommitVolumes') }}) postings: list[shared_posting.Posting] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('postings') }}) - pre_commit_volumes: dict[str, dict[str, shared_volume.Volume]] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('preCommitVolumes') }}) + reverted: bool = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('reverted') }}) timestamp: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('timestamp'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse, 'mm_field': fields.DateTime(format='iso') }}) - txid: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('txid') }}) + post_commit_volumes: Optional[dict[str, dict[str, shared_volume.Volume]]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('postCommitVolumes'), 'exclude': lambda f: f is None }}) + pre_commit_volumes: Optional[dict[str, dict[str, shared_volume.Volume]]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('preCommitVolumes'), 'exclude': lambda f: f is None }}) reference: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('reference'), 'exclude': lambda f: f is None }}) diff --git a/sdks/python/src/sdk/models/shared/transaction.py b/sdks/python/src/sdk/models/shared/transaction.py index 073ff6816..01cdd319b 100755 --- a/sdks/python/src/sdk/models/shared/transaction.py +++ b/sdks/python/src/sdk/models/shared/transaction.py @@ -15,10 +15,11 @@ @dataclasses.dataclass class Transaction: + id: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('id') }}) metadata: dict[str, str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('metadata') }}) postings: list[shared_posting.Posting] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('postings') }}) + reverted: bool = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('reverted') }}) timestamp: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('timestamp'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse, 'mm_field': fields.DateTime(format='iso') }}) - txid: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('txid') }}) reference: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('reference'), 'exclude': lambda f: f is None }}) diff --git a/sdks/python/src/sdk/models/shared/walletstransaction.py b/sdks/python/src/sdk/models/shared/walletstransaction.py index 102b08eb1..e499b671c 100755 --- a/sdks/python/src/sdk/models/shared/walletstransaction.py +++ b/sdks/python/src/sdk/models/shared/walletstransaction.py @@ -20,7 +20,7 @@ class WalletsTransaction: r"""Metadata associated with the wallet.""" postings: list[shared_posting.Posting] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('postings') }}) timestamp: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('timestamp'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse, 'mm_field': fields.DateTime(format='iso') }}) - txid: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('txid') }}) + id: Optional[int] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('id'), 'exclude': lambda f: f is None }}) ledger: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('ledger'), 'exclude': lambda f: f is None }}) post_commit_volumes: Optional[dict[str, dict[str, shared_walletsvolume.WalletsVolume]]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('postCommitVolumes'), 'exclude': lambda f: f is None }}) pre_commit_volumes: Optional[dict[str, dict[str, shared_walletsvolume.WalletsVolume]]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('preCommitVolumes'), 'exclude': lambda f: f is None }}) diff --git a/sdks/python/src/sdk/sdkconfiguration.py b/sdks/python/src/sdk/sdkconfiguration.py index b11db1640..6f5acfca6 100755 --- a/sdks/python/src/sdk/sdkconfiguration.py +++ b/sdks/python/src/sdk/sdkconfiguration.py @@ -22,7 +22,7 @@ class SDKConfiguration: server_idx: int = 0 server_defaults: list[dict[str, str]] = field(default_factory=list) language: str = 'python' - openapi_doc_version: str = 'v1.0.20230907' + openapi_doc_version: str = 'v1.0.20230908' sdk_version: str = 'v0.1.0' gen_version: str = '2.96.3' diff --git a/sdks/typescript/README.md b/sdks/typescript/README.md index bbfeb29d2..66a07b1b7 100755 --- a/sdks/typescript/README.md +++ b/sdks/typescript/README.md @@ -86,14 +86,10 @@ sdk.getVersions().then((res: GetVersionsResponse) => { * [countTransactions](docs/sdks/ledger/README.md#counttransactions) - Count the transactions from a ledger * [createTransaction](docs/sdks/ledger/README.md#createtransaction) - Create a new transaction to a ledger * [getAccount](docs/sdks/ledger/README.md#getaccount) - Get account by its address -* [getBalances](docs/sdks/ledger/README.md#getbalances) - Get the balances from a ledger's account * [getBalancesAggregated](docs/sdks/ledger/README.md#getbalancesaggregated) - Get the aggregated balances from selected accounts * [getInfo](docs/sdks/ledger/README.md#getinfo) - Show server information * [getLedgerInfo](docs/sdks/ledger/README.md#getledgerinfo) - Get information about a ledger * [getTransaction](docs/sdks/ledger/README.md#gettransaction) - Get transaction from a ledger by its ID -* [listAccounts](docs/sdks/ledger/README.md#listaccounts) - List accounts from a ledger -* [listLogs](docs/sdks/ledger/README.md#listlogs) - List the logs from a ledger -* [listTransactions](docs/sdks/ledger/README.md#listtransactions) - List transactions from a ledger * [readStats](docs/sdks/ledger/README.md#readstats) - Get statistics from a ledger * [revertTransaction](docs/sdks/ledger/README.md#reverttransaction) - Revert a ledger transaction by its ID diff --git a/sdks/typescript/docs/models/operations/addmetadataontransactionrequest.md b/sdks/typescript/docs/models/operations/addmetadataontransactionrequest.md index 4747ccfa6..f2b2ad73f 100755 --- a/sdks/typescript/docs/models/operations/addmetadataontransactionrequest.md +++ b/sdks/typescript/docs/models/operations/addmetadataontransactionrequest.md @@ -7,7 +7,6 @@ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | `idempotencyKey` | *string* | :heavy_minus_sign: | Use an idempotency key | | | `requestBody` | Record | :heavy_minus_sign: | metadata | | -| `async` | *boolean* | :heavy_minus_sign: | Set async mode. | true | | `dryRun` | *boolean* | :heavy_minus_sign: | Set the dryRun mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *number* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `id` | *number* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/addmetadatatoaccountrequest.md b/sdks/typescript/docs/models/operations/addmetadatatoaccountrequest.md index 0460d5933..c149c5de8 100755 --- a/sdks/typescript/docs/models/operations/addmetadatatoaccountrequest.md +++ b/sdks/typescript/docs/models/operations/addmetadatatoaccountrequest.md @@ -8,6 +8,5 @@ | `idempotencyKey` | *string* | :heavy_minus_sign: | Use an idempotency key | | | `requestBody` | Record | :heavy_check_mark: | metadata | | | `address` | *string* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | -| `async` | *boolean* | :heavy_minus_sign: | Set async mode. | true | | `dryRun` | *boolean* | :heavy_minus_sign: | Set the dry run mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/countaccountsmetadata.md b/sdks/typescript/docs/models/operations/countaccountsmetadata.md deleted file mode 100755 index 7ea898a09..000000000 --- a/sdks/typescript/docs/models/operations/countaccountsmetadata.md +++ /dev/null @@ -1,9 +0,0 @@ -# CountAccountsMetadata - -Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/countaccountsrequest.md b/sdks/typescript/docs/models/operations/countaccountsrequest.md index 807a1e09b..c3a24bdb6 100755 --- a/sdks/typescript/docs/models/operations/countaccountsrequest.md +++ b/sdks/typescript/docs/models/operations/countaccountsrequest.md @@ -3,8 +3,7 @@ ## Fields -| Field | Type | Required | Description | Example | -| ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *string* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | [CountAccountsMetadata](../../models/operations/countaccountsmetadata.md) | :heavy_minus_sign: | Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| --------------------- | --------------------- | --------------------- | --------------------- | --------------------- | +| `requestBody` | Record | :heavy_minus_sign: | N/A | | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/counttransactionsrequest.md b/sdks/typescript/docs/models/operations/counttransactionsrequest.md index bd1ed6766..259a97060 100755 --- a/sdks/typescript/docs/models/operations/counttransactionsrequest.md +++ b/sdks/typescript/docs/models/operations/counttransactionsrequest.md @@ -3,13 +3,8 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `account` | *string* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | -| `destination` | *string* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `endTime` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | Record | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `reference` | *string* | :heavy_minus_sign: | Filter transactions by reference field. | ref:001 | -| `source` | *string* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `startTime` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `requestBody` | Record | :heavy_minus_sign: | N/A | | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | +| `pit` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/counttransactionsrequestbody.md b/sdks/typescript/docs/models/operations/counttransactionsrequestbody.md deleted file mode 100755 index 94a1f6eee..000000000 --- a/sdks/typescript/docs/models/operations/counttransactionsrequestbody.md +++ /dev/null @@ -1,7 +0,0 @@ -# CountTransactionsRequestBody - - -## Fields - -| Field | Type | Required | Description | -| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/createtransactionrequest.md b/sdks/typescript/docs/models/operations/createtransactionrequest.md index 8bbbfef0a..3fbb5ed76 100755 --- a/sdks/typescript/docs/models/operations/createtransactionrequest.md +++ b/sdks/typescript/docs/models/operations/createtransactionrequest.md @@ -7,6 +7,5 @@ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `idempotencyKey` | *string* | :heavy_minus_sign: | Use an idempotency key | | | `postTransaction` | [shared.PostTransaction](../../models/shared/posttransaction.md) | :heavy_check_mark: | The request body must contain at least one of the following objects:
    - `postings`: suitable for simple transactions
    - `script`: enabling more complex transactions with Numscript
    | | -| `async` | *boolean* | :heavy_minus_sign: | Set async mode. | true | | `dryRun` | *boolean* | :heavy_minus_sign: | Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker. | true | | `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/getaccountrequest.md b/sdks/typescript/docs/models/operations/getaccountrequest.md index eea42675e..f7584abbb 100755 --- a/sdks/typescript/docs/models/operations/getaccountrequest.md +++ b/sdks/typescript/docs/models/operations/getaccountrequest.md @@ -6,4 +6,5 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | `address` | *string* | :heavy_check_mark: | Exact address of the account. It must match the following regular expressions pattern:
    ```
    ^\w+(:\w+)*$
    ```
    | users:001 | +| `expand` | *string* | :heavy_minus_sign: | N/A | | | `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/getbalancesaggregatedrequest.md b/sdks/typescript/docs/models/operations/getbalancesaggregatedrequest.md index b83ffef23..f39be3cb8 100755 --- a/sdks/typescript/docs/models/operations/getbalancesaggregatedrequest.md +++ b/sdks/typescript/docs/models/operations/getbalancesaggregatedrequest.md @@ -3,7 +3,6 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -| `address` | *string* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/getbalancesrequest.md b/sdks/typescript/docs/models/operations/getbalancesrequest.md deleted file mode 100755 index cb7baffe1..000000000 --- a/sdks/typescript/docs/models/operations/getbalancesrequest.md +++ /dev/null @@ -1,11 +0,0 @@ -# GetBalancesRequest - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *string* | :heavy_minus_sign: | Filter balances involving given account, either as source or destination. | users:001 | -| `cursor` | *string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `pageSize` | *number* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/getbalancesresponse.md b/sdks/typescript/docs/models/operations/getbalancesresponse.md deleted file mode 100755 index 402cd2d76..000000000 --- a/sdks/typescript/docs/models/operations/getbalancesresponse.md +++ /dev/null @@ -1,12 +0,0 @@ -# GetBalancesResponse - - -## Fields - -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | -| `balancesCursorResponse` | [shared.BalancesCursorResponse](../../models/shared/balancescursorresponse.md) | :heavy_minus_sign: | OK | -| `contentType` | *string* | :heavy_check_mark: | N/A | -| `errorResponse` | [shared.ErrorResponse](../../models/shared/errorresponse.md) | :heavy_minus_sign: | Error | -| `statusCode` | *number* | :heavy_check_mark: | N/A | -| `rawResponse` | [AxiosResponse>](https://axios-http.com/docs/res_schema) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/gettransactionrequest.md b/sdks/typescript/docs/models/operations/gettransactionrequest.md index c7935dc17..01c4816e9 100755 --- a/sdks/typescript/docs/models/operations/gettransactionrequest.md +++ b/sdks/typescript/docs/models/operations/gettransactionrequest.md @@ -5,5 +5,6 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *number* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `expand` | *string* | :heavy_minus_sign: | N/A | | +| `id` | *number* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/listaccountsrequest.md b/sdks/typescript/docs/models/operations/listaccountsrequest.md deleted file mode 100755 index 111e08b19..000000000 --- a/sdks/typescript/docs/models/operations/listaccountsrequest.md +++ /dev/null @@ -1,12 +0,0 @@ -# ListAccountsRequest - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `address` | *string* | :heavy_minus_sign: | Filter accounts by address pattern (regular expression placed between ^ and $). | users:.+ | -| `cursor` | *string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | Record | :heavy_minus_sign: | Filter accounts by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 | | -| `pageSize` | *number* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/listaccountsresponse.md b/sdks/typescript/docs/models/operations/listaccountsresponse.md deleted file mode 100755 index 16d5dff09..000000000 --- a/sdks/typescript/docs/models/operations/listaccountsresponse.md +++ /dev/null @@ -1,12 +0,0 @@ -# ListAccountsResponse - - -## Fields - -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | -| `accountsCursorResponse` | [shared.AccountsCursorResponse](../../models/shared/accountscursorresponse.md) | :heavy_minus_sign: | OK | -| `contentType` | *string* | :heavy_check_mark: | N/A | -| `errorResponse` | [shared.ErrorResponse](../../models/shared/errorresponse.md) | :heavy_minus_sign: | Error | -| `statusCode` | *number* | :heavy_check_mark: | N/A | -| `rawResponse` | [AxiosResponse>](https://axios-http.com/docs/res_schema) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/listlogsrequest.md b/sdks/typescript/docs/models/operations/listlogsrequest.md deleted file mode 100755 index 9e3344b4b..000000000 --- a/sdks/typescript/docs/models/operations/listlogsrequest.md +++ /dev/null @@ -1,12 +0,0 @@ -# ListLogsRequest - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `cursor` | *string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `endTime` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `pageSize` | *number* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `startTime` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/listlogsresponse.md b/sdks/typescript/docs/models/operations/listlogsresponse.md deleted file mode 100755 index b0da5ad0c..000000000 --- a/sdks/typescript/docs/models/operations/listlogsresponse.md +++ /dev/null @@ -1,12 +0,0 @@ -# ListLogsResponse - - -## Fields - -| Field | Type | Required | Description | -| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | -| `contentType` | *string* | :heavy_check_mark: | N/A | -| `errorResponse` | [shared.ErrorResponse](../../models/shared/errorresponse.md) | :heavy_minus_sign: | Error | -| `logsCursorResponse` | [shared.LogsCursorResponse](../../models/shared/logscursorresponse.md) | :heavy_minus_sign: | OK | -| `statusCode` | *number* | :heavy_check_mark: | N/A | -| `rawResponse` | [AxiosResponse>](https://axios-http.com/docs/res_schema) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/listtransactionsrequest.md b/sdks/typescript/docs/models/operations/listtransactionsrequest.md deleted file mode 100755 index 595487f57..000000000 --- a/sdks/typescript/docs/models/operations/listtransactionsrequest.md +++ /dev/null @@ -1,17 +0,0 @@ -# ListTransactionsRequest - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `account` | *string* | :heavy_minus_sign: | Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). | users:001 | -| `cursor` | *string* | :heavy_minus_sign: | Parameter used in pagination requests. Maximum page size is set to 15.
    Set to the value of next for the next page of results.
    Set to the value of previous for the previous page of results.
    No other parameters can be set when this parameter is set.
    | aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== | -| `destination` | *string* | :heavy_minus_sign: | Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). | users:001 | -| `endTime` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_minus_sign: | Filter transactions that occurred before this timestamp.
    The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute).
    | | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `metadata` | Record | :heavy_minus_sign: | Filter transactions by metadata key value pairs. Nested objects can be used as seen in the example below. | | -| `pageSize` | *number* | :heavy_minus_sign: | The maximum number of results to return per page.
    | | -| `reference` | *string* | :heavy_minus_sign: | Find transactions by reference field. | ref:001 | -| `source` | *string* | :heavy_minus_sign: | Filter transactions with postings involving given account at source (regular expression placed between ^ and $). | users:001 | -| `startTime` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_minus_sign: | Filter transactions that occurred after this timestamp.
    The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute).
    | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/listtransactionsresponse.md b/sdks/typescript/docs/models/operations/listtransactionsresponse.md deleted file mode 100755 index f4324aed5..000000000 --- a/sdks/typescript/docs/models/operations/listtransactionsresponse.md +++ /dev/null @@ -1,12 +0,0 @@ -# ListTransactionsResponse - - -## Fields - -| Field | Type | Required | Description | -| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -| `contentType` | *string* | :heavy_check_mark: | N/A | -| `errorResponse` | [shared.ErrorResponse](../../models/shared/errorresponse.md) | :heavy_minus_sign: | Error | -| `statusCode` | *number* | :heavy_check_mark: | N/A | -| `rawResponse` | [AxiosResponse>](https://axios-http.com/docs/res_schema) | :heavy_minus_sign: | N/A | -| `transactionsCursorResponse` | [shared.TransactionsCursorResponse](../../models/shared/transactionscursorresponse.md) | :heavy_minus_sign: | OK | \ No newline at end of file diff --git a/sdks/typescript/docs/models/operations/reverttransactionrequest.md b/sdks/typescript/docs/models/operations/reverttransactionrequest.md index 875b5254d..1b59c0b38 100755 --- a/sdks/typescript/docs/models/operations/reverttransactionrequest.md +++ b/sdks/typescript/docs/models/operations/reverttransactionrequest.md @@ -5,5 +5,5 @@ | Field | Type | Required | Description | Example | | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | -| `txid` | *number* | :heavy_check_mark: | Transaction ID. | 1234 | \ No newline at end of file +| `id` | *number* | :heavy_check_mark: | Transaction ID. | 1234 | +| `ledger` | *string* | :heavy_check_mark: | Name of the ledger. | ledger001 | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/account.md b/sdks/typescript/docs/models/shared/account.md deleted file mode 100755 index 9ebfbb918..000000000 --- a/sdks/typescript/docs/models/shared/account.md +++ /dev/null @@ -1,9 +0,0 @@ -# Account - - -## Fields - -| Field | Type | Required | Description | Example | -| ------------------------ | ------------------------ | ------------------------ | ------------------------ | ------------------------ | -| `address` | *string* | :heavy_check_mark: | N/A | users:001 | -| `metadata` | Record | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/accountscursorresponse.md b/sdks/typescript/docs/models/shared/accountscursorresponse.md deleted file mode 100755 index f2cf2269e..000000000 --- a/sdks/typescript/docs/models/shared/accountscursorresponse.md +++ /dev/null @@ -1,10 +0,0 @@ -# AccountsCursorResponse - -OK - - -## Fields - -| Field | Type | Required | Description | -| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | -| `cursor` | [AccountsCursorResponseCursor](../../models/shared/accountscursorresponsecursor.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/accountscursorresponsecursor.md b/sdks/typescript/docs/models/shared/accountscursorresponsecursor.md deleted file mode 100755 index 45c14f28e..000000000 --- a/sdks/typescript/docs/models/shared/accountscursorresponsecursor.md +++ /dev/null @@ -1,12 +0,0 @@ -# AccountsCursorResponseCursor - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -| `data` | [Account](../../models/shared/account.md)[] | :heavy_check_mark: | N/A | | -| `hasMore` | *boolean* | :heavy_check_mark: | N/A | false | -| `next` | *string* | :heavy_minus_sign: | N/A | | -| `pageSize` | *number* | :heavy_check_mark: | N/A | 15 | -| `previous` | *string* | :heavy_minus_sign: | N/A | YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/accountwithvolumesandbalances.md b/sdks/typescript/docs/models/shared/accountwithvolumesandbalances.md index 49b6b014e..94f265abb 100755 --- a/sdks/typescript/docs/models/shared/accountwithvolumesandbalances.md +++ b/sdks/typescript/docs/models/shared/accountwithvolumesandbalances.md @@ -6,7 +6,6 @@ | Field | Type | Required | Description | Example | | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | | `address` | *string* | :heavy_check_mark: | N/A | users:001 | -| `balances` | Record | :heavy_check_mark: | N/A | | | `metadata` | Record | :heavy_check_mark: | N/A | | | `type` | *string* | :heavy_minus_sign: | N/A | virtual | -| `volumes` | Record> | :heavy_check_mark: | N/A | | \ No newline at end of file +| `volumes` | Record> | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/balancescursorresponse.md b/sdks/typescript/docs/models/shared/balancescursorresponse.md deleted file mode 100755 index 772cfc7f7..000000000 --- a/sdks/typescript/docs/models/shared/balancescursorresponse.md +++ /dev/null @@ -1,10 +0,0 @@ -# BalancesCursorResponse - -OK - - -## Fields - -| Field | Type | Required | Description | -| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | -| `cursor` | [BalancesCursorResponseCursor](../../models/shared/balancescursorresponsecursor.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/balancescursorresponsecursor.md b/sdks/typescript/docs/models/shared/balancescursorresponsecursor.md deleted file mode 100755 index c05e7a38e..000000000 --- a/sdks/typescript/docs/models/shared/balancescursorresponsecursor.md +++ /dev/null @@ -1,12 +0,0 @@ -# BalancesCursorResponseCursor - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -| `data` | Record>[] | :heavy_check_mark: | N/A | | -| `hasMore` | *boolean* | :heavy_check_mark: | N/A | false | -| `next` | *string* | :heavy_minus_sign: | N/A | | -| `pageSize` | *number* | :heavy_check_mark: | N/A | 15 | -| `previous` | *string* | :heavy_minus_sign: | N/A | YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/expandedtransaction.md b/sdks/typescript/docs/models/shared/expandedtransaction.md index 16645cc58..5474669b0 100755 --- a/sdks/typescript/docs/models/shared/expandedtransaction.md +++ b/sdks/typescript/docs/models/shared/expandedtransaction.md @@ -5,10 +5,11 @@ | Field | Type | Required | Description | Example | | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `id` | *number* | :heavy_check_mark: | N/A | | | `metadata` | Record | :heavy_check_mark: | N/A | | -| `postCommitVolumes` | Record> | :heavy_check_mark: | N/A | | +| `postCommitVolumes` | Record> | :heavy_minus_sign: | N/A | | | `postings` | [Posting](../../models/shared/posting.md)[] | :heavy_check_mark: | N/A | | -| `preCommitVolumes` | Record> | :heavy_check_mark: | N/A | | +| `preCommitVolumes` | Record> | :heavy_minus_sign: | N/A | | | `reference` | *string* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_check_mark: | N/A | | -| `txid` | *number* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `reverted` | *boolean* | :heavy_check_mark: | N/A | | +| `timestamp` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/log.md b/sdks/typescript/docs/models/shared/log.md deleted file mode 100755 index 0e1072d3f..000000000 --- a/sdks/typescript/docs/models/shared/log.md +++ /dev/null @@ -1,12 +0,0 @@ -# Log - - -## Fields - -| Field | Type | Required | Description | Example | -| --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -| `data` | Record | :heavy_check_mark: | N/A | | -| `date` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_check_mark: | N/A | | -| `hash` | *string* | :heavy_check_mark: | N/A | 9ee060170400f556b7e1575cb13f9db004f150a08355c7431c62bc639166431e | -| `id` | *number* | :heavy_check_mark: | N/A | 1234 | -| `type` | [LogType](../../models/shared/logtype.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/logscursorresponse.md b/sdks/typescript/docs/models/shared/logscursorresponse.md deleted file mode 100755 index a8213fbfb..000000000 --- a/sdks/typescript/docs/models/shared/logscursorresponse.md +++ /dev/null @@ -1,10 +0,0 @@ -# LogsCursorResponse - -OK - - -## Fields - -| Field | Type | Required | Description | -| --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -| `cursor` | [LogsCursorResponseCursor](../../models/shared/logscursorresponsecursor.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/logscursorresponsecursor.md b/sdks/typescript/docs/models/shared/logscursorresponsecursor.md deleted file mode 100755 index b9b178949..000000000 --- a/sdks/typescript/docs/models/shared/logscursorresponsecursor.md +++ /dev/null @@ -1,12 +0,0 @@ -# LogsCursorResponseCursor - - -## Fields - -| Field | Type | Required | Description | Example | -| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -| `data` | [Log](../../models/shared/log.md)[] | :heavy_check_mark: | N/A | | -| `hasMore` | *boolean* | :heavy_check_mark: | N/A | false | -| `next` | *string* | :heavy_minus_sign: | N/A | | -| `pageSize` | *number* | :heavy_check_mark: | N/A | 15 | -| `previous` | *string* | :heavy_minus_sign: | N/A | YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/logtype.md b/sdks/typescript/docs/models/shared/logtype.md deleted file mode 100755 index cdf308896..000000000 --- a/sdks/typescript/docs/models/shared/logtype.md +++ /dev/null @@ -1,10 +0,0 @@ -# LogType - - -## Values - -| Name | Value | -| --------------------- | --------------------- | -| `NewTransaction` | NEW_TRANSACTION | -| `SetMetadata` | SET_METADATA | -| `RevertedTransaction` | REVERTED_TRANSACTION | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/posttransactionscriptvars.md b/sdks/typescript/docs/models/shared/posttransactionscriptvars.md new file mode 100755 index 000000000..ef1a0de95 --- /dev/null +++ b/sdks/typescript/docs/models/shared/posttransactionscriptvars.md @@ -0,0 +1,7 @@ +# PostTransactionScriptVars + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/query.md b/sdks/typescript/docs/models/shared/query.md index e3c3042a9..83c439610 100755 --- a/sdks/typescript/docs/models/shared/query.md +++ b/sdks/typescript/docs/models/shared/query.md @@ -11,6 +11,6 @@ | `pageSize` | *number* | :heavy_minus_sign: | N/A | | | `policy` | *string* | :heavy_minus_sign: | N/A | OR | | `raw` | [QueryRaw](../../models/shared/queryraw.md) | :heavy_minus_sign: | N/A | | -| `sort` | *string* | :heavy_minus_sign: | N/A | txid:asc | +| `sort` | *string* | :heavy_minus_sign: | N/A | id:asc | | `target` | *string* | :heavy_minus_sign: | N/A | | | `terms` | *string*[] | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/responsedata.md b/sdks/typescript/docs/models/shared/responsedata.md new file mode 100755 index 000000000..c3a85e750 --- /dev/null +++ b/sdks/typescript/docs/models/shared/responsedata.md @@ -0,0 +1,9 @@ +# ResponseData + +The payload + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/transaction.md b/sdks/typescript/docs/models/shared/transaction.md index c2ebb5f1b..50538e585 100755 --- a/sdks/typescript/docs/models/shared/transaction.md +++ b/sdks/typescript/docs/models/shared/transaction.md @@ -5,8 +5,9 @@ | Field | Type | Required | Description | Example | | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `id` | *number* | :heavy_check_mark: | N/A | | | `metadata` | Record | :heavy_check_mark: | N/A | | | `postings` | [Posting](../../models/shared/posting.md)[] | :heavy_check_mark: | N/A | | | `reference` | *string* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_check_mark: | N/A | | -| `txid` | *number* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `reverted` | *boolean* | :heavy_check_mark: | N/A | | +| `timestamp` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/transactionscursorresponse.md b/sdks/typescript/docs/models/shared/transactionscursorresponse.md deleted file mode 100755 index e190e98fe..000000000 --- a/sdks/typescript/docs/models/shared/transactionscursorresponse.md +++ /dev/null @@ -1,10 +0,0 @@ -# TransactionsCursorResponse - -OK - - -## Fields - -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -| `cursor` | [TransactionsCursorResponseCursor](../../models/shared/transactionscursorresponsecursor.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/transactionscursorresponsecursor.md b/sdks/typescript/docs/models/shared/transactionscursorresponsecursor.md deleted file mode 100755 index 5be82ef24..000000000 --- a/sdks/typescript/docs/models/shared/transactionscursorresponsecursor.md +++ /dev/null @@ -1,12 +0,0 @@ -# TransactionsCursorResponseCursor - - -## Fields - -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | -| `data` | [ExpandedTransaction](../../models/shared/expandedtransaction.md)[] | :heavy_check_mark: | N/A | | -| `hasMore` | *boolean* | :heavy_check_mark: | N/A | false | -| `next` | *string* | :heavy_minus_sign: | N/A | | -| `pageSize` | *number* | :heavy_check_mark: | N/A | 15 | -| `previous` | *string* | :heavy_minus_sign: | N/A | YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= | \ No newline at end of file diff --git a/sdks/typescript/docs/models/shared/walletstransaction.md b/sdks/typescript/docs/models/shared/walletstransaction.md index 43bcb386c..82b5c9482 100755 --- a/sdks/typescript/docs/models/shared/walletstransaction.md +++ b/sdks/typescript/docs/models/shared/walletstransaction.md @@ -5,11 +5,11 @@ | Field | Type | Required | Description | Example | | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `id` | *number* | :heavy_minus_sign: | N/A | | | `ledger` | *string* | :heavy_minus_sign: | N/A | | | `metadata` | Record | :heavy_check_mark: | Metadata associated with the wallet. | | | `postCommitVolumes` | Record> | :heavy_minus_sign: | N/A | | | `postings` | [Posting](../../models/shared/posting.md)[] | :heavy_check_mark: | N/A | | | `preCommitVolumes` | Record> | :heavy_minus_sign: | N/A | | | `reference` | *string* | :heavy_minus_sign: | N/A | ref:001 | -| `timestamp` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_check_mark: | N/A | | -| `txid` | *number* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `timestamp` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/sdks/typescript/docs/sdks/ledger/README.md b/sdks/typescript/docs/sdks/ledger/README.md index fa30c0f68..cd938a111 100755 --- a/sdks/typescript/docs/sdks/ledger/README.md +++ b/sdks/typescript/docs/sdks/ledger/README.md @@ -8,14 +8,10 @@ * [countTransactions](#counttransactions) - Count the transactions from a ledger * [createTransaction](#createtransaction) - Create a new transaction to a ledger * [getAccount](#getaccount) - Get account by its address -* [getBalances](#getbalances) - Get the balances from a ledger's account * [getBalancesAggregated](#getbalancesaggregated) - Get the aggregated balances from selected accounts * [getInfo](#getinfo) - Show server information * [getLedgerInfo](#getledgerinfo) - Get information about a ledger * [getTransaction](#gettransaction) - Get transaction from a ledger by its ID -* [listAccounts](#listaccounts) - List accounts from a ledger -* [listLogs](#listlogs) - List the logs from a ledger -* [listTransactions](#listtransactions) - List transactions from a ledger * [readStats](#readstats) - Get statistics from a ledger * [revertTransaction](#reverttransaction) - Revert a ledger transaction by its ID @@ -41,10 +37,9 @@ sdk.ledger.addMetadataOnTransaction({ "explicabo": "nobis", "enim": "omnis", }, - async: true, dryRun: true, + id: 1234, ledger: "ledger001", - txid: 1234, }).then((res: AddMetadataOnTransactionResponse) => { if (res.statusCode == 200) { // handle response @@ -88,7 +83,6 @@ sdk.ledger.addMetadataToAccount({ "iure": "culpa", }, address: "users:001", - async: true, dryRun: true, ledger: "ledger001", }).then((res: AddMetadataToAccountResponse) => { @@ -128,9 +122,13 @@ const sdk = new SDK({ }); sdk.ledger.countAccounts({ - address: "users:.+", + requestBody: { + "sapiente": "architecto", + "mollitia": "dolorem", + "culpa": "consequuntur", + "repellat": "mollitia", + }, ledger: "ledger001", - metadata: {}, }).then((res: CountAccountsResponse) => { if (res.statusCode == 200) { // handle response @@ -168,16 +166,13 @@ const sdk = new SDK({ }); sdk.ledger.countTransactions({ - account: "users:001", - destination: "users:001", - endTime: new Date("2020-02-15T22:48:47.492Z"), - ledger: "ledger001", - metadata: { - "mollitia": "dolorem", + requestBody: { + "numquam": "commodi", + "quam": "molestiae", + "velit": "error", }, - reference: "ref:001", - source: "users:001", - startTime: new Date("2022-09-05T05:51:25.673Z"), + ledger: "ledger001", + pit: new Date("2022-08-30T15:03:11.112Z"), }).then((res: CountTransactionsResponse) => { if (res.statusCode == 200) { // handle response @@ -215,12 +210,12 @@ const sdk = new SDK({ }); sdk.ledger.createTransaction({ - idempotencyKey: "repellat", + idempotencyKey: "vitae", postTransaction: { metadata: { - "occaecati": "numquam", - "commodi": "quam", - "molestiae": "velit", + "animi": "enim", + "odit": "quo", + "sequi": "tenetur", }, postings: [ { @@ -235,12 +230,6 @@ sdk.ledger.createTransaction({ destination: "users:002", source: "users:001", }, - { - amount: 100, - asset: "COIN", - destination: "users:002", - source: "users:001", - }, ], reference: "ref:001", script: { @@ -253,12 +242,13 @@ sdk.ledger.createTransaction({ ) ", vars: { - "quis": "vitae", + "possimus": "aut", + "quasi": "error", + "temporibus": "laborum", }, }, - timestamp: new Date("2021-09-08T21:06:19.630Z"), + timestamp: new Date("2022-01-11T05:45:42.485Z"), }, - async: true, dryRun: true, ledger: "ledger001", }).then((res: CreateTransactionResponse) => { @@ -299,6 +289,7 @@ const sdk = new SDK({ sdk.ledger.getAccount({ address: "users:001", + expand: "voluptatibus", ledger: "ledger001", }).then((res: GetAccountResponse) => { if (res.statusCode == 200) { @@ -320,47 +311,6 @@ sdk.ledger.getAccount({ **Promise<[operations.GetAccountResponse](../../models/operations/getaccountresponse.md)>** -## getBalances - -Get the balances from a ledger's account - -### Example Usage - -```typescript -import { SDK } from "@formance/formance-sdk"; -import { GetBalancesResponse } from "@formance/formance-sdk/dist/sdk/models/operations"; - -const sdk = new SDK({ - security: { - authorization: "", - }, -}); - -sdk.ledger.getBalances({ - address: "users:001", - cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - ledger: "ledger001", - pageSize: 317202, -}).then((res: GetBalancesResponse) => { - if (res.statusCode == 200) { - // handle response - } -}); -``` - -### Parameters - -| Parameter | Type | Required | Description | -| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | -| `request` | [operations.GetBalancesRequest](../../models/operations/getbalancesrequest.md) | :heavy_check_mark: | The request object to use for the request. | -| `config` | [AxiosRequestConfig](https://axios-http.com/docs/req_config) | :heavy_minus_sign: | Available config options for making requests. | - - -### Response - -**Promise<[operations.GetBalancesResponse](../../models/operations/getbalancesresponse.md)>** - - ## getBalancesAggregated Get the aggregated balances from selected accounts @@ -378,7 +328,6 @@ const sdk = new SDK({ }); sdk.ledger.getBalancesAggregated({ - address: "users:001", ledger: "ledger001", }).then((res: GetBalancesAggregatedResponse) => { if (res.statusCode == 200) { @@ -490,8 +439,9 @@ const sdk = new SDK({ }); sdk.ledger.getTransaction({ + expand: "vero", + id: 1234, ledger: "ledger001", - txid: 1234, }).then((res: GetTransactionResponse) => { if (res.statusCode == 200) { // handle response @@ -512,143 +462,6 @@ sdk.ledger.getTransaction({ **Promise<[operations.GetTransactionResponse](../../models/operations/gettransactionresponse.md)>** -## listAccounts - -List accounts from a ledger, sorted by address in descending order. - -### Example Usage - -```typescript -import { SDK } from "@formance/formance-sdk"; -import { ListAccountsResponse } from "@formance/formance-sdk/dist/sdk/models/operations"; - -const sdk = new SDK({ - security: { - authorization: "", - }, -}); - -sdk.ledger.listAccounts({ - address: "users:.+", - cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - ledger: "ledger001", - metadata: { - "quo": "sequi", - }, - pageSize: 949572, -}).then((res: ListAccountsResponse) => { - if (res.statusCode == 200) { - // handle response - } -}); -``` - -### Parameters - -| Parameter | Type | Required | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -| `request` | [operations.ListAccountsRequest](../../models/operations/listaccountsrequest.md) | :heavy_check_mark: | The request object to use for the request. | -| `config` | [AxiosRequestConfig](https://axios-http.com/docs/req_config) | :heavy_minus_sign: | Available config options for making requests. | - - -### Response - -**Promise<[operations.ListAccountsResponse](../../models/operations/listaccountsresponse.md)>** - - -## listLogs - -List the logs from a ledger, sorted by ID in descending order. - -### Example Usage - -```typescript -import { SDK } from "@formance/formance-sdk"; -import { ListLogsResponse } from "@formance/formance-sdk/dist/sdk/models/operations"; - -const sdk = new SDK({ - security: { - authorization: "", - }, -}); - -sdk.ledger.listLogs({ - cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - endTime: new Date("2022-05-04T04:15:52.352Z"), - ledger: "ledger001", - pageSize: 820994, - startTime: new Date("2022-11-26T13:23:33.410Z"), -}).then((res: ListLogsResponse) => { - if (res.statusCode == 200) { - // handle response - } -}); -``` - -### Parameters - -| Parameter | Type | Required | Description | -| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | -| `request` | [operations.ListLogsRequest](../../models/operations/listlogsrequest.md) | :heavy_check_mark: | The request object to use for the request. | -| `config` | [AxiosRequestConfig](https://axios-http.com/docs/req_config) | :heavy_minus_sign: | Available config options for making requests. | - - -### Response - -**Promise<[operations.ListLogsResponse](../../models/operations/listlogsresponse.md)>** - - -## listTransactions - -List transactions from a ledger, sorted by txid in descending order. - -### Example Usage - -```typescript -import { SDK } from "@formance/formance-sdk"; -import { ListTransactionsResponse } from "@formance/formance-sdk/dist/sdk/models/operations"; - -const sdk = new SDK({ - security: { - authorization: "", - }, -}); - -sdk.ledger.listTransactions({ - account: "users:001", - cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - destination: "users:001", - endTime: new Date("2021-04-29T07:12:18.684Z"), - ledger: "ledger001", - metadata: { - "quasi": "reiciendis", - "voluptatibus": "vero", - "nihil": "praesentium", - }, - pageSize: 976762, - reference: "ref:001", - source: "users:001", - startTime: new Date("2022-05-25T05:33:11.349Z"), -}).then((res: ListTransactionsResponse) => { - if (res.statusCode == 200) { - // handle response - } -}); -``` - -### Parameters - -| Parameter | Type | Required | Description | -| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -| `request` | [operations.ListTransactionsRequest](../../models/operations/listtransactionsrequest.md) | :heavy_check_mark: | The request object to use for the request. | -| `config` | [AxiosRequestConfig](https://axios-http.com/docs/req_config) | :heavy_minus_sign: | Available config options for making requests. | - - -### Response - -**Promise<[operations.ListTransactionsResponse](../../models/operations/listtransactionsresponse.md)>** - - ## readStats Get statistics from a ledger. (aggregate metrics on accounts and transactions) @@ -705,8 +518,8 @@ const sdk = new SDK({ }); sdk.ledger.revertTransaction({ + id: 1234, ledger: "ledger001", - txid: 1234, }).then((res: RevertTransactionResponse) => { if (res.statusCode == 200) { // handle response diff --git a/sdks/typescript/docs/sdks/orchestration/README.md b/sdks/typescript/docs/sdks/orchestration/README.md index f74922f84..2a59f65eb 100755 --- a/sdks/typescript/docs/sdks/orchestration/README.md +++ b/sdks/typescript/docs/sdks/orchestration/README.md @@ -32,7 +32,7 @@ const sdk = new SDK({ }); sdk.orchestration.cancelEvent({ - instanceID: "voluptate", + instanceID: "nihil", }).then((res: CancelEventResponse) => { if (res.statusCode == 200) { // handle response @@ -70,24 +70,19 @@ const sdk = new SDK({ }); sdk.orchestration.createWorkflow({ - name: "Thomas Batz", + name: "Jan Bednar", stages: [ { + "doloremque": "reprehenderit", + }, + { + "maiores": "dicta", "corporis": "dolore", }, { "dicta": "harum", "enim": "accusamus", }, - { - "repudiandae": "quae", - "ipsum": "quidem", - }, - { - "excepturi": "pariatur", - "modi": "praesentium", - "rem": "voluptates", - }, ], }).then((res: CreateWorkflowResponse) => { if (res.statusCode == 200) { @@ -126,7 +121,7 @@ const sdk = new SDK({ }); sdk.orchestration.deleteWorkflow({ - flowId: "quasi", + flowId: "commodi", }).then((res: DeleteWorkflowResponse) => { if (res.statusCode == 200) { // handle response @@ -202,7 +197,7 @@ const sdk = new SDK({ }); sdk.orchestration.getInstanceHistory({ - instanceID: "sint", + instanceID: "quae", }).then((res: GetInstanceHistoryResponse) => { if (res.statusCode == 200) { // handle response @@ -240,8 +235,8 @@ const sdk = new SDK({ }); sdk.orchestration.getInstanceStageHistory({ - instanceID: "veritatis", - number: 929297, + instanceID: "ipsum", + number: 692472, }).then((res: GetInstanceStageHistoryResponse) => { if (res.statusCode == 200) { // handle response @@ -279,7 +274,7 @@ const sdk = new SDK({ }); sdk.orchestration.getWorkflow({ - flowId: "incidunt", + flowId: "molestias", }).then((res: GetWorkflowResponse) => { if (res.statusCode == 200) { // handle response @@ -318,7 +313,7 @@ const sdk = new SDK({ sdk.orchestration.listInstances({ running: false, - workflowID: "enim", + workflowID: "excepturi", }).then((res: ListInstancesResponse) => { if (res.statusCode == 200) { // handle response @@ -427,10 +422,13 @@ const sdk = new SDK({ sdk.orchestration.runWorkflow({ requestBody: { - "est": "quibusdam", + "modi": "praesentium", + "rem": "voluptates", + "quasi": "repudiandae", + "sint": "veritatis", }, wait: false, - workflowID: "explicabo", + workflowID: "itaque", }).then((res: RunWorkflowResponse) => { if (res.statusCode == 200) { // handle response @@ -469,9 +467,9 @@ const sdk = new SDK({ sdk.orchestration.sendEvent({ requestBody: { - name: "Rudy Spencer", + name: "Erin Altenwerth", }, - instanceID: "qui", + instanceID: "explicabo", }).then((res: SendEventResponse) => { if (res.statusCode == 200) { // handle response diff --git a/sdks/typescript/docs/sdks/payments/README.md b/sdks/typescript/docs/sdks/payments/README.md index c6bac342b..4804ba1c0 100755 --- a/sdks/typescript/docs/sdks/payments/README.md +++ b/sdks/typescript/docs/sdks/payments/README.md @@ -86,7 +86,7 @@ sdk.payments.connectorsTransfer({ destination: "acct_1Gqj58KZcSIg2N2q", source: "acct_1Gqj58KZcSIg2N2q", }, - connector: Connector.Modulr, + connector: Connector.BankingCircle, }).then((res: ConnectorsTransferResponse) => { if (res.statusCode == 200) { // handle response @@ -124,16 +124,18 @@ const sdk = new SDK({ }); sdk.payments.getAccountBalances({ - accountId: "cupiditate", - asset: "quos", + accountId: "distinctio", + asset: "quibusdam", cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - from: new Date("2022-11-01T19:07:16.800Z"), - limit: 828940, - pageSize: 369808, + from: new Date("2022-09-26T08:57:48.803Z"), + limit: 183191, + pageSize: 397821, sort: [ - "fugit", + "quos", + "perferendis", + "magni", ], - to: new Date("2021-11-11T04:17:07.569Z"), + to: new Date("2021-11-22T01:26:35.048Z"), }).then((res: GetAccountBalancesResponse) => { if (res.statusCode == 200) { // handle response @@ -172,8 +174,8 @@ const sdk = new SDK({ }); sdk.payments.getConnectorTask({ - connector: Connector.Wise, - taskId: "facilis", + connector: Connector.Stripe, + taskId: "fugit", }).then((res: GetConnectorTaskResponse) => { if (res.statusCode == 200) { // handle response @@ -211,7 +213,7 @@ const sdk = new SDK({ }); sdk.payments.getPayment({ - paymentId: "tempore", + paymentId: "dolorum", }).then((res: GetPaymentResponse) => { if (res.statusCode == 200) { // handle response @@ -252,9 +254,11 @@ const sdk = new SDK({ sdk.payments.installConnector({ requestBody: { apiKey: "XXX", + endpoint: "XXX", + loginID: "XXX", pollingPeriod: "60s", }, - connector: Connector.Moneycorp, + connector: Connector.Wise, }).then((res: InstallConnectorResponse) => { if (res.statusCode == 200) { // handle response @@ -363,9 +367,9 @@ const sdk = new SDK({ }); sdk.payments.listConnectorTasks({ - connector: Connector.Modulr, + connector: Connector.BankingCircle, cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - pageSize: 248753, + pageSize: 735194, }).then((res: ListConnectorTasksResponse) => { if (res.statusCode == 200) { // handle response @@ -404,7 +408,7 @@ const sdk = new SDK({ }); sdk.payments.listConnectorsTransfers({ - connector: Connector.Mangopay, + connector: Connector.Wise, }).then((res: ListConnectorsTransfersResponse) => { if (res.statusCode == 200) { // handle response @@ -443,10 +447,10 @@ const sdk = new SDK({ sdk.payments.listPayments({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - pageSize: 576157, + pageSize: 962189, sort: [ - "provident", - "necessitatibus", + "non", + "eligendi", ], }).then((res: ListPaymentsResponse) => { if (res.statusCode == 200) { @@ -559,9 +563,11 @@ const sdk = new SDK({ sdk.payments.paymentslistAccounts({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - pageSize: 638921, + pageSize: 396098, sort: [ - "debitis", + "necessitatibus", + "sint", + "officia", ], }).then((res: PaymentslistAccountsResponse) => { if (res.statusCode == 200) { @@ -601,7 +607,7 @@ const sdk = new SDK({ }); sdk.payments.readConnectorConfig({ - connector: Connector.Moneycorp, + connector: Connector.DummyPay, }).then((res: ReadConnectorConfigResponse) => { if (res.statusCode == 200) { // handle response @@ -642,7 +648,7 @@ const sdk = new SDK({ }); sdk.payments.resetConnector({ - connector: Connector.BankingCircle, + connector: Connector.Moneycorp, }).then((res: ResetConnectorResponse) => { if (res.statusCode == 200) { // handle response @@ -681,7 +687,7 @@ const sdk = new SDK({ }); sdk.payments.uninstallConnector({ - connector: Connector.Modulr, + connector: Connector.Moneycorp, }).then((res: UninstallConnectorResponse) => { if (res.statusCode == 200) { // handle response @@ -720,9 +726,9 @@ const sdk = new SDK({ sdk.payments.updateMetadata({ paymentMetadata: { - key: "in", + key: "dolorum", }, - paymentId: "illum", + paymentId: "in", }).then((res: UpdateMetadataResponse) => { if (res.statusCode == 200) { // handle response diff --git a/sdks/typescript/docs/sdks/search/README.md b/sdks/typescript/docs/sdks/search/README.md index bc6bea580..3b41ab2df 100755 --- a/sdks/typescript/docs/sdks/search/README.md +++ b/sdks/typescript/docs/sdks/search/README.md @@ -25,25 +25,21 @@ sdk.search.search({ after: [ "users:002", "users:002", - "users:002", - "users:002", ], cursor: "YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol=", ledgers: [ "quickstart", "quickstart", "quickstart", + "quickstart", ], - pageSize: 116202, + pageSize: 978571, policy: "OR", raw: {}, - sort: "txid:asc", - target: "magnam", + sort: "id:asc", + target: "rerum", terms: [ "destination=central_bank1", - "destination=central_bank1", - "destination=central_bank1", - "destination=central_bank1", ], }).then((res: SearchResponse) => { if (res.statusCode == 200) { diff --git a/sdks/typescript/docs/sdks/wallets/README.md b/sdks/typescript/docs/sdks/wallets/README.md index a79a47640..1f5240179 100755 --- a/sdks/typescript/docs/sdks/wallets/README.md +++ b/sdks/typescript/docs/sdks/wallets/README.md @@ -40,7 +40,7 @@ sdk.wallets.confirmHold({ amount: 100, final: true, }, - holdId: "facere", + holdId: "magnam", }).then((res: ConfirmHoldResponse) => { if (res.statusCode == 200) { // handle response @@ -79,11 +79,11 @@ const sdk = new SDK({ sdk.wallets.createBalance({ createBalanceRequest: { - expiresAt: new Date("2022-08-09T06:36:34.417Z"), - name: "Tomas Friesen", - priority: 881736, + expiresAt: new Date("2020-07-23T21:23:35.691Z"), + name: "Beth Padberg", + priority: 581273, }, - id: "fb9ba88f-3a66-4997-874b-a4469b6e2141", + id: "5efb9ba8-8f3a-4669-9707-4ba4469b6e21", }).then((res: CreateBalanceResponse) => { if (res.statusCode == 200) { // handle response @@ -122,11 +122,10 @@ const sdk = new SDK({ sdk.wallets.createWallet({ metadata: { + "et": "excepturi", "ullam": "provident", - "quos": "sint", - "accusantium": "mollitia", }, - name: "Shaun Hammes", + name: "Kirk Bartoletti", }).then((res: CreateWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -166,27 +165,22 @@ const sdk = new SDK({ sdk.wallets.creditWallet({ creditWalletRequest: { amount: { - amount: 896547, - asset: "odit", + amount: 652103, + asset: "ad", }, - balance: "nemo", + balance: "eum", metadata: { - "iure": "doloribus", + "necessitatibus": "odit", }, - reference: "debitis", + reference: "nemo", sources: [ { - balance: "deleniti", - identifier: "facilis", - type: "in", - }, - { - identifier: "architecto", - type: "repudiandae", + identifier: "doloribus", + type: "debitis", }, ], }, - id: "5b7fd2ed-0289-421c-9dc6-92601fb576b0", + id: "4c8b711e-5b7f-4d2e-9028-921cddc69260", }).then((res: CreditWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -226,28 +220,28 @@ const sdk = new SDK({ sdk.wallets.debitWallet({ debitWalletRequest: { amount: { - amount: 866383, - asset: "nemo", + amount: 69167, + asset: "maiores", }, balances: [ - "perferendis", - "fugiat", - "amet", - "aut", + "ipsam", + "voluptate", + "autem", ], - description: "cumque", + description: "nam", destination: { - identifier: "hic", - type: "libero", + identifier: "pariatur", + type: "nemo", }, metadata: { - "dolores": "quis", - "totam": "dignissimos", - "eaque": "quis", + "perferendis": "fugiat", + "amet": "aut", + "cumque": "corporis", + "hic": "libero", }, pending: false, }, - id: "3202c73d-5fe9-4b90-8289-09b3fe49a8d9", + id: "b2587053-202c-473d-9fe9-b90c28909b3f", }).then((res: DebitWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -285,8 +279,8 @@ const sdk = new SDK({ }); sdk.wallets.getBalance({ - balanceName: "nobis", - id: "bf486333-23f9-4b77-b3a4-100674ebf692", + balanceName: "earum", + id: "49a8d9cb-f486-4333-a3f9-b77f3a410067", }).then((res: GetBalanceResponse) => { if (res.statusCode == 200) { // handle response @@ -324,7 +318,7 @@ const sdk = new SDK({ }); sdk.wallets.getHold({ - holdID: "atque", + holdID: "quaerat", }).then((res: GetHoldResponse) => { if (res.statusCode == 200) { // handle response @@ -364,10 +358,13 @@ const sdk = new SDK({ sdk.wallets.getHolds({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", metadata: { - "fugiat": "ab", + "quidem": "voluptatibus", + "voluptas": "natus", + "eos": "atque", + "sit": "fugiat", }, - pageSize: 743835, - walletID: "dolorum", + pageSize: 67249, + walletID: "soluta", }).then((res: GetHoldsResponse) => { if (res.statusCode == 200) { // handle response @@ -404,8 +401,8 @@ const sdk = new SDK({ sdk.wallets.getTransactions({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", - pageSize: 478596, - walletID: "voluptate", + pageSize: 679393, + walletID: "iusto", }).then((res: GetTransactionsResponse) => { if (res.statusCode == 200) { // handle response @@ -443,7 +440,7 @@ const sdk = new SDK({ }); sdk.wallets.getWallet({ - id: "a89ebf73-7ae4-4203-8e5e-6a95d8a0d446", + id: "7a89ebf7-37ae-4420-bce5-e6a95d8a0d44", }).then((res: GetWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -481,7 +478,7 @@ const sdk = new SDK({ }); sdk.wallets.getWalletSummary({ - id: "ce2af7a7-3cf3-4be4-93f8-70b326b5a734", + id: "6ce2af7a-73cf-43be-853f-870b326b5a73", }).then((res: GetWalletSummaryResponse) => { if (res.statusCode == 200) { // handle response @@ -519,7 +516,7 @@ const sdk = new SDK({ }); sdk.wallets.listBalances({ - id: "29cdb1a8-422b-4b67-9d23-22715bf0cbb1", + id: "429cdb1a-8422-4bb6-b9d2-322715bf0cbb", }).then((res: ListBalancesResponse) => { if (res.statusCode == 200) { // handle response @@ -559,13 +556,10 @@ const sdk = new SDK({ sdk.wallets.listWallets({ cursor: "aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ==", metadata: { - "ipsum": "veritatis", - "nobis": "quos", - "tempore": "cupiditate", - "aperiam": "delectus", + "saepe": "ipsum", }, - name: "Joanne Grant", - pageSize: 100294, + name: "Gayle Lueilwitz", + pageSize: 45614, }).then((res: ListWalletsResponse) => { if (res.statusCode == 200) { // handle response @@ -605,10 +599,13 @@ const sdk = new SDK({ sdk.wallets.updateWallet({ requestBody: { metadata: { - "aut": "quas", + "dolorem": "dolore", + "labore": "adipisci", + "dolorum": "architecto", + "quae": "aut", }, }, - id: "e0adcf4b-9218-479f-8e95-3f73ef7fbc7a", + id: "8e0adcf4-b921-4879-bce9-53f73ef7fbc7", }).then((res: UpdateWalletResponse) => { if (res.statusCode == 200) { // handle response @@ -646,7 +643,7 @@ const sdk = new SDK({ }); sdk.wallets.voidHold({ - holdId: "facilis", + holdId: "similique", }).then((res: VoidHoldResponse) => { if (res.statusCode == 200) { // handle response diff --git a/sdks/typescript/docs/sdks/webhooks/README.md b/sdks/typescript/docs/sdks/webhooks/README.md index ee99089e6..890ba5b8a 100755 --- a/sdks/typescript/docs/sdks/webhooks/README.md +++ b/sdks/typescript/docs/sdks/webhooks/README.md @@ -239,7 +239,6 @@ sdk.webhooks.insertConfig({ "TYPE1", "TYPE1", "TYPE1", - "TYPE1", ], secret: "V0bivxRWveaoz08afqjU6Ko/jwO0Cb+3", }).then((res: InsertConfigResponse) => { diff --git a/sdks/typescript/files.gen b/sdks/typescript/files.gen index 05945c5bb..420b8eaab 100755 --- a/sdks/typescript/files.gen +++ b/sdks/typescript/files.gen @@ -50,14 +50,10 @@ src/sdk/models/operations/countaccounts.ts src/sdk/models/operations/counttransactions.ts src/sdk/models/operations/createtransaction.ts src/sdk/models/operations/getaccount.ts -src/sdk/models/operations/getbalances.ts src/sdk/models/operations/getbalancesaggregated.ts src/sdk/models/operations/getinfo.ts src/sdk/models/operations/getledgerinfo.ts src/sdk/models/operations/gettransaction.ts -src/sdk/models/operations/listaccounts.ts -src/sdk/models/operations/listlogs.ts -src/sdk/models/operations/listtransactions.ts src/sdk/models/operations/readstats.ts src/sdk/models/operations/reverttransaction.ts src/sdk/models/operations/cancelevent.ts @@ -147,7 +143,6 @@ src/sdk/models/shared/posting.ts src/sdk/models/shared/posttransaction.ts src/sdk/models/shared/accountresponse.ts src/sdk/models/shared/accountwithvolumesandbalances.ts -src/sdk/models/shared/balancescursorresponse.ts src/sdk/models/shared/aggregatebalancesresponse.ts src/sdk/models/shared/configinforesponse.ts src/sdk/models/shared/configinfo.ts @@ -159,11 +154,6 @@ src/sdk/models/shared/migrationinfo.ts src/sdk/models/shared/gettransactionresponse.ts src/sdk/models/shared/expandedtransaction.ts src/sdk/models/shared/volume.ts -src/sdk/models/shared/accountscursorresponse.ts -src/sdk/models/shared/account.ts -src/sdk/models/shared/logscursorresponse.ts -src/sdk/models/shared/log.ts -src/sdk/models/shared/transactionscursorresponse.ts src/sdk/models/shared/statsresponse.ts src/sdk/models/shared/stats.ts src/sdk/models/shared/reverttransactionresponse.ts @@ -338,7 +328,6 @@ docs/models/operations/addmetadataontransactionrequest.md docs/models/operations/addmetadataontransactionresponse.md docs/models/operations/addmetadatatoaccountrequest.md docs/models/operations/addmetadatatoaccountresponse.md -docs/models/operations/countaccountsmetadata.md docs/models/operations/countaccountsrequest.md docs/models/operations/countaccountsresponse.md docs/models/operations/counttransactionsrequest.md @@ -347,8 +336,6 @@ docs/models/operations/createtransactionrequest.md docs/models/operations/createtransactionresponse.md docs/models/operations/getaccountrequest.md docs/models/operations/getaccountresponse.md -docs/models/operations/getbalancesrequest.md -docs/models/operations/getbalancesresponse.md docs/models/operations/getbalancesaggregatedrequest.md docs/models/operations/getbalancesaggregatedresponse.md docs/models/operations/getinforesponse.md @@ -356,12 +343,6 @@ docs/models/operations/getledgerinforequest.md docs/models/operations/getledgerinforesponse.md docs/models/operations/gettransactionrequest.md docs/models/operations/gettransactionresponse.md -docs/models/operations/listaccountsrequest.md -docs/models/operations/listaccountsresponse.md -docs/models/operations/listlogsrequest.md -docs/models/operations/listlogsresponse.md -docs/models/operations/listtransactionsrequest.md -docs/models/operations/listtransactionsresponse.md docs/models/operations/readstatsrequest.md docs/models/operations/readstatsresponse.md docs/models/operations/reverttransactionrequest.md @@ -498,8 +479,6 @@ docs/models/shared/posttransactionscript.md docs/models/shared/posttransaction.md docs/models/shared/accountresponse.md docs/models/shared/accountwithvolumesandbalances.md -docs/models/shared/balancescursorresponsecursor.md -docs/models/shared/balancescursorresponse.md docs/models/shared/aggregatebalancesresponse.md docs/models/shared/configinforesponse.md docs/models/shared/configinfo.md @@ -513,15 +492,6 @@ docs/models/shared/migrationinfo.md docs/models/shared/gettransactionresponse.md docs/models/shared/expandedtransaction.md docs/models/shared/volume.md -docs/models/shared/accountscursorresponsecursor.md -docs/models/shared/accountscursorresponse.md -docs/models/shared/account.md -docs/models/shared/logscursorresponsecursor.md -docs/models/shared/logscursorresponse.md -docs/models/shared/logtype.md -docs/models/shared/log.md -docs/models/shared/transactionscursorresponsecursor.md -docs/models/shared/transactionscursorresponse.md docs/models/shared/statsresponse.md docs/models/shared/stats.md docs/models/shared/reverttransactionresponse.md diff --git a/sdks/typescript/src/sdk/ledger.ts b/sdks/typescript/src/sdk/ledger.ts index 9ca8d6ba9..728ff1552 100755 --- a/sdks/typescript/src/sdk/ledger.ts +++ b/sdks/typescript/src/sdk/ledger.ts @@ -33,7 +33,7 @@ export class Ledger { ); const url: string = utils.generateURL( baseURL, - "/api/ledger/{ledger}/transactions/{txid}/metadata", + "/api/ledger/v2/{ledger}/transactions/{id}/metadata", req ); @@ -131,7 +131,7 @@ export class Ledger { ); const url: string = utils.generateURL( baseURL, - "/api/ledger/{ledger}/accounts/{address}/metadata", + "/api/ledger/v2/{ledger}/accounts/{address}/metadata", req ); @@ -229,7 +229,17 @@ export class Ledger { this.sdkConfiguration.serverURL, this.sdkConfiguration.serverDefaults ); - const url: string = utils.generateURL(baseURL, "/api/ledger/{ledger}/accounts", req); + const url: string = utils.generateURL(baseURL, "/api/ledger/v2/{ledger}/accounts", req); + + let [reqBodyHeaders, reqBody]: [object, any] = [{}, {}]; + + try { + [reqBodyHeaders, reqBody] = utils.serializeRequestBody(req, "requestBody", "json"); + } catch (e: unknown) { + if (e instanceof Error) { + throw new Error(`Error serializing request body, cause: ${e.message}`); + } + } const client: AxiosInstance = this.sdkConfiguration.defaultClient; let globalSecurity = this.sdkConfiguration.security; if (typeof globalSecurity === "function") { @@ -239,8 +249,7 @@ export class Ledger { globalSecurity = new shared.Security(globalSecurity); } const properties = utils.parseSecurityProperties(globalSecurity); - const headers = { ...config?.headers, ...properties.headers }; - const queryParams: string = utils.serializeQueryParams(req); + const headers = { ...reqBodyHeaders, ...config?.headers, ...properties.headers }; headers["Accept"] = "application/json"; headers[ @@ -249,10 +258,11 @@ export class Ledger { const httpRes: AxiosResponse = await client.request({ validateStatus: () => true, - url: url + queryParams, + url: url, method: "head", headers: headers, responseType: "arraybuffer", + data: reqBody, ...config, }); @@ -307,7 +317,17 @@ export class Ledger { this.sdkConfiguration.serverURL, this.sdkConfiguration.serverDefaults ); - const url: string = utils.generateURL(baseURL, "/api/ledger/{ledger}/transactions", req); + const url: string = utils.generateURL(baseURL, "/api/ledger/v2/{ledger}/transactions", req); + + let [reqBodyHeaders, reqBody]: [object, any] = [{}, {}]; + + try { + [reqBodyHeaders, reqBody] = utils.serializeRequestBody(req, "requestBody", "json"); + } catch (e: unknown) { + if (e instanceof Error) { + throw new Error(`Error serializing request body, cause: ${e.message}`); + } + } const client: AxiosInstance = this.sdkConfiguration.defaultClient; let globalSecurity = this.sdkConfiguration.security; if (typeof globalSecurity === "function") { @@ -317,7 +337,7 @@ export class Ledger { globalSecurity = new shared.Security(globalSecurity); } const properties = utils.parseSecurityProperties(globalSecurity); - const headers = { ...config?.headers, ...properties.headers }; + const headers = { ...reqBodyHeaders, ...config?.headers, ...properties.headers }; const queryParams: string = utils.serializeQueryParams(req); headers["Accept"] = "application/json"; @@ -331,6 +351,7 @@ export class Ledger { method: "head", headers: headers, responseType: "arraybuffer", + data: reqBody, ...config, }); @@ -385,7 +406,7 @@ export class Ledger { this.sdkConfiguration.serverURL, this.sdkConfiguration.serverDefaults ); - const url: string = utils.generateURL(baseURL, "/api/ledger/{ledger}/transactions", req); + const url: string = utils.generateURL(baseURL, "/api/ledger/v2/{ledger}/transactions", req); let [reqBodyHeaders, reqBody]: [object, any] = [{}, {}]; @@ -495,7 +516,7 @@ export class Ledger { ); const url: string = utils.generateURL( baseURL, - "/api/ledger/{ledger}/accounts/{address}", + "/api/ledger/v2/{ledger}/accounts/{address}", req ); const client: AxiosInstance = this.sdkConfiguration.defaultClient; @@ -508,6 +529,7 @@ export class Ledger { } const properties = utils.parseSecurityProperties(globalSecurity); const headers = { ...config?.headers, ...properties.headers }; + const queryParams: string = utils.serializeQueryParams(req); headers["Accept"] = "application/json"; headers[ @@ -516,7 +538,7 @@ export class Ledger { const httpRes: AxiosResponse = await client.request({ validateStatus: () => true, - url: url, + url: url + queryParams, method: "get", headers: headers, responseType: "arraybuffer", @@ -571,96 +593,6 @@ export class Ledger { return res; } - /** - * Get the balances from a ledger's account - */ - async getBalances( - req: operations.GetBalancesRequest, - config?: AxiosRequestConfig - ): Promise { - if (!(req instanceof utils.SpeakeasyBase)) { - req = new operations.GetBalancesRequest(req); - } - - const baseURL: string = utils.templateUrl( - this.sdkConfiguration.serverURL, - this.sdkConfiguration.serverDefaults - ); - const url: string = utils.generateURL(baseURL, "/api/ledger/{ledger}/balances", req); - const client: AxiosInstance = this.sdkConfiguration.defaultClient; - let globalSecurity = this.sdkConfiguration.security; - if (typeof globalSecurity === "function") { - globalSecurity = await globalSecurity(); - } - if (!(globalSecurity instanceof utils.SpeakeasyBase)) { - globalSecurity = new shared.Security(globalSecurity); - } - const properties = utils.parseSecurityProperties(globalSecurity); - const headers = { ...config?.headers, ...properties.headers }; - const queryParams: string = utils.serializeQueryParams(req); - headers["Accept"] = "application/json"; - - headers[ - "user-agent" - ] = `speakeasy-sdk/${this.sdkConfiguration.language} ${this.sdkConfiguration.sdkVersion} ${this.sdkConfiguration.genVersion} ${this.sdkConfiguration.openapiDocVersion}`; - - const httpRes: AxiosResponse = await client.request({ - validateStatus: () => true, - url: url + queryParams, - method: "get", - headers: headers, - responseType: "arraybuffer", - ...config, - }); - - const contentType: string = httpRes?.headers?.["content-type"] ?? ""; - - if (httpRes?.status == null) { - throw new Error(`status code not found in response: ${httpRes}`); - } - - const res: operations.GetBalancesResponse = new operations.GetBalancesResponse({ - statusCode: httpRes.status, - contentType: contentType, - rawResponse: httpRes, - }); - const decodedRes = new TextDecoder().decode(httpRes?.data); - switch (true) { - case httpRes?.status == 200: - if (utils.matchContentType(contentType, `application/json`)) { - res.balancesCursorResponse = utils.objectToClass( - JSON.parse(decodedRes), - shared.BalancesCursorResponse - ); - } else { - throw new errors.SDKError( - "unknown content-type received: " + contentType, - httpRes.status, - decodedRes, - httpRes - ); - } - break; - default: - if (utils.matchContentType(contentType, `application/json`)) { - res.errorResponse = utils.objectToClass( - JSON.parse(decodedRes), - shared.ErrorResponse - ); - } else { - throw new errors.SDKError( - "unknown content-type received: " + contentType, - httpRes.status, - decodedRes, - httpRes - ); - } - break; - } - - return res; - } - /** * Get the aggregated balances from selected accounts */ @@ -678,7 +610,7 @@ export class Ledger { ); const url: string = utils.generateURL( baseURL, - "/api/ledger/{ledger}/aggregate/balances", + "/api/ledger/v2/{ledger}/aggregate/balances", req ); const client: AxiosInstance = this.sdkConfiguration.defaultClient; @@ -691,7 +623,6 @@ export class Ledger { } const properties = utils.parseSecurityProperties(globalSecurity); const headers = { ...config?.headers, ...properties.headers }; - const queryParams: string = utils.serializeQueryParams(req); headers["Accept"] = "application/json"; headers[ @@ -700,7 +631,7 @@ export class Ledger { const httpRes: AxiosResponse = await client.request({ validateStatus: () => true, - url: url + queryParams, + url: url, method: "get", headers: headers, responseType: "arraybuffer", @@ -764,7 +695,7 @@ export class Ledger { this.sdkConfiguration.serverURL, this.sdkConfiguration.serverDefaults ); - const url: string = baseURL.replace(/\/$/, "") + "/api/ledger/_info"; + const url: string = baseURL.replace(/\/$/, "") + "/api/ledger/v2/_info"; const client: AxiosInstance = this.sdkConfiguration.defaultClient; let globalSecurity = this.sdkConfiguration.security; if (typeof globalSecurity === "function") { @@ -853,7 +784,7 @@ export class Ledger { this.sdkConfiguration.serverURL, this.sdkConfiguration.serverDefaults ); - const url: string = utils.generateURL(baseURL, "/api/ledger/{ledger}/_info", req); + const url: string = utils.generateURL(baseURL, "/api/ledger/v2/{ledger}/_info", req); const client: AxiosInstance = this.sdkConfiguration.defaultClient; let globalSecurity = this.sdkConfiguration.security; if (typeof globalSecurity === "function") { @@ -944,7 +875,7 @@ export class Ledger { ); const url: string = utils.generateURL( baseURL, - "/api/ledger/{ledger}/transactions/{txid}", + "/api/ledger/v2/{ledger}/transactions/{id}", req ); const client: AxiosInstance = this.sdkConfiguration.defaultClient; @@ -957,6 +888,7 @@ export class Ledger { } const properties = utils.parseSecurityProperties(globalSecurity); const headers = { ...config?.headers, ...properties.headers }; + const queryParams: string = utils.serializeQueryParams(req); headers["Accept"] = "application/json"; headers[ @@ -965,7 +897,7 @@ export class Ledger { const httpRes: AxiosResponse = await client.request({ validateStatus: () => true, - url: url, + url: url + queryParams, method: "get", headers: headers, responseType: "arraybuffer", @@ -1020,285 +952,6 @@ export class Ledger { return res; } - /** - * List accounts from a ledger - * - * @remarks - * List accounts from a ledger, sorted by address in descending order. - */ - async listAccounts( - req: operations.ListAccountsRequest, - config?: AxiosRequestConfig - ): Promise { - if (!(req instanceof utils.SpeakeasyBase)) { - req = new operations.ListAccountsRequest(req); - } - - const baseURL: string = utils.templateUrl( - this.sdkConfiguration.serverURL, - this.sdkConfiguration.serverDefaults - ); - const url: string = utils.generateURL(baseURL, "/api/ledger/{ledger}/accounts", req); - const client: AxiosInstance = this.sdkConfiguration.defaultClient; - let globalSecurity = this.sdkConfiguration.security; - if (typeof globalSecurity === "function") { - globalSecurity = await globalSecurity(); - } - if (!(globalSecurity instanceof utils.SpeakeasyBase)) { - globalSecurity = new shared.Security(globalSecurity); - } - const properties = utils.parseSecurityProperties(globalSecurity); - const headers = { ...config?.headers, ...properties.headers }; - const queryParams: string = utils.serializeQueryParams(req); - headers["Accept"] = "application/json"; - - headers[ - "user-agent" - ] = `speakeasy-sdk/${this.sdkConfiguration.language} ${this.sdkConfiguration.sdkVersion} ${this.sdkConfiguration.genVersion} ${this.sdkConfiguration.openapiDocVersion}`; - - const httpRes: AxiosResponse = await client.request({ - validateStatus: () => true, - url: url + queryParams, - method: "get", - headers: headers, - responseType: "arraybuffer", - ...config, - }); - - const contentType: string = httpRes?.headers?.["content-type"] ?? ""; - - if (httpRes?.status == null) { - throw new Error(`status code not found in response: ${httpRes}`); - } - - const res: operations.ListAccountsResponse = new operations.ListAccountsResponse({ - statusCode: httpRes.status, - contentType: contentType, - rawResponse: httpRes, - }); - const decodedRes = new TextDecoder().decode(httpRes?.data); - switch (true) { - case httpRes?.status == 200: - if (utils.matchContentType(contentType, `application/json`)) { - res.accountsCursorResponse = utils.objectToClass( - JSON.parse(decodedRes), - shared.AccountsCursorResponse - ); - } else { - throw new errors.SDKError( - "unknown content-type received: " + contentType, - httpRes.status, - decodedRes, - httpRes - ); - } - break; - default: - if (utils.matchContentType(contentType, `application/json`)) { - res.errorResponse = utils.objectToClass( - JSON.parse(decodedRes), - shared.ErrorResponse - ); - } else { - throw new errors.SDKError( - "unknown content-type received: " + contentType, - httpRes.status, - decodedRes, - httpRes - ); - } - break; - } - - return res; - } - - /** - * List the logs from a ledger - * - * @remarks - * List the logs from a ledger, sorted by ID in descending order. - */ - async listLogs( - req: operations.ListLogsRequest, - config?: AxiosRequestConfig - ): Promise { - if (!(req instanceof utils.SpeakeasyBase)) { - req = new operations.ListLogsRequest(req); - } - - const baseURL: string = utils.templateUrl( - this.sdkConfiguration.serverURL, - this.sdkConfiguration.serverDefaults - ); - const url: string = utils.generateURL(baseURL, "/api/ledger/{ledger}/logs", req); - const client: AxiosInstance = this.sdkConfiguration.defaultClient; - let globalSecurity = this.sdkConfiguration.security; - if (typeof globalSecurity === "function") { - globalSecurity = await globalSecurity(); - } - if (!(globalSecurity instanceof utils.SpeakeasyBase)) { - globalSecurity = new shared.Security(globalSecurity); - } - const properties = utils.parseSecurityProperties(globalSecurity); - const headers = { ...config?.headers, ...properties.headers }; - const queryParams: string = utils.serializeQueryParams(req); - headers["Accept"] = "application/json"; - - headers[ - "user-agent" - ] = `speakeasy-sdk/${this.sdkConfiguration.language} ${this.sdkConfiguration.sdkVersion} ${this.sdkConfiguration.genVersion} ${this.sdkConfiguration.openapiDocVersion}`; - - const httpRes: AxiosResponse = await client.request({ - validateStatus: () => true, - url: url + queryParams, - method: "get", - headers: headers, - responseType: "arraybuffer", - ...config, - }); - - const contentType: string = httpRes?.headers?.["content-type"] ?? ""; - - if (httpRes?.status == null) { - throw new Error(`status code not found in response: ${httpRes}`); - } - - const res: operations.ListLogsResponse = new operations.ListLogsResponse({ - statusCode: httpRes.status, - contentType: contentType, - rawResponse: httpRes, - }); - const decodedRes = new TextDecoder().decode(httpRes?.data); - switch (true) { - case httpRes?.status == 200: - if (utils.matchContentType(contentType, `application/json`)) { - res.logsCursorResponse = utils.objectToClass( - JSON.parse(decodedRes), - shared.LogsCursorResponse - ); - } else { - throw new errors.SDKError( - "unknown content-type received: " + contentType, - httpRes.status, - decodedRes, - httpRes - ); - } - break; - default: - if (utils.matchContentType(contentType, `application/json`)) { - res.errorResponse = utils.objectToClass( - JSON.parse(decodedRes), - shared.ErrorResponse - ); - } else { - throw new errors.SDKError( - "unknown content-type received: " + contentType, - httpRes.status, - decodedRes, - httpRes - ); - } - break; - } - - return res; - } - - /** - * List transactions from a ledger - * - * @remarks - * List transactions from a ledger, sorted by txid in descending order. - */ - async listTransactions( - req: operations.ListTransactionsRequest, - config?: AxiosRequestConfig - ): Promise { - if (!(req instanceof utils.SpeakeasyBase)) { - req = new operations.ListTransactionsRequest(req); - } - - const baseURL: string = utils.templateUrl( - this.sdkConfiguration.serverURL, - this.sdkConfiguration.serverDefaults - ); - const url: string = utils.generateURL(baseURL, "/api/ledger/{ledger}/transactions", req); - const client: AxiosInstance = this.sdkConfiguration.defaultClient; - let globalSecurity = this.sdkConfiguration.security; - if (typeof globalSecurity === "function") { - globalSecurity = await globalSecurity(); - } - if (!(globalSecurity instanceof utils.SpeakeasyBase)) { - globalSecurity = new shared.Security(globalSecurity); - } - const properties = utils.parseSecurityProperties(globalSecurity); - const headers = { ...config?.headers, ...properties.headers }; - const queryParams: string = utils.serializeQueryParams(req); - headers["Accept"] = "application/json"; - - headers[ - "user-agent" - ] = `speakeasy-sdk/${this.sdkConfiguration.language} ${this.sdkConfiguration.sdkVersion} ${this.sdkConfiguration.genVersion} ${this.sdkConfiguration.openapiDocVersion}`; - - const httpRes: AxiosResponse = await client.request({ - validateStatus: () => true, - url: url + queryParams, - method: "get", - headers: headers, - responseType: "arraybuffer", - ...config, - }); - - const contentType: string = httpRes?.headers?.["content-type"] ?? ""; - - if (httpRes?.status == null) { - throw new Error(`status code not found in response: ${httpRes}`); - } - - const res: operations.ListTransactionsResponse = new operations.ListTransactionsResponse({ - statusCode: httpRes.status, - contentType: contentType, - rawResponse: httpRes, - }); - const decodedRes = new TextDecoder().decode(httpRes?.data); - switch (true) { - case httpRes?.status == 200: - if (utils.matchContentType(contentType, `application/json`)) { - res.transactionsCursorResponse = utils.objectToClass( - JSON.parse(decodedRes), - shared.TransactionsCursorResponse - ); - } else { - throw new errors.SDKError( - "unknown content-type received: " + contentType, - httpRes.status, - decodedRes, - httpRes - ); - } - break; - default: - if (utils.matchContentType(contentType, `application/json`)) { - res.errorResponse = utils.objectToClass( - JSON.parse(decodedRes), - shared.ErrorResponse - ); - } else { - throw new errors.SDKError( - "unknown content-type received: " + contentType, - httpRes.status, - decodedRes, - httpRes - ); - } - break; - } - - return res; - } - /** * Get statistics from a ledger * @@ -1318,7 +971,7 @@ export class Ledger { this.sdkConfiguration.serverURL, this.sdkConfiguration.serverDefaults ); - const url: string = utils.generateURL(baseURL, "/api/ledger/{ledger}/stats", req); + const url: string = utils.generateURL(baseURL, "/api/ledger/v2/{ledger}/stats", req); const client: AxiosInstance = this.sdkConfiguration.defaultClient; let globalSecurity = this.sdkConfiguration.security; if (typeof globalSecurity === "function") { @@ -1409,7 +1062,7 @@ export class Ledger { ); const url: string = utils.generateURL( baseURL, - "/api/ledger/{ledger}/transactions/{txid}/revert", + "/api/ledger/v2/{ledger}/transactions/{id}/revert", req ); const client: AxiosInstance = this.sdkConfiguration.defaultClient; diff --git a/sdks/typescript/src/sdk/models/operations/addmetadataontransaction.ts b/sdks/typescript/src/sdk/models/operations/addmetadataontransaction.ts index 7aa0866b2..bfe4a81aa 100755 --- a/sdks/typescript/src/sdk/models/operations/addmetadataontransaction.ts +++ b/sdks/typescript/src/sdk/models/operations/addmetadataontransaction.ts @@ -19,12 +19,6 @@ export class AddMetadataOnTransactionRequest extends SpeakeasyBase { @SpeakeasyMetadata({ data: "request, media_type=application/json" }) requestBody?: Record; - /** - * Set async mode. - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=async" }) - async?: boolean; - /** * Set the dryRun mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. */ @@ -32,16 +26,16 @@ export class AddMetadataOnTransactionRequest extends SpeakeasyBase { dryRun?: boolean; /** - * Name of the ledger. + * Transaction ID. */ - @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=ledger" }) - ledger: string; + @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=id" }) + id: number; /** - * Transaction ID. + * Name of the ledger. */ - @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=txid" }) - txid: number; + @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=ledger" }) + ledger: string; } export class AddMetadataOnTransactionResponse extends SpeakeasyBase { diff --git a/sdks/typescript/src/sdk/models/operations/addmetadatatoaccount.ts b/sdks/typescript/src/sdk/models/operations/addmetadatatoaccount.ts index 9b242009b..778834852 100755 --- a/sdks/typescript/src/sdk/models/operations/addmetadatatoaccount.ts +++ b/sdks/typescript/src/sdk/models/operations/addmetadatatoaccount.ts @@ -31,12 +31,6 @@ export class AddMetadataToAccountRequest extends SpeakeasyBase { @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=address" }) address: string; - /** - * Set async mode. - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=async" }) - async?: boolean; - /** * Set the dry run mode. Dry run mode doesn't add the logs to the database or publish a message to the message broker. */ diff --git a/sdks/typescript/src/sdk/models/operations/countaccounts.ts b/sdks/typescript/src/sdk/models/operations/countaccounts.ts index 193f46896..2f1993d00 100755 --- a/sdks/typescript/src/sdk/models/operations/countaccounts.ts +++ b/sdks/typescript/src/sdk/models/operations/countaccounts.ts @@ -6,29 +6,15 @@ import { SpeakeasyBase, SpeakeasyMetadata } from "../../../internal/utils"; import * as shared from "../shared"; import { AxiosResponse } from "axios"; -/** - * Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - */ -export class CountAccountsMetadata extends SpeakeasyBase {} - export class CountAccountsRequest extends SpeakeasyBase { - /** - * Filter accounts by address pattern (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=address" }) - address?: string; + @SpeakeasyMetadata({ data: "request, media_type=application/json" }) + requestBody?: Record; /** * Name of the ledger. */ @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=ledger" }) ledger: string; - - /** - * Filter accounts by metadata key value pairs. The filter can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - */ - @SpeakeasyMetadata({ data: "queryParam, style=deepObject;explode=true;name=metadata" }) - metadata?: CountAccountsMetadata; } export class CountAccountsResponse extends SpeakeasyBase { diff --git a/sdks/typescript/src/sdk/models/operations/counttransactions.ts b/sdks/typescript/src/sdk/models/operations/counttransactions.ts index 932364eca..8d5aaa47f 100755 --- a/sdks/typescript/src/sdk/models/operations/counttransactions.ts +++ b/sdks/typescript/src/sdk/models/operations/counttransactions.ts @@ -7,27 +7,8 @@ import * as shared from "../shared"; import { AxiosResponse } from "axios"; export class CountTransactionsRequest extends SpeakeasyBase { - /** - * Filter transactions with postings involving given account, either as source or destination (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=account" }) - account?: string; - - /** - * Filter transactions with postings involving given account at destination (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=destination" }) - destination?: string; - - /** - * Filter transactions that occurred before this timestamp. - * - * @remarks - * The format is RFC3339 and is exclusive (for example, "2023-01-02T15:04:01Z" excludes the first second of 4th minute). - * - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=endTime" }) - endTime?: Date; + @SpeakeasyMetadata({ data: "request, media_type=application/json" }) + requestBody?: Record; /** * Name of the ledger. @@ -35,33 +16,8 @@ export class CountTransactionsRequest extends SpeakeasyBase { @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=ledger" }) ledger: string; - /** - * Filter transactions by metadata key value pairs. Nested objects can be used like this -> metadata[key]=value1&metadata[a.nested.key]=value2 - */ - @SpeakeasyMetadata({ data: "queryParam, style=deepObject;explode=true;name=metadata" }) - metadata?: Record; - - /** - * Filter transactions by reference field. - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=reference" }) - reference?: string; - - /** - * Filter transactions with postings involving given account at source (regular expression placed between ^ and $). - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=source" }) - source?: string; - - /** - * Filter transactions that occurred after this timestamp. - * - * @remarks - * The format is RFC3339 and is inclusive (for example, "2023-01-02T15:04:01Z" includes the first second of 4th minute). - * - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=startTime" }) - startTime?: Date; + @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=pit" }) + pit?: Date; } export class CountTransactionsResponse extends SpeakeasyBase { diff --git a/sdks/typescript/src/sdk/models/operations/createtransaction.ts b/sdks/typescript/src/sdk/models/operations/createtransaction.ts index 46fdea207..b89e36f26 100755 --- a/sdks/typescript/src/sdk/models/operations/createtransaction.ts +++ b/sdks/typescript/src/sdk/models/operations/createtransaction.ts @@ -24,12 +24,6 @@ export class CreateTransactionRequest extends SpeakeasyBase { @SpeakeasyMetadata({ data: "request, media_type=application/json" }) postTransaction: shared.PostTransaction; - /** - * Set async mode. - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=async" }) - async?: boolean; - /** * Set the dryRun mode. dry run mode doesn't add the logs to the database or publish a message to the message broker. */ diff --git a/sdks/typescript/src/sdk/models/operations/getaccount.ts b/sdks/typescript/src/sdk/models/operations/getaccount.ts index 3869c4029..bd361b491 100755 --- a/sdks/typescript/src/sdk/models/operations/getaccount.ts +++ b/sdks/typescript/src/sdk/models/operations/getaccount.ts @@ -19,6 +19,9 @@ export class GetAccountRequest extends SpeakeasyBase { @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=address" }) address: string; + @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=expand" }) + expand?: string; + /** * Name of the ledger. */ diff --git a/sdks/typescript/src/sdk/models/operations/getbalancesaggregated.ts b/sdks/typescript/src/sdk/models/operations/getbalancesaggregated.ts index 5dbf4c9a8..ad90fec3a 100755 --- a/sdks/typescript/src/sdk/models/operations/getbalancesaggregated.ts +++ b/sdks/typescript/src/sdk/models/operations/getbalancesaggregated.ts @@ -7,12 +7,6 @@ import * as shared from "../shared"; import { AxiosResponse } from "axios"; export class GetBalancesAggregatedRequest extends SpeakeasyBase { - /** - * Filter balances involving given account, either as source or destination. - */ - @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=address" }) - address?: string; - /** * Name of the ledger. */ diff --git a/sdks/typescript/src/sdk/models/operations/gettransaction.ts b/sdks/typescript/src/sdk/models/operations/gettransaction.ts index 541d8cfd9..e0059e0c8 100755 --- a/sdks/typescript/src/sdk/models/operations/gettransaction.ts +++ b/sdks/typescript/src/sdk/models/operations/gettransaction.ts @@ -7,17 +7,20 @@ import * as shared from "../shared"; import { AxiosResponse } from "axios"; export class GetTransactionRequest extends SpeakeasyBase { + @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=expand" }) + expand?: string; + /** - * Name of the ledger. + * Transaction ID. */ - @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=ledger" }) - ledger: string; + @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=id" }) + id: number; /** - * Transaction ID. + * Name of the ledger. */ - @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=txid" }) - txid: number; + @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=ledger" }) + ledger: string; } export class GetTransactionResponse extends SpeakeasyBase { diff --git a/sdks/typescript/src/sdk/models/operations/index.ts b/sdks/typescript/src/sdk/models/operations/index.ts index 1d88480ee..21b430b62 100755 --- a/sdks/typescript/src/sdk/models/operations/index.ts +++ b/sdks/typescript/src/sdk/models/operations/index.ts @@ -34,7 +34,6 @@ export * from "./deleteworkflow"; export * from "./getaccount"; export * from "./getaccountbalances"; export * from "./getbalance"; -export * from "./getbalances"; export * from "./getbalancesaggregated"; export * from "./getconnectortask"; export * from "./gethold"; @@ -55,7 +54,6 @@ export * from "./getwalletsummary"; export * from "./getworkflow"; export * from "./insertconfig"; export * from "./installconnector"; -export * from "./listaccounts"; export * from "./listallconnectors"; export * from "./listbalances"; export * from "./listclients"; @@ -63,10 +61,8 @@ export * from "./listconfigsavailableconnectors"; export * from "./listconnectorstransfers"; export * from "./listconnectortasks"; export * from "./listinstances"; -export * from "./listlogs"; export * from "./listpayments"; export * from "./listscopes"; -export * from "./listtransactions"; export * from "./listusers"; export * from "./listwallets"; export * from "./listworkflows"; diff --git a/sdks/typescript/src/sdk/models/operations/listaccounts.ts b/sdks/typescript/src/sdk/models/operations/listaccounts.ts index 13c5e1662..fcf1ea654 100755 --- a/sdks/typescript/src/sdk/models/operations/listaccounts.ts +++ b/sdks/typescript/src/sdk/models/operations/listaccounts.ts @@ -25,6 +25,9 @@ export class ListAccountsRequest extends SpeakeasyBase { @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=cursor" }) cursor?: string; + @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=expand" }) + expand?: string; + /** * Name of the ledger. */ diff --git a/sdks/typescript/src/sdk/models/operations/listtransactions.ts b/sdks/typescript/src/sdk/models/operations/listtransactions.ts index 25e66ae1b..4c18dc409 100755 --- a/sdks/typescript/src/sdk/models/operations/listtransactions.ts +++ b/sdks/typescript/src/sdk/models/operations/listtransactions.ts @@ -41,6 +41,9 @@ export class ListTransactionsRequest extends SpeakeasyBase { @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=endTime" }) endTime?: Date; + @SpeakeasyMetadata({ data: "queryParam, style=form;explode=true;name=expand" }) + expand?: string; + /** * Name of the ledger. */ diff --git a/sdks/typescript/src/sdk/models/operations/reverttransaction.ts b/sdks/typescript/src/sdk/models/operations/reverttransaction.ts index 27533720c..8303832b0 100755 --- a/sdks/typescript/src/sdk/models/operations/reverttransaction.ts +++ b/sdks/typescript/src/sdk/models/operations/reverttransaction.ts @@ -8,16 +8,16 @@ import { AxiosResponse } from "axios"; export class RevertTransactionRequest extends SpeakeasyBase { /** - * Name of the ledger. + * Transaction ID. */ - @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=ledger" }) - ledger: string; + @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=id" }) + id: number; /** - * Transaction ID. + * Name of the ledger. */ - @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=txid" }) - txid: number; + @SpeakeasyMetadata({ data: "pathParam, style=simple;explode=false;name=ledger" }) + ledger: string; } export class RevertTransactionResponse extends SpeakeasyBase { diff --git a/sdks/typescript/src/sdk/models/shared/accountwithvolumesandbalances.ts b/sdks/typescript/src/sdk/models/shared/accountwithvolumesandbalances.ts index 2c2988947..8047cfdcb 100755 --- a/sdks/typescript/src/sdk/models/shared/accountwithvolumesandbalances.ts +++ b/sdks/typescript/src/sdk/models/shared/accountwithvolumesandbalances.ts @@ -10,10 +10,6 @@ export class AccountWithVolumesAndBalances extends SpeakeasyBase { @Expose({ name: "address" }) address: string; - @SpeakeasyMetadata() - @Expose({ name: "balances" }) - balances: Record; - @SpeakeasyMetadata() @Expose({ name: "metadata" }) metadata: Record; @@ -24,5 +20,5 @@ export class AccountWithVolumesAndBalances extends SpeakeasyBase { @SpeakeasyMetadata() @Expose({ name: "volumes" }) - volumes: Record>; + volumes?: Record>; } diff --git a/sdks/typescript/src/sdk/models/shared/expandedtransaction.ts b/sdks/typescript/src/sdk/models/shared/expandedtransaction.ts index 275aa6a80..224e052c0 100755 --- a/sdks/typescript/src/sdk/models/shared/expandedtransaction.ts +++ b/sdks/typescript/src/sdk/models/shared/expandedtransaction.ts @@ -8,6 +8,10 @@ import { Volume } from "./volume"; import { Expose, Transform, Type } from "class-transformer"; export class ExpandedTransaction extends SpeakeasyBase { + @SpeakeasyMetadata() + @Expose({ name: "id" }) + id: number; + @SpeakeasyMetadata() @Expose({ name: "metadata" }) metadata: Record; @@ -24,7 +28,7 @@ export class ExpandedTransaction extends SpeakeasyBase { }, { toClassOnly: true } ) - postCommitVolumes: Record>; + postCommitVolumes?: Record>; @SpeakeasyMetadata({ elemType: Posting }) @Expose({ name: "postings" }) @@ -43,18 +47,18 @@ export class ExpandedTransaction extends SpeakeasyBase { }, { toClassOnly: true } ) - preCommitVolumes: Record>; + preCommitVolumes?: Record>; @SpeakeasyMetadata() @Expose({ name: "reference" }) reference?: string; + @SpeakeasyMetadata() + @Expose({ name: "reverted" }) + reverted: boolean; + @SpeakeasyMetadata() @Expose({ name: "timestamp" }) @Transform(({ value }) => new Date(value), { toClassOnly: true }) timestamp: Date; - - @SpeakeasyMetadata() - @Expose({ name: "txid" }) - txid: number; } diff --git a/sdks/typescript/src/sdk/models/shared/index.ts b/sdks/typescript/src/sdk/models/shared/index.ts index 039d0952b..bc2a1ee18 100755 --- a/sdks/typescript/src/sdk/models/shared/index.ts +++ b/sdks/typescript/src/sdk/models/shared/index.ts @@ -2,11 +2,9 @@ * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. */ -export * from "./account"; export * from "./accountbalance"; export * from "./accountresponse"; export * from "./accountscursor"; -export * from "./accountscursorresponse"; export * from "./accountwithvolumesandbalances"; export * from "./activityconfirmhold"; export * from "./activitycreatetransaction"; @@ -30,7 +28,6 @@ export * from "./attempt"; export * from "./attemptresponse"; export * from "./balance"; export * from "./balancescursor"; -export * from "./balancescursorresponse"; export * from "./balancewithassets"; export * from "./bankingcircleconfig"; export * from "./client"; @@ -94,8 +91,6 @@ export * from "./listscopesresponse"; export * from "./listusersresponse"; export * from "./listwalletsresponse"; export * from "./listworkflowsresponse"; -export * from "./log"; -export * from "./logscursorresponse"; export * from "./mangopayconfig"; export * from "./migrationinfo"; export * from "./modulrconfig"; @@ -150,7 +145,6 @@ export * from "./taskscursor"; export * from "./taskstripe"; export * from "./taskwise"; export * from "./transaction"; -export * from "./transactionscursorresponse"; export * from "./transferrequest"; export * from "./transferresponse"; export * from "./transfersresponse"; diff --git a/sdks/typescript/src/sdk/models/shared/transaction.ts b/sdks/typescript/src/sdk/models/shared/transaction.ts index 184abcedc..6c9c6d013 100755 --- a/sdks/typescript/src/sdk/models/shared/transaction.ts +++ b/sdks/typescript/src/sdk/models/shared/transaction.ts @@ -7,6 +7,10 @@ import { Posting } from "./posting"; import { Expose, Transform, Type } from "class-transformer"; export class Transaction extends SpeakeasyBase { + @SpeakeasyMetadata() + @Expose({ name: "id" }) + id: number; + @SpeakeasyMetadata() @Expose({ name: "metadata" }) metadata: Record; @@ -20,12 +24,12 @@ export class Transaction extends SpeakeasyBase { @Expose({ name: "reference" }) reference?: string; + @SpeakeasyMetadata() + @Expose({ name: "reverted" }) + reverted: boolean; + @SpeakeasyMetadata() @Expose({ name: "timestamp" }) @Transform(({ value }) => new Date(value), { toClassOnly: true }) timestamp: Date; - - @SpeakeasyMetadata() - @Expose({ name: "txid" }) - txid: number; } diff --git a/sdks/typescript/src/sdk/models/shared/walletstransaction.ts b/sdks/typescript/src/sdk/models/shared/walletstransaction.ts index 0c5f5c016..d5bd7e5bb 100755 --- a/sdks/typescript/src/sdk/models/shared/walletstransaction.ts +++ b/sdks/typescript/src/sdk/models/shared/walletstransaction.ts @@ -8,6 +8,10 @@ import { WalletsVolume } from "./walletsvolume"; import { Expose, Transform, Type } from "class-transformer"; export class WalletsTransaction extends SpeakeasyBase { + @SpeakeasyMetadata() + @Expose({ name: "id" }) + id?: number; + @SpeakeasyMetadata() @Expose({ name: "ledger" }) ledger?: string; @@ -60,8 +64,4 @@ export class WalletsTransaction extends SpeakeasyBase { @Expose({ name: "timestamp" }) @Transform(({ value }) => new Date(value), { toClassOnly: true }) timestamp: Date; - - @SpeakeasyMetadata() - @Expose({ name: "txid" }) - txid: number; } diff --git a/sdks/typescript/src/sdk/sdk.ts b/sdks/typescript/src/sdk/sdk.ts index 61fed5a52..5a96d5b24 100755 --- a/sdks/typescript/src/sdk/sdk.ts +++ b/sdks/typescript/src/sdk/sdk.ts @@ -65,7 +65,7 @@ export class SDKConfiguration { serverURL: string; serverDefaults: any; language = "typescript"; - openapiDocVersion = "v1.0.20230907"; + openapiDocVersion = "v1.0.20230908"; sdkVersion = "v0.1.0"; genVersion = "2.96.3"; diff --git a/tests/integration/go.mod b/tests/integration/go.mod index f8724ab5f..9382a9445 100644 --- a/tests/integration/go.mod +++ b/tests/integration/go.mod @@ -172,7 +172,6 @@ require ( github.com/ugorji/go/codec v1.2.11 // indirect github.com/uptrace/bun/dialect/sqlitedialect v1.1.14 // indirect github.com/uptrace/bun/driver/sqliteshim v1.1.14 // indirect - github.com/uptrace/bun/extra/bunbig v1.1.14 // indirect github.com/uptrace/bun/extra/bundebug v1.1.14 // indirect github.com/uptrace/bun/extra/bunotel v1.1.14 // indirect github.com/uptrace/opentelemetry-go-extra/otellogrus v0.1.21 // indirect @@ -223,7 +222,7 @@ require ( go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.9.0 // indirect - golang.org/x/mod v0.10.0 // indirect + golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sync v0.2.0 // indirect diff --git a/tests/integration/go.sum b/tests/integration/go.sum index 3d52c8759..a25a5235e 100644 --- a/tests/integration/go.sum +++ b/tests/integration/go.sum @@ -838,7 +838,6 @@ github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/numary/ledger v1.8.1 h1:XoFOw74R5w7SwOTVrT4omBpuGo5uQSuvhfhPPcGdAuo= github.com/oauth2-proxy/mockoidc v0.0.0-20220308204021-b9169deeb282 h1:TQMyrpijtkFyXpNI3rY5hsZQZw+paiH+BfAlsb81HBY= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -890,7 +889,6 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/psanford/memfs v0.0.0-20210214183328-a001468d78ef h1:NKxTG6GVGbfMXc2mIk+KphcH6hagbVXhcFkbTgYleTI= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -992,8 +990,6 @@ github.com/uptrace/bun/driver/pgdriver v1.1.14 h1:V2Etm7mLGS3mhx8ddxZcUnwZLX02Jm github.com/uptrace/bun/driver/pgdriver v1.1.14/go.mod h1:D4FjWV9arDYct6sjMJhFoyU71SpllZRHXFRRP2Kd0Kw= github.com/uptrace/bun/driver/sqliteshim v1.1.14 h1:DFPUJ6KjDP2myjq15gtYYNngmAFMww1Y2UFZv4tbUw8= github.com/uptrace/bun/driver/sqliteshim v1.1.14/go.mod h1:5BFN7V6Sm37Tn7UE4FWNm/F6V3iJPUzAJ7QyRwA5b1k= -github.com/uptrace/bun/extra/bunbig v1.1.14 h1:3vAI0x2ObtWaXp2G5YJA0fBJTGzwv5gwTPbtEj0Ma00= -github.com/uptrace/bun/extra/bunbig v1.1.14/go.mod h1:+tVzMLS0bTkILD9JcRm5INUd/Wwd/1gKIw6GogAUAfw= github.com/uptrace/bun/extra/bundebug v1.1.14 h1:9OCGfP9ZDlh41u6OLerWdhBtJAVGXHr0xtxO4xWi6t0= github.com/uptrace/bun/extra/bundebug v1.1.14/go.mod h1:lto3guzS2v6mnQp1+akyE+ecBLOltevDDe324NXEYdw= github.com/uptrace/bun/extra/bunotel v1.1.14 h1:jKA1zNfD2/Y/O3eFP15ao+V0cMigXN+ReNbsVUqrOhg= @@ -1184,8 +1180,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/tests/integration/suite/ledger-balances.go b/tests/integration/suite/ledger-balances.go deleted file mode 100644 index a4041e52e..000000000 --- a/tests/integration/suite/ledger-balances.go +++ /dev/null @@ -1,354 +0,0 @@ -package suite - -import ( - "fmt" - "math/big" - "sort" - "time" - - "github.com/formancehq/formance-sdk-go/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/pkg/models/shared" - . "github.com/formancehq/stack/tests/integration/internal" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Given("some empty environment", func() { - When("get balances and aggregate balances", func() { - var ( - timestamp1 = time.Now().Add(-10 * time.Hour).Round(time.Second).UTC() - timestamp2 = time.Now().Add(-9 * time.Hour).Round(time.Second).UTC() - ) - BeforeEach(func() { - response, err := Client().Ledger.CreateTransaction( - TestContext(), - operations.CreateTransactionRequest{ - PostTransaction: shared.PostTransaction{ - Metadata: map[string]string{}, - Postings: []shared.Posting{ - { - Amount: big.NewInt(100), - Asset: "USD", - Source: "world", - Destination: "foo:foo", - }, - }, - Timestamp: ×tamp1, - }, - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - response, err = Client().Ledger.CreateTransaction( - TestContext(), - operations.CreateTransactionRequest{ - PostTransaction: shared.PostTransaction{ - Metadata: map[string]string{}, - Postings: []shared.Posting{ - { - Amount: big.NewInt(200), - Asset: "USD", - Source: "world", - Destination: "foo:bar", - }, - }, - Timestamp: ×tamp2, - }, - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - }) - It("should be listed on api with GetBalances", func() { - response, err := Client().Ledger.GetBalances( - TestContext(), - operations.GetBalancesRequest{ - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - Expect(response.BalancesCursorResponse.Cursor.Data).To(HaveLen(3)) - Expect(response.BalancesCursorResponse.Cursor.Data[0]).To(Equal(map[string]map[string]*big.Int{ - "foo:bar": { - "USD": big.NewInt(200), - }, - })) - Expect(response.BalancesCursorResponse.Cursor.Data[1]).To(Equal(map[string]map[string]*big.Int{ - "foo:foo": { - "USD": big.NewInt(100), - }, - })) - Expect(response.BalancesCursorResponse.Cursor.Data[2]).To(Equal(map[string]map[string]*big.Int{ - "world": { - "USD": big.NewInt(-300), - }, - })) - }) - It("should be listed on api with GetBalances using accounts filter", func() { - response, err := Client().Ledger.GetBalances( - TestContext(), - operations.GetBalancesRequest{ - Address: ptr("foo:"), - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - balancesCursorResponse := response.BalancesCursorResponse - Expect(balancesCursorResponse.Cursor.Data).To(HaveLen(2)) - Expect(balancesCursorResponse.Cursor.Data[0]).To(Equal(map[string]map[string]*big.Int{ - "foo:bar": { - "USD": big.NewInt(200), - }, - })) - Expect(balancesCursorResponse.Cursor.Data[1]).To(Equal(map[string]map[string]*big.Int{ - "foo:foo": { - "USD": big.NewInt(100), - }, - })) - - response, err = Client().Ledger.GetBalances( - TestContext(), - operations.GetBalancesRequest{ - Address: ptr(":foo"), - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - balancesCursorResponse = response.BalancesCursorResponse - Expect(balancesCursorResponse.Cursor.Data).To(HaveLen(1)) - Expect(balancesCursorResponse.Cursor.Data[0]).To(Equal(map[string]map[string]*big.Int{ - "foo:foo": { - "USD": big.NewInt(100), - }, - })) - }) - It("should be listed on api with GetBalancesAggregated", func() { - response, err := Client().Ledger.GetBalancesAggregated( - TestContext(), - operations.GetBalancesAggregatedRequest{ - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - balances := response.AggregateBalancesResponse - Expect(balances.Data).To(Equal(map[string]*big.Int{ - "USD": big.NewInt(0), - })) - }) - It("should be listed on api with GetBalancesAggregated using accounts filter", func() { - response, err := Client().Ledger.GetBalancesAggregated( - TestContext(), - operations.GetBalancesAggregatedRequest{ - Address: ptr("foo:"), - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - balances := response.AggregateBalancesResponse - Expect(balances.Data).To(Equal(map[string]*big.Int{ - // Should be the sum of the two accounts foo:foo and foo:bar - "USD": big.NewInt(300), - })) - }) - }) -}) - -var _ = Given("some empty environment", func() { - When("get balances and aggregate balances emtpy", func() { - It("should be listed on api with GetBalances even if empty", func() { - response, err := Client().Ledger.GetBalances( - TestContext(), - operations.GetBalancesRequest{ - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - balancesCursorResponse := response.BalancesCursorResponse - Expect(balancesCursorResponse.Cursor.Data).To(HaveLen(0)) - }) - It("should be listed on api with GetBalancesAggregated", func() { - response, err := Client().Ledger.GetBalancesAggregated( - TestContext(), - operations.GetBalancesAggregatedRequest{ - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - balances := response.AggregateBalancesResponse - Expect(balances.Data).To(Equal(map[string]*big.Int{})) - }) - }) -}) - -var _ = Given("some environment with accounts and transactions", func() { - const ( - pageSize = int64(10) - transactionCounts = 2 * pageSize - ) - When("creating transactions", func() { - var ( - balances []map[string]map[string]*big.Int - ) - BeforeEach(func() { - for i := 0; i < int(transactionCounts); i++ { - now := time.Now() - asset := "USD" - if i%2 == 0 { - asset = "EUR" - } - - _, err := Client().Ledger.CreateTransaction( - TestContext(), - operations.CreateTransactionRequest{ - PostTransaction: shared.PostTransaction{ - Metadata: map[string]string{}, - Postings: []shared.Posting{ - { - Amount: big.NewInt(100), - Asset: asset, - Source: "world", - Destination: fmt.Sprintf("foo:%d", i), - }, - }, - Timestamp: &now, - }, - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - - balances = append(balances, map[string]map[string]*big.Int{ - fmt.Sprintf("foo:%d", i): { - asset: big.NewInt(100), - }, - }) - } - - balances = append([]map[string]map[string]*big.Int{ - { - "world": { - "USD": big.NewInt(-transactionCounts / 2 * 100), - "EUR": big.NewInt(-transactionCounts / 2 * 100), - }, - }, - }, balances...) - - sort.Slice(balances, func(i, j int) bool { - name1 := "" - for name := range balances[i] { - name1 = name - break - } - name2 := "" - for name := range balances[j] { - name2 = name - break - } - return name1 < name2 - }) - }) - AfterEach(func() { - balances = nil - }) - Then(fmt.Sprintf("listing balances using page size of %d", pageSize), func() { - var ( - rsp *shared.BalancesCursorResponse - ) - BeforeEach(func() { - response, err := Client().Ledger.GetBalances( - TestContext(), - operations.GetBalancesRequest{ - Ledger: "default", - PageSize: ptr(pageSize), - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - rsp = response.BalancesCursorResponse - Expect(rsp.Cursor.HasMore).To(BeTrue()) - Expect(rsp.Cursor.Previous).To(BeNil()) - Expect(rsp.Cursor.Next).NotTo(BeNil()) - }) - It("should return the first page", func() { - Expect(rsp.Cursor.PageSize).To(Equal(pageSize)) - Expect(rsp.Cursor.Data).To(Equal(balances[:pageSize])) - }) - Then("following next cursor", func() { - BeforeEach(func() { - response, err := Client().Ledger.GetBalances( - TestContext(), - operations.GetBalancesRequest{ - Cursor: rsp.Cursor.Next, - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - rsp = response.BalancesCursorResponse - }) - It("should return next page", func() { - Expect(rsp.Cursor.PageSize).To(Equal(pageSize)) - Expect(rsp.Cursor.Data).To(Equal(balances[pageSize : 2*pageSize])) - }) - Then("following next cursor", func() { - BeforeEach(func() { - response, err := Client().Ledger.GetBalances( - TestContext(), - operations.GetBalancesRequest{ - Cursor: rsp.Cursor.Next, - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - rsp = response.BalancesCursorResponse - }) - It("should return next page", func() { - Expect(rsp.Cursor.PageSize).To(Equal(pageSize)) - Expect(rsp.Cursor.Data).To(Equal(balances[len(balances)-1:])) - Expect(rsp.Cursor.Next).To(BeNil()) - }) - Then("following previous cursor", func() { - BeforeEach(func() { - response, err := Client().Ledger.GetBalances( - TestContext(), - operations.GetBalancesRequest{ - Cursor: rsp.Cursor.Previous, - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - rsp = response.BalancesCursorResponse - }) - It("should return first page", func() { - Expect(rsp.Cursor.PageSize).To(Equal(pageSize)) - Expect(rsp.Cursor.Data).To(Equal(balances[pageSize : 2*pageSize])) - }) - }) - }) - - }) - }) - }) -}) diff --git a/tests/integration/suite/ledger-create-transaction.go b/tests/integration/suite/ledger-create-transaction.go index 9c5e4c010..8df629977 100644 --- a/tests/integration/suite/ledger-create-transaction.go +++ b/tests/integration/suite/ledger-create-transaction.go @@ -6,9 +6,10 @@ import ( "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" - "github.com/formancehq/ledger/pkg/bus" + ledgerevents "github.com/formancehq/ledger/pkg/events" "github.com/formancehq/stack/libs/events" "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/formancehq/stack/libs/go-libs/pointer" . "github.com/formancehq/stack/tests/integration/internal" "github.com/nats-io/nats.go" . "github.com/onsi/ginkgo/v2" @@ -59,7 +60,8 @@ var _ = Given("some empty environment", func() { TestContext(), operations.GetTransactionRequest{ Ledger: "default", - Txid: rsp.Data.Txid, + ID: rsp.Data.ID, + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -71,7 +73,7 @@ var _ = Given("some empty environment", func() { Postings: rsp.Data.Postings, Reference: rsp.Data.Reference, Metadata: rsp.Data.Metadata, - Txid: rsp.Data.Txid, + ID: rsp.Data.ID, PreCommitVolumes: map[string]map[string]shared.Volume{ "world": { "USD": { @@ -111,6 +113,7 @@ var _ = Given("some empty environment", func() { operations.GetAccountRequest{ Address: "alice", Ledger: "default", + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -127,15 +130,12 @@ var _ = Given("some empty environment", func() { "balance": big.NewInt(100), }, }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(100), - }, })) }) It("should trigger a new event", func() { // Wait for created transaction event msg := WaitOnChanWithTimeout(msgs, 5*time.Second) - Expect(events.Check(msg.Data, "ledger", bus.EventTypeCommittedTransactions)).Should(Succeed()) + Expect(events.Check(msg.Data, "ledger", ledgerevents.EventTypeCommittedTransactions)).Should(Succeed()) }) It("should pop a transaction, two accounts and two assets entries on search service", func() { expectedTx := map[string]any{ @@ -281,13 +281,13 @@ var _ = Given("some empty environment", func() { BeforeEach(createTransaction) It("should be ok", func() { Expect(err).To(Succeed()) - Expect(response.CreateTransactionResponse.Data.Txid).To(Equal(int64(0))) + Expect(response.CreateTransactionResponse.Data.ID).To(Equal(int64(0))) }) Then("replaying with the same IK", func() { BeforeEach(createTransaction) It("should respond with the same tx id", func() { Expect(err).To(Succeed()) - Expect(response.CreateTransactionResponse.Data.Txid).To(Equal(int64(0))) + Expect(response.CreateTransactionResponse.Data.ID).To(Equal(int64(0))) }) }) }) diff --git a/tests/integration/suite/ledger-list-count-accounts.go b/tests/integration/suite/ledger-list-count-accounts.go index a95881b32..6d9760b46 100644 --- a/tests/integration/suite/ledger-list-count-accounts.go +++ b/tests/integration/suite/ledger-list-count-accounts.go @@ -113,8 +113,12 @@ var _ = Given("some empty environment", func() { response, err := Client().Ledger.ListAccounts( TestContext(), operations.ListAccountsRequest{ - Address: ptr("foo:"), - Ledger: "default", + Ledger: "default", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "address": "foo:", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -134,8 +138,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListAccounts( TestContext(), operations.ListAccountsRequest{ - Address: ptr(":foo"), - Ledger: "default", + Ledger: "default", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "address": ":foo", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -153,8 +161,10 @@ var _ = Given("some empty environment", func() { TestContext(), operations.ListAccountsRequest{ Ledger: "default", - Metadata: map[string]string{ - "clientType": "gold", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "metadata[clientType]": "gold", + }, }, }, ) diff --git a/tests/integration/suite/ledger-list-logs.go b/tests/integration/suite/ledger-list-logs.go index 90b0be54e..2b7da1a0b 100644 --- a/tests/integration/suite/ledger-list-logs.go +++ b/tests/integration/suite/ledger-list-logs.go @@ -109,7 +109,6 @@ var _ = Given("some empty environment", func() { Expect(logsCursorResponse.Cursor.Data[1].Type).To(Equal(shared.LogTypeNewTransaction)) // Cannot check date and txid inside Data since they are changing at // every run - Expect(logsCursorResponse.Cursor.Data[1].Date).To(Equal(timestamp2)) Expect(logsCursorResponse.Cursor.Data[1].Data["accountMetadata"]).To(Equal(map[string]any{})) Expect(logsCursorResponse.Cursor.Data[1].Data["transaction"]).To(BeAssignableToTypeOf(map[string]any{})) transaction := logsCursorResponse.Cursor.Data[1].Data["transaction"].(map[string]any) @@ -129,9 +128,6 @@ var _ = Given("some empty environment", func() { Expect(logsCursorResponse.Cursor.Data[2].ID).To(Equal(int64(0))) Expect(logsCursorResponse.Cursor.Data[2].Type).To(Equal(shared.LogTypeNewTransaction)) - // Cannot check date and txid inside Data since they are changing at - // every run - Expect(logsCursorResponse.Cursor.Data[2].Date).To(Equal(timestamp1)) Expect(logsCursorResponse.Cursor.Data[2].Data["accountMetadata"]).To(Equal(map[string]any{})) Expect(logsCursorResponse.Cursor.Data[2].Data["transaction"]).To(BeAssignableToTypeOf(map[string]any{})) transaction = logsCursorResponse.Cursor.Data[2].Data["transaction"].(map[string]any) @@ -147,85 +143,6 @@ var _ = Given("some empty environment", func() { }, })) }) - It("should be listed on api with ListLogs using time filters", func() { - st := time.Date(2023, 4, 11, 12, 0, 0, 0, time.UTC) - response, err := Client().Ledger.ListLogs( - TestContext(), - operations.ListLogsRequest{ - Ledger: "default", - StartTime: &st, - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - logsCursorResponse := response.LogsCursorResponse - Expect(logsCursorResponse.Cursor.Data).To(HaveLen(2)) - - Expect(logsCursorResponse.Cursor.Data[0].ID).To(Equal(int64(2))) - Expect(logsCursorResponse.Cursor.Data[0].Type).To(Equal(shared.LogTypeSetMetadata)) - Expect(logsCursorResponse.Cursor.Data[0].Data).To(Equal(map[string]any{ - "targetType": "ACCOUNT", - "metadata": map[string]any{ - "clientType": "gold", - }, - "targetId": "foo:baz", - })) - - Expect(logsCursorResponse.Cursor.Data[1].ID).To(Equal(int64(1))) - Expect(logsCursorResponse.Cursor.Data[1].Type).To(Equal(shared.LogTypeNewTransaction)) - Expect(logsCursorResponse.Cursor.Data[1].Date).To(Equal(timestamp2)) - Expect(logsCursorResponse.Cursor.Data[1].Data["accountMetadata"]).To(Equal(map[string]any{})) - Expect(logsCursorResponse.Cursor.Data[1].Data["transaction"]).To(BeAssignableToTypeOf(map[string]any{})) - transaction := logsCursorResponse.Cursor.Data[1].Data["transaction"].(map[string]any) - Expect(transaction["metadata"]).To(Equal(map[string]any{ - "clientType": "silver", - })) - Expect(transaction["reference"]).To(Equal("")) - Expect(transaction["timestamp"]).To(Equal("2023-04-12T10:00:00Z")) - Expect(transaction["postings"]).To(Equal([]any{ - map[string]any{ - "amount": float64(200), - "asset": "USD", - "source": "world", - "destination": "foo:bar", - }, - })) - - et := time.Date(2023, 4, 11, 12, 0, 0, 0, time.UTC) - response, err = Client().Ledger.ListLogs( - TestContext(), - operations.ListLogsRequest{ - EndTime: &et, - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(response.StatusCode).To(Equal(200)) - - logsCursorResponse = response.LogsCursorResponse - Expect(logsCursorResponse.Cursor.Data).To(HaveLen(1)) - - Expect(logsCursorResponse.Cursor.Data[0].ID).To(Equal(int64(0))) - Expect(logsCursorResponse.Cursor.Data[0].Type).To(Equal(shared.LogTypeNewTransaction)) - // Cannot check date and txid inside Data since they are changing at - // every run - Expect(logsCursorResponse.Cursor.Data[0].Date).To(Equal(timestamp1)) - Expect(logsCursorResponse.Cursor.Data[0].Data["accountMetadata"]).To(Equal(map[string]any{})) - Expect(logsCursorResponse.Cursor.Data[0].Data["transaction"]).To(BeAssignableToTypeOf(map[string]any{})) - transaction = logsCursorResponse.Cursor.Data[0].Data["transaction"].(map[string]any) - Expect(transaction["metadata"]).To(Equal(map[string]any{})) - Expect(transaction["reference"]).To(Equal("")) - Expect(transaction["timestamp"]).To(Equal("2023-04-11T10:00:00Z")) - Expect(transaction["postings"]).To(Equal([]any{ - map[string]any{ - "amount": float64(100), - "asset": "USD", - "source": "world", - "destination": "foo:foo", - }, - })) - }) }) }) diff --git a/tests/integration/suite/ledger-list-transactions.go b/tests/integration/suite/ledger-list-transactions.go index 04abfb3c0..db25c7dbe 100644 --- a/tests/integration/suite/ledger-list-transactions.go +++ b/tests/integration/suite/ledger-list-transactions.go @@ -8,6 +8,7 @@ import ( "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" "github.com/formancehq/stack/libs/go-libs/metadata" + "github.com/formancehq/stack/libs/go-libs/pointer" . "github.com/formancehq/stack/tests/integration/internal" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -54,7 +55,7 @@ var _ = Given("some empty environment", func() { Postings: ret.Data.Postings, Reference: ret.Data.Reference, Metadata: ret.Data.Metadata, - Txid: ret.Data.Txid, + ID: ret.Data.ID, PreCommitVolumes: map[string]map[string]shared.Volume{ "world": { "USD": { @@ -104,6 +105,7 @@ var _ = Given("some empty environment", func() { operations.ListTransactionsRequest{ Ledger: "default", PageSize: ptr(pageSize), + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -125,6 +127,7 @@ var _ = Given("some empty environment", func() { operations.ListTransactionsRequest{ Cursor: rsp.Cursor.Next, Ledger: "default", + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -144,6 +147,7 @@ var _ = Given("some empty environment", func() { operations.ListTransactionsRequest{ Cursor: rsp.Cursor.Previous, Ledger: "default", + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -207,7 +211,7 @@ var _ = Given("some empty environment", func() { Postings: ret.Data.Postings, Reference: ret.Data.Reference, Metadata: ret.Data.Metadata, - Txid: ret.Data.Txid, + ID: ret.Data.ID, PreCommitVolumes: map[string]map[string]shared.Volume{ "world": { "USD": { @@ -269,7 +273,7 @@ var _ = Given("some empty environment", func() { Postings: ret.Data.Postings, Reference: ret.Data.Reference, Metadata: ret.Data.Metadata, - Txid: ret.Data.Txid, + ID: ret.Data.ID, PreCommitVolumes: map[string]map[string]shared.Volume{ "world": { "USD": { @@ -331,7 +335,7 @@ var _ = Given("some empty environment", func() { Postings: ret.Data.Postings, Reference: ret.Data.Reference, Metadata: ret.Data.Metadata, - Txid: ret.Data.Txid, + ID: ret.Data.ID, PreCommitVolumes: map[string]map[string]shared.Volume{ "world": { "USD": { @@ -381,8 +385,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - Account: ptr("foo:"), + Ledger: "default", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "account": "foo:", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -393,8 +401,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - Account: ptr("not_existing"), + Ledger: "default", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "account": "not_existing", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -405,8 +417,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - Destination: ptr(":baz"), + Ledger: "default", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "destination": ":baz", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -417,8 +433,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - Destination: ptr("not_existing"), + Ledger: "default", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "destination": "not_existing", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -430,7 +450,11 @@ var _ = Given("some empty environment", func() { TestContext(), operations.CountTransactionsRequest{ Ledger: "default", - Source: ptr("foo:"), + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "source": "foo:", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -442,7 +466,11 @@ var _ = Given("some empty environment", func() { TestContext(), operations.CountTransactionsRequest{ Ledger: "default", - Source: ptr("world"), + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "source": "world", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -454,8 +482,10 @@ var _ = Given("some empty environment", func() { TestContext(), operations.CountTransactionsRequest{ Ledger: "default", - Metadata: map[string]string{ - "foo": "bar", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "metadata[foo]": "bar", + }, }, }, ) @@ -468,8 +498,10 @@ var _ = Given("some empty environment", func() { TestContext(), operations.CountTransactionsRequest{ Ledger: "default", - Metadata: map[string]string{ - "foo": "not_existing", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "metadata[foo]": "not_existing", + }, }, }, ) @@ -481,8 +513,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - StartTime: ×tamp2, + Ledger: "default", + RequestBody: map[string]interface{}{ + "$gte": map[string]any{ + "timestamp": timestamp2.Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -493,8 +529,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - StartTime: ×tamp3, + Ledger: "default", + RequestBody: map[string]interface{}{ + "$gte": map[string]any{ + "timestamp": timestamp3.Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -505,8 +545,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - StartTime: ptr(time.Now().UTC()), + Ledger: "default", + RequestBody: map[string]interface{}{ + "$gte": map[string]any{ + "timestamp": time.Now().UTC().Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -517,8 +561,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - EndTime: ×tamp3, + Ledger: "default", + RequestBody: map[string]interface{}{ + "$lt": map[string]any{ + "timestamp": timestamp3.Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -529,8 +577,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - EndTime: ×tamp2, + Ledger: "default", + RequestBody: map[string]interface{}{ + "$lt": map[string]any{ + "timestamp": timestamp2.Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -541,8 +593,12 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.CountTransactions( TestContext(), operations.CountTransactionsRequest{ - Ledger: "default", - EndTime: ptr(time.Date(2023, 4, 9, 10, 0, 0, 0, time.UTC)), + Ledger: "default", + RequestBody: map[string]interface{}{ + "$lt": map[string]any{ + "timestamp": time.Date(2023, 4, 9, 10, 0, 0, 0, time.UTC).Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -555,6 +611,7 @@ var _ = Given("some empty environment", func() { TestContext(), operations.ListTransactionsRequest{ Ledger: "default", + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -568,8 +625,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Account: ptr("foo:"), - Ledger: "default", + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "account": "foo:", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -583,8 +645,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Account: ptr("not_existing"), - Ledger: "default", + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "account": "not_existing", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -595,8 +662,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Destination: ptr("foo:"), - Ledger: "default", + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "destination": "foo:", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -610,8 +682,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Destination: ptr("not_existing"), - Ledger: "default", + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "destination": "not_existing", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -622,8 +699,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Source: ptr("foo:"), Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "source": "foo:", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -634,8 +716,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Source: ptr("world"), Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "source": "world", + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -650,9 +737,12 @@ var _ = Given("some empty environment", func() { TestContext(), operations.ListTransactionsRequest{ Ledger: "default", - Metadata: map[string]string{ - "foo": "bar", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "metadata[foo]": "bar", + }, }, + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -666,9 +756,12 @@ var _ = Given("some empty environment", func() { TestContext(), operations.ListTransactionsRequest{ Ledger: "default", - Metadata: map[string]string{ - "foo": "not_existing", + RequestBody: map[string]interface{}{ + "$match": map[string]any{ + "metadata[foo]": "not_existing", + }, }, + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -679,8 +772,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Ledger: "default", - StartTime: ×tamp2, + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$gte": map[string]any{ + "timestamp": timestamp2.Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -693,8 +791,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Ledger: "default", - StartTime: ×tamp3, + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$gte": map[string]any{ + "timestamp": timestamp3.Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -706,8 +809,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Ledger: "default", - StartTime: ptr(time.Now().UTC()), + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$gte": map[string]any{ + "timestamp": time.Now().UTC().Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -718,8 +826,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Ledger: "default", - EndTime: ×tamp3, + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$lt": map[string]any{ + "timestamp": timestamp3.Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -732,8 +845,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Ledger: "default", - EndTime: ×tamp2, + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$lt": map[string]any{ + "timestamp": timestamp2.Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -745,8 +863,13 @@ var _ = Given("some empty environment", func() { response, err = Client().Ledger.ListTransactions( TestContext(), operations.ListTransactionsRequest{ - Ledger: "default", - EndTime: ptr(time.Date(2023, 4, 9, 10, 0, 0, 0, time.UTC)), + Ledger: "default", + Expand: pointer.For("volumes"), + RequestBody: map[string]interface{}{ + "$lt": map[string]any{ + "timestamp": time.Date(2023, 4, 9, 10, 0, 0, 0, time.UTC).Format(time.RFC3339), + }, + }, }, ) Expect(err).ToNot(HaveOccurred()) @@ -754,12 +877,13 @@ var _ = Given("some empty environment", func() { transactionCursorResponse = response.TransactionsCursorResponse Expect(transactionCursorResponse.Cursor.Data).Should(HaveLen(0)) }) - It("should be getable on api", func() { + It("should be gettable on api", func() { response, err := Client().Ledger.GetTransaction( TestContext(), operations.GetTransactionRequest{ Ledger: "default", - Txid: t1.Txid, + ID: t1.ID, + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -770,7 +894,8 @@ var _ = Given("some empty environment", func() { TestContext(), operations.GetTransactionRequest{ Ledger: "default", - Txid: t2.Txid, + ID: t2.ID, + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -781,7 +906,8 @@ var _ = Given("some empty environment", func() { TestContext(), operations.GetTransactionRequest{ Ledger: "default", - Txid: t3.Txid, + ID: t3.ID, + Expand: pointer.For("volumes"), }, ) Expect(err).ToNot(HaveOccurred()) @@ -792,7 +918,7 @@ var _ = Given("some empty environment", func() { TestContext(), operations.GetTransactionRequest{ Ledger: "default", - Txid: 666, + ID: 666, }, ) Expect(err).ToNot(HaveOccurred()) diff --git a/tests/integration/suite/ledger-revert-transaction.go b/tests/integration/suite/ledger-revert-transaction.go index a48884d6b..353a8e15c 100644 --- a/tests/integration/suite/ledger-revert-transaction.go +++ b/tests/integration/suite/ledger-revert-transaction.go @@ -6,8 +6,7 @@ import ( "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" - "github.com/formancehq/ledger/pkg/bus" - "github.com/formancehq/ledger/pkg/core" + ledgerevents "github.com/formancehq/ledger/pkg/events" "github.com/formancehq/stack/libs/events" . "github.com/formancehq/stack/tests/integration/internal" "github.com/nats-io/nats.go" @@ -64,7 +63,7 @@ var _ = Given("some empty environment", func() { TestContext(), operations.RevertTransactionRequest{ Ledger: "default", - Txid: createTransactionResponse.Data.Txid, + ID: createTransactionResponse.Data.ID, }, ) Expect(err).To(Succeed()) @@ -73,20 +72,20 @@ var _ = Given("some empty environment", func() { It("should trigger a new event", func() { // Wait for created transaction event msg := WaitOnChanWithTimeout(msgs, 5*time.Second) - Expect(events.Check(msg.Data, "ledger", bus.EventTypeRevertedTransaction)).Should(Succeed()) + Expect(events.Check(msg.Data, "ledger", ledgerevents.EventTypeRevertedTransaction)).Should(Succeed()) }) - It("should set a metadata on the original transaction", func() { + It("should revert the original transaction", func() { response, err := Client().Ledger.GetTransaction( TestContext(), operations.GetTransactionRequest{ Ledger: "default", - Txid: createTransactionResponse.Data.Txid, + ID: createTransactionResponse.Data.ID, }, ) - Expect(err).To(Succeed()) + Expect(err).NotTo(HaveOccurred()) Expect(response.StatusCode).To(Equal(200)) - Expect(core.IsReverted(response.GetTransactionResponse.Data.Metadata)).To(BeTrue()) + Expect(response.GetTransactionResponse.Data.Reverted).To(BeTrue()) }) Then("trying to revert again", func() { It("should be rejected", func() { @@ -94,7 +93,7 @@ var _ = Given("some empty environment", func() { TestContext(), operations.RevertTransactionRequest{ Ledger: "default", - Txid: createTransactionResponse.Data.Txid, + ID: createTransactionResponse.Data.ID, }, ) Expect(err).To(BeNil()) diff --git a/tests/integration/suite/ledger-set-metadata-on-account.go b/tests/integration/suite/ledger-set-metadata-on-account.go index 0e5e4ea69..2b0b37453 100644 --- a/tests/integration/suite/ledger-set-metadata-on-account.go +++ b/tests/integration/suite/ledger-set-metadata-on-account.go @@ -1,13 +1,12 @@ package suite import ( - "math/big" "reflect" "time" "github.com/formancehq/formance-sdk-go/pkg/models/operations" "github.com/formancehq/formance-sdk-go/pkg/models/shared" - "github.com/formancehq/ledger/pkg/bus" + ledgerevents "github.com/formancehq/ledger/pkg/events" "github.com/formancehq/stack/libs/events" . "github.com/formancehq/stack/tests/integration/internal" "github.com/nats-io/nats.go" @@ -56,15 +55,13 @@ var _ = Given("some empty environment", func() { Expect(response.AccountResponse.Data).Should(Equal(shared.AccountWithVolumesAndBalances{ Address: "foo", Metadata: metadata, - Volumes: map[string]map[string]*big.Int{}, - Balances: map[string]*big.Int{}, })) }) It("should trigger a new event", func() { msg := WaitOnChanWithTimeout(msgs, 5*time.Second) - Expect(events.Check(msg.Data, "ledger", bus.EventTypeSavedMetadata)).Should(Succeed()) + Expect(events.Check(msg.Data, "ledger", ledgerevents.EventTypeSavedMetadata)).Should(Succeed()) }) - It("should pop an account with the correct metadata on search service", func() { + FIt("should pop an account with the correct metadata on search service", func() { Eventually(func() bool { response, err := Client().Search.Search( TestContext(), diff --git a/tests/integration/suite/ledger-set-metadata-on-transaction.go b/tests/integration/suite/ledger-set-metadata-on-transaction.go index 6e86f61b3..4bd3020a3 100644 --- a/tests/integration/suite/ledger-set-metadata-on-transaction.go +++ b/tests/integration/suite/ledger-set-metadata-on-transaction.go @@ -47,7 +47,7 @@ var _ = Given("some empty environment", func() { TestContext(), operations.GetTransactionRequest{ Ledger: "default", - Txid: rsp.Data.Txid, + ID: rsp.Data.ID, }, ) Expect(err).ToNot(HaveOccurred()) @@ -63,7 +63,7 @@ var _ = Given("some empty environment", func() { operations.AddMetadataOnTransactionRequest{ RequestBody: metadata, Ledger: "default", - Txid: 666, + ID: 666, }, ) Expect(err).ToNot(HaveOccurred()) @@ -79,19 +79,19 @@ var _ = Given("some empty environment", func() { operations.AddMetadataOnTransactionRequest{ RequestBody: metadata, Ledger: "default", - Txid: rsp.Data.Txid, + ID: rsp.Data.ID, }, ) Expect(err).To(Succeed()) Expect(response.StatusCode).To(Equal(204)) }) - It("should eventually be available on api", func() { + It("should be available on api", func() { // Check existence on api response, err := Client().Ledger.GetTransaction( TestContext(), operations.GetTransactionRequest{ Ledger: "default", - Txid: rsp.Data.Txid, + ID: rsp.Data.ID, }, ) Expect(err).ToNot(HaveOccurred()) diff --git a/tests/integration/suite/orchestration-workflows-execute.go b/tests/integration/suite/orchestration-workflows-execute.go index 157f072ae..79af1d5e8 100644 --- a/tests/integration/suite/orchestration-workflows-execute.go +++ b/tests/integration/suite/orchestration-workflows-execute.go @@ -102,28 +102,28 @@ var _ = Given("An empty environment", func() { Expect(instanceResponse.Data.TerminatedAt).NotTo(BeZero()) Expect(instanceResponse.Data.Status).To(HaveLen(1)) }) - Then("checking ledger account balance", func() { - var balancesCursorResponse *shared.BalancesCursorResponse - BeforeEach(func() { - reponse, err := Client().Ledger.GetBalances( - TestContext(), - operations.GetBalancesRequest{ - Address: ptr("bank"), - Ledger: "default", - }, - ) - Expect(err).ToNot(HaveOccurred()) - Expect(reponse.StatusCode).To(Equal(200)) - - balancesCursorResponse = reponse.BalancesCursorResponse - }) - It("should return 100 USD/2 available", func() { - Expect(balancesCursorResponse.Cursor.Data).To(HaveLen(1)) - Expect(balancesCursorResponse.Cursor.Data[0]).To(HaveLen(1)) - Expect(balancesCursorResponse.Cursor.Data[0]["bank"]).To(HaveLen(1)) - Expect(balancesCursorResponse.Cursor.Data[0]["bank"]["EUR/2"]).To(Equal(big.NewInt(100))) - }) - }) + //Then("checking ledger account balance", func() { + // var balancesCursorResponse *shared.BalancesCursorResponse + // BeforeEach(func() { + // reponse, err := Client().Ledger.GetBalances( + // TestContext(), + // operations.GetBalancesRequest{ + // Address: ptr("bank"), + // Ledger: "default", + // }, + // ) + // Expect(err).ToNot(HaveOccurred()) + // Expect(reponse.StatusCode).To(Equal(200)) + // + // balancesCursorResponse = reponse.BalancesCursorResponse + // }) + // It("should return 100 USD/2 available", func() { + // Expect(balancesCursorResponse.Cursor.Data).To(HaveLen(1)) + // Expect(balancesCursorResponse.Cursor.Data[0]).To(HaveLen(1)) + // Expect(balancesCursorResponse.Cursor.Data[0]["bank"]).To(HaveLen(1)) + // Expect(balancesCursorResponse.Cursor.Data[0]["bank"]["EUR/2"]).To(Equal(big.NewInt(100))) + // }) + //}) Then("reading history", func() { var getWorkflowInstanceHistoryResponse *shared.GetWorkflowInstanceHistoryResponse BeforeEach(func() {